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