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