2 * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 RCSID("$Id: sl.c,v 1.29 2001/02/20 01:44:55 assar Exp $");
43 print_sl (FILE *stream, int mdoc, int longp, SL_cmd *c)
44 __attribute__ ((unused));
47 print_sl (FILE *stream, int mdoc, int longp, SL_cmd *c)
51 fprintf(stream, "= Ns");
52 fprintf(stream, " Ar ");
63 mandoc_template(SL_cmd *cmds,
64 const char *extra_string)
67 char timestr[64], cmd[64];
71 printf(".\\\" Things to fix:\n");
72 printf(".\\\" * correct section, and operating system\n");
73 printf(".\\\" * remove Op from mandatory flags\n");
74 printf(".\\\" * use better macros for arguments (like .Pa for files)\n");
77 strftime(timestr, sizeof(timestr), "%b %d, %Y", localtime(&t));
78 printf(".Dd %s\n", timestr);
79 p = strrchr(getprogname(), '/');
80 if(p) p++; else p = getprogname();
81 strncpy(cmd, p, sizeof(cmd));
82 cmd[sizeof(cmd)-1] = '\0';
85 printf(".Dt %s SECTION\n", cmd);
86 printf(".Os OPERATING_SYSTEM\n");
88 printf(".Nm %s\n", p);
90 printf("in search of a description\n");
91 printf(".Sh SYNOPSIS\n");
93 for(c = cmds; c->name; ++c) {
94 /* if (c->func == NULL)
96 printf(".Op Fl %s", c->name);
97 /* print_sl(stdout, 1, 0, c);*/
101 if (extra_string && *extra_string)
102 printf (".Ar %s\n", extra_string);
103 printf(".Sh DESCRIPTION\n");
104 printf("Supported options:\n");
105 printf(".Bl -tag -width Ds\n");
107 for(c = cmds; c->name; ++c) {
110 printf ("\n%s\n", prev->usage);
112 printf (".It Fl %s", c->name);
115 printf (", %s\n", c->name);
118 printf ("\n%s\n", prev->usage);
121 printf(".\\\".Sh ENVIRONMENT\n");
122 printf(".\\\".Sh FILES\n");
123 printf(".\\\".Sh EXAMPLES\n");
124 printf(".\\\".Sh DIAGNOSTICS\n");
125 printf(".\\\".Sh SEE ALSO\n");
126 printf(".\\\".Sh STANDARDS\n");
127 printf(".\\\".Sh HISTORY\n");
128 printf(".\\\".Sh AUTHORS\n");
129 printf(".\\\".Sh BUGS\n");
133 sl_match (SL_cmd *cmds, char *cmd, int exactp)
135 SL_cmd *c, *current = NULL, *partial_cmd = NULL;
136 int partial_match = 0;
138 for (c = cmds; c->name; ++c) {
141 if (strcmp (cmd, c->name) == 0)
143 else if (strncmp (cmd, c->name, strlen(cmd)) == 0 &&
144 partial_cmd != current) {
146 partial_cmd = current;
149 if (partial_match == 1 && !exactp)
156 sl_help (SL_cmd *cmds, int argc, char **argv)
160 if (getenv("SLMANDOC")) {
161 mandoc_template(cmds, NULL);
167 for (c = cmds; c->name; ++c) {
170 printf ("\n\t%s%s", prev_c->usage ? prev_c->usage : "",
171 prev_c->usage ? "\n" : "");
173 printf ("%s", c->name);
175 printf (", %s", c->name);
178 printf ("\n\t%s%s", prev_c->usage ? prev_c->usage : "",
179 prev_c->usage ? "\n" : "");
181 c = sl_match (cmds, argv[1], 0);
183 printf ("No such command: %s. "
184 "Try \"help\" for a list of all commands\n",
187 printf ("%s\t%s\n", c->name, c->usage);
188 if(c->help && *c->help)
189 printf ("%s\n", c->help);
190 if((++c)->name && c->func == NULL) {
191 printf ("Synonyms:");
192 while (c->name && c->func == NULL)
193 printf ("\t%s", (c++)->name);
202 char *readline(char *prompt);
203 void add_history(char *p);
208 readline(char *prompt)
211 printf ("%s", prompt);
213 if(fgets(buf, sizeof(buf), stdin) == NULL)
215 if (buf[strlen(buf) - 1] == '\n')
216 buf[strlen(buf) - 1] = '\0';
228 sl_command(SL_cmd *cmds, int argc, char **argv)
231 c = sl_match (cmds, argv[0], 0);
234 return (*c->func)(argc, argv);
243 sl_make_argv(char *line, int *ret_argc, char ***ret_argv)
251 argv = malloc(nargv * sizeof(*argv));
256 for(p = strtok_r (line, " \t", &foo);
258 p = strtok_r (NULL, " \t", &foo)) {
259 if(argc == nargv - 1) {
262 tmp = realloc (argv, nargv * sizeof(*argv));
277 static jmp_buf sl_jmp;
279 static void sl_sigint(int sig)
284 static char *sl_readline(const char *prompt)
288 old = signal(SIGINT, sl_sigint);
291 s = readline((char*)prompt);
296 /* return values: 0 on success, -1 on fatal error, or return value of command */
298 sl_command_loop(SL_cmd *cmds, const char *prompt, void **data)
306 buf = sl_readline(prompt);
312 ret = sl_make_argv(buf, &argc, &argv);
314 fprintf(stderr, "sl_loop: out of memory\n");
319 ret = sl_command(cmds, argc, argv);
321 printf ("Unrecognized command: %s\n", argv[0]);
331 sl_loop(SL_cmd *cmds, const char *prompt)
335 while((ret = sl_command_loop(cmds, prompt, &data)) == 0)
341 sl_apropos (SL_cmd *cmd, const char *topic)
343 for (; cmd->name != NULL; ++cmd)
344 if (cmd->usage != NULL && strstr(cmd->usage, topic) != NULL)
345 printf ("%-20s%s\n", cmd->name, cmd->usage);