xref: /titanic_41/usr/src/lib/krb5/ss/parse.c (revision 56a424cca6b3f91f31bdab72a4626c48c779fe8b)
17c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
27c478bd9Sstevel@tonic-gate 
37c478bd9Sstevel@tonic-gate /*
47c478bd9Sstevel@tonic-gate  * Copyright 1987, 1988 by MIT Student Information Processing Board
57c478bd9Sstevel@tonic-gate  *
67c478bd9Sstevel@tonic-gate  * For copyright info, see copyright.h.
77c478bd9Sstevel@tonic-gate  */
87c478bd9Sstevel@tonic-gate 
97c478bd9Sstevel@tonic-gate #include "ss_internal.h"
107c478bd9Sstevel@tonic-gate #include "copyright.h"
11*56a424ccSmp153739 #include <errno.h>
127c478bd9Sstevel@tonic-gate 
137c478bd9Sstevel@tonic-gate enum parse_mode { WHITESPACE, TOKEN, QUOTED_STRING };
147c478bd9Sstevel@tonic-gate 
157c478bd9Sstevel@tonic-gate /*
167c478bd9Sstevel@tonic-gate  * parse(line_ptr, argc_ptr)
177c478bd9Sstevel@tonic-gate  *
187c478bd9Sstevel@tonic-gate  * Function:
197c478bd9Sstevel@tonic-gate  *      Parses line, dividing at whitespace, into tokens, returns
207c478bd9Sstevel@tonic-gate  *      the "argc" and "argv" values.
217c478bd9Sstevel@tonic-gate  * Arguments:
227c478bd9Sstevel@tonic-gate  *      line_ptr (char *)
237c478bd9Sstevel@tonic-gate  *              Pointer to text string to be parsed.
247c478bd9Sstevel@tonic-gate  *      argc_ptr (int *)
257c478bd9Sstevel@tonic-gate  *              Where to put the "argc" (number of tokens) value.
267c478bd9Sstevel@tonic-gate  * Returns:
277c478bd9Sstevel@tonic-gate  *      argv (char **)
287c478bd9Sstevel@tonic-gate  *              Series of pointers to parsed tokens.
297c478bd9Sstevel@tonic-gate  */
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #define NEW_ARGV(old,n) (char **)realloc((char *)old,\
327c478bd9Sstevel@tonic-gate 					 (unsigned)(n+2)*sizeof(char*))
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate char **ss_parse (sci_idx, line_ptr, argc_ptr)
357c478bd9Sstevel@tonic-gate     int sci_idx;
367c478bd9Sstevel@tonic-gate     register char *line_ptr;
377c478bd9Sstevel@tonic-gate     int *argc_ptr;
387c478bd9Sstevel@tonic-gate {
397c478bd9Sstevel@tonic-gate     register char **argv, *cp;
407c478bd9Sstevel@tonic-gate     register int argc;
417c478bd9Sstevel@tonic-gate     register enum parse_mode parse_mode;
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate     argv = (char **) malloc (sizeof(char *));
447c478bd9Sstevel@tonic-gate     if (argv == (char **)NULL) {
457c478bd9Sstevel@tonic-gate 	ss_error(sci_idx, errno, "Can't allocate storage");
467c478bd9Sstevel@tonic-gate 	*argc_ptr = 0;
477c478bd9Sstevel@tonic-gate 	return(argv);
487c478bd9Sstevel@tonic-gate     }
497c478bd9Sstevel@tonic-gate     *argv = (char *)NULL;
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate     argc = 0;
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate     parse_mode = WHITESPACE;	/* flushing whitespace */
547c478bd9Sstevel@tonic-gate     cp = line_ptr;		/* cp is for output */
557c478bd9Sstevel@tonic-gate     while (1) {
567c478bd9Sstevel@tonic-gate #ifdef DEBUG
577c478bd9Sstevel@tonic-gate 	{
58*56a424ccSmp153739 	    printf ("character `%c', mode %d\n", *line_ptr, parse_mode);
597c478bd9Sstevel@tonic-gate 	}
607c478bd9Sstevel@tonic-gate #endif
617c478bd9Sstevel@tonic-gate 	while (parse_mode == WHITESPACE) {
627c478bd9Sstevel@tonic-gate 	    if (*line_ptr == '\0')
637c478bd9Sstevel@tonic-gate 		goto end_of_line;
647c478bd9Sstevel@tonic-gate 	    if (*line_ptr == ' ' || *line_ptr == '\t') {
657c478bd9Sstevel@tonic-gate 		line_ptr++;
667c478bd9Sstevel@tonic-gate 		continue;
677c478bd9Sstevel@tonic-gate 	    }
687c478bd9Sstevel@tonic-gate 	    if (*line_ptr == '"') {
697c478bd9Sstevel@tonic-gate 		/* go to quoted-string mode */
707c478bd9Sstevel@tonic-gate 		parse_mode = QUOTED_STRING;
717c478bd9Sstevel@tonic-gate 		cp = line_ptr++;
727c478bd9Sstevel@tonic-gate 		argv = NEW_ARGV (argv, argc);
737c478bd9Sstevel@tonic-gate 		argv[argc++] = cp;
747c478bd9Sstevel@tonic-gate 		argv[argc] = NULL;
757c478bd9Sstevel@tonic-gate 	    }
767c478bd9Sstevel@tonic-gate 	    else {
777c478bd9Sstevel@tonic-gate 		/* random-token mode */
787c478bd9Sstevel@tonic-gate 		parse_mode = TOKEN;
797c478bd9Sstevel@tonic-gate 		cp = line_ptr;
807c478bd9Sstevel@tonic-gate 		argv = NEW_ARGV (argv, argc);
817c478bd9Sstevel@tonic-gate 		argv[argc++] = line_ptr;
827c478bd9Sstevel@tonic-gate 		argv[argc] = NULL;
837c478bd9Sstevel@tonic-gate 	    }
847c478bd9Sstevel@tonic-gate 	}
857c478bd9Sstevel@tonic-gate 	while (parse_mode == TOKEN) {
867c478bd9Sstevel@tonic-gate 	    if (*line_ptr == '\0') {
877c478bd9Sstevel@tonic-gate 		*cp++ = '\0';
887c478bd9Sstevel@tonic-gate 		goto end_of_line;
897c478bd9Sstevel@tonic-gate 	    }
907c478bd9Sstevel@tonic-gate 	    else if (*line_ptr == ' ' || *line_ptr == '\t') {
917c478bd9Sstevel@tonic-gate 		*cp++ = '\0';
927c478bd9Sstevel@tonic-gate 		line_ptr++;
937c478bd9Sstevel@tonic-gate 		parse_mode = WHITESPACE;
947c478bd9Sstevel@tonic-gate 	    }
957c478bd9Sstevel@tonic-gate 	    else if (*line_ptr == '"') {
967c478bd9Sstevel@tonic-gate 		line_ptr++;
977c478bd9Sstevel@tonic-gate 		parse_mode = QUOTED_STRING;
987c478bd9Sstevel@tonic-gate 	    }
997c478bd9Sstevel@tonic-gate 	    else {
1007c478bd9Sstevel@tonic-gate 		*cp++ = *line_ptr++;
1017c478bd9Sstevel@tonic-gate 	    }
1027c478bd9Sstevel@tonic-gate 	}
1037c478bd9Sstevel@tonic-gate 	while (parse_mode == QUOTED_STRING) {
1047c478bd9Sstevel@tonic-gate 	    if (*line_ptr == '\0') {
1057c478bd9Sstevel@tonic-gate 		ss_error (sci_idx, 0,
1067c478bd9Sstevel@tonic-gate 			  "Unbalanced quotes in command line");
1077c478bd9Sstevel@tonic-gate 		free (argv);
1087c478bd9Sstevel@tonic-gate 		*argc_ptr = 0;
1097c478bd9Sstevel@tonic-gate 		return NULL;
1107c478bd9Sstevel@tonic-gate 	    }
1117c478bd9Sstevel@tonic-gate 	    else if (*line_ptr == '"') {
1127c478bd9Sstevel@tonic-gate 		if (*++line_ptr == '"') {
1137c478bd9Sstevel@tonic-gate 		    *cp++ = '"';
1147c478bd9Sstevel@tonic-gate 		    line_ptr++;
1157c478bd9Sstevel@tonic-gate 		}
1167c478bd9Sstevel@tonic-gate 		else {
1177c478bd9Sstevel@tonic-gate 		    parse_mode = TOKEN;
1187c478bd9Sstevel@tonic-gate 		}
1197c478bd9Sstevel@tonic-gate 	    }
1207c478bd9Sstevel@tonic-gate 	    else {
1217c478bd9Sstevel@tonic-gate 		*cp++ = *line_ptr++;
1227c478bd9Sstevel@tonic-gate 	    }
1237c478bd9Sstevel@tonic-gate 	}
1247c478bd9Sstevel@tonic-gate     }
1257c478bd9Sstevel@tonic-gate end_of_line:
1267c478bd9Sstevel@tonic-gate     *argc_ptr = argc;
1277c478bd9Sstevel@tonic-gate #ifdef DEBUG
1287c478bd9Sstevel@tonic-gate     {
1297c478bd9Sstevel@tonic-gate 	int i;
1307c478bd9Sstevel@tonic-gate 	printf ("argc = %d\n", argc);
1317c478bd9Sstevel@tonic-gate 	for (i = 0; i <= argc; i++)
1327c478bd9Sstevel@tonic-gate 	    printf ("\targv[%2d] = `%s'\n", i,
1337c478bd9Sstevel@tonic-gate 		    argv[i] ? argv[i] : "<NULL>");
1347c478bd9Sstevel@tonic-gate     }
1357c478bd9Sstevel@tonic-gate #endif
1367c478bd9Sstevel@tonic-gate     return(argv);
1377c478bd9Sstevel@tonic-gate }
138