PREPROC.C
上传用户:hlzzc88
上传日期:2007-01-06
资源大小:220k
文件大小:19k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*                               `
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. #include        <stdio.h>
  23. #include  <ctype.h>
  24. #include "utype.h"
  25. #include "cmdline.h"
  26. #include        "expr.h"
  27. #include        "c.h"
  28. #include        "errors.h"
  29. #include "time.h"
  30. extern short inputline[];
  31. extern FILE *inputFile;
  32. extern TABLE gsyms,defsyms;
  33. extern long ival;
  34. extern char laststr[];
  35. extern HASHREC **defhash;
  36. extern char *infile;
  37. extern int incconst;
  38. extern char *prm_searchpath;
  39. extern int prm_cplusplus, prm_ansi;
  40. extern short *lptr;
  41. extern int cantnewline;
  42. extern char *infile;
  43. extern int backupchar;
  44. extern int floatregs,dataregs,addrregs,basefr,basedr,basear;
  45. extern int prm_cmangle;
  46. extern enum e_sym lastst;
  47. extern char lastid[];
  48. extern int lastch;
  49. extern int lineno;
  50. extern int global_flag;
  51. typedef struct _list {
  52. struct _list *link;
  53. char *data;
  54. } LIST;
  55. typedef struct _startups_ {
  56. struct _startups_ *link;
  57. char *name;
  58. int prio;
  59. } STARTUPS;
  60. char *errfile;
  61. int errlineno = 0;
  62. IFSTRUCT   *ifshold[10];
  63. char  *inclfname[10];
  64. FILE            *inclfile[10];
  65. int             incldepth = 0;
  66. int             inclline[10];
  67. short            *lptr;
  68. LIST *incfiles = 0,*lastinc;
  69. IFSTRUCT *ifs = 0;
  70. int ifskip = 0;
  71. int elsetaken = 0;
  72. void filemac(short *string);
  73. void datemac(short *string);
  74. void timemac(short *string);
  75. void linemac(short *string);
  76. static char *unmangid; /* In this module we have to ignore leading underscores */
  77. static STARTUPS *startuplist, *rundownlist;
  78. static short defkw[] = { 'd','e','f','i','n','e','d', 0 };
  79. /* List of standard macros */
  80. #define INGROWNMACROS 4
  81. struct inmac {
  82. char *s;
  83. void (*func)();
  84. } ingrownmacros[INGROWNMACROS] = { 
  85. { "__FILE__",filemac }, { "__DATE__",datemac, },
  86. { "__TIME__", timemac }, { "__LINE__",linemac } };
  87. void pushif(void);
  88. /* Moudle init */
  89. void preprocini()
  90. {
  91. floatregs = basefr;
  92. dataregs = basedr;
  93. addrregs = basear;
  94. incldepth = 0;
  95. incfiles = 0;
  96. ifs = 0;
  97. ifskip = elsetaken = 0;
  98. unmangid = lastid;
  99. if (prm_cmangle)
  100. unmangid++;
  101. startuplist = rundownlist = 0;
  102. }
  103. /* Preprocessor dispatch */
  104. int preprocess(void)
  105. {
  106.         ++lptr;
  107.         lastch = ' ';
  108.         getsym();               /* get first word on line */
  109.         if( lastst != id  && lastst != kw_else && lastst!= kw_if) {
  110.                 generror(ERR_IDEXPECT,0,0);
  111.                 return incldepth == 0;
  112.                 }
  113.         if( strcmp(unmangid,"include") == 0 )
  114.                 return doinclude();
  115.         else if( strcmp(unmangid,"define") == 0 )
  116.                 return dodefine();
  117. else if (strcmp(unmangid,"endif") == 0)
  118. return doendif();
  119. else if (lastst == kw_else)
  120. return doelse();
  121. else if (strcmp(unmangid,"ifdef") == 0)
  122. return doifdef(TRUE);
  123. else if (strcmp(unmangid,"ifndef") == 0)
  124. return doifdef(FALSE);
  125. else if (lastst == kw_if) {
  126. repdefines(lptr);
  127. defcheck(lptr);
  128. return doif(0);
  129. }
  130.         else if( strcmp(unmangid,"elif") == 0 ) {
  131. repdefines(lptr);
  132. defcheck(lptr);
  133.                 return doelif();
  134. }
  135. else if (strcmp(unmangid,"undef") == 0)
  136. return(doundef());
  137. else if (strcmp(unmangid,"error") == 0)
  138. return(doerror());
  139. else if (strcmp(unmangid,"pragma") == 0)
  140. return(dopragma());
  141. else if (strcmp(unmangid,"line") == 0)
  142. return(doline());
  143.         else    {
  144.                 gensymerror(ERR_PREPROCID,unmangid);
  145.                 return incldepth == 0;
  146.                 }
  147. }
  148. int doerror(void)
  149. {
  150. char *temp;
  151. int i=0;
  152. if (ifskip)
  153. return incldepth == 0;
  154. global_flag++;
  155. temp = xalloc(pstrlen(lptr)*3+2);
  156. pstrcpy(temp,lptr);
  157. while (*lptr)
  158. i+=installphichar(*lptr++,temp,i);
  159. temp[i-1] = 0;
  160. global_flag--;
  161. basicerror(ERR_ERROR,temp);
  162. return incldepth == 0;
  163. }
  164. int dopragma(void)
  165. {
  166. char buf[40],*p=buf;
  167.   STARTUPS *a;
  168. int val = 0,sflag;
  169. if (ifskip)
  170. return incldepth == 0;
  171. lineToCpp();
  172. getsym();
  173. if (lastst != id)
  174. return incldepth == 0;
  175. if (!strcmp(unmangid,"startup"))
  176. sflag = 1;
  177. else if (!strcmp(unmangid,"rundown"))
  178. sflag = 0;
  179. else if (!strncmp(unmangid,"regopt",6)) {
  180. short *s = lptr;
  181. dataregs = floatregs = addrregs = 0;
  182. while (*s != 'n') {
  183. switch (*s) {
  184. case 'a':
  185. case 'A':
  186. addrregs = 1;
  187. break;
  188. case 'f':
  189. case 'F':
  190. floatregs = 1;
  191. break;
  192. case 'd':
  193. case 'D':
  194. dataregs = 1;
  195. break;
  196. }
  197. s++;
  198. }
  199. return incldepth == 0;
  200. }
  201. else return incldepth == 0;
  202. if (prm_cmangle)
  203. *p++ = '_';
  204. while (isalnum(*lptr) || *lptr == '_')
  205. *p++=*lptr++;
  206. *p=0;
  207. while (*lptr && (*lptr == ' ' || *lptr == 't' || *lptr == ','))
  208. lptr++;
  209. if (*lptr  && *lptr != 'n' && !isdigit(*lptr)) {
  210. generror(ERR_ILLCHAR,*lptr,0);
  211. while (*lptr)
  212. lptr++;
  213. }
  214. if (isdigit(*lptr))
  215. while (isdigit(*lptr)) {
  216. val *= 10;
  217. val += (*lptr++)-'0';
  218. }
  219. else
  220. val = 64;
  221. ++global_flag;
  222. a = xalloc(sizeof(STARTUPS));
  223. a->name = litlate(buf);
  224. a->prio = val;
  225.   if (sflag) {
  226. a->link = startuplist;
  227. startuplist = a;
  228. }
  229. else {
  230. a->link = rundownlist;
  231. rundownlist = a;
  232. }
  233. --global_flag;
  234. while (*lptr && (*lptr == ' ' || *lptr == 't'))
  235. lptr++;
  236. if (*lptr  && *lptr != 'n')
  237. generror(ERR_ILLCHAR,*lptr,0);
  238. return incldepth == 0;
  239. }
  240. void dumpstartups(void)
  241. /*
  242.  * Dump references to startup/rundown code
  243.  */
  244. {
  245. SYM *s;
  246. if (startuplist) {
  247. startupseg();
  248. while (startuplist) {
  249. s = search(startuplist->name,&gsyms);
  250. if (!s || s->tp->type != bt_ifunc)
  251. gensymerror(ERR_UPDOWN,startuplist->name);
  252. else  {
  253. gensrref(s,startuplist->prio);
  254. s->tp->uflags |= UF_USED;
  255. }
  256. startuplist = startuplist->link;
  257. }
  258. }
  259. if (rundownlist) {
  260. rundownseg();
  261. while (rundownlist) {
  262. s = search(rundownlist->name,&gsyms);
  263. if (!s || s->tp->type != bt_ifunc)
  264. gensymerror(ERR_UPDOWN,rundownlist->name);
  265. else {
  266. gensrref(s,rundownlist->prio);
  267. s->tp->uflags |= UF_USED;
  268. }
  269. rundownlist = rundownlist->link;
  270. }
  271. }
  272. }
  273. int doline(void)
  274. /*
  275.  * Handle #line directive
  276.  */
  277. {
  278. int n;
  279. getsym();
  280. if (lastst != iconst) 
  281. gensymerror(ERR_PREPROCID,"#line");
  282. else {
  283. n = ival;
  284. getsym();
  285. if (lastst != sconst) 
  286. gensymerror(ERR_PREPROCID,"#line");
  287. else 
  288. if (!ifskip) {
  289. errfile = litlate(laststr);
  290. errlineno = n-1;
  291. }
  292. }
  293. return incldepth == 0;
  294. }
  295. int doinclude(void)
  296. /*
  297.  * HAndle include files
  298.  */
  299. {       int     rv;
  300. FILE *oldfile = inputFile;
  301. incconst = TRUE;
  302.         getsym();               /* get file to include */
  303. incconst = FALSE;
  304. if (ifskip)
  305. return incldepth == 0;
  306.         if( lastst != sconst ) {
  307.                 gensymerror(ERR_INCLFILE,"include");
  308.                 return incldepth == 0;
  309.                 }
  310. if (incldepth > 9) {
  311. generror(ERR_PREPROCID, 0,0);
  312. return incldepth == 0;
  313. }
  314.         inputFile = SearchPath(laststr,prm_searchpath,"r");
  315.         if( inputFile == 0 ) {
  316.                 gensymerror(ERR_CANTOPEN,laststr);
  317.                 inputFile = oldfile;
  318.                 rv = incldepth == 0;
  319.                 }
  320.         else    {
  321. LIST *list;
  322. pushif();
  323. ifshold[incldepth] = ifs;
  324. elsetaken = 0;
  325. ifskip = 0;
  326. ifs = 0;
  327.         inclline[incldepth] = lineno;
  328.          inclfile[incldepth] = oldfile;  /* push current input file */
  329. inclfname[incldepth++] = infile;
  330. global_flag++;
  331. infile = litlate(laststr);
  332. list = xalloc(sizeof(LIST));
  333. list->data = infile;
  334. list->link = 0;
  335. if (incfiles)
  336. lastinc = lastinc->link = list;
  337. else
  338. incfiles = lastinc = list;
  339. errfile = infile;
  340. errlineno = 0;
  341. global_flag--;
  342.                 rv = incldepth == 1;
  343.                 lineno = 0;
  344.                 }
  345.         return rv;
  346. }
  347. short *plitlate(short *string)
  348. {
  349. short *temp = xalloc(pstrlen(string)*sizeof(short)+sizeof(short));
  350. pstrcpy(temp,string);
  351. return temp;
  352. }
  353. void glbdefine(char *name, char*value)
  354. {
  355. {       SYM     *sp;
  356. short *p;
  357. DEFSTRUCT *def;
  358. if (( sp = search(name,&defsyms) )!= 0)
  359. return;
  360.         ++global_flag;          /* always do #define as globals */
  361.         sp = xalloc(sizeof(SYM));
  362.         sp->name = litlate(name);
  363. def = xalloc(sizeof(DEFSTRUCT));
  364. def->args = 0;
  365. def->argcount = 0;
  366. def->string = p = xalloc(strlen(value)*sizeof(short));
  367. while (*value)
  368. *p++=*value++;
  369. *p++=0;
  370.         sp->value.s = (char *) def;
  371.         insert(sp,&defsyms);
  372.         --global_flag;
  373.         return;
  374. }
  375. }
  376. /* Handle #defines
  377.  * Doesn't check for redefine with different value
  378.  * Does handle ANSI macros
  379.  */
  380. int dodefine(void)
  381. {       SYM     *sp;
  382. DEFSTRUCT *def;
  383. short *args[40],count=0;
  384. short *olptr;
  385. int p;
  386.         getsym();               /* get past #define */
  387. if (ifskip)
  388. return incldepth == 0;
  389. olptr = lptr;
  390.         if( lastst != id ) {
  391.                 generror(ERR_IDEXPECT,0,0);
  392.                 return incldepth == 0;
  393.                 }
  394. if (( sp = search(unmangid,&defsyms) )!= 0)
  395. undef2();
  396.         ++global_flag;          /* always do #define as globals */
  397.         sp = xalloc(sizeof(SYM));
  398.         sp->name = litlate(unmangid);
  399. def = xalloc(sizeof(DEFSTRUCT));
  400. def->args = 0;
  401. def->argcount = 0;
  402. if (lastch == '(') {
  403. getdefsym();
  404. getdefsym();
  405. while (lastst == id) {
  406. args[count++] = plitlate(unmangid);
  407. getdefsym();
  408. if (lastst != comma)
  409. break;
  410. getdefsym();
  411. }
  412. if (lastst != closepa)
  413.   generror(ERR_PUNCT,closepa,0);
  414. olptr = lptr;
  415. def->args = xalloc(count*sizeof(short *));
  416. memcpy(def->args,args,count*sizeof(short *));
  417. def->argcount = count+1;
  418. }
  419. while (iswhitespacechar(*olptr))
  420. olptr++;
  421. p = pstrlen(olptr);
  422. if (olptr[p-1] == 0x0a)
  423. olptr[p-1] = 0;
  424. def->string = plitlate(olptr);
  425.         sp->value.s = (char *) def;
  426.         insert(sp,&defsyms);
  427.         --global_flag;
  428.         return incldepth == 0;
  429. }
  430. /*
  431.  * Undefine
  432.  */
  433. int doundef(void)
  434. {
  435. getsym();
  436. if (!ifskip)
  437. undef2();
  438. return(incldepth == 0);
  439. }
  440. int undef2(void)
  441. {
  442. if (lastst != id) 
  443.     generror(ERR_IDEXPECT,0,0);
  444. else {
  445. SYM **p = (SYM **)LookupHash(unmangid,defhash,HASHTABLESIZE);
  446. if (p) {
  447. *p = (*p)->next;
  448. }
  449. }
  450. }
  451. void getdefsym(void)
  452. {
  453. if (backupchar != -1) {
  454. lastst = backupchar;
  455. backupchar = -1;
  456. return;
  457. }
  458. restart:        /* we come back here after comments */
  459.         while(iswhitespacechar(lastch))
  460.                 getch();
  461.         if( lastch == -1)
  462.                 lastst = eof;
  463.         else if(isdigit(lastch))
  464.                 getnum();
  465.         else if(isstartchar(lastch)) {
  466. lptr--;
  467.                 defid(unmangid,&lptr,0);
  468. lastch = *lptr++;
  469. lastst = id;
  470. }
  471.         else if (getsym2())
  472. goto restart;
  473. }
  474. int defid(short *name, short **p, char *q)
  475. /*
  476.  * Get an identifier during macro replacement
  477.  */
  478. {
  479. int count = 0,i=0;
  480. while (issymchar(**p)) {
  481. if (count < 100) {
  482. name[count++] = *(*p);
  483. if (q)
  484. i+=installphichar(*(*p),q,i);
  485. }
  486. (*p)++;
  487. }
  488. if (q) {
  489. if ((q[i-1] & 0xf0) == 0x90)
  490. q[i-1] = 0x90;
  491.        q[i] = '';
  492. }
  493. name[count] = 0;
  494. return(count);
  495. }
  496. /* 
  497.  * Insert a replacement string
  498.  */
  499. int definsert(short *end, short *begin, short * text, int len, int replen)
  500. {
  501. short *q;
  502. int i,p, r;
  503. int val;
  504. if (begin != inputline) 
  505. if (*(begin-1) == '#') {
  506. if (*(begin-2) != '#') {
  507. begin--;
  508. replen++;
  509. r = pstrlen(text);
  510. text[r++] = '"';
  511. text[r] = 0;
  512. for (i=r; i >= 0; i--)
  513. text[i+1] = text[i];
  514. *text = '"';
  515. }
  516. }
  517. p = pstrlen(text);
  518. val = p - replen;
  519. r = pstrlen(begin);
  520. if (val + strlen(begin) >= len-1) {
  521. generror(ERR_MACROSUBS,0,0);
  522. return(-8000);
  523. }
  524. if (val > 0)
  525. for (q = begin + r+1; q >= end; q--)
  526. *(q+val) = *q;
  527. else
  528. if (val < 0) {
  529. r = pstrlen(end)+1;
  530. for (q = end; q < end+r; q++ )
  531. *(q+val) = *q;
  532. }
  533. for (i=0; i < p; i++)
  534. begin[i] = text[i]; 
  535. return(val);
  536. }
  537. /* replace macro args */
  538. int defreplace(short *macro, int count, short **oldargs, short **newargs)
  539. {
  540. int i,rv;
  541. int instring = 0;
  542. short narg[1024];
  543. short name[100];
  544. short *p=macro,*q;
  545. while (*p) {
  546. if (*p == instring)
  547. instring = 0;
  548. else if (*p == ''' || *p == '"')
  549. instring = *p;
  550. else if (!instring && isstartchar(*p)) {
  551. q = p;
  552. defid(name,&p,0);
  553. for (i=0; i < count; i++)
  554. if (!pstrcmp(name,oldargs[i])) {
  555. pstrcpy(narg,newargs[i]);
  556. if ((rv = definsert(p,q,narg,1024-(q-macro),p-q)) == -8000)
  557. return(FALSE);
  558. else {
  559. p += rv;
  560. break;
  561. }
  562. }
  563. }
  564. p++;
  565. }
  566. return(TRUE);
  567. }
  568. /* Handlers for default macros */
  569. void cnvt(short *out,char *in)
  570. {
  571. while (*in) 
  572. *out++=*in++;
  573. *out = 0;
  574. }
  575. void filemac(short *string)
  576. {
  577. char str1[40];
  578. sprintf(str1,""%s"",infile);
  579. cnvt(string,str1);
  580. }
  581. void datemac(short *string)
  582. {
  583. char str1[40];
  584. struct tm *t1;
  585. time_t t2;
  586. time(&t2);
  587. t1 = localtime(&t2);
  588.   strftime(str1,40,""%b %d %Y"",t1);
  589. cnvt(string,str1);
  590. }
  591. void timemac(short *string)
  592. {
  593. char str1[40];
  594. struct tm *t1;
  595. time_t t2;
  596. time(&t2);
  597. t1 = localtime(&t2);
  598. str1[0] = '"';
  599.   strftime(str1,40,""%X"",t1);
  600. cnvt(string,str1);
  601. }
  602. void linemac(short *string)
  603. {
  604. char str1[40];
  605. sprintf(str1,"%d",lineno);
  606. cnvt(string,str1);
  607. }
  608. /* Scan for default macros and replace them */
  609. void defmacroreplace(short *macro, short *name)
  610. {
  611. int i;
  612. macro[0] = 0;
  613. for (i=0; i < INGROWNMACROS; i++)
  614. if (!strcmp(name,ingrownmacros[i].s)) {
  615. (ingrownmacros[i].func)(macro);
  616. break;
  617. }
  618. }
  619. /* Scan line for macros and do replacements */
  620. void defcheck(short *line)
  621. {
  622. short macro[1024];
  623. short name[100];
  624. short *args[40];
  625. char ascii[60];
  626. int tryagain = TRUE, changed = FALSE, waiting = FALSE,rv;
  627. short *p = line,*q;
  628. SYM *sp;
  629. while (tryagain) {
  630. p = line;
  631. tryagain = FALSE;
  632. while(*p) {
  633. q = p;
  634. if (*p == '"') {
  635. waiting = !waiting;
  636. p++;
  637. }
  638. else if (waiting)
  639. p++;
  640. else if (isstartchar(*p)) {
  641. defid(name,&p,ascii);
  642. if ((sp = search(ascii,&defsyms)) != 0) {
  643. DEFSTRUCT *def = sp->value.s;
  644. pstrcpy(macro,def->string);
  645. if (def->argcount) {
  646. int count = 0;
  647. short *q = p;
  648. while (iswhitespacechar(*q))
  649. q++;
  650. if (*q++ != '(')
  651. goto join;
  652. p = q;
  653. if (def->argcount > 1) {
  654. do {
  655. short *nm = name;
  656. int nestedparen = 0;
  657. while (((*p != ',' && *p != ')') || nestedparen) && *p != 'n') {
  658. if (*p == '(')
  659. nestedparen++;
  660. if (*p == ')' && nestedparen)
  661. nestedparen--;
  662. *nm++ = *p++;
  663. }
  664. while (iswhitespacechar(*(nm-1)))
  665. nm--;
  666. *nm = 0;
  667. nm = name;
  668. while (iswhitespacechar(*nm))
  669. nm++;
  670. args[count++] = plitlate(nm);
  671. } while (*p++ == ',');
  672. }
  673. else while (iswhitespacechar(*p++));
  674. if (*(p-1) != ')' || count != def->argcount-1) {
  675. generror(ERR_MACROSUBS,0,0);
  676. return;
  677. }
  678. /* Can't replace if tokenizing next */
  679. if (*p == '#' && *(p+1) == '#')
  680. continue;
  681. if (count == 0)
  682. goto insert;
  683. if (!defreplace(macro,count,def->args,args))
  684. return;
  685. }
  686. insert:
  687. if ((rv=definsert(p,q,macro,4096-(q-line),p-q))==-8000)
  688. return;
  689. p+=rv;
  690. changed = tryagain = TRUE;
  691. }
  692. else {
  693. join:
  694. defmacroreplace(macro,ascii);
  695. if (macro[0]) {
  696. if ((rv=definsert(p,q,macro,4096-(q-line),p-q))==-8000)
  697. return;
  698. p += rv;
  699. changed = TRUE;
  700. }
  701. }
  702. }
  703. else p++;
  704. }
  705. }
  706. /* Token pasting */
  707. if (changed) {
  708. p = q = line;
  709. while (*p) {
  710. if (*p == '#' && *(p+1) == '#')
  711. p+=2;
  712. else
  713. *q++ = *p++;
  714. }
  715. *q = 0;
  716. }
  717. }
  718. static void repdefines(short *lptr)
  719. /*
  720.  * replace 'defined' keyword in #IF and #ELIF statements
  721.  */
  722. {
  723. short *q = lptr;
  724. short name[40];
  725. char ascii[60];
  726. while (*lptr) {
  727. if (!pstrncmp(lptr,defkw,7)) {
  728. lptr +=7;
  729. if (*lptr == '(') 
  730. lptr++;
  731. else 
  732.   expecttoken(openpa,0);
  733.       while(iswhitespacechar(*lptr))
  734.               lptr++;
  735. defid(name,&lptr,ascii);
  736.       while(iswhitespacechar(*lptr))
  737.               lptr++;
  738. if (*lptr == ')')
  739. lptr++;
  740. else
  741. expecttoken(closepa,0);
  742. if (search(ascii,&defsyms) != 0)
  743. *q++ = '1';
  744. else
  745. *q++ = '0';
  746. *q++ = ' ';
  747. }
  748. else {
  749. *q++ = *lptr++;
  750. }
  751. }
  752.   *q = 0;
  753. }
  754. void pushif(void)
  755. /* Push an if context */
  756. {
  757. IFSTRUCT *p;
  758. global_flag++;
  759. p = xalloc(sizeof(IFSTRUCT));
  760. global_flag--;
  761. p->link = ifs;
  762. p->iflevel = ifskip;
  763. p->elsetaken = elsetaken;
  764. elsetaken = FALSE;
  765. ifs = p;
  766. }
  767. void popif(void)
  768. /* Pop an if context */
  769. {
  770. if (ifs) {
  771. ifskip = ifs->iflevel;
  772. elsetaken = ifs->elsetaken;
  773. ifs = ifs->link;
  774. }
  775. else {
  776. ifskip = 0;
  777. elsetaken = 0;
  778. }
  779. }
  780. void ansieol(void)
  781. {
  782. if (prm_ansi) {
  783. while (iswhitespacechar(*lptr))
  784. lptr++;
  785. if (*lptr) {
  786. lastch = *lptr;
  787. lastst = kw_if;
  788. generror(ERR_UNEXPECT,0,0);
  789. }
  790. }
  791. }
  792. int doifdef (int flag)
  793. /* Handle IFDEF */
  794. {
  795. SYM *sp;
  796. getch();
  797. while(isspace(lastch))
  798. getch();
  799. if (!isstartchar(lastch)) {
  800.     generror(ERR_IDEXPECT,0,0);
  801.     return incldepth == 0;
  802. }
  803. else
  804. getid();
  805.   sp = search(unmangid,&defsyms);
  806.   pushif();
  807. if (sp && !flag || !sp && flag)
  808. ifskip = TRUE;
  809. ansieol();
  810. return(incldepth == 0);
  811. }
  812. int doif(int flag)
  813. /* Handle #if */
  814. {
  815. getsym();
  816.   pushif();
  817. cantnewline = TRUE;
  818. if (!intexpr(0))
  819. ifskip = TRUE;
  820. cantnewline = FALSE;
  821. ansieol();
  822. return(incldepth == 0);
  823. }
  824. int doelif(void)
  825. /* Handle #elif */
  826. {
  827. int is;
  828. getsym();
  829. cantnewline = TRUE;
  830. is = !intexpr(0);
  831. cantnewline = FALSE;
  832. if (ifs) {
  833. if (!ifs->iflevel)
  834. ifskip = !ifskip || is || elsetaken;
  835. if (!ifskip)
  836. elsetaken = TRUE;
  837. }
  838. else
  839. generror(ERR_PREPROCMATCH,0,0);
  840. ansieol();
  841. return(incldepth == 0);
  842. }
  843. /* handle else */
  844. int doelse(void)
  845. {
  846. if (ifs) {
  847. if (!ifs->iflevel)
  848. ifskip = !ifskip || elsetaken;
  849. }
  850. else
  851. generror(ERR_PREPROCMATCH,0,0);
  852. ansieol();
  853. return(incldepth == 0);
  854. }
  855. /* HAndle endif */
  856. int doendif(void)
  857. {
  858. if (!ifs)
  859. generror(ERR_PREPROCMATCH,0,0);
  860. popif();
  861. ansieol();
  862. return(incldepth == 0);
  863. }