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

cpp.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdarg.h>
#include "cpp.h"

Include dependency graph for cpp.c:

Include dependency graph

Go to the source code of this file.

Defines

#define OUTS   16384

Functions

void control (Tokenrow *trp)
void dofree (void *p)
void * domalloc (int size)
void error (enum errtype type, char *string,...)
int main (int argc, char **argv)
void process (Tokenrow *trp)

Variables

Sourcecursource
char * curtime
int ifdepth
int ifsatisfied [NIF]
int incdepth
int nerrs
token nltoken = { NL, 0, 0, 0, 1, (uchar*)"\n" }
char outbuf [OUTS]
char * outp = outbuf
char rcsid [] = "cpp.c - faked rcsid"
int skipping


Define Documentation

#define OUTS   16384
 

Definition at line 10 of file cpp.c.


Function Documentation

void control Tokenrow trp  ) 
 

Definition at line 90 of file cpp.c.

References atol(), tokenrow::bp, cursource, dodefine(), doinclude(), error(), ERROR, eval(), expandrow(), FATAL, source::filename, nlist::flag, ifdepth, source::ifdepth, ifsatisfied, KDEFINE, KDEFINED, KELIF, KELSE, KENDIF, KERROR, KEVAL, KIF, KIFDEF, KIFNDEF, KINCLUDE, KLINE, KPRAGMA, KUNDEF, token::len, source::line, lookup(), tokenrow::lp, NAME, newstring(), Nlist, np, NULL, NUMBER, setempty(), skipping, token::t, Token, Tokenrow, tokenrow::tp, token::type, nlist::val, and WARNING.

Referenced by AAS_ApplyFriction(), Controls_Update(), PM_Friction(), PM_NoclipMove(), and process().

00091 {
00092     Nlist *np;
00093     Token *tp;
00094 
00095     tp = trp->tp;
00096     if (tp->type!=NAME) {
00097         if (tp->type==NUMBER)
00098             goto kline;
00099         if (tp->type != NL)
00100             error(ERROR, "Unidentifiable control line");
00101         return;         /* else empty line */
00102     }
00103     if ((np = lookup(tp, 0))==NULL || (np->flag&ISKW)==0 && !skipping) {
00104         error(WARNING, "Unknown preprocessor control %t", tp);
00105         return;
00106     }
00107     if (skipping) {
00108         switch (np->val) {
00109         case KENDIF:
00110             if (--ifdepth<skipping)
00111                 skipping = 0;
00112             --cursource->ifdepth;
00113             setempty(trp);
00114             return;
00115 
00116         case KIFDEF:
00117         case KIFNDEF:
00118         case KIF:
00119             if (++ifdepth >= NIF)
00120                 error(FATAL, "#if too deeply nested");
00121             ++cursource->ifdepth;
00122             return;
00123 
00124         case KELIF:
00125         case KELSE:
00126             if (ifdepth<=skipping)
00127                 break;
00128             return;
00129 
00130         default:
00131             return;
00132         }
00133     }
00134     switch (np->val) {
00135     case KDEFINE:
00136         dodefine(trp);
00137         break;
00138 
00139     case KUNDEF:
00140         tp += 1;
00141         if (tp->type!=NAME || trp->lp - trp->bp != 4) {
00142             error(ERROR, "Syntax error in #undef");
00143             break;
00144         }
00145         if ((np = lookup(tp, 0)) != NULL)
00146             np->flag &= ~ISDEFINED;
00147         break;
00148 
00149     case KPRAGMA:
00150         return;
00151 
00152     case KIFDEF:
00153     case KIFNDEF:
00154     case KIF:
00155         if (++ifdepth >= NIF)
00156             error(FATAL, "#if too deeply nested");
00157         ++cursource->ifdepth;
00158         ifsatisfied[ifdepth] = 0;
00159         if (eval(trp, np->val))
00160             ifsatisfied[ifdepth] = 1;
00161         else
00162             skipping = ifdepth;
00163         break;
00164 
00165     case KELIF:
00166         if (ifdepth==0) {
00167             error(ERROR, "#elif with no #if");
00168             return;
00169         }
00170         if (ifsatisfied[ifdepth]==2)
00171             error(ERROR, "#elif after #else");
00172         if (eval(trp, np->val)) {
00173             if (ifsatisfied[ifdepth])
00174                 skipping = ifdepth;
00175             else {
00176                 skipping = 0;
00177                 ifsatisfied[ifdepth] = 1;
00178             }
00179         } else
00180             skipping = ifdepth;
00181         break;
00182 
00183     case KELSE:
00184         if (ifdepth==0 || cursource->ifdepth==0) {
00185             error(ERROR, "#else with no #if");
00186             return;
00187         }
00188         if (ifsatisfied[ifdepth]==2)
00189             error(ERROR, "#else after #else");
00190         if (trp->lp - trp->bp != 3)
00191             error(ERROR, "Syntax error in #else");
00192         skipping = ifsatisfied[ifdepth]? ifdepth: 0;
00193         ifsatisfied[ifdepth] = 2;
00194         break;
00195 
00196     case KENDIF:
00197         if (ifdepth==0 || cursource->ifdepth==0) {
00198             error(ERROR, "#endif with no #if");
00199             return;
00200         }
00201         --ifdepth;
00202         --cursource->ifdepth;
00203         if (trp->lp - trp->bp != 3)
00204             error(WARNING, "Syntax error in #endif");
00205         break;
00206 
00207     case KERROR:
00208         trp->tp = tp+1;
00209         error(WARNING, "#error directive: %r", trp);
00210         break;
00211 
00212     case KLINE:
00213         trp->tp = tp+1;
00214         expandrow(trp, "<line>");
00215         tp = trp->bp+2;
00216     kline:
00217         if (tp+1>=trp->lp || tp->type!=NUMBER || tp+3<trp->lp
00218          || (tp+3==trp->lp && ((tp+1)->type!=STRING)||*(tp+1)->t=='L')){
00219             error(ERROR, "Syntax error in #line");
00220             return;
00221         }
00222         cursource->line = atol((char*)tp->t)-1;
00223         if (cursource->line<0 || cursource->line>=32768)
00224             error(WARNING, "#line specifies number out of range");
00225         tp = tp+1;
00226         if (tp+1<trp->lp)
00227             cursource->filename=(char*)newstring(tp->t+1,tp->len-2,0);
00228         return;
00229 
00230     case KDEFINED:
00231         error(ERROR, "Bad syntax for control line");
00232         break;
00233 
00234     case KINCLUDE:
00235         doinclude(trp);
00236         trp->lp = trp->bp;
00237         return;
00238 
00239     case KEVAL:
00240         eval(trp, np->val);
00241         break;
00242 
00243     default:
00244         error(ERROR, "Preprocessor control `%t' not yet implemented", tp);
00245         break;
00246     }
00247     setempty(trp);
00248     return;
00249 }

Here is the call graph for this function:

void dofree void *  p  ) 
 

Definition at line 262 of file cpp.c.

References free(), and p.

Referenced by doconcat(), dodefine(), expand(), substargs(), and unsetsource().

00263 {
00264     free(p);
00265 }

Here is the call graph for this function:

void* domalloc int  size  ) 
 

Definition at line 252 of file cpp.c.

References error(), FATAL, malloc(), and p.

Referenced by iniths(), maketokenrow(), newhideset(), newstring(), setobjname(), and setsource().

00253 {
00254     void *p = malloc(size);
00255 
00256     if (p==NULL)
00257         error(FATAL, "Out of memory from malloc");
00258     return p;
00259 }

Here is the call graph for this function:

void error enum errtype  type,
char *  string,
  ...
 

Definition at line 268 of file cpp.c.

Referenced by Com_Error(), Error(), NET_GetLocalAddress(), PC_EvaluateTokens(), Sys_Error(), TestEdge(), and Warning().

00269 {
00270     va_list ap;
00271     char *cp, *ep;
00272     Token *tp;
00273     Tokenrow *trp;
00274     Source *s;
00275     int i;
00276 
00277     fprintf(stderr, "cpp: ");
00278     for (s=cursource; s; s=s->next)
00279         if (*s->filename)
00280             fprintf(stderr, "%s:%d ", s->filename, s->line);
00281     va_start(ap, string);
00282     for (ep=string; *ep; ep++) {
00283         if (*ep=='%') {
00284             switch (*++ep) {
00285 
00286             case 's':
00287                 cp = va_arg(ap, char *);
00288                 fprintf(stderr, "%s", cp);
00289                 break;
00290             case 'd':
00291                 i = va_arg(ap, int);
00292                 fprintf(stderr, "%d", i);
00293                 break;
00294             case 't':
00295                 tp = va_arg(ap, Token *);
00296                 fprintf(stderr, "%.*s", tp->len, tp->t);
00297                 break;
00298 
00299             case 'r':
00300                 trp = va_arg(ap, Tokenrow *);
00301                 for (tp=trp->tp; tp<trp->lp&&tp->type!=NL; tp++) {
00302                     if (tp>trp->tp && tp->wslen)
00303                         fputc(' ', stderr);
00304                     fprintf(stderr, "%.*s", tp->len, tp->t);
00305                 }
00306                 break;
00307 
00308             default:
00309                 fputc(*ep, stderr);
00310                 break;
00311             }
00312         } else
00313             fputc(*ep, stderr);
00314     }
00315     va_end(ap);
00316     fputc('\n', stderr);
00317     if (type==FATAL)
00318         exit(1);
00319     if (type!=WARNING)
00320         nerrs = 1;
00321     fflush(stderr);
00322 }

int main int  argc,
char **  argv
 

Definition at line 24 of file cpp.c.

References argc, argv, ctime(), curtime, exit(), expandlex(), fflush(), fixlex(), flushout(), genline(), iniths(), maketokenrow(), nerrs, NULL, process(), setbuf(), setup(), stderr, t, time(), time_t, Tokenrow, and tr.

00025 {
00026     Tokenrow tr;
00027     time_t t;
00028     char ebuf[BUFSIZ];
00029 
00030     setbuf(stderr, ebuf);
00031     t = time(NULL);
00032     curtime = ctime(&t);
00033     maketokenrow(3, &tr);
00034     expandlex();
00035     setup(argc, argv);
00036     fixlex();
00037     iniths();
00038     genline();
00039     process(&tr);
00040     flushout();
00041     fflush(stderr);
00042     exit(nerrs > 0);
00043     return 0;
00044 }

Here is the call graph for this function:

void process Tokenrow trp  ) 
 

Definition at line 47 of file cpp.c.

00048 {
00049     int anymacros = 0;
00050 
00051     for (;;) {
00052         if (trp->tp >= trp->lp) {
00053             trp->tp = trp->lp = trp->bp;
00054             outp = outbuf;
00055             anymacros |= gettokens(trp, 1);
00056             trp->tp = trp->bp;
00057         }
00058         if (trp->tp->type == END) {
00059             if (--incdepth>=0) {
00060                 if (cursource->ifdepth)
00061                     error(ERROR,
00062                      "Unterminated conditional in #include");
00063                 unsetsource();
00064                 cursource->line += cursource->lineinc;
00065                 trp->tp = trp->lp;
00066                 genline();
00067                 continue;
00068             }
00069             if (ifdepth)
00070                 error(ERROR, "Unterminated #if/#ifdef/#ifndef");
00071             break;
00072         }
00073         if (trp->tp->type==SHARP) {
00074             trp->tp += 1;
00075             control(trp);
00076         } else if (!skipping && anymacros)
00077             expandrow(trp, NULL);
00078         if (skipping)
00079             setempty(trp);
00080         puttokens(trp);
00081         anymacros = 0;
00082         cursource->line += cursource->lineinc;
00083         if (cursource->lineinc>1) {
00084             genline();
00085         }
00086     }
00087 }


Variable Documentation

Source* cursource
 

Definition at line 13 of file cpp.c.

Referenced by control(), genline(), gettokens(), process(), puttokens(), setsource(), and unsetsource().

char* curtime
 

Definition at line 16 of file cpp.c.

int ifdepth
 

Definition at line 18 of file cpp.c.

Referenced by control().

int ifsatisfied[NIF]
 

Definition at line 19 of file cpp.c.

Referenced by control().

int incdepth
 

Definition at line 17 of file cpp.c.

Referenced by doinclude(), and process().

int nerrs
 

Definition at line 14 of file cpp.c.

Referenced by error(), and main().

struct token nltoken = { NL, 0, 0, 0, 1, (uchar*)"\n" }
 

Definition at line 15 of file cpp.c.

char outbuf[OUTS]
 

Definition at line 11 of file cpp.c.

Referenced by gettokens().

char* outp = outbuf
 

Definition at line 12 of file cpp.c.

Referenced by builtin(), genline(), process(), S_AdpcmDecode(), and S_AdpcmEncode().

char rcsid[] = "cpp.c - faked rcsid"
 

Definition at line 8 of file cpp.c.

Referenced by asdl_progend(), emitheader(), main(), main_init(), opt(), and setup().

int skipping
 

Definition at line 20 of file cpp.c.

Referenced by control(), and process().


Generated on Thu Aug 25 15:47:07 2005 for Quake III Arena by  doxygen 1.3.9.1