diff --git a/Error-log b/Error-log index b603ae4..9912464 100644 --- a/Error-log +++ b/Error-log @@ -20,3 +20,6 @@ Tod Olson complained about the I/O performance C support). Reported 11/95, improved 4/96. Things generally improved all over by improving the efficiency of optional argument handling (but especially I/O, I think). + +I changed the meta-arg parser (C, Scheme, and doc) so that newline + *always* terminates an arg -- empty or non-empty. KISS. diff --git a/proc2.c b/proc2.c index f38b944..d715593 100644 --- a/proc2.c +++ b/proc2.c @@ -58,15 +58,16 @@ ** - The only special chars are space, tab, newline, and \. ** - Every space char terminates an argument. ** Multiple spaces therefore introduce empty-string arguments. -** - A newline terminates the argument list, and will also terminate a -** non-empty argument (but a newline following a space does not introduce -** a final "" argument; it only terminates the argument list). +** - A newline terminates an argument, and also terminates the argument list. +** This means that an empty line parses to the singleton list whose one +** element is the empty string: (""). The grammar doesn't admit the empty +** list. ** - Tab is not allowed. ** This is to prevent you from being screwed by thinking you had several ** spaces where you really had a tab, and vice-versa. ** - The only other special character is \, the knock-down character. ** \ escapes \, space, tab, and newline, turning off their special -** functions. The ANSI C escape sequences, such as \n and \t are +** functions. The ANSI C escape sequences (\b, \n, \r and \t) are ** supported; these also produce argument-constituents -- \n doesn't act ** like a terminating newline. \nnn for *exactly* three octal digits reads ** as the char whose ASCII code is nnn. It is an error if \ is followed by @@ -190,14 +191,14 @@ char **process_meta_arg(char **av) argv = Malloc(char*, argv_len); if( !argv ) goto lose3; - while( EOF != (c=getc(script)) && '\n' != c ) { + do { char *arg; - ungetc(c,script); arg = read_arg(script); if( !arg ) goto lose2; Maybe_Grow_Vec(argv, argv_len, argv_i, char*, lose1); argv[argv_i++] = arg; } + while( EOF != (c=getc(script)) && '\n' != c ); for(av_len=0; av[av_len]; av_len++); /* Compute length of av. */ @@ -222,10 +223,9 @@ char **process_meta_arg(char **av) return NULL; } -/* Read in one arg and it's terminating space. -** If arg is terminated by a newline, leave the newline in -** the stream so the outer loop can see it. Return a newly-allocated -** string containing the arg; NULL if there's an error. +/* Read in one arg, but not its terminating space or newline. +** Return a newly-allocated string containing the arg; +** NULL if there's an error. */ static char *read_arg(FILE *f) { @@ -241,8 +241,7 @@ static char *read_arg(FILE *f) while(1) { int c = getc(f); - if( c == EOF || c == ' ' ) break; - if( c == '\n' ) {ungetc(c, f); break;} + if( c == EOF || c == ' ' || c == '\n' ) {ungetc(c, f); break;} /* Do knock-down processing. */ if( c == '\\' ) { diff --git a/scsh/meta-arg.scm b/scsh/meta-arg.scm index 7e07058..f20866e 100644 --- a/scsh/meta-arg.scm +++ b/scsh/meta-arg.scm @@ -65,22 +65,20 @@ (define (read-secondary-args port) (let lp ((args '())) - (let ((c (peek-char port))) + (let* ((args (cons (read-secondary-arg port) args)) + (c (read-char port))) (if (or (eof-object? c) (char=? c #\newline)) (reverse args) - (lp (cons (read-secondary-arg port) args)))))) + (lp args))))) - -;;; Read in one secondary arg. +;;; Read in one secondary arg, but not its delimiting space or newline. (define (read-secondary-arg port) (let lp ((chars '())) (let ((c (peek-char port))) - (cond ((or (eof-object? c) (char=? c #\newline)) - (apply string (reverse chars))) - - ((char=? c #\space) - (read-char port) + (cond ((or (eof-object? c) + (char=? c #\newline) + (char=? c #\space)) (apply string (reverse chars))) ((char=? c tab)