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 }