/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Copyright 1987, 1988 by MIT Student Information Processing Board * * For copyright info, see copyright.h. */ #include "ss_internal.h" #include "copyright.h" #include enum parse_mode { WHITESPACE, TOKEN, QUOTED_STRING }; /* * parse(line_ptr, argc_ptr) * * Function: * Parses line, dividing at whitespace, into tokens, returns * the "argc" and "argv" values. * Arguments: * line_ptr (char *) * Pointer to text string to be parsed. * argc_ptr (int *) * Where to put the "argc" (number of tokens) value. * Returns: * argv (char **) * Series of pointers to parsed tokens in the original string. */ #define NEW_ARGV(old,n) (char **)realloc((char *)old, \ (unsigned)(n+2)*sizeof(char*)) char **ss_parse (sci_idx, line_ptr, argc_ptr) int sci_idx; char *line_ptr; int *argc_ptr; { char **argv, *cp; char **newargv; int argc; enum parse_mode parse_mode; argv = (char **) malloc (sizeof(char *)); if (argv == (char **)NULL) { ss_error(sci_idx, errno, "Can't allocate storage"); *argc_ptr = 0; return(argv); } *argv = (char *)NULL; argc = 0; parse_mode = WHITESPACE; /* flushing whitespace */ cp = line_ptr; /* cp is for output */ while (1) { #ifdef DEBUG { printf ("character `%c', mode %d\n", *line_ptr, parse_mode); } #endif while (parse_mode == WHITESPACE) { if (*line_ptr == '\0') goto end_of_line; if (*line_ptr == ' ' || *line_ptr == '\t') { line_ptr++; continue; } if (*line_ptr == '"') { /* go to quoted-string mode */ parse_mode = QUOTED_STRING; cp = line_ptr++; newargv = NEW_ARGV (argv, argc); if (newargv == NULL) { out_of_mem_in_argv: free(argv); ss_error(sci_idx, errno, "Can't allocate storage"); *argc_ptr = 0; return NULL; } argv = newargv; argv[argc++] = cp; argv[argc] = NULL; } else { /* random-token mode */ parse_mode = TOKEN; cp = line_ptr; newargv = NEW_ARGV (argv, argc); if (newargv == NULL) goto out_of_mem_in_argv; argv = newargv; argv[argc++] = line_ptr; argv[argc] = NULL; } } while (parse_mode == TOKEN) { if (*line_ptr == '\0') { *cp++ = '\0'; goto end_of_line; } else if (*line_ptr == ' ' || *line_ptr == '\t') { *cp++ = '\0'; line_ptr++; parse_mode = WHITESPACE; } else if (*line_ptr == '"') { line_ptr++; parse_mode = QUOTED_STRING; } else { *cp++ = *line_ptr++; } } while (parse_mode == QUOTED_STRING) { if (*line_ptr == '\0') { ss_error (sci_idx, 0, "Unbalanced quotes in command line"); free (argv); *argc_ptr = 0; return NULL; } else if (*line_ptr == '"') { if (*++line_ptr == '"') { *cp++ = '"'; line_ptr++; } else { parse_mode = TOKEN; } } else { *cp++ = *line_ptr++; } } } end_of_line: *argc_ptr = argc; #ifdef DEBUG { int i; printf ("argc = %d\n", argc); for (i = 0; i <= argc; i++) printf ("\targv[%2d] = `%s'\n", i, argv[i] ? argv[i] : ""); } #endif return(argv); }