Remove building with NOCRYPTO option
[minix.git] / crypto / external / bsd / heimdal / dist / lib / sl / sl.c
bloba23014c0c458b461a6500128ff76e998cabdfb74
1 /* $NetBSD: sl.c,v 1.1.1.2 2014/04/24 12:45:53 pettai Exp $ */
3 /*
4 * Copyright (c) 1995 - 2006 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
36 #include <config.h>
38 #include "sl_locl.h"
39 #include <setjmp.h>
41 static void
42 mandoc_template(SL_cmd *cmds,
43 const char *extra_string)
45 SL_cmd *c, *prev;
46 char timestr[64], cmd[64];
47 const char *p;
48 time_t t;
50 printf(".\\\" Things to fix:\n");
51 printf(".\\\" * correct section, and operating system\n");
52 printf(".\\\" * remove Op from mandatory flags\n");
53 printf(".\\\" * use better macros for arguments (like .Pa for files)\n");
54 printf(".\\\"\n");
55 t = time(NULL);
56 strftime(timestr, sizeof(timestr), "%b %d, %Y", localtime(&t));
57 printf(".Dd %s\n", timestr);
58 p = strrchr(getprogname(), '/');
59 if(p) p++; else p = getprogname();
60 strncpy(cmd, p, sizeof(cmd));
61 cmd[sizeof(cmd)-1] = '\0';
62 strupr(cmd);
64 printf(".Dt %s SECTION\n", cmd);
65 printf(".Os OPERATING_SYSTEM\n");
66 printf(".Sh NAME\n");
67 printf(".Nm %s\n", p);
68 printf(".Nd\n");
69 printf("in search of a description\n");
70 printf(".Sh SYNOPSIS\n");
71 printf(".Nm\n");
72 for(c = cmds; c->name; ++c) {
73 /* if (c->func == NULL)
74 continue; */
75 printf(".Op Fl %s", c->name);
76 printf("\n");
79 if (extra_string && *extra_string)
80 printf (".Ar %s\n", extra_string);
81 printf(".Sh DESCRIPTION\n");
82 printf("Supported options:\n");
83 printf(".Bl -tag -width Ds\n");
84 prev = NULL;
85 for(c = cmds; c->name; ++c) {
86 if (c->func) {
87 if (prev)
88 printf ("\n%s\n", prev->usage);
90 printf (".It Fl %s", c->name);
91 prev = c;
92 } else
93 printf (", %s\n", c->name);
95 if (prev)
96 printf ("\n%s\n", prev->usage);
98 printf(".El\n");
99 printf(".\\\".Sh ENVIRONMENT\n");
100 printf(".\\\".Sh FILES\n");
101 printf(".\\\".Sh EXAMPLES\n");
102 printf(".\\\".Sh DIAGNOSTICS\n");
103 printf(".\\\".Sh SEE ALSO\n");
104 printf(".\\\".Sh STANDARDS\n");
105 printf(".\\\".Sh HISTORY\n");
106 printf(".\\\".Sh AUTHORS\n");
107 printf(".\\\".Sh BUGS\n");
110 SL_cmd *
111 sl_match (SL_cmd *cmds, char *cmd, int exactp)
113 SL_cmd *c, *current = NULL, *partial_cmd = NULL;
114 int partial_match = 0;
116 for (c = cmds; c->name; ++c) {
117 if (c->func)
118 current = c;
119 if (strcmp (cmd, c->name) == 0)
120 return current;
121 else if (strncmp (cmd, c->name, strlen(cmd)) == 0 &&
122 partial_cmd != current) {
123 ++partial_match;
124 partial_cmd = current;
127 if (partial_match == 1 && !exactp)
128 return partial_cmd;
129 else
130 return NULL;
133 void
134 sl_help (SL_cmd *cmds, int argc, char **argv)
136 SL_cmd *c, *prev_c;
138 if (getenv("SLMANDOC")) {
139 mandoc_template(cmds, NULL);
140 return;
143 if (argc == 1) {
144 prev_c = NULL;
145 for (c = cmds; c->name; ++c) {
146 if (c->func) {
147 if(prev_c)
148 printf ("\n\t%s%s", prev_c->usage ? prev_c->usage : "",
149 prev_c->usage ? "\n" : "");
150 prev_c = c;
151 printf ("%s", c->name);
152 } else
153 printf (", %s", c->name);
155 if(prev_c)
156 printf ("\n\t%s%s", prev_c->usage ? prev_c->usage : "",
157 prev_c->usage ? "\n" : "");
158 } else {
159 c = sl_match (cmds, argv[1], 0);
160 if (c == NULL)
161 printf ("No such command: %s. "
162 "Try \"help\" for a list of all commands\n",
163 argv[1]);
164 else {
165 printf ("%s\t%s\n", c->name, c->usage);
166 if(c->help && *c->help)
167 printf ("%s\n", c->help);
168 if((++c)->name && c->func == NULL) {
169 printf ("Synonyms:");
170 while (c->name && c->func == NULL)
171 printf ("\t%s", (c++)->name);
172 printf ("\n");
178 #ifdef HAVE_READLINE
180 char *readline(char *prompt);
181 void add_history(char *p);
183 #else
185 static char *
186 readline(char *prompt)
188 char buf[BUFSIZ];
189 printf ("%s", prompt);
190 fflush (stdout);
191 if(fgets(buf, sizeof(buf), stdin) == NULL)
192 return NULL;
193 buf[strcspn(buf, "\r\n")] = '\0';
194 return strdup(buf);
197 static void
198 add_history(char *p)
202 #endif
205 sl_command(SL_cmd *cmds, int argc, char **argv)
207 SL_cmd *c;
208 c = sl_match (cmds, argv[0], 0);
209 if (c == NULL)
210 return -1;
211 return (*c->func)(argc, argv);
214 struct sl_data {
215 int max_count;
216 char **ptr;
220 sl_make_argv(char *line, int *ret_argc, char ***ret_argv)
222 char *p, *begining;
223 int argc, nargv;
224 char **argv;
225 int quote = 0;
227 nargv = 10;
228 argv = malloc(nargv * sizeof(*argv));
229 if(argv == NULL)
230 return ENOMEM;
231 argc = 0;
233 p = line;
235 while(isspace((unsigned char)*p))
236 p++;
237 begining = p;
239 while (1) {
240 if (*p == '\0') {
242 } else if (*p == '"') {
243 quote = !quote;
244 memmove(&p[0], &p[1], strlen(&p[1]) + 1);
245 continue;
246 } else if (*p == '\\') {
247 if (p[1] == '\0')
248 goto failed;
249 memmove(&p[0], &p[1], strlen(&p[1]) + 1);
250 p += 2;
251 continue;
252 } else if (quote || !isspace((unsigned char)*p)) {
253 p++;
254 continue;
255 } else
256 *p++ = '\0';
257 if (quote)
258 goto failed;
259 if(argc == nargv - 1) {
260 char **tmp;
261 nargv *= 2;
262 tmp = realloc (argv, nargv * sizeof(*argv));
263 if (tmp == NULL) {
264 free(argv);
265 return ENOMEM;
267 argv = tmp;
269 argv[argc++] = begining;
270 while(isspace((unsigned char)*p))
271 p++;
272 if (*p == '\0')
273 break;
274 begining = p;
276 argv[argc] = NULL;
277 *ret_argc = argc;
278 *ret_argv = argv;
279 return 0;
280 failed:
281 free(argv);
282 return ERANGE;
285 static jmp_buf sl_jmp;
287 static void sl_sigint(int sig)
289 longjmp(sl_jmp, 1);
292 static char *sl_readline(const char *prompt)
294 char *s;
295 void (*old)(int);
296 old = signal(SIGINT, sl_sigint);
297 if(setjmp(sl_jmp))
298 printf("\n");
299 s = readline(rk_UNCONST(prompt));
300 signal(SIGINT, old);
301 return s;
304 /* return values:
305 * 0 on success,
306 * -1 on fatal error,
307 * -2 if EOF, or
308 * return value of command */
310 sl_command_loop(SL_cmd *cmds, const char *prompt, void **data)
312 int ret = 0;
313 char *buf;
314 int argc;
315 char **argv;
317 buf = sl_readline(prompt);
318 if(buf == NULL)
319 return -2;
321 if(*buf)
322 add_history(buf);
323 ret = sl_make_argv(buf, &argc, &argv);
324 if(ret) {
325 fprintf(stderr, "sl_loop: out of memory\n");
326 free(buf);
327 return -1;
329 if (argc >= 1) {
330 ret = sl_command(cmds, argc, argv);
331 if(ret == -1) {
332 printf ("Unrecognized command: %s\n", argv[0]);
333 ret = 0;
336 free(buf);
337 free(argv);
338 return ret;
342 sl_loop(SL_cmd *cmds, const char *prompt)
344 void *data = NULL;
345 int ret;
346 while((ret = sl_command_loop(cmds, prompt, &data)) >= 0)
348 return ret;
351 void
352 sl_apropos (SL_cmd *cmd, const char *topic)
354 for (; cmd->name != NULL; ++cmd)
355 if (cmd->usage != NULL && strstr(cmd->usage, topic) != NULL)
356 printf ("%-20s%s\n", cmd->name, cmd->usage);
360 * Help to be used with slc.
363 void
364 sl_slc_help (SL_cmd *cmds, int argc, char **argv)
366 if(argc == 0) {
367 sl_help(cmds, 1, argv - 1 /* XXX */);
368 } else {
369 SL_cmd *c = sl_match (cmds, argv[0], 0);
370 if(c == NULL) {
371 fprintf (stderr, "No such command: %s. "
372 "Try \"help\" for a list of commands\n",
373 argv[0]);
374 } else {
375 if(c->func) {
376 static char help[] = "--help";
377 char *fake[3];
378 fake[0] = argv[0];
379 fake[1] = help;
380 fake[2] = NULL;
381 (*c->func)(2, fake);
382 fprintf(stderr, "\n");
384 if(c->help && *c->help)
385 fprintf (stderr, "%s\n", c->help);
386 if((++c)->name && c->func == NULL) {
387 int f = 0;
388 fprintf (stderr, "Synonyms:");
389 while (c->name && c->func == NULL) {
390 fprintf (stderr, "%s%s", f ? ", " : " ", (c++)->name);
391 f = 1;
393 fprintf (stderr, "\n");