17dd7cddfSDavid du Colombier /***** spin: pc_zpp.c *****/
27dd7cddfSDavid du Colombier
3312a1df1SDavid du Colombier /* Copyright (c) 1997-2003 by Lucent Technologies, Bell Laboratories. */
47dd7cddfSDavid du Colombier /* All Rights Reserved. This software is for educational purposes only. */
5312a1df1SDavid du Colombier /* No guarantee whatsoever is expressed or implied by the distribution of */
6312a1df1SDavid du Colombier /* this code. Permission is given to distribute this code provided that */
7312a1df1SDavid du Colombier /* this introductory message is not removed and no monies are exchanged. */
8312a1df1SDavid du Colombier /* Software written by Gerard J. Holzmann. For tool documentation see: */
9312a1df1SDavid du Colombier /* http://spinroot.com/ */
10312a1df1SDavid du Colombier /* Send all bug-reports and/or questions to: bugs@spinroot.com */
11312a1df1SDavid du Colombier
12312a1df1SDavid du Colombier /* pc_zpp.c is only used in the PC version of Spin */
13312a1df1SDavid du Colombier /* it is included to avoid too great a reliance on an external cpp */
147dd7cddfSDavid du Colombier
157dd7cddfSDavid du Colombier #include <stdlib.h>
167dd7cddfSDavid du Colombier #include <stdio.h>
177dd7cddfSDavid du Colombier #include <string.h>
187dd7cddfSDavid du Colombier #include <ctype.h>
19*00d97012SDavid du Colombier #include "spin.h"
207dd7cddfSDavid du Colombier
217dd7cddfSDavid du Colombier #ifdef PC
227dd7cddfSDavid du Colombier enum cstate { PLAIN, IN_STRING, IN_QUOTE, S_COMM, COMMENT, E_COMM };
237dd7cddfSDavid du Colombier
247dd7cddfSDavid du Colombier #define MAXNEST 32
257dd7cddfSDavid du Colombier #define MAXDEF 128
26*00d97012SDavid du Colombier #define MAXLINE 2048
27*00d97012SDavid du Colombier #define GENEROUS 8192
287dd7cddfSDavid du Colombier
297dd7cddfSDavid du Colombier #define debug(x,y) if (verbose) printf(x,y)
307dd7cddfSDavid du Colombier
31312a1df1SDavid du Colombier static FILE *outpp /* = stdout */;
327dd7cddfSDavid du Colombier
337dd7cddfSDavid du Colombier static int if_truth[MAXNEST];
347dd7cddfSDavid du Colombier static int printing[MAXNEST];
357dd7cddfSDavid du Colombier static int if_depth, nr_defs, verbose = 0;
367dd7cddfSDavid du Colombier static enum cstate state = PLAIN;
37312a1df1SDavid du Colombier static char Out1[GENEROUS], Out2[GENEROUS];
387dd7cddfSDavid du Colombier
397dd7cddfSDavid du Colombier static struct Defines {
407dd7cddfSDavid du Colombier int exists;
417dd7cddfSDavid du Colombier char *src, *trg;
427dd7cddfSDavid du Colombier } d[MAXDEF];
437dd7cddfSDavid du Colombier
447dd7cddfSDavid du Colombier static int process(char *, int, char *);
457dd7cddfSDavid du Colombier static int zpp_do(char *);
467dd7cddfSDavid du Colombier
47*00d97012SDavid du Colombier extern char *emalloc(size_t); /* main.c */
48312a1df1SDavid du Colombier
497dd7cddfSDavid du Colombier static int
do_define(char * p)507dd7cddfSDavid du Colombier do_define(char *p)
517dd7cddfSDavid du Colombier { char *q, *r, *s;
527dd7cddfSDavid du Colombier
537dd7cddfSDavid du Colombier for (q = p+strlen(p)-1; q > p; q--)
547dd7cddfSDavid du Colombier if (*q == '\n' || *q == '\t' || *q == ' ')
557dd7cddfSDavid du Colombier *q = '\0';
567dd7cddfSDavid du Colombier else
577dd7cddfSDavid du Colombier break;
587dd7cddfSDavid du Colombier
597dd7cddfSDavid du Colombier q = p + strspn(p, " \t");
607dd7cddfSDavid du Colombier if (!(r = strchr(q, '\t')))
617dd7cddfSDavid du Colombier r = strchr(q, ' ');
627dd7cddfSDavid du Colombier if (!r) { s = ""; goto adddef; }
637dd7cddfSDavid du Colombier s = r + strspn(r, " \t");
647dd7cddfSDavid du Colombier *r = '\0';
657dd7cddfSDavid du Colombier if (strchr(q, '('))
667dd7cddfSDavid du Colombier { debug("zpp: #define with arguments %s\n", q);
677dd7cddfSDavid du Colombier return 0;
687dd7cddfSDavid du Colombier }
697dd7cddfSDavid du Colombier for (r = q+strlen(q)-1; r > q; r--)
707dd7cddfSDavid du Colombier if (*r == ' ' || *r == '\t')
717dd7cddfSDavid du Colombier *r = '\0';
727dd7cddfSDavid du Colombier else
737dd7cddfSDavid du Colombier break;
747dd7cddfSDavid du Colombier if (nr_defs >= MAXDEF)
757dd7cddfSDavid du Colombier { debug("zpp: too many #defines (max %d)\n", nr_defs);
767dd7cddfSDavid du Colombier return 0;
777dd7cddfSDavid du Colombier }
787dd7cddfSDavid du Colombier if (strcmp(q, s) != 0)
797dd7cddfSDavid du Colombier { int j;
807dd7cddfSDavid du Colombier adddef: for (j = 0; j < nr_defs; j++)
817dd7cddfSDavid du Colombier if (!strcmp(d[j].src, q))
827dd7cddfSDavid du Colombier d[j].exists = 0;
83312a1df1SDavid du Colombier d[nr_defs].src = emalloc(strlen(q)+1);
84312a1df1SDavid du Colombier d[nr_defs].trg = emalloc(strlen(s)+1);
857dd7cddfSDavid du Colombier strcpy(d[nr_defs].src, q);
867dd7cddfSDavid du Colombier strcpy(d[nr_defs].trg, s);
877dd7cddfSDavid du Colombier d[nr_defs++].exists = 1;
887dd7cddfSDavid du Colombier }
897dd7cddfSDavid du Colombier return 1;
907dd7cddfSDavid du Colombier }
917dd7cddfSDavid du Colombier
927dd7cddfSDavid du Colombier static int
isvalid(int c)937dd7cddfSDavid du Colombier isvalid(int c)
947dd7cddfSDavid du Colombier {
957dd7cddfSDavid du Colombier return (isalnum(c) || c == '_');
967dd7cddfSDavid du Colombier }
977dd7cddfSDavid du Colombier
987dd7cddfSDavid du Colombier static char *
apply(char * p0)997dd7cddfSDavid du Colombier apply(char *p0)
1007dd7cddfSDavid du Colombier { char *out, *in1, *in2, *startat;
1017dd7cddfSDavid du Colombier int i, j;
1027dd7cddfSDavid du Colombier
1037dd7cddfSDavid du Colombier startat = in1 = Out2; strcpy(Out2, p0);
1047dd7cddfSDavid du Colombier out = Out1; *out = '\0';
1057dd7cddfSDavid du Colombier
1067dd7cddfSDavid du Colombier for (i = nr_defs-1; i >= 0; i--)
1077dd7cddfSDavid du Colombier { if (!d[i].exists) continue;
108312a1df1SDavid du Colombier j = (int) strlen(d[i].src);
1097dd7cddfSDavid du Colombier more: in2 = strstr(startat, d[i].src);
1107dd7cddfSDavid du Colombier if (!in2) /* no more matches */
1117dd7cddfSDavid du Colombier { startat = in1;
1127dd7cddfSDavid du Colombier continue;
1137dd7cddfSDavid du Colombier }
1147dd7cddfSDavid du Colombier if ((in2 == in1 || !isvalid(*(in2-1)))
1157dd7cddfSDavid du Colombier && (in2+j == '\0' || !isvalid(*(in2+j))))
1167dd7cddfSDavid du Colombier { *in2 = '\0';
117312a1df1SDavid du Colombier
118312a1df1SDavid du Colombier if (strlen(in1)+strlen(d[i].trg)+strlen(in2+j) >= GENEROUS)
119312a1df1SDavid du Colombier {
120*00d97012SDavid du Colombier printf("spin: macro expansion overflow %s -> %s ?\n",
121312a1df1SDavid du Colombier d[i].src, d[i].trg);
122312a1df1SDavid du Colombier return in1;
123312a1df1SDavid du Colombier }
1247dd7cddfSDavid du Colombier strcat(out, in1);
1257dd7cddfSDavid du Colombier strcat(out, d[i].trg);
1267dd7cddfSDavid du Colombier strcat(out, in2+j);
1277dd7cddfSDavid du Colombier if (in1 == Out2)
1287dd7cddfSDavid du Colombier { startat = in1 = Out1;
1297dd7cddfSDavid du Colombier out = Out2;
1307dd7cddfSDavid du Colombier } else
1317dd7cddfSDavid du Colombier { startat = in1 = Out2;
1327dd7cddfSDavid du Colombier out = Out1;
1337dd7cddfSDavid du Colombier }
1347dd7cddfSDavid du Colombier *out = '\0';
1357dd7cddfSDavid du Colombier } else
1367dd7cddfSDavid du Colombier { startat = in2+1; /* +1 not +j.. */
1377dd7cddfSDavid du Colombier }
1387dd7cddfSDavid du Colombier goto more; /* recursive defines */
1397dd7cddfSDavid du Colombier }
1407dd7cddfSDavid du Colombier return in1;
1417dd7cddfSDavid du Colombier }
1427dd7cddfSDavid du Colombier
1437dd7cddfSDavid du Colombier static char *
do_common(char * p)1447dd7cddfSDavid du Colombier do_common(char *p)
1457dd7cddfSDavid du Colombier { char *q, *s;
1467dd7cddfSDavid du Colombier
1477dd7cddfSDavid du Colombier q = p + strspn(p, " \t");
1487dd7cddfSDavid du Colombier for (s = (q + strlen(q) - 1); s > q; s--)
1497dd7cddfSDavid du Colombier if (*s == ' ' || *s == '\t' || *s == '\n')
1507dd7cddfSDavid du Colombier *s = '\0';
1517dd7cddfSDavid du Colombier else
1527dd7cddfSDavid du Colombier break;
1537dd7cddfSDavid du Colombier return q;
1547dd7cddfSDavid du Colombier }
1557dd7cddfSDavid du Colombier
1567dd7cddfSDavid du Colombier static int
do_undefine(char * p)1577dd7cddfSDavid du Colombier do_undefine(char *p)
1587dd7cddfSDavid du Colombier { int i; char *q = do_common(p);
1597dd7cddfSDavid du Colombier
1607dd7cddfSDavid du Colombier for (i = 0; i < nr_defs; i++)
1617dd7cddfSDavid du Colombier if (!strcmp(d[i].src, q))
1627dd7cddfSDavid du Colombier d[i].exists = 0;
1637dd7cddfSDavid du Colombier return 1;
1647dd7cddfSDavid du Colombier }
1657dd7cddfSDavid du Colombier
1667dd7cddfSDavid du Colombier static char *
check_ifdef(char * p)1677dd7cddfSDavid du Colombier check_ifdef(char *p)
1687dd7cddfSDavid du Colombier { int i; char *q = do_common(p);
1697dd7cddfSDavid du Colombier
1707dd7cddfSDavid du Colombier for (i = 0; i < nr_defs; i++)
1717dd7cddfSDavid du Colombier if (d[i].exists
1727dd7cddfSDavid du Colombier && !strcmp(d[i].src, q))
1737dd7cddfSDavid du Colombier return d[i].trg;
1747dd7cddfSDavid du Colombier return (char *) 0;
1757dd7cddfSDavid du Colombier }
1767dd7cddfSDavid du Colombier
1777dd7cddfSDavid du Colombier static int
do_ifdef(char * p)1787dd7cddfSDavid du Colombier do_ifdef(char *p)
1797dd7cddfSDavid du Colombier {
1807dd7cddfSDavid du Colombier if (++if_depth >= MAXNEST)
1817dd7cddfSDavid du Colombier { debug("zpp: too deeply nested (max %d)\n", MAXNEST);
1827dd7cddfSDavid du Colombier return 0;
1837dd7cddfSDavid du Colombier }
1847dd7cddfSDavid du Colombier if_truth[if_depth] = (check_ifdef(p) != (char *)0);
1857dd7cddfSDavid du Colombier printing[if_depth] = printing[if_depth-1]&&if_truth[if_depth];
1867dd7cddfSDavid du Colombier
1877dd7cddfSDavid du Colombier return 1;
1887dd7cddfSDavid du Colombier }
1897dd7cddfSDavid du Colombier
1907dd7cddfSDavid du Colombier static int
do_ifndef(char * p)1917dd7cddfSDavid du Colombier do_ifndef(char *p)
1927dd7cddfSDavid du Colombier {
1937dd7cddfSDavid du Colombier if (++if_depth >= MAXNEST)
1947dd7cddfSDavid du Colombier { debug("zpp: too deeply nested (max %d)\n", MAXNEST);
1957dd7cddfSDavid du Colombier return 0;
1967dd7cddfSDavid du Colombier }
1977dd7cddfSDavid du Colombier if_truth[if_depth] = (check_ifdef(p) == (char *)0);
1987dd7cddfSDavid du Colombier printing[if_depth] = printing[if_depth-1]&&if_truth[if_depth];
1997dd7cddfSDavid du Colombier
2007dd7cddfSDavid du Colombier return 1;
2017dd7cddfSDavid du Colombier }
2027dd7cddfSDavid du Colombier
2037dd7cddfSDavid du Colombier static int
is_simple(char * q)2047dd7cddfSDavid du Colombier is_simple(char *q)
2057dd7cddfSDavid du Colombier {
2067dd7cddfSDavid du Colombier if (!q) return 0;
2077dd7cddfSDavid du Colombier if (strcmp(q, "0") == 0)
2087dd7cddfSDavid du Colombier if_truth[if_depth] = 0;
2097dd7cddfSDavid du Colombier else if (strcmp(q, "1") == 0)
2107dd7cddfSDavid du Colombier if_truth[if_depth] = 1;
2117dd7cddfSDavid du Colombier else
2127dd7cddfSDavid du Colombier return 0;
2137dd7cddfSDavid du Colombier return 1;
2147dd7cddfSDavid du Colombier }
2157dd7cddfSDavid du Colombier
2167dd7cddfSDavid du Colombier static int
do_if(char * p)2177dd7cddfSDavid du Colombier do_if(char *p)
2187dd7cddfSDavid du Colombier { char *q = do_common(p);
2197dd7cddfSDavid du Colombier if (++if_depth >= MAXNEST)
2207dd7cddfSDavid du Colombier { debug("zpp: too deeply nested (max %d)\n", MAXNEST);
2217dd7cddfSDavid du Colombier return 0;
2227dd7cddfSDavid du Colombier }
2237dd7cddfSDavid du Colombier if (!is_simple(q)
2247dd7cddfSDavid du Colombier && !is_simple(check_ifdef(q)))
2257dd7cddfSDavid du Colombier { debug("zpp: cannot handle #if %s\n", q);
2267dd7cddfSDavid du Colombier return 0;
2277dd7cddfSDavid du Colombier }
2287dd7cddfSDavid du Colombier printing[if_depth] = printing[if_depth-1]&&if_truth[if_depth];
2297dd7cddfSDavid du Colombier
2307dd7cddfSDavid du Colombier return 1;
2317dd7cddfSDavid du Colombier }
2327dd7cddfSDavid du Colombier
2337dd7cddfSDavid du Colombier static int
do_else(char * p)234*00d97012SDavid du Colombier do_else(char *p)
2357dd7cddfSDavid du Colombier {
236*00d97012SDavid du Colombier debug("zpp: do_else %s", p);
2377dd7cddfSDavid du Colombier if_truth[if_depth] = 1-if_truth[if_depth];
2387dd7cddfSDavid du Colombier printing[if_depth] = printing[if_depth-1]&&if_truth[if_depth];
2397dd7cddfSDavid du Colombier
2407dd7cddfSDavid du Colombier return 1;
2417dd7cddfSDavid du Colombier }
2427dd7cddfSDavid du Colombier
2437dd7cddfSDavid du Colombier static int
do_endif(char * p)2447dd7cddfSDavid du Colombier do_endif(char *p)
2457dd7cddfSDavid du Colombier {
2467dd7cddfSDavid du Colombier if (--if_depth < 0)
2477dd7cddfSDavid du Colombier { debug("zpp: unbalanced #endif %s\n", p);
2487dd7cddfSDavid du Colombier return 0;
2497dd7cddfSDavid du Colombier }
2507dd7cddfSDavid du Colombier return 1;
2517dd7cddfSDavid du Colombier }
2527dd7cddfSDavid du Colombier
2537dd7cddfSDavid du Colombier static int
do_include(char * p)2547dd7cddfSDavid du Colombier do_include(char *p)
2557dd7cddfSDavid du Colombier { char *r, *q;
2567dd7cddfSDavid du Colombier
2577dd7cddfSDavid du Colombier q = strchr(p, '<');
2587dd7cddfSDavid du Colombier r = strrchr(p, '>');
2597dd7cddfSDavid du Colombier if (!q || !r)
2607dd7cddfSDavid du Colombier { q = strchr (p, '\"');
2617dd7cddfSDavid du Colombier r = strrchr(p, '\"');
2627dd7cddfSDavid du Colombier if (!q || !r || q == r)
2637dd7cddfSDavid du Colombier { debug("zpp: malformed #include %s", p);
2647dd7cddfSDavid du Colombier return 0;
2657dd7cddfSDavid du Colombier } }
2667dd7cddfSDavid du Colombier *r = '\0';
2677dd7cddfSDavid du Colombier return zpp_do(++q);
2687dd7cddfSDavid du Colombier }
2697dd7cddfSDavid du Colombier
2707dd7cddfSDavid du Colombier static int
in_comment(char * p)2717dd7cddfSDavid du Colombier in_comment(char *p)
2727dd7cddfSDavid du Colombier { char *q = p;
2737dd7cddfSDavid du Colombier
2747dd7cddfSDavid du Colombier for (q = p; *q != '\n' && *q != '\0'; q++)
2757dd7cddfSDavid du Colombier switch (state) {
2767dd7cddfSDavid du Colombier case PLAIN:
2777dd7cddfSDavid du Colombier switch (*q) {
2787dd7cddfSDavid du Colombier case '"': state = IN_STRING; break;
2797dd7cddfSDavid du Colombier case '\'': state = IN_QUOTE; break;
2807dd7cddfSDavid du Colombier case '/': state = S_COMM; break;
2817dd7cddfSDavid du Colombier case '\\': q++; break;
2827dd7cddfSDavid du Colombier }
2837dd7cddfSDavid du Colombier break;
2847dd7cddfSDavid du Colombier case IN_STRING:
2857dd7cddfSDavid du Colombier if (*q == '"') state = PLAIN;
2867dd7cddfSDavid du Colombier else if (*q == '\\') q++;
2877dd7cddfSDavid du Colombier break;
2887dd7cddfSDavid du Colombier case IN_QUOTE:
2897dd7cddfSDavid du Colombier if (*q == '\'') state = PLAIN;
2907dd7cddfSDavid du Colombier else if (*q == '\\') q++;
2917dd7cddfSDavid du Colombier break;
2927dd7cddfSDavid du Colombier case S_COMM:
2937dd7cddfSDavid du Colombier if (*q == '*')
2947dd7cddfSDavid du Colombier { *(q-1) = *q = ' ';
2957dd7cddfSDavid du Colombier state = COMMENT;
2967dd7cddfSDavid du Colombier } else if (*q != '/')
2977dd7cddfSDavid du Colombier state = PLAIN;
2987dd7cddfSDavid du Colombier break;
2997dd7cddfSDavid du Colombier case COMMENT:
3007dd7cddfSDavid du Colombier state = (*q == '*') ? E_COMM: COMMENT;
3017dd7cddfSDavid du Colombier *q = ' ';
3027dd7cddfSDavid du Colombier break;
3037dd7cddfSDavid du Colombier case E_COMM:
3047dd7cddfSDavid du Colombier if (*q == '/')
3057dd7cddfSDavid du Colombier state = PLAIN;
3067dd7cddfSDavid du Colombier else if (*q != '*')
3077dd7cddfSDavid du Colombier state = COMMENT;
3087dd7cddfSDavid du Colombier *q = ' ';
3097dd7cddfSDavid du Colombier break;
3107dd7cddfSDavid du Colombier }
3117dd7cddfSDavid du Colombier if (state == S_COMM) state = PLAIN;
3127dd7cddfSDavid du Colombier else if (state == E_COMM) state = COMMENT;
3137dd7cddfSDavid du Colombier return (state == COMMENT);
3147dd7cddfSDavid du Colombier }
3157dd7cddfSDavid du Colombier
3167dd7cddfSDavid du Colombier static int
strip_cpp_comments(char * p)317*00d97012SDavid du Colombier strip_cpp_comments(char *p)
318*00d97012SDavid du Colombier { char *q;
319*00d97012SDavid du Colombier
320*00d97012SDavid du Colombier q = strstr(p, "//");
321*00d97012SDavid du Colombier if (q)
322*00d97012SDavid du Colombier { if (q > p && *(q-1) == '\\')
323*00d97012SDavid du Colombier { return strip_cpp_comments(q+1);
324*00d97012SDavid du Colombier }
325*00d97012SDavid du Colombier *q = '\n';
326*00d97012SDavid du Colombier *(q+1) = '\0';
327*00d97012SDavid du Colombier return 1;
328*00d97012SDavid du Colombier }
329*00d97012SDavid du Colombier return 0;
330*00d97012SDavid du Colombier }
331*00d97012SDavid du Colombier
332*00d97012SDavid du Colombier static int
zpp_do(char * fnm)3337dd7cddfSDavid du Colombier zpp_do(char *fnm)
3347dd7cddfSDavid du Colombier { char buf[2048], buf2[MAXLINE], *p; int n, on;
3357dd7cddfSDavid du Colombier FILE *inp; int lno = 0, nw_lno = 0;
3367dd7cddfSDavid du Colombier
3377dd7cddfSDavid du Colombier if ((inp = fopen(fnm, "r")) == NULL)
338*00d97012SDavid du Colombier { fprintf(stdout, "spin: error: No file '%s'\n", fnm);
339*00d97012SDavid du Colombier exit(1); /* 4.1.2 was stderr */
3407dd7cddfSDavid du Colombier }
3417dd7cddfSDavid du Colombier printing[0] = if_truth[0] = 1;
3427dd7cddfSDavid du Colombier fprintf(outpp, "#line %d \"%s\"\n", lno+1, fnm);
3437dd7cddfSDavid du Colombier while (fgets(buf, MAXLINE, inp))
344312a1df1SDavid du Colombier { lno++; n = (int) strlen(buf);
3457dd7cddfSDavid du Colombier on = 0; nw_lno = 0;
3467dd7cddfSDavid du Colombier while (n > 2 && buf[n-2] == '\\')
3477dd7cddfSDavid du Colombier { buf[n-2] = '\0';
348*00d97012SDavid du Colombier feedme:
349*00d97012SDavid du Colombier if (!fgets(buf2, MAXLINE, inp))
3507dd7cddfSDavid du Colombier { debug("zpp: unexpected EOF ln %d\n", lno);
3517dd7cddfSDavid du Colombier return 0; /* switch to cpp */
3527dd7cddfSDavid du Colombier }
3537dd7cddfSDavid du Colombier lno++;
3547dd7cddfSDavid du Colombier if (n + (int) strlen(buf2) >= 2048)
3557dd7cddfSDavid du Colombier { debug("zpp: line %d too long\n", lno);
3567dd7cddfSDavid du Colombier return 0;
3577dd7cddfSDavid du Colombier }
3587dd7cddfSDavid du Colombier strcat(buf, buf2);
359312a1df1SDavid du Colombier n = (int) strlen(buf);
3607dd7cddfSDavid du Colombier }
361*00d97012SDavid du Colombier
362*00d97012SDavid du Colombier if (strip_cpp_comments(&buf[on]))
363*00d97012SDavid du Colombier n = (int) strlen(buf);
364*00d97012SDavid du Colombier
3657dd7cddfSDavid du Colombier if (in_comment(&buf[on]))
3667dd7cddfSDavid du Colombier { buf[n-1] = '\0'; /* eat newline */
3677dd7cddfSDavid du Colombier on = n-1; nw_lno = 1;
3687dd7cddfSDavid du Colombier goto feedme;
3697dd7cddfSDavid du Colombier }
3707dd7cddfSDavid du Colombier p = buf + strspn(buf, " \t");
3717dd7cddfSDavid du Colombier if (nw_lno && *p != '#')
3727dd7cddfSDavid du Colombier fprintf(outpp, "#line %d \"%s\"\n", lno, fnm);
3737dd7cddfSDavid du Colombier if (*p == '#')
3747dd7cddfSDavid du Colombier { if (!process(p+1, lno+1, fnm))
3757dd7cddfSDavid du Colombier return 0;
3767dd7cddfSDavid du Colombier } else if (printing[if_depth])
3777dd7cddfSDavid du Colombier fprintf(outpp, "%s", apply(buf));
3787dd7cddfSDavid du Colombier }
3797dd7cddfSDavid du Colombier fclose(inp);
3807dd7cddfSDavid du Colombier return 1;
3817dd7cddfSDavid du Colombier }
3827dd7cddfSDavid du Colombier
3837dd7cddfSDavid du Colombier int
try_zpp(char * fnm,char * onm)3847dd7cddfSDavid du Colombier try_zpp(char *fnm, char *onm)
3857dd7cddfSDavid du Colombier { int r;
386*00d97012SDavid du Colombier if ((outpp = fopen(onm, MFLAGS)) == NULL)
3877dd7cddfSDavid du Colombier return 0;
3887dd7cddfSDavid du Colombier r = zpp_do(fnm);
3897dd7cddfSDavid du Colombier fclose(outpp);
3907dd7cddfSDavid du Colombier return r; /* 1 = ok; 0 = use cpp */
3917dd7cddfSDavid du Colombier }
3927dd7cddfSDavid du Colombier
3937dd7cddfSDavid du Colombier static struct Directives {
3947dd7cddfSDavid du Colombier int len;
3957dd7cddfSDavid du Colombier char *directive;
3967dd7cddfSDavid du Colombier int (*handler)(char *);
3977dd7cddfSDavid du Colombier int interp;
3987dd7cddfSDavid du Colombier } s[] = {
3997dd7cddfSDavid du Colombier { 6, "define", do_define, 1 },
4007dd7cddfSDavid du Colombier { 4, "else", do_else, 0 },
4017dd7cddfSDavid du Colombier { 5, "endif", do_endif, 0 },
4027dd7cddfSDavid du Colombier { 5, "ifdef", do_ifdef, 0 },
4037dd7cddfSDavid du Colombier { 6, "ifndef", do_ifndef, 0 },
404f3793cddSDavid du Colombier { 2, "if", do_if, 0 },
4057dd7cddfSDavid du Colombier { 7, "include", do_include, 1 },
4067dd7cddfSDavid du Colombier { 8, "undefine", do_undefine, 1 },
4077dd7cddfSDavid du Colombier };
4087dd7cddfSDavid du Colombier
4097dd7cddfSDavid du Colombier static int
process(char * q,int lno,char * fnm)4107dd7cddfSDavid du Colombier process(char *q, int lno, char *fnm)
4117dd7cddfSDavid du Colombier { char *p; int i, r;
4127dd7cddfSDavid du Colombier
4137dd7cddfSDavid du Colombier for (p = q; *p; p++)
4147dd7cddfSDavid du Colombier if (*p != ' ' && *p != '\t')
4157dd7cddfSDavid du Colombier break;
416*00d97012SDavid du Colombier
417*00d97012SDavid du Colombier if (strncmp(p, "line", 4) == 0)
418*00d97012SDavid du Colombier { p += 4;
419*00d97012SDavid du Colombier while (*p == ' ' || *p == '\t')
420*00d97012SDavid du Colombier { p++;
421*00d97012SDavid du Colombier }
422*00d97012SDavid du Colombier lno = atoi(p);
423*00d97012SDavid du Colombier return 1; /* line directive */
424*00d97012SDavid du Colombier }
425*00d97012SDavid du Colombier if (isdigit((int) *p))
426*00d97012SDavid du Colombier { lno = atoi(p);
427*00d97012SDavid du Colombier return 1;
428*00d97012SDavid du Colombier }
429*00d97012SDavid du Colombier if (strncmp(p, "error", 5) == 0)
430*00d97012SDavid du Colombier { printf("spin: %s", p);
431*00d97012SDavid du Colombier exit(1);
432*00d97012SDavid du Colombier }
433*00d97012SDavid du Colombier if (strncmp(p, "warning", 7) == 0)
434*00d97012SDavid du Colombier { printf("spin: %s", p);
435*00d97012SDavid du Colombier return 1;
436*00d97012SDavid du Colombier }
437f3793cddSDavid du Colombier for (i = 0; i < (int) (sizeof(s)/sizeof(struct Directives)); i++)
4387dd7cddfSDavid du Colombier if (!strncmp(s[i].directive, p, s[i].len))
4397dd7cddfSDavid du Colombier { if (s[i].interp
4407dd7cddfSDavid du Colombier && !printing[if_depth])
4417dd7cddfSDavid du Colombier return 1;
4427dd7cddfSDavid du Colombier fprintf(outpp, "#line %d \"%s\"\n", lno, fnm);
4437dd7cddfSDavid du Colombier r = s[i].handler(p + s[i].len);
4447dd7cddfSDavid du Colombier if (i == 6) /* include */
4457dd7cddfSDavid du Colombier fprintf(outpp, "#line %d \"%s\"\n", lno, fnm);
4467dd7cddfSDavid du Colombier return r;
4477dd7cddfSDavid du Colombier }
4487dd7cddfSDavid du Colombier
4497dd7cddfSDavid du Colombier debug("zpp: unrecognized directive: %s", p);
4507dd7cddfSDavid du Colombier return 0;
4517dd7cddfSDavid du Colombier }
4527dd7cddfSDavid du Colombier #endif
453