I changed the meta-arg parsers (C and Scheme) so that newline *always*

terminates an arg, even if it is an empty arg. Consistency. KISS.
This commit is contained in:
shivers 1996-08-29 08:35:25 +00:00
parent 4961de1b9b
commit aabe436bef
3 changed files with 21 additions and 21 deletions

View File

@ -20,3 +20,6 @@ Tod Olson <ta-olson@uchicago.edu> complained about the I/O performance
C support). Reported 11/95, improved 4/96. C support). Reported 11/95, improved 4/96.
Things generally improved all over by improving the efficiency Things generally improved all over by improving the efficiency
of optional argument handling (but especially I/O, I think). 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.

23
proc2.c
View File

@ -58,15 +58,16 @@
** - The only special chars are space, tab, newline, and \. ** - The only special chars are space, tab, newline, and \.
** - Every space char terminates an argument. ** - Every space char terminates an argument.
** Multiple spaces therefore introduce empty-string arguments. ** Multiple spaces therefore introduce empty-string arguments.
** - A newline terminates the argument list, and will also terminate a ** - A newline terminates an argument, and also terminates the argument list.
** non-empty argument (but a newline following a space does not introduce ** This means that an empty line parses to the singleton list whose one
** a final "" argument; it only terminates the argument list). ** element is the empty string: (""). The grammar doesn't admit the empty
** list.
** - Tab is not allowed. ** - Tab is not allowed.
** This is to prevent you from being screwed by thinking you had several ** This is to prevent you from being screwed by thinking you had several
** spaces where you really had a tab, and vice-versa. ** spaces where you really had a tab, and vice-versa.
** - The only other special character is \, the knock-down character. ** - The only other special character is \, the knock-down character.
** \ escapes \, space, tab, and newline, turning off their special ** \ 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 ** supported; these also produce argument-constituents -- \n doesn't act
** like a terminating newline. \nnn for *exactly* three octal digits reads ** 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 ** 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); argv = Malloc(char*, argv_len);
if( !argv ) goto lose3; if( !argv ) goto lose3;
while( EOF != (c=getc(script)) && '\n' != c ) { do {
char *arg; char *arg;
ungetc(c,script);
arg = read_arg(script); arg = read_arg(script);
if( !arg ) goto lose2; if( !arg ) goto lose2;
Maybe_Grow_Vec(argv, argv_len, argv_i, char*, lose1); Maybe_Grow_Vec(argv, argv_len, argv_i, char*, lose1);
argv[argv_i++] = arg; argv[argv_i++] = arg;
} }
while( EOF != (c=getc(script)) && '\n' != c );
for(av_len=0; av[av_len]; av_len++); /* Compute length of av. */ 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; return NULL;
} }
/* Read in one arg and it's terminating space. /* Read in one arg, but not its terminating space or newline.
** If arg is terminated by a newline, leave the newline in ** Return a newly-allocated string containing the arg;
** the stream so the outer loop can see it. Return a newly-allocated ** NULL if there's an error.
** string containing the arg; NULL if there's an error.
*/ */
static char *read_arg(FILE *f) static char *read_arg(FILE *f)
{ {
@ -241,8 +241,7 @@ static char *read_arg(FILE *f)
while(1) { while(1) {
int c = getc(f); int c = getc(f);
if( c == EOF || c == ' ' ) break; if( c == EOF || c == ' ' || c == '\n' ) {ungetc(c, f); break;}
if( c == '\n' ) {ungetc(c, f); break;}
/* Do knock-down processing. */ /* Do knock-down processing. */
if( c == '\\' ) { if( c == '\\' ) {

View File

@ -65,22 +65,20 @@
(define (read-secondary-args port) (define (read-secondary-args port)
(let lp ((args '())) (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)) (if (or (eof-object? c) (char=? c #\newline))
(reverse args) (reverse args)
(lp (cons (read-secondary-arg port) args)))))) (lp args)))))
;;; Read in one secondary arg, but not its delimiting space or newline.
;;; Read in one secondary arg.
(define (read-secondary-arg port) (define (read-secondary-arg port)
(let lp ((chars '())) (let lp ((chars '()))
(let ((c (peek-char port))) (let ((c (peek-char port)))
(cond ((or (eof-object? c) (char=? c #\newline)) (cond ((or (eof-object? c)
(apply string (reverse chars))) (char=? c #\newline)
(char=? c #\space))
((char=? c #\space)
(read-char port)
(apply string (reverse chars))) (apply string (reverse chars)))
((char=? c tab) ((char=? c tab)