1 /************************************************************************/
2 /* */
3 /* File: pp5.c */
4 /* */
5 /* Conditional processing. */
6 /* */
7 /* Written by: */
8 /* Gary Oliver */
9 /* 3420 NW Elmwood Dr. */
10 /* PO Box 826 */
11 /* Corvallis, Oregon 97339 */
12 /* (503)758-5549 */
13 /* Maintained by: */
14 /* Kirk Bailey */
15 /* Logical Systems */
16 /* P.O. Box 1702 */
17 /* Corvallis, OR 97339 */
18 /* (503)753-9051 */
19 /* */
20 /* This program is hereby placed in the public domain. In */
21 /* contrast to other claims of "public domain", this means no */
22 /* copyright is claimed and you may do anything you like with PP, */
23 /* including selling it! As a gesture of courtesy, please retain */
24 /* the authorship information in the source code and */
25 /* documentation. */
26 /* */
27 /* Functions contained within this module: */
28 /* */
29 /* doelse Process #else/#elif directive. */
30 /* doendif Process #endif directive. */
31 /* doif Process #if directive. */
32 /* doifs Do work for #ifdef/#ifndef stuff. */
33 /* */
34 /************************************************************************/
35
36 #include "pp.h"
37 #include "ppext.h"
38
39 /************************************************************************/
40 /* */
41 /* doelse */
42 /* */
43 /* Process #else/#elif statement. */
44 /* */
45 /************************************************************************/
46
47 void
doelse(elif)48 doelse(elif)
49 int elif; /* TRUE if #elif; FALSE if #else */
50 {
51 #if DEBUG
52 if(Debug) printf("doelse: %d\n",Iflevel);
53 #endif /* DEBUG */
54 if(Iflevel)
55 {
56 /* We are processing an if */
57 if(Ifstack[Iflevel].i_else)
58 non_fatal("\"#else\" already encountered","");
59 else
60 {
61 if(Ifstate == IFTRUE)
62 Ifstate = Ifstack[Iflevel].i_state = IFNEVER;
63 else if(Ifstate == IFFALSE)
64 {
65 if(elif)
66 {
67 /*
68 * Note that we first need to pretend that we are in a TRUE branch so
69 * that routines which "eval" causes to be called will correctly process
70 * the "elif" expression (in particular "_docall").
71 */
72 Ifstate = Ifstack[Iflevel].i_state =
73 IFTRUE;
74 Ifstate = Ifstack[Iflevel].i_state =
75 eval() ? IFTRUE : IFFALSE;
76 }
77 else
78 {
79 Ifstate = Ifstack[Iflevel].i_state =
80 IFTRUE;
81 }
82 }
83 /* If have seen an #else */
84 Ifstack[Iflevel].i_else = !elif;
85 }
86 }
87 else
88 {
89 if(elif)
90 non_fatal("\"#elif\" outside of \"#if\"","");
91 else
92 non_fatal("\"#else\" outside of \"#if\"","");
93 }
94 }
95
96 /************************************************************************/
97 /* */
98 /* doendif */
99 /* */
100 /* Process #endif statement. */
101 /* */
102 /************************************************************************/
103
104 void
doendif()105 doendif()
106 {
107 #if DEBUG
108 if(Debug) printf("doendif: %d\n",Iflevel);
109 #endif /* DEBUG */
110 if(Iflevel)
111 Ifstate = Ifstack[--Iflevel].i_state; /* Pop stack */
112 else
113 non_fatal("\"#endif\" outside of \"#if\"","");
114 }
115
116 /************************************************************************/
117 /* */
118 /* doif */
119 /* */
120 /* Process #if statement. */
121 /* */
122 /************************************************************************/
123
124 void
doif()125 doif()
126 {
127 if(Iflevel >= IFSTACKSIZE)
128 non_fatal("\"#if\" stack overflow","");
129 else
130 {
131 if(Ifstate == IFTRUE)
132 {
133 Ifstate = Ifstack[++Iflevel].i_state =
134 eval() ? IFTRUE : IFFALSE;
135 }
136 else
137 {
138 Ifstate = Ifstack[++Iflevel].i_state =
139 IFNEVER; /* NO #else */
140 scaneol(); /* Just absorb the rest */
141 }
142 Ifstack[Iflevel].i_else = FALSE; /* No #else seen */
143 }
144 }
145
146 /************************************************************************/
147 /* */
148 /* doifs */
149 /* */
150 /* Process some kind of #ifxdef statement. */
151 /* */
152 /* Lookup token and set Ifstack to inform output routine to */
153 /* emit code or not. */
154 /* */
155 /************************************************************************/
156
157 void
doifs(t)158 doifs(t)
159 int t; /* Type of if TRUE if #ifdef */
160 {
161 register int iftype;
162
163 if(Ifstate == IFTRUE)
164 {
165 /* Get next non-space token */
166 if(getnstoken(GT_STR) == LETTER)
167 {
168 #if DEBUG
169 if(Debug) printf("doifs: %d %s",t,Token);
170 #endif /* DEBUG */
171 iftype = (lookup(Token,NULL) ? TRUE : FALSE) ^
172 (t ? FALSE : TRUE) ? IFTRUE : IFFALSE;
173 }
174 else
175 {
176 iftype = IFFALSE;
177 illegal_symbol();
178 }
179 }
180 else
181 iftype = IFNEVER; /* Inside false #if -- No #else */
182
183 if(Iflevel >= IFSTACKSIZE)
184 non_fatal("\"#if\" stack overflow","");
185 else
186 {
187 Ifstate = Ifstack[++Iflevel].i_state = iftype;
188 Ifstack[Iflevel].i_else = FALSE;
189 }
190
191 #if DEBUG
192 if(Debug) printf("doifs: %d %d %d\n",t,iftype,Iflevel);
193 #endif /* DEBUG */
194 }
195
196