diff options
author | 1994-08-18 16:48:22 +0000 | |
---|---|---|
committer | 1994-08-18 16:48:22 +0000 | |
commit | 7ccbe4609af7a4292f4155873ead82d94918ef68 (patch) | |
tree | f35965df838c6980e4c8cc9955d0749ce62e19cb /util | |
parent | 6d85e8458e7fefb2984b9167853f3d73d933ecc7 (diff) |
Initial revision
Diffstat (limited to 'util')
-rw-r--r-- | util/et/error_message.c | 67 | ||||
-rw-r--r-- | util/et/error_table.y | 230 | ||||
-rw-r--r-- | util/et/et_lex.lex.l | 23 | ||||
-rw-r--r-- | util/et/et_name.c | 41 | ||||
-rw-r--r-- | util/et/vfprintf.c | 45 | ||||
-rw-r--r-- | util/ss/execute_cmd.c | 215 | ||||
-rw-r--r-- | util/ss/invocation.c | 78 | ||||
-rw-r--r-- | util/ss/mk_cmds.c | 100 | ||||
-rw-r--r-- | util/ss/parse.c | 135 | ||||
-rw-r--r-- | util/ss/prompt.c | 27 | ||||
-rw-r--r-- | util/ss/test_ss.c | 100 |
11 files changed, 1061 insertions, 0 deletions
diff --git a/util/et/error_message.c b/util/et/error_message.c new file mode 100644 index 0000000..507e0f1 --- /dev/null +++ b/util/et/error_message.c @@ -0,0 +1,67 @@ +/* + * util/et/error_message.c + * + * Copyright 1987 by the Student Information Processing Board + * of the Massachusetts Institute of Technology + * + * For copyright info, see "mit-sipb-copyright.h". + */ + +#include <stdio.h> +#include "error_table.h" +#include "mit-sipb-copyright.h" +#include "internal.h" + +static const char copyright[] = + "Copyright 1986, 1987, 1988 by the Student Information Processing Board\nand the department of Information Systems\nof the Massachusetts Institute of Technology"; + +static char buffer[25]; + +struct et_list * _et_list = (struct et_list *) NULL; + +const char * error_message (code) +long code; +{ + int offset; + struct et_list *et; + int table_num; + int started = 0; + char *cp; + + offset = code & ((1<<ERRCODE_RANGE)-1); + table_num = code - offset; + if (!table_num) { + if (offset < sys_nerr) + return(sys_errlist[offset]); + else + goto oops; + } + for (et = _et_list; et; et = et->next) { + if (et->table->base == table_num) { + /* This is the right table */ + if (et->table->n_msgs <= offset) + goto oops; + return(et->table->msgs[offset]); + } + } +oops: + strcpy (buffer, "Unknown code "); + if (table_num) { + strcat (buffer, error_table_name (table_num)); + strcat (buffer, " "); + } + for (cp = buffer; *cp; cp++) + ; + if (offset >= 100) { + *cp++ = '0' + offset / 100; + offset %= 100; + started++; + } + if (started || offset >= 10) { + *cp++ = '0' + offset / 10; + offset %= 10; + } + *cp++ = '0' + offset; + *cp = '\0'; + return(buffer); +} diff --git a/util/et/error_table.y b/util/et/error_table.y new file mode 100644 index 0000000..ad4ffb1 --- /dev/null +++ b/util/et/error_table.y @@ -0,0 +1,230 @@ +%{ +#include <stdio.h> +char *str_concat(), *ds(), *quote(); +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +char *current_token = (char *)NULL; +extern char *table_name; +%} +%union { + char *dynstr; +} + +%token ERROR_TABLE ERROR_CODE_ENTRY END +%token <dynstr> STRING QUOTED_STRING +%type <dynstr> ec_name description table_id +%{ +%} +%start error_table +%% + +error_table : ERROR_TABLE table_id error_codes END + { table_name = ds($2); + current_token = table_name; + put_ecs(); } + ; + +table_id : STRING + { current_token = $1; + set_table_num($1); + $$ = $1; } + ; + +error_codes : error_codes ec_entry + | ec_entry + ; + +ec_entry : ERROR_CODE_ENTRY ec_name ',' description + { add_ec($2, $4); + free($2); + free($4); } + | ERROR_CODE_ENTRY ec_name '=' STRING ',' description + { add_ec_val($2, $4, $6); + free($2); + free($4); + free($6); + } + ; + +ec_name : STRING + { $$ = ds($1); + current_token = $$; } + ; + +description : QUOTED_STRING + { $$ = ds($1); + current_token = $$; } + ; + +%% +/* + * + * Copyright 1986, 1987 by the MIT Student Information Processing Board + * + * For copyright info, see mit-sipb-copyright.h. + */ + +#include <string.h> +#include <assert.h> +#include <ctype.h> +#include <sys/types.h> +#include <sys/time.h> +#include "internal.h" +#include "error_table.h" +#include "mit-sipb-copyright.h" + + +extern FILE *hfile, *cfile; + +static long gensym_n = 0; +char * +gensym(x) + char const *x; +{ + char *symbol; + if (!gensym_n) { + struct timeval tv; + struct timezone tzp; + gettimeofday(&tv, &tzp); + gensym_n = (tv.tv_sec%10000)*100 + tv.tv_usec/10000; + } + symbol = malloc(32 * sizeof(char)); + gensym_n++; + sprintf(symbol, "et%ld", gensym_n); + return(symbol); +} + +char * +ds(string) + char const *string; +{ + char *rv; + rv = malloc(strlen(string)+1); + strcpy(rv, string); + return(rv); +} + +char * +quote(string) + char const *string; +{ + char *rv; + rv = malloc(strlen(string)+3); + strcpy(rv, "\""); + strcat(rv, string); + strcat(rv, "\""); + return(rv); +} + +long table_number; +int current = 0; +char **error_codes = (char **)NULL; + +add_ec(name, description) + char const *name, *description; +{ + fprintf(cfile, "\t\"%s\",\n", description); + if (error_codes == (char **)NULL) { + error_codes = (char **)malloc(sizeof(char *)); + *error_codes = (char *)NULL; + } + error_codes = (char **)realloc((char *)error_codes, + (current + 2)*sizeof(char *)); + error_codes[current++] = ds(name); + error_codes[current] = (char *)NULL; +} + +add_ec_val(name, val, description) + char const *name, *val, *description; +{ + const int ncurrent = atoi(val); + if (ncurrent < current) { + printf("Error code %s (%d) out of order", name, + current); + return; + } + + while (ncurrent > current) + fputs("\t(char *)NULL,\n", cfile), current++; + + fprintf(cfile, "\t\"%s\",\n", description); + if (error_codes == (char **)NULL) { + error_codes = (char **)malloc(sizeof(char *)); + *error_codes = (char *)NULL; + } + error_codes = (char **)realloc((char *)error_codes, + (current + 2)*sizeof(char *)); + error_codes[current++] = ds(name); + error_codes[current] = (char *)NULL; +} + +put_ecs() +{ + int i; + for (i = 0; i < current; i++) { + if (error_codes[i] != (char *)NULL) + fprintf(hfile, "#define %-40s (%ldL)\n", + error_codes[i], table_number + i); + } +} + +/* + * char_to_num -- maps letters and numbers into a small numbering space + * uppercase -> 1-26 + * lowercase -> 27-52 + * digits -> 53-62 + * underscore-> 63 + */ + +static const char char_set[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; + +int char_to_num(c) + char c; +{ + const char *where; + int diff; + + where = strchr (char_set, c); + if (where) { + diff = where - char_set + 1; + assert (diff < (1 << ERRCODE_RANGE)); + return diff; + } + else if (isprint (c)) + fprintf (stderr, + "Illegal character `%c' in error table name\n", + c); + else + fprintf (stderr, + "Illegal character %03o in error table name\n", + c); + exit (1); +} + +set_table_num(string) + char *string; +{ + if (char_to_num (string[0]) > char_to_num ('z')) { + fprintf (stderr, "%s%s%s%s", + "First character of error table name must be ", + "a letter; name ``", + string, "'' rejected\n"); + exit (1); + } + if (strlen(string) > 4) { + fprintf(stderr, "Table name %s too long, truncated ", + string); + string[4] = '\0'; + fprintf(stderr, "to %s\n", string); + } + while (*string != '\0') { + table_number = (table_number << BITS_PER_CHAR) + + char_to_num(*string); + string++; + } + table_number = table_number << ERRCODE_RANGE; +} + +#include "et_lex.lex.c" diff --git a/util/et/et_lex.lex.l b/util/et/et_lex.lex.l new file mode 100644 index 0000000..b363e8c --- /dev/null +++ b/util/et/et_lex.lex.l @@ -0,0 +1,23 @@ +PC [^\"] +AN [A-Z_a-z0-9] +%% + +error_table return ERROR_TABLE; +et return ERROR_TABLE; +error_code return ERROR_CODE_ENTRY; +ec return ERROR_CODE_ENTRY; +end return END; + +[\t\n ] ; + +\"{PC}*\" { register char *p; yylval.dynstr = ds(yytext+1); + if (p=strrchr(yylval.dynstr, '"')) *p='\0'; + return QUOTED_STRING; + } + +{AN}* { yylval.dynstr = ds(yytext); return STRING; } + +#.*\n ; + +. { return (*yytext); } +%% diff --git a/util/et/et_name.c b/util/et/et_name.c new file mode 100644 index 0000000..044302b --- /dev/null +++ b/util/et/et_name.c @@ -0,0 +1,41 @@ +/* + * Copyright 1987 by MIT Student Information Processing Board + * + * For copyright info, see mit-sipb-copyright.h. + */ + +#include "error_table.h" +#include "mit-sipb-copyright.h" +#include "internal.h" + +#ifndef lint +static const char copyright[] = + "Copyright 1987,1988 by Student Information Processing Board, Massachusetts Institute of Technology"; +#endif + +static const char char_set[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; + +static char buf[6]; + +const char * error_table_name(num) + int num; +{ + int ch; + int i; + char *p; + + /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */ + p = buf; + num >>= ERRCODE_RANGE; + /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */ + num &= 077777777; + /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */ + for (i = 4; i >= 0; i--) { + ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1); + if (ch != 0) + *p++ = char_set[ch-1]; + } + *p = '\0'; + return(buf); +} diff --git a/util/et/vfprintf.c b/util/et/vfprintf.c new file mode 100644 index 0000000..6558992 --- /dev/null +++ b/util/et/vfprintf.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* based on @(#)vfprintf.c 5.2 (Berkeley) 6/27/88 */ + +#include <stdio.h> +#include <varargs.h> + +int +vfprintf(iop, fmt, ap) + FILE *iop; + char *fmt; + va_list ap; +{ + int len; + char localbuf[BUFSIZ]; + + if (iop->_flag & _IONBF) { + iop->_flag &= ~_IONBF; + iop->_ptr = iop->_base = localbuf; + len = _doprnt(fmt, ap, iop); + (void) fflush(iop); + iop->_flag |= _IONBF; + iop->_base = NULL; + iop->_bufsiz = 0; + iop->_cnt = 0; + } else + len = _doprnt(fmt, ap, iop); + + return (ferror(iop) ? EOF : len); +} diff --git a/util/ss/execute_cmd.c b/util/ss/execute_cmd.c new file mode 100644 index 0000000..52f07e2 --- /dev/null +++ b/util/ss/execute_cmd.c @@ -0,0 +1,215 @@ +/* + * Copyright 1987, 1988, 1989 by Massachusetts Institute of Technology + * + * For copyright info, see copyright.h. + */ + +#include "ss_internal.h" +#include "copyright.h" +#include <stdio.h> + + +/* + * get_request(tbl, idx) + * + * Function: + * Gets the idx'th request from the request table pointed to + * by tbl. + * Arguments: + * tbl (ss_request_table *) + * pointer to request table + * idx (int) + * index into table + * Returns: + * (ss_request_entry *) + * pointer to request table entry + * Notes: + * Has been replaced by a macro. + */ + +#ifdef __SABER__ +/* sigh. saber won't deal with pointer-to-const-struct */ +static struct _ss_request_entry * get_request (tbl, idx) + ss_request_table * tbl; + int idx; +{ + struct _ss_request_table *tbl1 = (struct _ss_request_table *) tbl; + struct _ss_request_entry *e = (struct _ss_request_entry *) tbl1->requests; + return e + idx; +} +#else +#define get_request(tbl,idx) ((tbl) -> requests + (idx)) +#endif + +/* + * check_request_table(rqtbl, argc, argv, sci_idx) + * + * Function: + * If the command string in argv[0] is in the request table, execute + * the commands and return error code 0. Otherwise, return error + * code ss_et_command_not_found. + * Arguments: + * rqtbl (ss_request_table *) + * pointer to request table + * argc (int) + * number of elements in argv[] + * argv (char *[]) + * argument string array + * sci_idx (int) + * ss-internal index for subsystem control info structure + * Returns: + * (int) + * zero if command found, ss_et_command_not_found otherwise + * Notes: + */ + +static int check_request_table (rqtbl, argc, argv, sci_idx) + register ss_request_table *rqtbl; + int argc; + char *argv[]; + int sci_idx; +{ +#ifdef __SABER__ + struct _ss_request_entry *request; +#else + register ss_request_entry *request; +#endif + register ss_data *info; + register char const * const * name; + char *string = argv[0]; + int i; + + info = ss_info(sci_idx); + info->argc = argc; + info->argv = argv; + for (i = 0; (request = get_request(rqtbl, i))->command_names; i++) { + for (name = request->command_names; *name; name++) + if (!strcmp(*name, string)) { + info->current_request = request->command_names[0]; + (request->function)(argc, (const char *const *) argv, + sci_idx,info->info_ptr); + info->current_request = (char *)NULL; + return(0); + } + } + return(SS_ET_COMMAND_NOT_FOUND); +} + +/* + * really_execute_command(sci_idx, argc, argv) + * + * Function: + * Fills in the argc, argv values in the subsystem entry and + * call the appropriate routine. + * Arguments: + * sci_idx (int) + * ss-internal index for subsystem control info structure + * argc (int) + * number of arguments in argument list + * argv (char **[]) + * pointer to parsed argument list (may be reallocated + * on abbrev expansion) + * + * Returns: + * (int) + * Zero if successful, ss_et_command_not_found otherwise. + * Notes: + */ + +static int really_execute_command (sci_idx, argc, argv) + int sci_idx; + int argc; + char **argv[]; +{ + register ss_request_table **rqtbl; + register ss_data *info; + + info = ss_info(sci_idx); + + for (rqtbl = info->rqt_tables; *rqtbl; rqtbl++) { + if (check_request_table (*rqtbl, argc, *argv, sci_idx) == 0) + return(0); + } + return(SS_ET_COMMAND_NOT_FOUND); +} + +/* + * ss_execute_command(sci_idx, argv) + * + * Function: + * Executes a parsed command list within the subsystem. + * Arguments: + * sci_idx (int) + * ss-internal index for subsystem control info structure + * argv (char *[]) + * parsed argument list + * Returns: + * (int) + * Zero if successful, ss_et_command_not_found otherwise. + * Notes: + */ + +ss_execute_command(sci_idx, argv) + int sci_idx; + register char *argv[]; +{ + register int i, argc; + char **argp; + + argc = 0; + for (argp = argv; *argp; argp++) + argc++; + argp = (char **)malloc((argc+1)*sizeof(char *)); + for (i = 0; i <= argc; i++) + argp[i] = argv[i]; + i = really_execute_command(sci_idx, argc, &argp); + free(argp); + return(i); +} + +/* + * ss_execute_line(sci_idx, line_ptr) + * + * Function: + * Parses and executes a command line within a subsystem. + * Arguments: + * sci_idx (int) + * ss-internal index for subsystem control info structure + * line_ptr (char *) + * Pointer to command line to be parsed. + * Returns: + * (int) + * Error code. + * Notes: + */ + +int ss_execute_line (sci_idx, line_ptr) + int sci_idx; + char *line_ptr; +{ + char **argv; + int argc; + + /* flush leading whitespace */ + while (line_ptr[0] == ' ' || line_ptr[0] == '\t') + line_ptr++; + + /* check if it should be sent to operating system for execution */ + if (*line_ptr == '!') { + if (ss_info(sci_idx)->flags.escape_disabled) + return SS_ET_ESCAPE_DISABLED; + else { + line_ptr++; + system(line_ptr); + return 0; + } + } + + /* parse it */ + argv = ss_parse(sci_idx, line_ptr, &argc); + if (argc == 0) + return 0; + + /* look it up in the request tables, execute if found */ + return really_execute_command (sci_idx, argc, &argv); +} diff --git a/util/ss/invocation.c b/util/ss/invocation.c new file mode 100644 index 0000000..c7cef48 --- /dev/null +++ b/util/ss/invocation.c @@ -0,0 +1,78 @@ +/* + * Copyright 1987, 1988 by MIT Student Information Processing Board + * + * For copyright information, see copyright.h. + */ +#include "ss_internal.h" +#include "copyright.h" +#define size sizeof(ss_data *) + + +int ss_create_invocation(subsystem_name, version_string, info_ptr, + request_table_ptr, code_ptr) + char *subsystem_name, *version_string; + char *info_ptr; + ss_request_table *request_table_ptr; + int *code_ptr; +{ + register int sci_idx; + register ss_data *new_table; + register ss_data **table; + + *code_ptr = 0; + table = _ss_table; + new_table = (ss_data *) malloc(sizeof(ss_data)); + + if (table == (ss_data **) NULL) { + table = (ss_data **) malloc(2 * size); + table[0] = table[1] = (ss_data *)NULL; + } + initialize_ss_error_table (); + + for (sci_idx = 1; table[sci_idx] != (ss_data *)NULL; sci_idx++) + ; + table = (ss_data **) realloc((char *)table, + ((unsigned)sci_idx+2)*size); + table[sci_idx+1] = (ss_data *) NULL; + table[sci_idx] = new_table; + + new_table->subsystem_name = subsystem_name; + new_table->subsystem_version = version_string; + new_table->argv = (char **)NULL; + new_table->current_request = (char *)NULL; + new_table->info_dirs = (char **)malloc(sizeof(char *)); + *new_table->info_dirs = (char *)NULL; + new_table->info_ptr = info_ptr; + new_table->prompt = malloc((unsigned)strlen(subsystem_name)+4); + strcpy(new_table->prompt, subsystem_name); + strcat(new_table->prompt, ": "); +#ifdef silly + new_table->abbrev_info = ss_abbrev_initialize("/etc/passwd", code_ptr); +#else + new_table->abbrev_info = NULL; +#endif + new_table->flags.escape_disabled = 0; + new_table->flags.abbrevs_disabled = 0; + new_table->rqt_tables = + (ss_request_table **) calloc(2, sizeof(ss_request_table *)); + *(new_table->rqt_tables) = request_table_ptr; + *(new_table->rqt_tables+1) = (ss_request_table *) NULL; + _ss_table = table; + return(sci_idx); +} + +void +ss_delete_invocation(sci_idx) + int sci_idx; +{ + register ss_data *t; + int ignored_code; + + t = ss_info(sci_idx); + free(t->prompt); + free((char *)t->rqt_tables); + while(t->info_dirs[0] != (char *)NULL) + ss_delete_info_dir(sci_idx, t->info_dirs[0], &ignored_code); + free((char *)t->info_dirs); + free((char *)t); +} diff --git a/util/ss/mk_cmds.c b/util/ss/mk_cmds.c new file mode 100644 index 0000000..fa69b59 --- /dev/null +++ b/util/ss/mk_cmds.c @@ -0,0 +1,100 @@ +/* + * make_commands.c + * + * util/ss/mk_cmds.c + * + * Copyright 1987, 1988 by MIT Student Information Processing Board + * + * For copyright information, see copyright.h. + */ + +#include "copyright.h" +#include <stdio.h> +#include <sys/param.h> +#include <sys/types.h> +#include <sys/file.h> +#include <string.h> +#include "ss_internal.h" + +static const char copyright[] = + "Copyright 1987 by MIT Student Information Processing Board"; + +extern pointer malloc PROTOTYPE((unsigned)); +extern char *last_token; +extern FILE *output_file; + +extern FILE *yyin, *yyout; +#ifndef NO_YYLINENO +extern int yylineno; +#endif + +int main(argc, argv) + int argc; + char **argv; +{ + char c_file[MAXPATHLEN]; + int result; + char *path, *p; + + if (argc != 2) { + fputs("Usage: ", stderr); + fputs(argv[0], stderr); + fputs("cmdtbl.ct\n", stderr); + exit(1); + } + + path = malloc(strlen(argv[1])+4); /* extra space to add ".ct" */ + strcpy(path, argv[1]); + p = strrchr(path, '/'); + if (p == (char *)NULL) + p = path; + else + p++; + p = strrchr(p, '.'); + if (p == (char *)NULL || strcmp(p, ".ct")) + strcat(path, ".ct"); + yyin = fopen(path, "r"); + if (!yyin) { + perror(path); + exit(1); + } + + p = strrchr(path, '.'); + *p = '\0'; + strcpy(c_file, path); + strcat(c_file, ".c"); + *p = '.'; + + output_file = fopen(c_file, "w+"); + if (!output_file) { + perror(c_file); + exit(1); + } + + fputs("/* ", output_file); + fputs(c_file, output_file); + fputs(" - automatically generated from ", output_file); + fputs(path, output_file); + fputs(" */\n", output_file); + fputs("#include <ss/ss.h>\n\n", output_file); + fputs("#ifndef __STDC__\n#define const\n#endif\n\n", output_file); + /* parse it */ + result = yyparse(); + /* put file descriptors back where they belong */ + fclose(yyin); /* bye bye input file */ + fclose(output_file); /* bye bye output file */ + + return result; +} + +yyerror(s) + char *s; +{ + fputs(s, stderr); +#ifdef NO_YYLINENO + fprintf(stderr, "\nLast token was '%s'\n", last_token); +#else + fprintf(stderr, "\nLine %d; last token was '%s'\n", + yylineno, last_token); +#endif +} diff --git a/util/ss/parse.c b/util/ss/parse.c new file mode 100644 index 0000000..ddb6378 --- /dev/null +++ b/util/ss/parse.c @@ -0,0 +1,135 @@ +/* + * Copyright 1987, 1988 by MIT Student Information Processing Board + * + * For copyright info, see copyright.h. + */ + +#include "ss_internal.h" +#include "copyright.h" + + +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. + */ + +#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; + register char *line_ptr; + int *argc_ptr; +{ + register char **argv, *cp; + register int argc; + register 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++; + argv = NEW_ARGV (argv, argc); + argv[argc++] = cp; + argv[argc] = NULL; + } + else { + /* random-token mode */ + parse_mode = TOKEN; + cp = line_ptr; + argv = NEW_ARGV (argv, argc); + 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] : "<NULL>"); + } +#endif + return(argv); +} diff --git a/util/ss/prompt.c b/util/ss/prompt.c new file mode 100644 index 0000000..5df2731 --- /dev/null +++ b/util/ss/prompt.c @@ -0,0 +1,27 @@ +/* + * prompt.c: Routines for retrieving and setting a prompt. + * + * util/ss/prompt.c + * + * Copyright 1987, 1988 by MIT Student Information Processing Board + * + * For copyright information, see copyright.h. + */ + +#include "copyright.h" +#include <stdio.h> +#include "ss_internal.h" + +ss_set_prompt(sci_idx, new_prompt) + int sci_idx; + char *new_prompt; +{ + ss_info(sci_idx)->prompt = new_prompt; +} + +char * +ss_get_prompt(sci_idx) + int sci_idx; +{ + return(ss_info(sci_idx)->prompt); +} diff --git a/util/ss/test_ss.c b/util/ss/test_ss.c new file mode 100644 index 0000000..db0af6f --- /dev/null +++ b/util/ss/test_ss.c @@ -0,0 +1,100 @@ +/* + * util/ss/test_ss.c + */ + + +#include <stdio.h> +#include "ss.h" + +extern ss_request_table test_cmds; + +#define TRUE 1 +#define FALSE 0 + +static char def_subsystem_name[5] = "test"; +static char version [4] = "1.0"; +extern void ss_listen(); + +int main(argc, argv) + int argc; + char **argv; +{ + int code; + char *argv0 = argv[0]; + char *initial_request = (char *)NULL; + int quit = FALSE; /* quit after processing request */ + int sci_idx; + char *subsystem_name; + + subsystem_name = def_subsystem_name; + + for (; *argv; ++argv, --argc) { + printf("checking arg: %s\n", *argv); + if (!strcmp(*argv, "-prompt")) { + if (argc == 1) { + fprintf(stderr, + "No argument supplied with -prompt\n"); + exit(1); + } + argc--; argv++; + subsystem_name = *argv; + } + else if (!strcmp(*argv, "-request") || !strcmp(*argv, "-rq")) { + if (argc == 1) { + fprintf(stderr, + "No string supplied with -request.\n"); + exit(1); + } + argc--; argv++; + initial_request = *argv; + } + else if (!strcmp(*argv, "-quit")) + quit = TRUE; + else if (!strcmp(*argv, "-no_quit")) + quit = FALSE; + else if (**argv == '-') { + fprintf(stderr, "Unknown control argument %s\n", + *argv); + fprintf(stderr, + "Usage: %s [gateway] [ -prompt name ] [ -request name ] [ -quit ]\n", + argv0); + exit(1); + } + } + + sci_idx = ss_create_invocation(subsystem_name, version, + (char *)NULL, &test_cmds, &code); + if (code) { + ss_perror(sci_idx, code, "creating invocation"); + exit(1); + } + + (void) ss_add_request_table (sci_idx, &ss_std_requests, 1, &code); + if (code) { + ss_perror (sci_idx, code, "adding standard requests"); + exit (1); + } + + if (!quit) + printf("test version %s. Type '?' for a list of commands.\n\n", + version); + + if (initial_request != (char *)NULL) { + code = ss_execute_line(sci_idx, initial_request); + if (code != 0) + ss_perror(sci_idx, code, initial_request); + } + if (!quit || code) + (void) ss_listen (sci_idx, &code); + exit(0); +} + + +void test_cmd (argc, argv) + int argc; + char **argv; +{ + while (++argv, --argc) + fputs(*argv, stdout); + putchar ('\n'); +} |