parse.c revision d1154eb460efe588eaed3d439c1caaca149fa362
16fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org/* 26fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * Copyright 1987, 1988 by MIT Student Information Processing Board 36fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * 46fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * Permission to use, copy, modify, and distribute this software and 56fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * its documentation for any purpose is hereby granted, provided that 66fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in 76fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * advertising or publicity pertaining to distribution of the software 86fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * without specific, written prior permission. M.I.T. and the 96fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * M.I.T. S.I.P.B. make no representations about the suitability of 106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * this software for any purpose. It is provided "as is" without 1190c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org * express or implied warranty. 1290c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org */ 1393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "config.h" 1593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#ifdef HAS_STDLIB_H 1693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include <stdlib.h> 1793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 1893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include <string.h> 196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#ifdef HAVE_ERRNO_H 2093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include <errno.h> 2193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 22693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com 236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "ss_internal.h" 246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgenum parse_mode { WHITESPACE, TOKEN, QUOTED_STRING }; 26693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com 2741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org/* 287765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org * parse(line_ptr, argc_ptr) 297765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org * 307765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org * Function: 317765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org * Parses line, dividing at whitespace, into tokens, returns 327765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org * the "argc" and "argv" values. 336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * Arguments: 346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * line_ptr (char *) 356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * Pointer to text string to be parsed. 36dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org * argc_ptr (int *) 3776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org * Where to put the "argc" (number of tokens) value. 3893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org * Returns: 39dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org * argv (char **) 406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * Series of pointers to parsed tokens. 417765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org */ 427765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org 4393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#define NEW_ARGV(old,n) (char **)realloc((char *)old,\ 446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org (unsigned)(n+2)*sizeof(char*)) 45dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org 46dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgchar **ss_parse (sci_idx, line_ptr, argc_ptr) 476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int sci_idx; 48dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org register char *line_ptr; 496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int *argc_ptr; 506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org{ 51693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com register char **argv, *cp; 52693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com register int argc; 53693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com register enum parse_mode parse_mode; 54693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com 5593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org argv = (char **) malloc (sizeof(char *)); 5693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (argv == (char **)NULL) { 576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ss_error(sci_idx, errno, "Can't allocate storage"); 58693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com *argc_ptr = 0; 59693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com return(argv); 60ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org } 61ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org *argv = (char *)NULL; 62dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org 63dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org argc = 0; 64dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org 65dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org parse_mode = WHITESPACE; /* flushing whitespace */ 666fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org cp = line_ptr; /* cp is for output */ 67dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org while (1) { 68dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#ifdef DEBUG 696fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org { 70dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org printf ("character `%c', mode %d\n", *line_ptr, parse_mode); 71dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org } 726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#endif 7393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org while (parse_mode == WHITESPACE) { 746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (*line_ptr == '\0') 75dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org goto end_of_line; 766fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (*line_ptr == ' ' || *line_ptr == '\t') { 776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org line_ptr++; 78dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org continue; 79dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org } 80dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org if (*line_ptr == '"') { 81dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org /* go to quoted-string mode */ 82dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org parse_mode = QUOTED_STRING; 836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org cp = line_ptr++; 8441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org argv = NEW_ARGV (argv, argc); 857765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org argv[argc++] = cp; 866fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org argv[argc] = NULL; 876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 88dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org else { 89dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org /* random-token mode */ 906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org parse_mode = TOKEN; 91dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org cp = line_ptr; 926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org argv = NEW_ARGV (argv, argc); 93dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org argv[argc++] = line_ptr; 9487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org argv[argc] = NULL; 95dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org } 96ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org } 97ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org while (parse_mode == TOKEN) { 9887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (*line_ptr == '\0') { 996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *cp++ = '\0'; 10087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org goto end_of_line; 10187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } 1026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (*line_ptr == ' ' || *line_ptr == '\t') { 1036fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *cp++ = '\0'; 1046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org line_ptr++; 1056fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org parse_mode = WHITESPACE; 1066fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 1076fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (*line_ptr == '"') { 108dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org line_ptr++; 109dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org parse_mode = QUOTED_STRING; 11087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } 111dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org else { 1126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *cp++ = *line_ptr++; 11387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } 11487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } 1156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org while (parse_mode == QUOTED_STRING) { 1166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (*line_ptr == '\0') { 1176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ss_error (sci_idx, 0, 1186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org "Unbalanced quotes in command line"); 1196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org free (argv); 1206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *argc_ptr = 0; 12193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return NULL; 1226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 1236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else if (*line_ptr == '"') { 1246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (*++line_ptr == '"') { 1256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *cp++ = '"'; 1266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org line_ptr++; 1276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 1286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org else { 129693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com parse_mode = TOKEN; 1306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 131dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org } 132dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org else { 13393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org *cp++ = *line_ptr++; 134dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org } 135dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org } 136dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org } 137dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgend_of_line: 138dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org *argc_ptr = argc; 139dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#ifdef DEBUG 140e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org { 141e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org int i; 142e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org printf ("argc = %d\n", argc); 14393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org for (i = 0; i <= argc; i++) 14493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org printf ("\targv[%2d] = `%s'\n", i, 14587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org argv[i] ? argv[i] : "<NULL>"); 146dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org } 14793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#endif 14893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return(argv); 149dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org} 150dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org