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