diff options
Diffstat (limited to 'ioq3-r437/src/tools/lcc/cpp/lex.c')
-rw-r--r-- | ioq3-r437/src/tools/lcc/cpp/lex.c | 580 |
1 files changed, 0 insertions, 580 deletions
diff --git a/ioq3-r437/src/tools/lcc/cpp/lex.c b/ioq3-r437/src/tools/lcc/cpp/lex.c deleted file mode 100644 index 8030354e..00000000 --- a/ioq3-r437/src/tools/lcc/cpp/lex.c +++ /dev/null @@ -1,580 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "cpp.h" - -/* - * lexical FSM encoding - * when in state state, and one of the characters - * in ch arrives, enter nextstate. - * States >= S_SELF are either final, or at least require special action. - * In 'fsm' there is a line for each state X charset X nextstate. - * List chars that overwrite previous entries later (e.g. C_ALPH - * can be overridden by '_' by a later entry; and C_XX is the - * the universal set, and should always be first. - * States above S_SELF are represented in the big table as negative values. - * S_SELF and S_SELFB encode the resulting token type in the upper bits. - * These actions differ in that S_SELF doesn't have a lookahead char, - * S_SELFB does. - * - * The encoding is blown out into a big table for time-efficiency. - * Entries have - * nextstate: 6 bits; ?\ marker: 1 bit; tokentype: 9 bits. - */ - -#define MAXSTATE 32 -#define ACT(tok,act) ((tok<<7)+act) -#define QBSBIT 0100 -#define GETACT(st) (st>>7)&0x1ff - -/* character classes */ -#define C_WS 1 -#define C_ALPH 2 -#define C_NUM 3 -#define C_EOF 4 -#define C_XX 5 - -enum state { - START=0, NUM1, NUM2, NUM3, ID1, ST1, ST2, ST3, COM1, COM2, COM3, COM4, - CC1, CC2, WS1, PLUS1, MINUS1, STAR1, SLASH1, PCT1, SHARP1, - CIRC1, GT1, GT2, LT1, LT2, OR1, AND1, ASG1, NOT1, DOTS1, - S_SELF=MAXSTATE, S_SELFB, S_EOF, S_NL, S_EOFSTR, - S_STNL, S_COMNL, S_EOFCOM, S_COMMENT, S_EOB, S_WS, S_NAME -}; - -int tottok; -int tokkind[256]; -struct fsm { - int state; /* if in this state */ - uchar ch[4]; /* and see one of these characters */ - int nextstate; /* enter this state if +ve */ -}; - -/*const*/ struct fsm fsm[] = { - /* start state */ - {START, { C_XX }, ACT(UNCLASS,S_SELF)}, - {START, { ' ', '\t', '\v' }, WS1}, - {START, { C_NUM }, NUM1}, - {START, { '.' }, NUM3}, - {START, { C_ALPH }, ID1}, - {START, { 'L' }, ST1}, - {START, { '"' }, ST2}, - {START, { '\'' }, CC1}, - {START, { '/' }, COM1}, - {START, { EOFC }, S_EOF}, - {START, { '\n' }, S_NL}, - {START, { '-' }, MINUS1}, - {START, { '+' }, PLUS1}, - {START, { '<' }, LT1}, - {START, { '>' }, GT1}, - {START, { '=' }, ASG1}, - {START, { '!' }, NOT1}, - {START, { '&' }, AND1}, - {START, { '|' }, OR1}, - {START, { '#' }, SHARP1}, - {START, { '%' }, PCT1}, - {START, { '[' }, ACT(SBRA,S_SELF)}, - {START, { ']' }, ACT(SKET,S_SELF)}, - {START, { '(' }, ACT(LP,S_SELF)}, - {START, { ')' }, ACT(RP,S_SELF)}, - {START, { '*' }, STAR1}, - {START, { ',' }, ACT(COMMA,S_SELF)}, - {START, { '?' }, ACT(QUEST,S_SELF)}, - {START, { ':' }, ACT(COLON,S_SELF)}, - {START, { ';' }, ACT(SEMIC,S_SELF)}, - {START, { '{' }, ACT(CBRA,S_SELF)}, - {START, { '}' }, ACT(CKET,S_SELF)}, - {START, { '~' }, ACT(TILDE,S_SELF)}, - {START, { '^' }, CIRC1}, - - /* saw a digit */ - {NUM1, { C_XX }, ACT(NUMBER,S_SELFB)}, - {NUM1, { C_NUM, C_ALPH, '.' }, NUM1}, - {NUM1, { 'E', 'e' }, NUM2}, - {NUM1, { '_' }, ACT(NUMBER,S_SELFB)}, - - /* saw possible start of exponent, digits-e */ - {NUM2, { C_XX }, ACT(NUMBER,S_SELFB)}, - {NUM2, { '+', '-' }, NUM1}, - {NUM2, { C_NUM, C_ALPH }, NUM1}, - {NUM2, { '_' }, ACT(NUMBER,S_SELFB)}, - - /* saw a '.', which could be a number or an operator */ - {NUM3, { C_XX }, ACT(DOT,S_SELFB)}, - {NUM3, { '.' }, DOTS1}, - {NUM3, { C_NUM }, NUM1}, - - {DOTS1, { C_XX }, ACT(UNCLASS, S_SELFB)}, - {DOTS1, { C_NUM }, NUM1}, - {DOTS1, { '.' }, ACT(ELLIPS, S_SELF)}, - - /* saw a letter or _ */ - {ID1, { C_XX }, ACT(NAME,S_NAME)}, - {ID1, { C_ALPH, C_NUM }, ID1}, - - /* saw L (start of wide string?) */ - {ST1, { C_XX }, ACT(NAME,S_NAME)}, - {ST1, { C_ALPH, C_NUM }, ID1}, - {ST1, { '"' }, ST2}, - {ST1, { '\'' }, CC1}, - - /* saw " beginning string */ - {ST2, { C_XX }, ST2}, - {ST2, { '"' }, ACT(STRING, S_SELF)}, - {ST2, { '\\' }, ST3}, - {ST2, { '\n' }, S_STNL}, - {ST2, { EOFC }, S_EOFSTR}, - - /* saw \ in string */ - {ST3, { C_XX }, ST2}, - {ST3, { '\n' }, S_STNL}, - {ST3, { EOFC }, S_EOFSTR}, - - /* saw ' beginning character const */ - {CC1, { C_XX }, CC1}, - {CC1, { '\'' }, ACT(CCON, S_SELF)}, - {CC1, { '\\' }, CC2}, - {CC1, { '\n' }, S_STNL}, - {CC1, { EOFC }, S_EOFSTR}, - - /* saw \ in ccon */ - {CC2, { C_XX }, CC1}, - {CC2, { '\n' }, S_STNL}, - {CC2, { EOFC }, S_EOFSTR}, - - /* saw /, perhaps start of comment */ - {COM1, { C_XX }, ACT(SLASH, S_SELFB)}, - {COM1, { '=' }, ACT(ASSLASH, S_SELF)}, - {COM1, { '*' }, COM2}, - {COM1, { '/' }, COM4}, - - /* saw / then *, start of comment */ - {COM2, { C_XX }, COM2}, - {COM2, { '\n' }, S_COMNL}, - {COM2, { '*' }, COM3}, - {COM2, { EOFC }, S_EOFCOM}, - - /* saw the * possibly ending a comment */ - {COM3, { C_XX }, COM2}, - {COM3, { '\n' }, S_COMNL}, - {COM3, { '*' }, COM3}, - {COM3, { '/' }, S_COMMENT}, - - /* // comment */ - {COM4, { C_XX }, COM4}, - {COM4, { '\n' }, S_NL}, - {COM4, { EOFC }, S_EOFCOM}, - - /* saw white space, eat it up */ - {WS1, { C_XX }, S_WS}, - {WS1, { ' ', '\t', '\v' }, WS1}, - - /* saw -, check --, -=, -> */ - {MINUS1, { C_XX }, ACT(MINUS, S_SELFB)}, - {MINUS1, { '-' }, ACT(MMINUS, S_SELF)}, - {MINUS1, { '=' }, ACT(ASMINUS,S_SELF)}, - {MINUS1, { '>' }, ACT(ARROW,S_SELF)}, - - /* saw +, check ++, += */ - {PLUS1, { C_XX }, ACT(PLUS, S_SELFB)}, - {PLUS1, { '+' }, ACT(PPLUS, S_SELF)}, - {PLUS1, { '=' }, ACT(ASPLUS, S_SELF)}, - - /* saw <, check <<, <<=, <= */ - {LT1, { C_XX }, ACT(LT, S_SELFB)}, - {LT1, { '<' }, LT2}, - {LT1, { '=' }, ACT(LEQ, S_SELF)}, - {LT2, { C_XX }, ACT(LSH, S_SELFB)}, - {LT2, { '=' }, ACT(ASLSH, S_SELF)}, - - /* saw >, check >>, >>=, >= */ - {GT1, { C_XX }, ACT(GT, S_SELFB)}, - {GT1, { '>' }, GT2}, - {GT1, { '=' }, ACT(GEQ, S_SELF)}, - {GT2, { C_XX }, ACT(RSH, S_SELFB)}, - {GT2, { '=' }, ACT(ASRSH, S_SELF)}, - - /* = */ - {ASG1, { C_XX }, ACT(ASGN, S_SELFB)}, - {ASG1, { '=' }, ACT(EQ, S_SELF)}, - - /* ! */ - {NOT1, { C_XX }, ACT(NOT, S_SELFB)}, - {NOT1, { '=' }, ACT(NEQ, S_SELF)}, - - /* & */ - {AND1, { C_XX }, ACT(AND, S_SELFB)}, - {AND1, { '&' }, ACT(LAND, S_SELF)}, - {AND1, { '=' }, ACT(ASAND, S_SELF)}, - - /* | */ - {OR1, { C_XX }, ACT(OR, S_SELFB)}, - {OR1, { '|' }, ACT(LOR, S_SELF)}, - {OR1, { '=' }, ACT(ASOR, S_SELF)}, - - /* # */ - {SHARP1, { C_XX }, ACT(SHARP, S_SELFB)}, - {SHARP1, { '#' }, ACT(DSHARP, S_SELF)}, - - /* % */ - {PCT1, { C_XX }, ACT(PCT, S_SELFB)}, - {PCT1, { '=' }, ACT(ASPCT, S_SELF)}, - - /* * */ - {STAR1, { C_XX }, ACT(STAR, S_SELFB)}, - {STAR1, { '=' }, ACT(ASSTAR, S_SELF)}, - - /* ^ */ - {CIRC1, { C_XX }, ACT(CIRC, S_SELFB)}, - {CIRC1, { '=' }, ACT(ASCIRC, S_SELF)}, - - {-1} -}; - -/* first index is char, second is state */ -/* increase #states to power of 2 to encourage use of shift */ -short bigfsm[256][MAXSTATE]; - -void -expandlex(void) -{ - /*const*/ struct fsm *fp; - int i, j, nstate; - - for (fp = fsm; fp->state>=0; fp++) { - for (i=0; fp->ch[i]; i++) { - nstate = fp->nextstate; - if (nstate >= S_SELF) - nstate = ~nstate; - switch (fp->ch[i]) { - - case C_XX: /* random characters */ - for (j=0; j<256; j++) - bigfsm[j][fp->state] = nstate; - continue; - case C_ALPH: - for (j=0; j<=256; j++) - if (('a'<=j&&j<='z') || ('A'<=j&&j<='Z') - || j=='_') - bigfsm[j][fp->state] = nstate; - continue; - case C_NUM: - for (j='0'; j<='9'; j++) - bigfsm[j][fp->state] = nstate; - continue; - default: - bigfsm[fp->ch[i]][fp->state] = nstate; - } - } - } - /* install special cases for ? (trigraphs), \ (splicing), runes, and EOB */ - for (i=0; i<MAXSTATE; i++) { - for (j=0; j<0xFF; j++) - if (j=='?' || j=='\\') { - if (bigfsm[j][i]>0) - bigfsm[j][i] = ~bigfsm[j][i]; - bigfsm[j][i] &= ~QBSBIT; - } - bigfsm[EOB][i] = ~S_EOB; - if (bigfsm[EOFC][i]>=0) - bigfsm[EOFC][i] = ~S_EOF; - } -} - -void -fixlex(void) -{ - /* do C++ comments? */ - if (Cplusplus==0) - bigfsm['/'][COM1] = bigfsm['x'][COM1]; -} - -/* - * fill in a row of tokens from input, terminated by NL or END - * First token is put at trp->lp. - * Reset is non-zero when the input buffer can be "rewound." - * The value is a flag indicating that possible macros have - * been seen in the row. - */ -int -gettokens(Tokenrow *trp, int reset) -{ - register int c, state, oldstate; - register uchar *ip; - register Token *tp, *maxp; - int runelen; - Source *s = cursource; - int nmac = 0; - - tp = trp->lp; - ip = s->inp; - if (reset) { - s->lineinc = 0; - if (ip>=s->inl) { /* nothing in buffer */ - s->inl = s->inb; - fillbuf(s); - ip = s->inp = s->inb; - } else if (ip >= s->inb+(3*INS/4)) { - memmove(s->inb, ip, 4+s->inl-ip); - s->inl = s->inb+(s->inl-ip); - ip = s->inp = s->inb; - } - } - maxp = &trp->bp[trp->max]; - runelen = 1; - for (;;) { - continue2: - if (tp>=maxp) { - trp->lp = tp; - tp = growtokenrow(trp); - maxp = &trp->bp[trp->max]; - } - tp->type = UNCLASS; - tp->hideset = 0; - tp->t = ip; - tp->wslen = 0; - tp->flag = 0; - state = START; - for (;;) { - oldstate = state; - c = *ip; - if ((state = bigfsm[c][state]) >= 0) { - ip += runelen; - runelen = 1; - continue; - } - state = ~state; - reswitch: - switch (state&0177) { - case S_SELF: - ip += runelen; - runelen = 1; - case S_SELFB: - tp->type = GETACT(state); - tp->len = ip - tp->t; - tp++; - goto continue2; - - case S_NAME: /* like S_SELFB but with nmac check */ - tp->type = NAME; - tp->len = ip - tp->t; - nmac |= quicklook(tp->t[0], tp->len>1?tp->t[1]:0); - tp++; - goto continue2; - - case S_WS: - tp->wslen = ip - tp->t; - tp->t = ip; - state = START; - continue; - - default: - if ((state&QBSBIT)==0) { - ip += runelen; - runelen = 1; - continue; - } - state &= ~QBSBIT; - s->inp = ip; - if (c=='?') { /* check trigraph */ - if (trigraph(s)) { - state = oldstate; - continue; - } - goto reswitch; - } - if (c=='\\') { /* line-folding */ - if (foldline(s)) { - s->lineinc++; - state = oldstate; - continue; - } - goto reswitch; - } - error(WARNING, "Lexical botch in cpp"); - ip += runelen; - runelen = 1; - continue; - - case S_EOB: - s->inp = ip; - fillbuf(cursource); - state = oldstate; - continue; - - case S_EOF: - tp->type = END; - tp->len = 0; - s->inp = ip; - if (tp!=trp->bp && (tp-1)->type!=NL && cursource->fd!=-1) - error(WARNING,"No newline at end of file"); - trp->lp = tp+1; - return nmac; - - case S_STNL: - error(ERROR, "Unterminated string or char const"); - case S_NL: - tp->t = ip; - tp->type = NL; - tp->len = 1; - tp->wslen = 0; - s->lineinc++; - s->inp = ip+1; - trp->lp = tp+1; - return nmac; - - case S_EOFSTR: - error(FATAL, "EOF in string or char constant"); - break; - - case S_COMNL: - s->lineinc++; - state = COM2; - ip += runelen; - runelen = 1; - if (ip >= s->inb+(7*INS/8)) { /* very long comment */ - memmove(tp->t, ip, 4+s->inl-ip); - s->inl -= ip-tp->t; - ip = tp->t+1; - } - continue; - - case S_EOFCOM: - error(WARNING, "EOF inside comment"); - --ip; - case S_COMMENT: - ++ip; - tp->t = ip; - tp->t[-1] = ' '; - tp->wslen = 1; - state = START; - continue; - } - break; - } - ip += runelen; - runelen = 1; - tp->len = ip - tp->t; - tp++; - } -} - -/* have seen ?; handle the trigraph it starts (if any) else 0 */ -int -trigraph(Source *s) -{ - int c; - - while (s->inp+2 >= s->inl && fillbuf(s)!=EOF) - ; - if (s->inp[1]!='?') - return 0; - c = 0; - switch(s->inp[2]) { - case '=': - c = '#'; break; - case '(': - c = '['; break; - case '/': - c = '\\'; break; - case ')': - c = ']'; break; - case '\'': - c = '^'; break; - case '<': - c = '{'; break; - case '!': - c = '|'; break; - case '>': - c = '}'; break; - case '-': - c = '~'; break; - } - if (c) { - *s->inp = c; - memmove(s->inp+1, s->inp+3, s->inl-s->inp+2); - s->inl -= 2; - } - return c; -} - -int -foldline(Source *s) -{ - while (s->inp+1 >= s->inl && fillbuf(s)!=EOF) - ; - if (s->inp[1] == '\n') { - memmove(s->inp, s->inp+2, s->inl-s->inp+3); - s->inl -= 2; - return 1; - } - return 0; -} - -int -fillbuf(Source *s) -{ - int n, nr; - - nr = INS/8; - if ((char *)s->inl+nr > (char *)s->inb+INS) - error(FATAL, "Input buffer overflow"); - if (s->fd<0 || (n=read(s->fd, (char *)s->inl, INS/8)) <= 0) - n = 0; - if ((*s->inp&0xff) == EOB) /* sentinel character appears in input */ - *s->inp = EOFC; - s->inl += n; - s->inl[0] = s->inl[1]= s->inl[2]= s->inl[3] = EOB; - if (n==0) { - s->inl[0] = s->inl[1]= s->inl[2]= s->inl[3] = EOFC; - return EOF; - } - return 0; -} - -/* - * Push down to new source of characters. - * If fd>0 and str==NULL, then from a file `name'; - * if fd==-1 and str, then from the string. - */ -Source * -setsource(char *name, int fd, char *str) -{ - Source *s = new(Source); - int len; - - s->line = 1; - s->lineinc = 0; - s->fd = fd; - s->filename = name; - s->next = cursource; - s->ifdepth = 0; - cursource = s; - /* slop at right for EOB */ - if (str) { - len = strlen(str); - s->inb = domalloc(len+4); - s->inp = s->inb; - strncpy((char *)s->inp, str, len); - } else { - s->inb = domalloc(INS+4); - s->inp = s->inb; - len = 0; - } - s->inl = s->inp+len; - s->inl[0] = s->inl[1] = EOB; - return s; -} - -void -unsetsource(void) -{ - Source *s = cursource; - - if (s->fd>=0) { - close(s->fd); - dofree(s->inb); - } - cursource = s->next; - dofree(s); -} |