Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

tokens.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include "cpp.h"
00005 
00006 static char wbuf[2*OBS];
00007 static char *wbp = wbuf;
00008 
00009 /*
00010  * 1 for tokens that don't need whitespace when they get inserted
00011  * by macro expansion
00012  */
00013 static const char wstab[] = {
00014     0,  /* END */
00015     0,  /* UNCLASS */
00016     0,  /* NAME */
00017     0,  /* NUMBER */
00018     0,  /* STRING */
00019     0,  /* CCON */
00020     1,  /* NL */
00021     0,  /* WS */
00022     0,  /* DSHARP */
00023     0,  /* EQ */
00024     0,  /* NEQ */
00025     0,  /* LEQ */
00026     0,  /* GEQ */
00027     0,  /* LSH */
00028     0,  /* RSH */
00029     0,  /* LAND */
00030     0,  /* LOR */
00031     0,  /* PPLUS */
00032     0,  /* MMINUS */
00033     0,  /* ARROW */
00034     1,  /* SBRA */
00035     1,  /* SKET */
00036     1,  /* LP */
00037     1,  /* RP */
00038     0,  /* DOT */
00039     0,  /* AND */
00040     0,  /* STAR */
00041     0,  /* PLUS */
00042     0,  /* MINUS */
00043     0,  /* TILDE */
00044     0,  /* NOT */
00045     0,  /* SLASH */
00046     0,  /* PCT */
00047     0,  /* LT */
00048     0,  /* GT */
00049     0,  /* CIRC */
00050     0,  /* OR */
00051     0,  /* QUEST */
00052     0,  /* COLON */
00053     0,  /* ASGN */
00054     1,  /* COMMA */
00055     0,  /* SHARP */
00056     1,  /* SEMIC */
00057     1,  /* CBRA */
00058     1,  /* CKET */
00059     0,  /* ASPLUS */
00060     0,  /* ASMINUS */
00061     0,  /* ASSTAR */
00062     0,  /* ASSLASH */
00063     0,  /* ASPCT */
00064     0,  /* ASCIRC */
00065     0,  /* ASLSH */
00066     0,  /* ASRSH */
00067     0,  /* ASOR */
00068     0,  /* ASAND */
00069     0,  /* ELLIPS */
00070     0,  /* DSHARP1 */
00071     0,  /* NAME1 */
00072     0,  /* DEFINED */
00073     0,  /* UMINUS */
00074 };
00075 
00076 void
00077 maketokenrow(int size, Tokenrow *trp)
00078 {
00079     trp->max = size;
00080     if (size>0)
00081         trp->bp = (Token *)domalloc(size*sizeof(Token));
00082     else
00083         trp->bp = NULL;
00084     trp->tp = trp->bp;
00085     trp->lp = trp->bp;
00086 }
00087 
00088 Token *
00089 growtokenrow(Tokenrow *trp)
00090 {
00091     int ncur = trp->tp - trp->bp;
00092     int nlast = trp->lp - trp->bp;
00093 
00094     trp->max = 3*trp->max/2 + 1;
00095     trp->bp = (Token *)realloc(trp->bp, trp->max*sizeof(Token));
00096     if (trp->bp == NULL)
00097         error(FATAL, "Out of memory from realloc");
00098     trp->lp = &trp->bp[nlast];
00099     trp->tp = &trp->bp[ncur];
00100     return trp->lp;
00101 }
00102 
00103 /*
00104  * Compare a row of tokens, ignoring the content of WS; return !=0 if different
00105  */
00106 int
00107 comparetokens(Tokenrow *tr1, Tokenrow *tr2)
00108 {
00109     Token *tp1, *tp2;
00110 
00111     tp1 = tr1->tp;
00112     tp2 = tr2->tp;
00113     if (tr1->lp-tp1 != tr2->lp-tp2)
00114         return 1;
00115     for (; tp1<tr1->lp ; tp1++, tp2++) {
00116         if (tp1->type != tp2->type
00117          || (tp1->wslen==0) != (tp2->wslen==0)
00118          || tp1->len != tp2->len
00119          || strncmp((char*)tp1->t, (char*)tp2->t, tp1->len)!=0)
00120             return 1;
00121     }
00122     return 0;
00123 }
00124 
00125 /*
00126  * replace ntok tokens starting at dtr->tp with the contents of str.
00127  * tp ends up pointing just beyond the replacement.
00128  * Canonical whitespace is assured on each side.
00129  */
00130 void
00131 insertrow(Tokenrow *dtr, int ntok, Tokenrow *str)
00132 {
00133     int nrtok = rowlen(str);
00134 
00135     dtr->tp += ntok;
00136     adjustrow(dtr, nrtok-ntok);
00137     dtr->tp -= ntok;
00138     movetokenrow(dtr, str);
00139     makespace(dtr);
00140     dtr->tp += nrtok;
00141     makespace(dtr);
00142 }
00143 
00144 /*
00145  * make sure there is WS before trp->tp, if tokens might merge in the output
00146  */
00147 void
00148 makespace(Tokenrow *trp)
00149 {
00150     uchar *tt;
00151     Token *tp = trp->tp;
00152 
00153     if (tp >= trp->lp)
00154         return;
00155     if (tp->wslen) {
00156         if (tp->flag&XPWS
00157          && (wstab[tp->type] || trp->tp>trp->bp && wstab[(tp-1)->type])) {
00158             tp->wslen = 0;
00159             return;
00160         }
00161         tp->t[-1] = ' ';
00162         return;
00163     }
00164     if (wstab[tp->type] || trp->tp>trp->bp && wstab[(tp-1)->type])
00165         return;
00166     tt = newstring(tp->t, tp->len, 1);
00167     *tt++ = ' ';
00168     tp->t = tt;
00169     tp->wslen = 1;
00170     tp->flag |= XPWS;
00171 }
00172 
00173 /*
00174  * Copy an entire tokenrow into another, at tp.
00175  * It is assumed that there is enough space.
00176  *  Not strictly conforming.
00177  */
00178 void
00179 movetokenrow(Tokenrow *dtr, Tokenrow *str)
00180 {
00181     int nby;
00182 
00183     /* nby = sizeof(Token) * (str->lp - str->bp); */
00184     nby = (char *)str->lp - (char *)str->bp;
00185     memmove(dtr->tp, str->bp, nby);
00186 }
00187 
00188 /*
00189  * Move the tokens in a row, starting at tr->tp, rightward by nt tokens;
00190  * nt may be negative (left move).
00191  * The row may need to be grown.
00192  * Non-strictly conforming because of the (char *), but easily fixed
00193  */
00194 void
00195 adjustrow(Tokenrow *trp, int nt)
00196 {
00197     int nby, size;
00198 
00199     if (nt==0)
00200         return;
00201     size = (trp->lp - trp->bp) + nt;
00202     while (size > trp->max)
00203         growtokenrow(trp);
00204     /* nby = sizeof(Token) * (trp->lp - trp->tp); */
00205     nby = (char *)trp->lp - (char *)trp->tp;
00206     if (nby)
00207         memmove(trp->tp+nt, trp->tp, nby);
00208     trp->lp += nt;
00209 }
00210 
00211 /*
00212  * Copy a row of tokens into the destination holder, allocating
00213  * the space for the contents.  Return the destination.
00214  */
00215 Tokenrow *
00216 copytokenrow(Tokenrow *dtr, Tokenrow *str)
00217 {
00218     int len = rowlen(str);
00219 
00220     maketokenrow(len, dtr);
00221     movetokenrow(dtr, str);
00222     dtr->lp += len;
00223     return dtr;
00224 }
00225 
00226 /*
00227  * Produce a copy of a row of tokens.  Start at trp->tp.
00228  * The value strings are copied as well.  The first token
00229  * has WS available.
00230  */
00231 Tokenrow *
00232 normtokenrow(Tokenrow *trp)
00233 {
00234     Token *tp;
00235     Tokenrow *ntrp = new(Tokenrow);
00236     int len;
00237 
00238     len = trp->lp - trp->tp;
00239     if (len<=0)
00240         len = 1;
00241     maketokenrow(len, ntrp);
00242     for (tp=trp->tp; tp < trp->lp; tp++) {
00243         *ntrp->lp = *tp;
00244         if (tp->len) {
00245             ntrp->lp->t = newstring(tp->t, tp->len, 1);
00246             *ntrp->lp->t++ = ' ';
00247             if (tp->wslen)
00248                 ntrp->lp->wslen = 1;
00249         }
00250         ntrp->lp++;
00251     }
00252     if (ntrp->lp > ntrp->bp)
00253         ntrp->bp->wslen = 0;
00254     return ntrp;
00255 }
00256 
00257 /*
00258  * Debugging
00259  */
00260 void
00261 peektokens(Tokenrow *trp, char *str)
00262 {
00263     Token *tp;
00264 
00265     tp = trp->tp;
00266     flushout();
00267     if (str)
00268         fprintf(stderr, "%s ", str);
00269     if (tp<trp->bp || tp>trp->lp)
00270         fprintf(stderr, "(tp offset %d) ", tp-trp->bp);
00271     for (tp=trp->bp; tp<trp->lp && tp<trp->bp+32; tp++) {
00272         if (tp->type!=NL) {
00273             int c = tp->t[tp->len];
00274             tp->t[tp->len] = 0;
00275             fprintf(stderr, "%s", tp->t);
00276             tp->t[tp->len] = c;
00277         }
00278         if (tp->type==NAME) {
00279             fprintf(stderr, tp==trp->tp?"{*":"{");
00280             prhideset(tp->hideset);
00281             fprintf(stderr, "} ");
00282         } else
00283             fprintf(stderr, tp==trp->tp?"{%x*} ":"{%x} ", tp->type);
00284     }
00285     fprintf(stderr, "\n");
00286     fflush(stderr);
00287 }
00288 
00289 void
00290 puttokens(Tokenrow *trp)
00291 {
00292     Token *tp;
00293     int len;
00294     uchar *p;
00295 
00296     if (verbose)
00297         peektokens(trp, "");
00298     tp = trp->bp;
00299     for (; tp<trp->lp; tp++) {
00300         len = tp->len+tp->wslen;
00301         p = tp->t-tp->wslen;
00302         while (tp<trp->lp-1 && p+len == (tp+1)->t - (tp+1)->wslen) {
00303             tp++;
00304             len += tp->wslen+tp->len;
00305         }
00306         if (len>OBS/2) {        /* handle giant token */
00307             if (wbp > wbuf)
00308                 write(1, wbuf, wbp-wbuf);
00309             write(1, (char *)p, len);
00310             wbp = wbuf;
00311         } else {    
00312             memcpy(wbp, p, len);
00313             wbp += len;
00314         }
00315         if (wbp >= &wbuf[OBS]) {
00316             write(1, wbuf, OBS);
00317             if (wbp > &wbuf[OBS])
00318                 memcpy(wbuf, wbuf+OBS, wbp - &wbuf[OBS]);
00319             wbp -= OBS;
00320         }
00321     }
00322     trp->tp = tp;
00323     if (cursource->fd==0)
00324         flushout();
00325 }
00326 
00327 void
00328 flushout(void)
00329 {
00330     if (wbp>wbuf) {
00331         write(1, wbuf, wbp-wbuf);
00332         wbp = wbuf;
00333     }
00334 }
00335 
00336 /*
00337  * turn a row into just a newline
00338  */
00339 void
00340 setempty(Tokenrow *trp)
00341 {
00342     trp->tp = trp->bp;
00343     trp->lp = trp->bp+1;
00344     *trp->bp = nltoken;
00345 }
00346 
00347 /*
00348  * generate a number
00349  */
00350 char *
00351 outnum(char *p, int n)
00352 {
00353     if (n>=10)
00354         p = outnum(p, n/10);
00355     *p++ = n%10 + '0';
00356     return p;
00357 }
00358 
00359 /*
00360  * allocate and initialize a new string from s, of length l, at offset o
00361  * Null terminated.
00362  */
00363 uchar *
00364 newstring(uchar *s, int l, int o)
00365 {
00366     uchar *ns = (uchar *)domalloc(l+o+1);
00367 
00368     ns[l+o] = '\0';
00369     return (uchar*)strncpy((char*)ns+o, (char*)s, l) - o;
00370 }

Generated on Thu Aug 25 12:38:09 2005 for Quake III Arena by  doxygen 1.3.9.1