Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

tokens.c (6800B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include "cpp.h"
      5 
      6 static char wbuf[2*OBS];
      7 static char *wbp = wbuf;
      8 
      9 /*
     10  * 1 for tokens that don't need whitespace when they get inserted
     11  * by macro expansion
     12  */
     13 static const char wstab[] = {
     14 	0,	/* END */
     15 	0,	/* UNCLASS */
     16 	0,	/* NAME */
     17 	0,	/* NUMBER */
     18 	0,	/* STRING */
     19 	0,	/* CCON */
     20 	1,	/* NL */
     21 	0,	/* WS */
     22 	0,	/* DSHARP */
     23 	0,	/* EQ */
     24 	0,	/* NEQ */
     25 	0,	/* LEQ */
     26 	0,	/* GEQ */
     27 	0,	/* LSH */
     28 	0,	/* RSH */
     29 	0,	/* LAND */
     30 	0,	/* LOR */
     31 	0,	/* PPLUS */
     32 	0,	/* MMINUS */
     33 	0,	/* ARROW */
     34 	1,	/* SBRA */
     35 	1,	/* SKET */
     36 	1,	/* LP */
     37 	1,	/* RP */
     38 	0,	/* DOT */
     39 	0,	/* AND */
     40 	0,	/* STAR */
     41 	0,	/* PLUS */
     42 	0,	/* MINUS */
     43 	0,	/* TILDE */
     44 	0,	/* NOT */
     45 	0,	/* SLASH */
     46 	0,	/* PCT */
     47 	0,	/* LT */
     48 	0,	/* GT */
     49 	0,	/* CIRC */
     50 	0,	/* OR */
     51 	0,	/* QUEST */
     52 	0,	/* COLON */
     53 	0,	/* ASGN */
     54 	1,	/* COMMA */
     55 	0,	/* SHARP */
     56 	1,	/* SEMIC */
     57 	1,	/* CBRA */
     58 	1,	/* CKET */
     59 	0,	/* ASPLUS */
     60  	0,	/* ASMINUS */
     61  	0,	/* ASSTAR */
     62  	0,	/* ASSLASH */
     63  	0,	/* ASPCT */
     64  	0,	/* ASCIRC */
     65  	0,	/* ASLSH */
     66 	0,	/* ASRSH */
     67  	0,	/* ASOR */
     68  	0,	/* ASAND */
     69 	0,	/* ELLIPS */
     70 	0,	/* DSHARP1 */
     71 	0,	/* NAME1 */
     72 	0,	/* DEFINED */
     73 	0,	/* UMINUS */
     74 };
     75 
     76 void
     77 maketokenrow(int size, Tokenrow *trp)
     78 {
     79 	trp->max = size;
     80 	if (size>0)
     81 		trp->bp = (Token *)domalloc(size*sizeof(Token));
     82 	else
     83 		trp->bp = NULL;
     84 	trp->tp = trp->bp;
     85 	trp->lp = trp->bp;
     86 }
     87 
     88 Token *
     89 growtokenrow(Tokenrow *trp)
     90 {
     91 	int ncur = trp->tp - trp->bp;
     92 	int nlast = trp->lp - trp->bp;
     93 
     94 	trp->max = 3*trp->max/2 + 1;
     95 	trp->bp = (Token *)realloc(trp->bp, trp->max*sizeof(Token));
     96 	if (trp->bp == NULL)
     97 		error(FATAL, "Out of memory from realloc");
     98 	trp->lp = &trp->bp[nlast];
     99 	trp->tp = &trp->bp[ncur];
    100 	return trp->lp;
    101 }
    102 
    103 /*
    104  * Compare a row of tokens, ignoring the content of WS; return !=0 if different
    105  */
    106 int
    107 comparetokens(Tokenrow *tr1, Tokenrow *tr2)
    108 {
    109 	Token *tp1, *tp2;
    110 
    111 	tp1 = tr1->tp;
    112 	tp2 = tr2->tp;
    113 	if (tr1->lp-tp1 != tr2->lp-tp2)
    114 		return 1;
    115 	for (; tp1<tr1->lp ; tp1++, tp2++) {
    116 		if (tp1->type != tp2->type
    117 		 || (tp1->wslen==0) != (tp2->wslen==0)
    118 		 || tp1->len != tp2->len
    119 		 || strncmp((char*)tp1->t, (char*)tp2->t, tp1->len)!=0)
    120 			return 1;
    121 	}
    122 	return 0;
    123 }
    124 
    125 /*
    126  * replace ntok tokens starting at dtr->tp with the contents of str.
    127  * tp ends up pointing just beyond the replacement.
    128  * Canonical whitespace is assured on each side.
    129  */
    130 void
    131 insertrow(Tokenrow *dtr, int ntok, Tokenrow *str)
    132 {
    133 	int nrtok = rowlen(str);
    134 
    135 	dtr->tp += ntok;
    136 	adjustrow(dtr, nrtok-ntok);
    137 	dtr->tp -= ntok;
    138 	movetokenrow(dtr, str);
    139 	makespace(dtr);
    140 	dtr->tp += nrtok;
    141 	makespace(dtr);
    142 }
    143 
    144 /*
    145  * make sure there is WS before trp->tp, if tokens might merge in the output
    146  */
    147 void
    148 makespace(Tokenrow *trp)
    149 {
    150 	uchar *tt;
    151 	Token *tp = trp->tp;
    152 
    153 	if (tp >= trp->lp)
    154 		return;
    155 	if (tp->wslen) {
    156 		if (tp->flag&XPWS
    157 		 && (wstab[tp->type] || trp->tp>trp->bp && wstab[(tp-1)->type])) {
    158 			tp->wslen = 0;
    159 			return;
    160 		}
    161 		tp->t[-1] = ' ';
    162 		return;
    163 	}
    164 	if (wstab[tp->type] || trp->tp>trp->bp && wstab[(tp-1)->type])
    165 		return;
    166 	tt = newstring(tp->t, tp->len, 1);
    167 	*tt++ = ' ';
    168 	tp->t = tt;
    169 	tp->wslen = 1;
    170 	tp->flag |= XPWS;
    171 }
    172 
    173 /*
    174  * Copy an entire tokenrow into another, at tp.
    175  * It is assumed that there is enough space.
    176  *  Not strictly conforming.
    177  */
    178 void
    179 movetokenrow(Tokenrow *dtr, Tokenrow *str)
    180 {
    181 	int nby;
    182 
    183 	/* nby = sizeof(Token) * (str->lp - str->bp); */
    184 	nby = (char *)str->lp - (char *)str->bp;
    185 	memmove(dtr->tp, str->bp, nby);
    186 }
    187 
    188 /*
    189  * Move the tokens in a row, starting at tr->tp, rightward by nt tokens;
    190  * nt may be negative (left move).
    191  * The row may need to be grown.
    192  * Non-strictly conforming because of the (char *), but easily fixed
    193  */
    194 void
    195 adjustrow(Tokenrow *trp, int nt)
    196 {
    197 	int nby, size;
    198 
    199 	if (nt==0)
    200 		return;
    201 	size = (trp->lp - trp->bp) + nt;
    202 	while (size > trp->max)
    203 		growtokenrow(trp);
    204 	/* nby = sizeof(Token) * (trp->lp - trp->tp); */
    205 	nby = (char *)trp->lp - (char *)trp->tp;
    206 	if (nby)
    207 		memmove(trp->tp+nt, trp->tp, nby);
    208 	trp->lp += nt;
    209 }
    210 
    211 /*
    212  * Copy a row of tokens into the destination holder, allocating
    213  * the space for the contents.  Return the destination.
    214  */
    215 Tokenrow *
    216 copytokenrow(Tokenrow *dtr, Tokenrow *str)
    217 {
    218 	int len = rowlen(str);
    219 
    220 	maketokenrow(len, dtr);
    221 	movetokenrow(dtr, str);
    222 	dtr->lp += len;
    223 	return dtr;
    224 }
    225 
    226 /*
    227  * Produce a copy of a row of tokens.  Start at trp->tp.
    228  * The value strings are copied as well.  The first token
    229  * has WS available.
    230  */
    231 Tokenrow *
    232 normtokenrow(Tokenrow *trp)
    233 {
    234 	Token *tp;
    235 	Tokenrow *ntrp = new(Tokenrow);
    236 	int len;
    237 
    238 	len = trp->lp - trp->tp;
    239 	if (len<=0)
    240 		len = 1;
    241 	maketokenrow(len, ntrp);
    242 	for (tp=trp->tp; tp < trp->lp; tp++) {
    243 		*ntrp->lp = *tp;
    244 		if (tp->len) {
    245 			ntrp->lp->t = newstring(tp->t, tp->len, 1);
    246 			*ntrp->lp->t++ = ' ';
    247 			if (tp->wslen)
    248 				ntrp->lp->wslen = 1;
    249 		}
    250 		ntrp->lp++;
    251 	}
    252 	if (ntrp->lp > ntrp->bp)
    253 		ntrp->bp->wslen = 0;
    254 	return ntrp;
    255 }
    256 
    257 /*
    258  * Debugging
    259  */
    260 void
    261 peektokens(Tokenrow *trp, char *str)
    262 {
    263 	Token *tp;
    264 
    265 	tp = trp->tp;
    266 	flushout();
    267 	if (str)
    268 		fprintf(stderr, "%s ", str);
    269 	if (tp<trp->bp || tp>trp->lp)
    270 		fprintf(stderr, "(tp offset %d) ", tp-trp->bp);
    271 	for (tp=trp->bp; tp<trp->lp && tp<trp->bp+32; tp++) {
    272 		if (tp->type!=NL) {
    273 			int c = tp->t[tp->len];
    274 			tp->t[tp->len] = 0;
    275 			fprintf(stderr, "%s", tp->t);
    276 			tp->t[tp->len] = c;
    277 		}
    278 		if (tp->type==NAME) {
    279 			fprintf(stderr, tp==trp->tp?"{*":"{");
    280 			prhideset(tp->hideset);
    281 			fprintf(stderr, "} ");
    282 		} else
    283 			fprintf(stderr, tp==trp->tp?"{%x*} ":"{%x} ", tp->type);
    284 	}
    285 	fprintf(stderr, "\n");
    286 	fflush(stderr);
    287 }
    288 
    289 void
    290 puttokens(Tokenrow *trp)
    291 {
    292 	Token *tp;
    293 	int len;
    294 	uchar *p;
    295 
    296 	if (verbose)
    297 		peektokens(trp, "");
    298 	tp = trp->bp;
    299 	for (; tp<trp->lp; tp++) {
    300 		len = tp->len+tp->wslen;
    301 		p = tp->t-tp->wslen;
    302 		while (tp<trp->lp-1 && p+len == (tp+1)->t - (tp+1)->wslen) {
    303 			tp++;
    304 			len += tp->wslen+tp->len;
    305 		}
    306 		if (len>OBS/2) {		/* handle giant token */
    307 			if (wbp > wbuf)
    308 				write(1, wbuf, wbp-wbuf);
    309 			write(1, (char *)p, len);
    310 			wbp = wbuf;
    311 		} else {	
    312 			memcpy(wbp, p, len);
    313 			wbp += len;
    314 		}
    315 		if (wbp >= &wbuf[OBS]) {
    316 			write(1, wbuf, OBS);
    317 			if (wbp > &wbuf[OBS])
    318 				memcpy(wbuf, wbuf+OBS, wbp - &wbuf[OBS]);
    319 			wbp -= OBS;
    320 		}
    321 	}
    322 	trp->tp = tp;
    323 	if (cursource->fd==0)
    324 		flushout();
    325 }
    326 
    327 void
    328 flushout(void)
    329 {
    330 	if (wbp>wbuf) {
    331 		write(1, wbuf, wbp-wbuf);
    332 		wbp = wbuf;
    333 	}
    334 }
    335 
    336 /*
    337  * turn a row into just a newline
    338  */
    339 void
    340 setempty(Tokenrow *trp)
    341 {
    342 	trp->tp = trp->bp;
    343 	trp->lp = trp->bp+1;
    344 	*trp->bp = nltoken;
    345 }
    346 
    347 /*
    348  * generate a number
    349  */
    350 char *
    351 outnum(char *p, int n)
    352 {
    353 	if (n>=10)
    354 		p = outnum(p, n/10);
    355 	*p++ = n%10 + '0';
    356 	return p;
    357 }
    358 
    359 /*
    360  * allocate and initialize a new string from s, of length l, at offset o
    361  * Null terminated.
    362  */
    363 uchar *
    364 newstring(uchar *s, int l, int o)
    365 {
    366 	uchar *ns = (uchar *)domalloc(l+o+1);
    367 
    368 	ns[l+o] = '\0';
    369 	return (uchar*)strncpy((char*)ns+o, (char*)s, l) - o;
    370 }