lexical #6/6, whitespace

This commit is contained in:
rlar 2012-08-03 20:20:18 +02:00
parent ea558fbc7f
commit 62a4ee77d5
1 changed files with 113 additions and 84 deletions

View File

@ -22,7 +22,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include <pwd.h>
#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 <sys/ioctl.h>
#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);
}