xref: /illumos-gate/usr/src/lib/krb5/ss/parse.c (revision a5f69788de7ac07553de47f7fec8c05a9a94c105)
1 #pragma ident	"%Z%%M%	%I%	%E% SMI"
2 
3 /*
4  * Copyright 1987, 1988 by MIT Student Information Processing Board
5  *
6  * For copyright info, see copyright.h.
7  */
8 
9 #include "ss_internal.h"
10 #include "copyright.h"
11 
12 /* global indicating if we should be printing debug messages */
13 extern int g_displayDebugSS;
14 
15 
16 enum parse_mode { WHITESPACE, TOKEN, QUOTED_STRING };
17 
18 /*
19  * parse(line_ptr, argc_ptr)
20  *
21  * Function:
22  *      Parses line, dividing at whitespace, into tokens, returns
23  *      the "argc" and "argv" values.
24  * Arguments:
25  *      line_ptr (char *)
26  *              Pointer to text string to be parsed.
27  *      argc_ptr (int *)
28  *              Where to put the "argc" (number of tokens) value.
29  * Returns:
30  *      argv (char **)
31  *              Series of pointers to parsed tokens.
32  */
33 
34 #define NEW_ARGV(old,n) (char **)realloc((char *)old,\
35 					 (unsigned)(n+2)*sizeof(char*))
36 
37 char **ss_parse (sci_idx, line_ptr, argc_ptr)
38     int sci_idx;
39     register char *line_ptr;
40     int *argc_ptr;
41 {
42     register char **argv, *cp;
43     register int argc;
44     register enum parse_mode parse_mode;
45 
46     argv = (char **) malloc (sizeof(char *));
47     if (argv == (char **)NULL) {
48 	ss_error(sci_idx, errno, "Can't allocate storage");
49 	*argc_ptr = 0;
50 	return(argv);
51     }
52     *argv = (char *)NULL;
53 
54     argc = 0;
55 
56     parse_mode = WHITESPACE;	/* flushing whitespace */
57     cp = line_ptr;		/* cp is for output */
58     while (1) {
59 #ifdef DEBUG
60 	{
61 		if (g_displayDebugSS)
62 			printf ("character `%c', mode %d\n",
63 				*line_ptr, parse_mode);
64 	}
65 #endif
66 	while (parse_mode == WHITESPACE) {
67 	    if (*line_ptr == '\0')
68 		goto end_of_line;
69 	    if (*line_ptr == ' ' || *line_ptr == '\t') {
70 		line_ptr++;
71 		continue;
72 	    }
73 	    if (*line_ptr == '"') {
74 		/* go to quoted-string mode */
75 		parse_mode = QUOTED_STRING;
76 		cp = line_ptr++;
77 		argv = NEW_ARGV (argv, argc);
78 		argv[argc++] = cp;
79 		argv[argc] = NULL;
80 	    }
81 	    else {
82 		/* random-token mode */
83 		parse_mode = TOKEN;
84 		cp = line_ptr;
85 		argv = NEW_ARGV (argv, argc);
86 		argv[argc++] = line_ptr;
87 		argv[argc] = NULL;
88 	    }
89 	}
90 	while (parse_mode == TOKEN) {
91 	    if (*line_ptr == '\0') {
92 		*cp++ = '\0';
93 		goto end_of_line;
94 	    }
95 	    else if (*line_ptr == ' ' || *line_ptr == '\t') {
96 		*cp++ = '\0';
97 		line_ptr++;
98 		parse_mode = WHITESPACE;
99 	    }
100 	    else if (*line_ptr == '"') {
101 		line_ptr++;
102 		parse_mode = QUOTED_STRING;
103 	    }
104 	    else {
105 		*cp++ = *line_ptr++;
106 	    }
107 	}
108 	while (parse_mode == QUOTED_STRING) {
109 	    if (*line_ptr == '\0') {
110 		ss_error (sci_idx, 0,
111 			  "Unbalanced quotes in command line");
112 		free (argv);
113 		*argc_ptr = 0;
114 		return NULL;
115 	    }
116 	    else if (*line_ptr == '"') {
117 		if (*++line_ptr == '"') {
118 		    *cp++ = '"';
119 		    line_ptr++;
120 		}
121 		else {
122 		    parse_mode = TOKEN;
123 		}
124 	    }
125 	    else {
126 		*cp++ = *line_ptr++;
127 	    }
128 	}
129     }
130 end_of_line:
131     *argc_ptr = argc;
132 #ifdef DEBUG
133 
134 	if (g_displayDebugSS)
135     	{
136 		int i;
137 		printf ("argc = %d\n", argc);
138 		for (i = 0; i <= argc; i++)
139 	    		printf ("\targv[%2d] = `%s'\n", i,
140 		    		argv[i] ? argv[i] : "<NULL>");
141     	}
142 #endif
143     return(argv);
144 }
145