diff options
author | mp <mp@FreeBSD.org> | 2005-04-24 19:41:08 +0000 |
---|---|---|
committer | mp <mp@FreeBSD.org> | 2005-04-24 19:41:08 +0000 |
commit | 94a109bd814074f290affa8f7698847719d55833 (patch) | |
tree | 6daeb0464a7bc8705c0246b7fd98e212b6beed09 /contrib/tcsh/sh.lex.c | |
parent | bbd1addf8f9452690ad13ce5b875ee4cc9633958 (diff) | |
download | FreeBSD-src-94a109bd814074f290affa8f7698847719d55833.zip FreeBSD-src-94a109bd814074f290affa8f7698847719d55833.tar.gz |
Import of tcsh-6.14.00
Diffstat (limited to 'contrib/tcsh/sh.lex.c')
-rw-r--r-- | contrib/tcsh/sh.lex.c | 323 |
1 files changed, 204 insertions, 119 deletions
diff --git a/contrib/tcsh/sh.lex.c b/contrib/tcsh/sh.lex.c index e6c7e2d..e18728f 100644 --- a/contrib/tcsh/sh.lex.c +++ b/contrib/tcsh/sh.lex.c @@ -1,4 +1,4 @@ -/* $Header: /src/pub/tcsh/sh.lex.c,v 3.57 2003/08/04 16:19:13 christos Exp $ */ +/* $Header: /src/pub/tcsh/sh.lex.c,v 3.62 2004/12/25 21:15:07 christos Exp $ */ /* * sh.lex.c: Lexical analysis into tokens */ @@ -32,9 +32,11 @@ */ #include "sh.h" -RCSID("$Id: sh.lex.c,v 3.57 2003/08/04 16:19:13 christos Exp $") +RCSID("$Id: sh.lex.c,v 3.62 2004/12/25 21:15:07 christos Exp $") #include "ed.h" + +#include <assert.h> /* #define DEBUG_INP */ /* #define DEBUG_SEEK */ @@ -47,21 +49,22 @@ RCSID("$Id: sh.lex.c,v 3.57 2003/08/04 16:19:13 christos Exp $") * There is some involved processing here, because of the complications * of input buffering, and especially because of history substitution. */ -static Char *word __P((void)); -static int getC1 __P((int)); +static Char *word __P((int)); +static eChar getC1 __P((int)); static void getdol __P((void)); -static void getexcl __P((int)); -static struct Hist *findev __P((Char *, bool)); +static void getexcl __P((Char)); +static struct Hist *findev __P((Char *, int)); static void setexclp __P((Char *)); -static int bgetc __P((void)); +static eChar bgetc __P((void)); static void balloc __P((int)); static void bfree __P((void)); -static struct wordent *gethent __P((int)); +static struct wordent *gethent __P((Char)); static int matchs __P((Char *, Char *)); static int getsel __P((int *, int *, int)); static struct wordent *getsub __P((struct wordent *)); -static Char *subword __P((Char *, int, bool *)); -static struct wordent *dosub __P((int, struct wordent *, bool)); +static Char *subword __P((Char *, Char, int *)); +static struct wordent *dosub __P((Char, struct wordent *, int)); +static ssize_t wide_read __P((int, Char *, size_t, int)); /* * Peekc is a peek character for getC, peekread for readc. @@ -111,7 +114,7 @@ static Char labuf[BUFSIZE]; * when called by the alias routine to determine whether to keep the * argument list. */ -static bool hadhist = 0; +static int hadhist = 0; /* * Avoid alias expansion recursion via \!# @@ -121,12 +124,12 @@ int hleft; Char histline[BUFSIZE + 2]; /* last line input */ /* The +2 is to fool hp's optimizer */ -bool histvalid = 0; /* is histline valid */ +int histvalid = 0; /* is histline valid */ static Char *histlinep = NULL; /* current pointer into histline */ static Char getCtmp; -#define getC(f) (((getCtmp = peekc) != '\0') ? (peekc = 0, getCtmp) : getC1(f)) +#define getC(f) (((getCtmp = peekc) != '\0') ? (peekc = 0, (eChar)getCtmp) : getC1(f)) #define ungetC(c) peekc = (Char) c #define ungetD(c) peekd = (Char) c @@ -137,6 +140,11 @@ time_t Htime = (time_t)0; static time_t a2time_t __P((Char *)); /* + * special parsing rules apply for source -h + */ +extern int enterhist; + +/* * for history event processing * in the command 'echo !?foo?:1 !$' we want the !$ to expand from the line * 'foo' was found instead of the last command @@ -148,7 +156,8 @@ lex(hp) struct wordent *hp; { struct wordent *wdp; - int c; + eChar c; + int parsehtime = enterhist; uselastevent = 1; @@ -163,7 +172,7 @@ lex(hp) do c = readc(0); while (c == ' ' || c == '\t'); - if (c == HISTSUB && intty) + if (c == (eChar)HISTSUB && intty) /* ^lef^rit from tty is short !:s^lef^rit */ getexcl(c); else @@ -183,7 +192,8 @@ lex(hp) wdp->next = new; hp->prev = new; wdp = new; - wdp->word = word(); + wdp->word = word(parsehtime); + parsehtime = 0; } while (wdp->word[0] != '\n'); if (histlinep < histline + BUFSIZE) { *histlinep = '\0'; @@ -199,8 +209,8 @@ lex(hp) } static time_t -a2time_t(word) - Char *word; +a2time_t(wordx) + Char *wordx; { /* Attempt to distinguish timestamps from other possible entries. * Format: "+NNNNNNNNNN" (10 digits, left padded with ascii '0') */ @@ -209,7 +219,7 @@ a2time_t(word) Char *s; int ct; - if (!word || *(s = word) != '+') + if (!wordx || *(s = wordx) != '+') return (time_t)0; for (++s, ret = 0, ct = 0; *s; ++s, ++ct) @@ -282,18 +292,16 @@ freelex(vp) } static Char * -word() +word(parsehtime) + int parsehtime; { - Char c, c1; - Char *wp; + eChar c, c1; + Char *wp, *unfinished = 0; Char wbuf[BUFSIZE]; Char hbuf[12]; int h; - bool dolflg; + int dolflg; int i; -#if defined(DSPMBYTE) - int mbytepos = 1; -#endif /* DSPMBYTE */ wp = wbuf; i = BUFSIZE - 4; @@ -315,18 +323,20 @@ loop: goto ret; case '#': - if (intty) + if (intty || (enterhist && !parsehtime)) break; c = 0; h = 0; do { c1 = c; c = getC(0); - if (h < 12) + if (h < 11 && parsehtime) hbuf[h++] = c; } while (c != '\n'); - hbuf[11] = '\0'; - Htime = a2time_t(hbuf); + if (parsehtime) { + hbuf[11] = '\0'; + Htime = a2time_t(hbuf); + } if (c1 == '\\') goto loop; /*FALLTHROUGH*/ @@ -345,7 +355,7 @@ loop: onelflg = 2; goto loop; } - if (c != HIST) + if (c != (eChar)HIST) *wp++ = '\\', --i; c |= QUOTE; default: @@ -354,13 +364,6 @@ loop: c1 = 0; dolflg = DOALL; for (;;) { -#if defined(DSPMBYTE) - if (mbytepos == 2) - mbytepos = 1; - else if (mbytepos == 1 && Ismbyte1(c) && 2 <= i) - mbytepos = 2; - else -#endif /* DSPMBYTE */ if (c1) { if (c == c1) { c1 = 0; @@ -375,7 +378,7 @@ loop: * * Actually, all I really want to be able to say is 'foo\'bar' --> foo'bar */ - if (c == HIST) + if (c == (eChar)HIST) c |= QUOTE; else { if (bslash_quote && @@ -408,7 +411,7 @@ loop: onelflg = 2; break; } - if (c != HIST) + if (c != (eChar)HIST) *wp++ = '\\', --i; c |= QUOTE; } @@ -416,7 +419,7 @@ loop: c1 = c; dolflg = c == '"' ? DOALL : DOEXCL; } - else if (c != '#' || !intty) { + else if (c != '#' || (!intty && !enterhist)) { ungetC(c); break; } @@ -424,6 +427,17 @@ loop: if (--i > 0) { *wp++ = c; c = getC(dolflg); + if (!unfinished) + unfinished = wp - 1; + switch (NLSFinished(unfinished, wp - unfinished, c)) { + case 1: + case 0: + c |= QUOTE; + break; + default: + unfinished = 0; + break; + } } else { seterror(ERR_WTOOLONG); @@ -436,11 +450,11 @@ ret: return (Strsave(wbuf)); } -static int +static eChar getC1(flag) int flag; { - Char c; + eChar c; for (;;) { if ((c = peekc) != 0) { @@ -487,7 +501,7 @@ getC1(flag) getdol(); continue; } - if (c == HIST && (flag & DOEXCL)) { + if (c == (eChar)HIST && (flag & DOEXCL)) { getexcl(0); continue; } @@ -501,9 +515,9 @@ getdol() { Char *np, *ep; Char name[4 * MAXVARLEN + 1]; - int c; - int sc; - bool special = 0, toolong; + eChar c; + eChar sc; + int special = 0, toolong; np = name, *np++ = '$'; c = sc = getC(DOEXCL); @@ -664,7 +678,7 @@ getdol() /* scan s// [eichin:19910926.0512EST] */ if (c == 's') { int delimcnt = 2; - int delim = getC(0); + eChar delim = getC(0); *np++ = (Char) delim; if (!delim || letter(delim) @@ -672,7 +686,7 @@ getdol() seterror(ERR_BADSUBST); break; } - while ((c = getC(0)) != (-1)) { + while ((c = getC(0)) != CHAR_ERR) { *np++ = (Char) c; if(c == delim) delimcnt--; if(!delimcnt) break; @@ -729,6 +743,7 @@ addla(cp) if (lap) (void) Strcpy(buf, lap); (void) Strcpy(labuf, cp); + NLSQuote(labuf); if (lap) (void) Strcat(labuf, buf); lap = labuf; @@ -741,11 +756,11 @@ static int quesarg; static void getexcl(sc) - int sc; + Char sc; { struct wordent *hp, *ip; int left, right, dol; - int c; + eChar c; if (sc == 0) { sc = getC(0); @@ -827,10 +842,10 @@ getsub(en) struct wordent *en; { Char *cp; - int delim; - int c; - int sc; - bool global; + eChar delim; + eChar c; + eChar sc; + int global; Char orhsb[sizeof(rhsb) / sizeof(Char)]; #ifndef COMPAT @@ -953,7 +968,7 @@ getsub(en) default: if (c == '\n') unreadc(c); - seterror(ERR_BADBANGMOD, c); + seterror(ERR_BADBANGMOD, (int)c); return (en); } (void) Strcpy(slhs, lhsb); @@ -980,12 +995,12 @@ getsub(en) #define HIST_PURGE -50000000 static struct wordent * dosub(sc, en, global) - int sc; + Char sc; struct wordent *en; - bool global; + int global; { struct wordent lexi; - bool didsub = 0, didone = 0; + int didsub = 0, didone = 0; struct wordent *hp = &lexi; struct wordent *wdp; int i = exclc; @@ -1041,8 +1056,8 @@ dosub(sc, en, global) static Char * subword(cp, type, adid) Char *cp; - int type; - bool *adid; + Char type; + int *adid; { Char wbuf[BUFSIZE]; Char *wp, *mp, *np; @@ -1117,7 +1132,7 @@ subword(cp, type, adid) Char * domod(cp, type) Char *cp; - int type; + Char type; { Char *wp, *xp; int c; @@ -1133,22 +1148,12 @@ domod(cp, type) return (wp); case 'l': - wp = Strsave(cp); - for (cp = wp; *cp; cp++) - if (Isupper(*cp)) { - *cp = Tolower(*cp); - return wp; - } - return wp; + wp = NLSChangeCase(cp, 1); + return wp ? wp : Strsave(cp); case 'u': - wp = Strsave(cp); - for (cp = wp; *cp; cp++) - if (Islower(*cp)) { - *cp = Toupper(*cp); - return wp; - } - return wp; + wp = NLSChangeCase(cp, 0); + return wp ? wp : Strsave(cp); case 'h': case 't': @@ -1195,9 +1200,9 @@ getsel(al, ar, dol) int *al, *ar; int dol; { - int c = getC(0); + eChar c = getC(0); int i; - bool first = *al < 0; + int first = *al < 0; switch (c) { @@ -1278,16 +1283,16 @@ getsel(al, ar, dol) static struct wordent * gethent(sc) - int sc; + Char sc; { struct Hist *hp; Char *np; - int c; + eChar c; int event; - bool back = 0; + int back = 0; - c = sc == HISTSUB ? HIST : getC(0); - if (c == HIST) { + c = sc == HISTSUB ? (eChar)HIST : getC(0); + if (c == (eChar)HIST) { if (alhistp) return (alhistp); event = eventno; @@ -1405,7 +1410,7 @@ gethent(sc) static struct Hist * findev(cp, anyarg) Char *cp; - bool anyarg; + int anyarg; { struct Hist *hp; @@ -1465,18 +1470,17 @@ setexclp(cp) void unreadc(c) - int c; + Char c; { peekread = (Char) c; } -int +eChar readc(wanteof) - bool wanteof; + int wanteof; { - int c; + eChar c; static int sincereal; /* Number of real EOFs we've seen */ - extern int numeof; #ifdef DEBUG_INP xprintf("readc\n"); @@ -1542,7 +1546,7 @@ top: do { if (arginp == INVPTR || onelflg == 1) { if (wanteof) - return (-1); + return CHAR_ERR; exitstat(); } if (arginp) { @@ -1556,7 +1560,7 @@ top: reread: #endif /* BSDJOBS */ c = bgetc(); - if (c < 0) { + if (c == CHAR_ERR) { #ifndef WINNT_NATIVE # ifndef POSIX # ifdef TERMIO @@ -1569,7 +1573,7 @@ reread: # endif /* POSIX */ #endif /* !WINNT_NATIVE */ if (wanteof) - return (-1); + return CHAR_ERR; /* was isatty but raw with ignoreeof yields problems */ #ifndef WINNT_NATIVE # ifndef POSIX @@ -1680,12 +1684,68 @@ balloc(buf) } } -static int +static ssize_t +wide_read(fildes, buf, nchars, use_fclens) + int fildes; + Char *buf; + size_t nchars; + int use_fclens; +{ + char cbuf[BUFSIZE + 1]; + ssize_t res, r; + size_t partial; + + assert (nchars <= sizeof(cbuf)/sizeof(*cbuf)); + USE(use_fclens); + res = 0; + partial = 0; + do { + size_t i; + + do + r = read(fildes, cbuf + partial, + nchars > partial ? nchars - partial : 1); + while (partial != 0 && r < 0 && errno == EINTR); + if (partial == 0 && r <= 0) + break; + partial += r; + i = 0; + while (i < partial) { + int len; + + len = normal_mbtowc(buf + res, cbuf + i, partial - i); + if (len == -1) { + reset_mbtowc(); + if (partial < MB_LEN_MAX && r > 0) + /* Maybe a partial character and there is still a chance + to read more */ + break; + buf[res] = (unsigned char)cbuf[i] | INVALID_BYTE; + } + if (len <= 0) + len = 1; +#ifdef WIDE_STRINGS + if (use_fclens) + fclens[res] = len; +#endif + i += len; + res++; + nchars--; + } + if (i != partial) + memmove(cbuf, cbuf + i, partial - i); + partial -= i; + } while (partial != 0); + /* Throwing away possible partial multibyte characters on error */ + return res != 0 ? res : r; +} + +static eChar bgetc() { + Char ch; int c, off, buf; int numleft = 0, roomleft; - char tbuf[BUFSIZE + 1]; if (cantell) { if (fseekp < fbobp || fseekp > feobp) { @@ -1693,32 +1753,28 @@ bgetc() (void) lseek(SHIN, fseekp, L_SET); } if (fseekp == feobp) { - int i; - fbobp = feobp; do - c = read(SHIN, tbuf, BUFSIZE); + c = wide_read(SHIN, fbuf[0], BUFSIZE, 1); while (c < 0 && errno == EINTR); #ifdef convex if (c < 0) stderror(ERR_SYSTEM, progname, strerror(errno)); #endif /* convex */ if (c <= 0) - return (-1); - for (i = 0; i < c; i++) - fbuf[0][i] = (unsigned char) tbuf[i]; + return CHAR_ERR; feobp += c; } #ifndef WINNT_NATIVE - c = fbuf[0][fseekp - fbobp]; + ch = fbuf[0][fseekp - fbobp]; fseekp++; #else do { - c = fbuf[0][fseekp - fbobp]; + ch = fbuf[0][fseekp - fbobp]; fseekp++; - } while(c == '\r'); + } while(ch == '\r'); #endif /* !WINNT_NATIVE */ - return (c); + return (ch); } while (fseekp >= feobp) { @@ -1752,29 +1808,27 @@ bgetc() buf = (int) feobp / BUFSIZE; balloc(buf); roomleft = BUFSIZE - off; - c = read(SHIN, tbuf, (size_t) roomleft); - if (c > 0) { - int i; - Char *ptr = fbuf[buf] + off; - - for (i = 0; i < c; i++) - ptr[i] = (unsigned char) tbuf[i]; + c = wide_read(SHIN, fbuf[buf] + off, (size_t) roomleft, 0); + if (c > 0) feobp += c; - } } if (c == 0 || (c < 0 && fixio(SHIN, errno) == -1)) - return (-1); + return CHAR_ERR; } +#ifdef SIG_WINDOW + if (windowchg) + (void) check_window_size(0); /* for window systems */ +#endif /* SIG_WINDOW */ #ifndef WINNT_NATIVE - c = fbuf[(int) fseekp / BUFSIZE][(int) fseekp % BUFSIZE]; + ch = fbuf[(int) fseekp / BUFSIZE][(int) fseekp % BUFSIZE]; fseekp++; #else do { - c = fbuf[(int) fseekp / BUFSIZE][(int) fseekp % BUFSIZE]; + ch = fbuf[(int) fseekp / BUFSIZE][(int) fseekp % BUFSIZE]; fseekp++; - } while(c == '\r'); + } while(ch == '\r'); #endif /* !WINNT_NATIVE */ - return (c); + return (ch); } static void @@ -1821,6 +1875,28 @@ bseek(l) xprintf(CGETS(16, 6, "seek to file %x\n"), fseekp); #endif fseekp = l->f_seek; +#ifdef WIDE_STRINGS + if (cantell) { + if (fseekp >= fbobp) { + size_t i; + off_t o; + + o = fbobp; + for (i = 0; i < feobp - fbobp; i++) { + if (fseekp == o) { + fseekp = fbobp + i; + return; + } + o += fclens[i]; + } + if (fseekp == o) { + fseekp = feobp; + return; + } + } + fbobp = feobp = fseekp + 1; /* To force lseek() */ + } +#endif return; default: xprintf(CGETS(16, 7, "Bad seek type %d\n"), aret); @@ -1849,8 +1925,17 @@ struct Ain *l; #endif return; case TCSH_F_SEEK: - /*SUPPRESS 112*/ - l->f_seek = fseekp; +#ifdef WIDE_STRINGS + if (cantell && fseekp >= fbobp && fseekp < feobp) { + size_t i; + + l->f_seek = fbobp; + for (i = 0; i < fseekp - fbobp; i++) + l->f_seek += fclens[i]; + } else +#endif + /*SUPPRESS 112*/ + l->f_seek = fseekp; l->a_seek = NULL; #ifdef DEBUG_SEEK xprintf(CGETS(16, 10, "tell file %x\n"), fseekp); |