From 62a4ee77d56bdaaafb486912569583addda5078c Mon Sep 17 00:00:00 2001 From: rlar Date: Fri, 3 Aug 2012 20:20:18 +0200 Subject: [PATCH] lexical #6/6, whitespace --- src/frontend/parser/lexical.c | 197 +++++++++++++++++++--------------- 1 file changed, 113 insertions(+), 84 deletions(-) diff --git a/src/frontend/parser/lexical.c b/src/frontend/parser/lexical.c index f1c9ec3d1..1fb49d767 100644 --- a/src/frontend/parser/lexical.c +++ b/src/frontend/parser/lexical.c @@ -22,7 +22,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include #endif - /* MW. Linux has TIOCSTI, so we include all headers here */ +/* MW. Linux has TIOCSTI, so we include all headers here */ #if !defined(__MINGW32__) && !defined(_MSC_VER) #include #endif @@ -64,6 +64,7 @@ static int numeofs = 0; #define ESCAPE '\033' + /* Return a list of words, with backslash quoting and '' quoting done. * Strings en(void) closed in "" or `` are made single words and returned, * but with the "" or `` still present. For the \ and '' cases, the @@ -74,22 +75,23 @@ static int numeofs = 0; * have no business being in the string. */ -#define append(word) \ - do { \ - wordlist *aux = wl_cons(word, NULL); \ - if (cw) \ - cw->wl_next = aux; \ - aux->wl_prev = cw; \ - cw = aux; \ - if (!wlist) \ - wlist = cw; \ +#define append(word) \ + do { \ + wordlist *aux = wl_cons(word, NULL); \ + if (cw) \ + cw->wl_next = aux; \ + aux->wl_prev = cw; \ + cw = aux; \ + if (!wlist) \ + wlist = cw; \ } while(0) -#define newword \ - do { \ - append(copy(buf)); \ - bzero(buf, NEW_BSIZE_SP); \ - i = 0; \ + +#define newword \ + do { \ + append(copy(buf)); \ + bzero(buf, NEW_BSIZE_SP); \ + i = 0; \ } while(0) @@ -103,12 +105,14 @@ pwlist_echo(wordlist *wlist, char *name) if (!cp_echo || cp_debug) return; + fprintf(cp_err, "%s ", name); for (wl = wlist; wl; wl = wl->wl_next) - fprintf(cp_err, "%s ", wl->wl_word ); - fprintf(cp_err, "\n"); + fprintf(cp_err, "%s ", wl->wl_word); + fprintf(cp_err, "\n"); } + /* CDHW */ wordlist * @@ -120,7 +124,7 @@ cp_lexer(char *string) char buf[NEW_BSIZE_SP], linebuf[NEW_BSIZE_SP]; int paren; - if (!cp_inp_cur) + if (!cp_inp_cur) cp_inp_cur = cp_in; /* prompt for string if none is passed */ @@ -128,6 +132,7 @@ cp_lexer(char *string) cp_ccon(TRUE); prompt(); } + nloop: wlist = cw = NULL; i = 0; @@ -135,7 +140,9 @@ nloop: paren = 0; bzero(linebuf, NEW_BSIZE_SP); bzero(buf, NEW_BSIZE_SP); + for (;;) { + if (string) { c = *string++; if (c == '\0') @@ -146,15 +153,19 @@ nloop: c = input(cp_inp_cur); } -gotchar: - if ((c != EOF) && (c != ESCAPE)) - linebuf[j++] = (char) c; + gotchar: + + if ((c != EOF) && (c != ESCAPE)) + linebuf[j++] = (char) c; + if (c != EOF) numeofs = 0; + if (i == NEW_BSIZE_SP - 1) { fprintf(cp_err, "Warning: word too long.\n"); c = ' '; } + if (j == NEW_BSIZE_SP - 1) { fprintf(cp_err, "Warning: line too long.\n"); if (cp_bqflag) @@ -162,16 +173,21 @@ gotchar: else c = '\n'; } + if (c != EOF) /* Don't need to do this really. */ c = strip(c); + if ((c == '\\' && DIR_TERM != '\\') || (c == '\026') /* ^V */ ) { c = quote(string ? *string++ : input(cp_inp_cur)); linebuf[j++] = (char) strip(c); } + if ((c == '\n') && cp_bqflag) c = ' '; + if ((c == EOF) && cp_bqflag) c = '\n'; + if ((c == cp_hash) && !cp_interactive && (j == 1)) { wl_free(wlist); wlist = cw = NULL; @@ -183,18 +199,19 @@ gotchar: } if ((c == '(') || (c == '[')) /* MW. Nedded by parse() */ - paren++; - else if ((c == ')') || (c == ']')) - paren--; + paren++; + else if ((c == ')') || (c == ']')) + paren--; switch (c) { - case ' ': - case '\t': + + case ' ': + case '\t': if (i > 0) newword; break; - case '\n': + case '\n': if (i) { buf[i] = '\0'; newword; @@ -203,19 +220,19 @@ gotchar: append(NULL); goto done; - case '\'': + case '\'': while (((c = (string ? *string++ : input(cp_inp_cur))) != '\'') - && (i < NEW_BSIZE_SP - 1)) { + && (i < NEW_BSIZE_SP - 1)) { if ((c == '\n') || (c == EOF) || (c == ESCAPE)) goto gotchar; - buf[i++] = (char) quote(c); - linebuf[j++] = (char) c; + buf[i++] = (char) quote(c); + linebuf[j++] = (char) c; } linebuf[j++] = '\''; break; - case '"': - case '`': + case '"': + case '`': d = c; buf[i++] = (char) d; while (((c = (string ? *string++ : input(cp_inp_cur))) != d) @@ -236,9 +253,10 @@ gotchar: linebuf[j++] = (char) d; break; - case '\004': - case EOF: + case '\004': + case EOF: if (cp_interactive && !cp_nocc && !string) { + if (j == 0) { if (cp_ignoreeof && (numeofs++ < 23)) { fputs("Use \"quit\" to quit.\n", stdout); @@ -249,6 +267,7 @@ gotchar: append(NULL); goto done; } + // cp_ccom doesn't mess wlist, read only access to wlist->wl_word cp_ccom(wlist, buf, FALSE); wl_free(wlist); @@ -258,23 +277,24 @@ gotchar: #ifdef TIOCSTI (void) ioctl(fileno(cp_out), TIOCSTI, linebuf + j); #else - fputc(linebuf[j], cp_out); /* But you can't edit */ + fputc(linebuf[j], cp_out); /* But you can't edit */ #endif wlist = cw = NULL; goto nloop; } /* EOF during a source */ - if (cp_interactive) { - fputs("quit\n", stdout); - cp_doquit(); - append(NULL); - goto done; - } + if (cp_interactive) { + fputs("quit\n", stdout); + cp_doquit(); + append(NULL); + goto done; + } - wl_free(wlist); - return NULL; - case ESCAPE: + wl_free(wlist); + return NULL; + + case ESCAPE: if (cp_interactive && !cp_nocc) { fputs("\b\b \b\b\r", cp_out); prompt(); @@ -282,7 +302,7 @@ gotchar: #ifdef TIOCSTI (void) ioctl(fileno(cp_out), TIOCSTI, linebuf + j); #else - fputc(linebuf[j], cp_out); /* But you can't edit */ + fputc(linebuf[j], cp_out); /* But you can't edit */ #endif // cp_ccom doesn't mess wlist, read only access to wlist->wl_word cp_ccom(wlist, buf, TRUE); @@ -291,53 +311,59 @@ gotchar: goto nloop; } goto ldefault; - case ',': - if ((paren < 1) && (i > 0)) { - newword; - break; - } - goto ldefault; - case ';': /* CDHW semicolon inside parentheses is part of expression */ - if (paren > 0) { - buf[i++] = (char) c; - break; - } - goto ldefault; - case '&': /* va: $&name is one word */ - if ((i == 1) && (buf[i-1] == '$') && (c == '&')) { - buf[i++] = (char) c; - break; - } - goto ldefault; - case '<': - case '>': /* va: <=, >= are unbreakable words */ - if(string) - if ((i == 0) && (*string == '=')) { - buf[i++] = (char) c; - break; - } - goto ldefault; - default: + + case ',': + if ((paren < 1) && (i > 0)) { + newword; + break; + } + goto ldefault; + + case ';': /* CDHW semicolon inside parentheses is part of expression */ + if (paren > 0) { + buf[i++] = (char) c; + break; + } + goto ldefault; + + case '&': /* va: $&name is one word */ + if ((i == 1) && (buf[i-1] == '$') && (c == '&')) { + buf[i++] = (char) c; + break; + } + goto ldefault; + + case '<': + case '>': /* va: <=, >= are unbreakable words */ + if(string) + if ((i == 0) && (*string == '=')) { + buf[i++] = (char) c; + break; + } + goto ldefault; + + default: /* We have to remember the special case $< * here */ ldefault: if ((cp_chars[c] & CPC_BRL) && (i > 0)) - if ((c != '<') || (buf[i - 1] != '$')) + if ((c != '<') || (buf[i-1] != '$')) newword; buf[i++] = (char) c; if (cp_chars[c] & CPC_BRR) - if ((c != '<') || (i < 2) || (buf[i - 2] != '$')) + if ((c != '<') || (i < 2) || (buf[i-2] != '$')) newword; } } -done: +done: if (wlist->wl_word) pwlist_echo(wlist,"Command>"); return wlist; } + static void prompt(void) { @@ -345,24 +371,27 @@ prompt(void) if (cp_interactive == FALSE) return; + if (cp_altprompt) s = cp_altprompt; else if (cp_promptstring) s = cp_promptstring; else s = "-> "; + while (*s) { switch (strip(*s)) { - case '!': - fprintf(cp_out, "%d", cp_event); - break; - case '\\': - if (*(s + 1)) - (void) putc(strip(*++s), cp_out); - default: - (void) putc(strip(*s), cp_out); + case '!': + fprintf(cp_out, "%d", cp_event); + break; + case '\\': + if (*(s + 1)) + (void) putc(strip(*++s), cp_out); + default: + (void) putc(strip(*s), cp_out); } s++; } + (void) fflush(cp_out); }