119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright 1987, 1988 by MIT Student Information Processing Board 319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Permission to use, copy, modify, and distribute this software and 519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * its documentation for any purpose is hereby granted, provided that 619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in 719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * advertising or publicity pertaining to distribution of the software 819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * without specific, written prior permission. M.I.T. and the 919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * M.I.T. S.I.P.B. make no representations about the suitability of 1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * this software for any purpose. It is provided "as is" without 1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * express or implied warranty. 1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAS_STDLIB_H 1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdlib.h> 1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h> 1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_ERRNO_H 1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <errno.h> 2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ss_internal.h" 2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectenum parse_mode { WHITESPACE, TOKEN, QUOTED_STRING }; 2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * parse(line_ptr, argc_ptr) 2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Function: 3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Parses line, dividing at whitespace, into tokens, returns 3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * the "argc" and "argv" values. 3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Arguments: 3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * line_ptr (char *) 3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Pointer to text string to be parsed. 3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * argc_ptr (int *) 3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Where to put the "argc" (number of tokens) value. 3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Returns: 3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * argv (char **) 3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Series of pointers to parsed tokens. 4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define NEW_ARGV(old,n) (char **)realloc((char *)old,\ 4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (unsigned)(n+2)*sizeof(char*)) 4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectchar **ss_parse (sci_idx, line_ptr, argc_ptr) 4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int sci_idx; 4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project register char *line_ptr; 4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int *argc_ptr; 4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project register char **argv, *cp; 5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project register int argc; 5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project register enum parse_mode parse_mode; 5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project argv = (char **) malloc (sizeof(char *)); 5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (argv == (char **)NULL) { 5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ss_error(sci_idx, errno, "Can't allocate storage"); 5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *argc_ptr = 0; 5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return(argv); 5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *argv = (char *)NULL; 6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project argc = 0; 6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project parse_mode = WHITESPACE; /* flushing whitespace */ 6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cp = line_ptr; /* cp is for output */ 6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (1) { 6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef DEBUG 6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf ("character `%c', mode %d\n", *line_ptr, parse_mode); 7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (parse_mode == WHITESPACE) { 7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (*line_ptr == '\0') 7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto end_of_line; 7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (*line_ptr == ' ' || *line_ptr == '\t') { 7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project line_ptr++; 7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (*line_ptr == '"') { 8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* go to quoted-string mode */ 8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project parse_mode = QUOTED_STRING; 8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cp = line_ptr++; 8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project argv = NEW_ARGV (argv, argc); 8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project argv[argc++] = cp; 8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project argv[argc] = NULL; 8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else { 8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* random-token mode */ 8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project parse_mode = TOKEN; 9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cp = line_ptr; 9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project argv = NEW_ARGV (argv, argc); 9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project argv[argc++] = line_ptr; 9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project argv[argc] = NULL; 9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (parse_mode == TOKEN) { 9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (*line_ptr == '\0') { 9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *cp++ = '\0'; 9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto end_of_line; 10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else if (*line_ptr == ' ' || *line_ptr == '\t') { 10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *cp++ = '\0'; 10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project line_ptr++; 10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project parse_mode = WHITESPACE; 10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else if (*line_ptr == '"') { 10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project line_ptr++; 10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project parse_mode = QUOTED_STRING; 10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else { 11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *cp++ = *line_ptr++; 11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (parse_mode == QUOTED_STRING) { 11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (*line_ptr == '\0') { 11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ss_error (sci_idx, 0, 11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project "Unbalanced quotes in command line"); 11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free (argv); 11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *argc_ptr = 0; 12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return NULL; 12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else if (*line_ptr == '"') { 12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (*++line_ptr == '"') { 12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *cp++ = '"'; 12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project line_ptr++; 12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else { 12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project parse_mode = TOKEN; 12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else { 13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *cp++ = *line_ptr++; 13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectend_of_line: 13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *argc_ptr = argc; 13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef DEBUG 13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project { 14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int i; 14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf ("argc = %d\n", argc); 14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i = 0; i <= argc; i++) 14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf ("\targv[%2d] = `%s'\n", i, 14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project argv[i] ? argv[i] : "<NULL>"); 14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return(argv); 14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 149