1*7f2fe78bSCy Schubert /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2*7f2fe78bSCy Schubert /*
3*7f2fe78bSCy Schubert * Copyright 2007 Massachusetts Institute of Technology.
4*7f2fe78bSCy Schubert * All Rights Reserved.
5*7f2fe78bSCy Schubert *
6*7f2fe78bSCy Schubert * Export of this software from the United States of America may
7*7f2fe78bSCy Schubert * require a specific license from the United States Government.
8*7f2fe78bSCy Schubert * It is the responsibility of any person or organization contemplating
9*7f2fe78bSCy Schubert * export to obtain such a license before exporting.
10*7f2fe78bSCy Schubert *
11*7f2fe78bSCy Schubert * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12*7f2fe78bSCy Schubert * distribute this software and its documentation for any purpose and
13*7f2fe78bSCy Schubert * without fee is hereby granted, provided that the above copyright
14*7f2fe78bSCy Schubert * notice appear in all copies and that both that copyright notice and
15*7f2fe78bSCy Schubert * this permission notice appear in supporting documentation, and that
16*7f2fe78bSCy Schubert * the name of M.I.T. not be used in advertising or publicity pertaining
17*7f2fe78bSCy Schubert * to distribution of the software without specific, written prior
18*7f2fe78bSCy Schubert * permission. Furthermore if you modify this software you must label
19*7f2fe78bSCy Schubert * your software as modified software and not distribute it in such a
20*7f2fe78bSCy Schubert * fashion that it might be confused with the original M.I.T. software.
21*7f2fe78bSCy Schubert * M.I.T. makes no representations about the suitability of
22*7f2fe78bSCy Schubert * this software for any purpose. It is provided "as is" without express
23*7f2fe78bSCy Schubert * or implied warranty.
24*7f2fe78bSCy Schubert */
25*7f2fe78bSCy Schubert /*
26*7f2fe78bSCy Schubert * Copyright 1987, 1988 by MIT Student Information Processing Board
27*7f2fe78bSCy Schubert *
28*7f2fe78bSCy Schubert * For copyright info, see copyright.h.
29*7f2fe78bSCy Schubert */
30*7f2fe78bSCy Schubert
31*7f2fe78bSCy Schubert #include "ss_internal.h"
32*7f2fe78bSCy Schubert #include "copyright.h"
33*7f2fe78bSCy Schubert #include <errno.h>
34*7f2fe78bSCy Schubert
35*7f2fe78bSCy Schubert enum parse_mode { WHITESPACE, TOKEN, QUOTED_STRING };
36*7f2fe78bSCy Schubert
37*7f2fe78bSCy Schubert /*
38*7f2fe78bSCy Schubert * parse(line_ptr, argc_ptr)
39*7f2fe78bSCy Schubert *
40*7f2fe78bSCy Schubert * Function:
41*7f2fe78bSCy Schubert * Parses line, dividing at whitespace, into tokens, returns
42*7f2fe78bSCy Schubert * the "argc" and "argv" values.
43*7f2fe78bSCy Schubert * Arguments:
44*7f2fe78bSCy Schubert * line_ptr (char *)
45*7f2fe78bSCy Schubert * Pointer to text string to be parsed.
46*7f2fe78bSCy Schubert * argc_ptr (int *)
47*7f2fe78bSCy Schubert * Where to put the "argc" (number of tokens) value.
48*7f2fe78bSCy Schubert * Returns:
49*7f2fe78bSCy Schubert * argv (char **)
50*7f2fe78bSCy Schubert * Series of pointers to parsed tokens in the original string.
51*7f2fe78bSCy Schubert */
52*7f2fe78bSCy Schubert
53*7f2fe78bSCy Schubert #define NEW_ARGV(old,n) (char **)realloc((char *)old, \
54*7f2fe78bSCy Schubert (unsigned)(n+2)*sizeof(char*))
55*7f2fe78bSCy Schubert
ss_parse(sci_idx,line_ptr,argc_ptr)56*7f2fe78bSCy Schubert char **ss_parse (sci_idx, line_ptr, argc_ptr)
57*7f2fe78bSCy Schubert int sci_idx;
58*7f2fe78bSCy Schubert char *line_ptr;
59*7f2fe78bSCy Schubert int *argc_ptr;
60*7f2fe78bSCy Schubert {
61*7f2fe78bSCy Schubert char **argv, *cp;
62*7f2fe78bSCy Schubert char **newargv;
63*7f2fe78bSCy Schubert int argc;
64*7f2fe78bSCy Schubert enum parse_mode parse_mode;
65*7f2fe78bSCy Schubert
66*7f2fe78bSCy Schubert argv = (char **) malloc (sizeof(char *));
67*7f2fe78bSCy Schubert if (argv == (char **)NULL) {
68*7f2fe78bSCy Schubert ss_error(sci_idx, errno, "Can't allocate storage");
69*7f2fe78bSCy Schubert *argc_ptr = 0;
70*7f2fe78bSCy Schubert return(argv);
71*7f2fe78bSCy Schubert }
72*7f2fe78bSCy Schubert *argv = (char *)NULL;
73*7f2fe78bSCy Schubert
74*7f2fe78bSCy Schubert argc = 0;
75*7f2fe78bSCy Schubert
76*7f2fe78bSCy Schubert parse_mode = WHITESPACE; /* flushing whitespace */
77*7f2fe78bSCy Schubert cp = line_ptr; /* cp is for output */
78*7f2fe78bSCy Schubert while (1) {
79*7f2fe78bSCy Schubert #ifdef DEBUG
80*7f2fe78bSCy Schubert {
81*7f2fe78bSCy Schubert printf ("character `%c', mode %d\n", *line_ptr, parse_mode);
82*7f2fe78bSCy Schubert }
83*7f2fe78bSCy Schubert #endif
84*7f2fe78bSCy Schubert while (parse_mode == WHITESPACE) {
85*7f2fe78bSCy Schubert if (*line_ptr == '\0')
86*7f2fe78bSCy Schubert goto end_of_line;
87*7f2fe78bSCy Schubert if (*line_ptr == ' ' || *line_ptr == '\t') {
88*7f2fe78bSCy Schubert line_ptr++;
89*7f2fe78bSCy Schubert continue;
90*7f2fe78bSCy Schubert }
91*7f2fe78bSCy Schubert if (*line_ptr == '"') {
92*7f2fe78bSCy Schubert /* go to quoted-string mode */
93*7f2fe78bSCy Schubert parse_mode = QUOTED_STRING;
94*7f2fe78bSCy Schubert cp = line_ptr++;
95*7f2fe78bSCy Schubert newargv = NEW_ARGV (argv, argc);
96*7f2fe78bSCy Schubert if (newargv == NULL) {
97*7f2fe78bSCy Schubert out_of_mem_in_argv:
98*7f2fe78bSCy Schubert free(argv);
99*7f2fe78bSCy Schubert ss_error(sci_idx, errno, "Can't allocate storage");
100*7f2fe78bSCy Schubert *argc_ptr = 0;
101*7f2fe78bSCy Schubert return NULL;
102*7f2fe78bSCy Schubert }
103*7f2fe78bSCy Schubert argv = newargv;
104*7f2fe78bSCy Schubert argv[argc++] = cp;
105*7f2fe78bSCy Schubert argv[argc] = NULL;
106*7f2fe78bSCy Schubert }
107*7f2fe78bSCy Schubert else {
108*7f2fe78bSCy Schubert /* random-token mode */
109*7f2fe78bSCy Schubert parse_mode = TOKEN;
110*7f2fe78bSCy Schubert cp = line_ptr;
111*7f2fe78bSCy Schubert newargv = NEW_ARGV (argv, argc);
112*7f2fe78bSCy Schubert if (newargv == NULL)
113*7f2fe78bSCy Schubert goto out_of_mem_in_argv;
114*7f2fe78bSCy Schubert argv = newargv;
115*7f2fe78bSCy Schubert argv[argc++] = line_ptr;
116*7f2fe78bSCy Schubert argv[argc] = NULL;
117*7f2fe78bSCy Schubert }
118*7f2fe78bSCy Schubert }
119*7f2fe78bSCy Schubert while (parse_mode == TOKEN) {
120*7f2fe78bSCy Schubert if (*line_ptr == '\0') {
121*7f2fe78bSCy Schubert *cp++ = '\0';
122*7f2fe78bSCy Schubert goto end_of_line;
123*7f2fe78bSCy Schubert }
124*7f2fe78bSCy Schubert else if (*line_ptr == ' ' || *line_ptr == '\t') {
125*7f2fe78bSCy Schubert *cp++ = '\0';
126*7f2fe78bSCy Schubert line_ptr++;
127*7f2fe78bSCy Schubert parse_mode = WHITESPACE;
128*7f2fe78bSCy Schubert }
129*7f2fe78bSCy Schubert else if (*line_ptr == '"') {
130*7f2fe78bSCy Schubert line_ptr++;
131*7f2fe78bSCy Schubert parse_mode = QUOTED_STRING;
132*7f2fe78bSCy Schubert }
133*7f2fe78bSCy Schubert else {
134*7f2fe78bSCy Schubert *cp++ = *line_ptr++;
135*7f2fe78bSCy Schubert }
136*7f2fe78bSCy Schubert }
137*7f2fe78bSCy Schubert while (parse_mode == QUOTED_STRING) {
138*7f2fe78bSCy Schubert if (*line_ptr == '\0') {
139*7f2fe78bSCy Schubert ss_error (sci_idx, 0,
140*7f2fe78bSCy Schubert "Unbalanced quotes in command line");
141*7f2fe78bSCy Schubert free (argv);
142*7f2fe78bSCy Schubert *argc_ptr = 0;
143*7f2fe78bSCy Schubert return NULL;
144*7f2fe78bSCy Schubert }
145*7f2fe78bSCy Schubert else if (*line_ptr == '"') {
146*7f2fe78bSCy Schubert if (*++line_ptr == '"') {
147*7f2fe78bSCy Schubert *cp++ = '"';
148*7f2fe78bSCy Schubert line_ptr++;
149*7f2fe78bSCy Schubert }
150*7f2fe78bSCy Schubert else {
151*7f2fe78bSCy Schubert parse_mode = TOKEN;
152*7f2fe78bSCy Schubert }
153*7f2fe78bSCy Schubert }
154*7f2fe78bSCy Schubert else {
155*7f2fe78bSCy Schubert *cp++ = *line_ptr++;
156*7f2fe78bSCy Schubert }
157*7f2fe78bSCy Schubert }
158*7f2fe78bSCy Schubert }
159*7f2fe78bSCy Schubert end_of_line:
160*7f2fe78bSCy Schubert *argc_ptr = argc;
161*7f2fe78bSCy Schubert #ifdef DEBUG
162*7f2fe78bSCy Schubert {
163*7f2fe78bSCy Schubert int i;
164*7f2fe78bSCy Schubert printf ("argc = %d\n", argc);
165*7f2fe78bSCy Schubert for (i = 0; i <= argc; i++)
166*7f2fe78bSCy Schubert printf ("\targv[%2d] = `%s'\n", i,
167*7f2fe78bSCy Schubert argv[i] ? argv[i] : "<NULL>");
168*7f2fe78bSCy Schubert }
169*7f2fe78bSCy Schubert #endif
170*7f2fe78bSCy Schubert return(argv);
171*7f2fe78bSCy Schubert }
172