summaryrefslogtreecommitdiffstats
path: root/contrib/tcsh/sh.lex.c
diff options
context:
space:
mode:
authormp <mp@FreeBSD.org>2005-04-24 19:41:08 +0000
committermp <mp@FreeBSD.org>2005-04-24 19:41:08 +0000
commit94a109bd814074f290affa8f7698847719d55833 (patch)
tree6daeb0464a7bc8705c0246b7fd98e212b6beed09 /contrib/tcsh/sh.lex.c
parentbbd1addf8f9452690ad13ce5b875ee4cc9633958 (diff)
downloadFreeBSD-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.c323
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);
OpenPOWER on IntegriCloud