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