source: trunk/tools/wrc/preproc.c@ 3459

Last change on this file since 3459 was 3459, checked in by sandervl, 25 years ago

added warpin installation script & app + wrc bugfix

File size: 5.6 KB
Line 
1/*
2 * Copyright 1998 Bertho A. Stultiens (BS)
3 *
4 */
5
6#include "config.h"
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#include "wrc.h"
13#include "utils.h"
14#include "preproc.h"
15#include "parser.h"
16
17
18extern void set_pp_ignore(int); /* From parser.l */
19
20static char *current_define;
21
22#define HASHKEY 2039
23static struct pp_entry *pp_defines[HASHKEY];
24
25#define MAXIFSTACK 64
26static struct if_state ifstack[MAXIFSTACK];
27static int ifstackidx = 0;
28
29#if 0
30void pp_status(void)
31{
32 int i;
33 int sum;
34 int total = 0;
35 struct pp_entry *ppp;
36
37 printf("Defines statistics:\n");
38 for(i = 0; i < HASHKEY; i++)
39 {
40 sum = 0;
41 for(ppp = pp_defines[i]; ppp; ppp = ppp->next)
42 sum++;
43 total += sum;
44 printf("%4d, %3d\n", i, sum);
45 }
46 printf("Total defines: %d\n", total);
47}
48#pragma exit pp_status
49#endif
50
51/* Don't comment on the hash, its primitive but functional... */
52int pp_hash(char *str)
53{
54 int sum = 0;
55 while(*str)
56 sum += *str++;
57 return sum % HASHKEY;
58}
59
60struct pp_entry *pp_lookup(char *ident)
61{
62 int index = pp_hash(ident);
63 struct pp_entry *ppp;
64 for(ppp = pp_defines[index]; ppp; ppp = ppp->next)
65 {
66 if(!strcmp(ident, ppp->ident))
67 return ppp;
68 }
69 return NULL;
70}
71
72void set_define(char *name)
73{
74 current_define = xstrdup(name);
75}
76
77void del_define(char *name)
78{
79 int index;
80 struct pp_entry *ppp;
81
82 if((ppp = pp_lookup(name)) == NULL)
83 {
84 if(pedantic)
85 yywarning("%s was not defined", name);
86 return;
87 }
88
89 index = pp_hash(name);
90 if(pp_defines[index] == ppp)
91 {
92 pp_defines[index] = ppp->next;
93 if(pp_defines[index])
94 pp_defines[index]->prev = NULL;
95 }
96 else
97 {
98 ppp->prev->next = ppp->next;
99 if(ppp->next)
100 ppp->next->prev = ppp->prev;
101 }
102 free(ppp);
103}
104
105void add_define(char *text)
106{
107 int len;
108 char *cptr;
109 int index = pp_hash(current_define);
110 struct pp_entry *ppp;
111 if(pp_lookup(current_define) != NULL)
112 {
113 if(pedantic)
114 yywarning("Redefinition of %s", current_define);
115 del_define(current_define);
116 }
117 ppp = (struct pp_entry *)xmalloc(sizeof(struct pp_entry));
118 ppp->ident = current_define;
119 ppp->subst = xstrdup(text);
120 ppp->next = pp_defines[index];
121 pp_defines[index] = ppp;
122 if(ppp->next)
123 ppp->next->prev = ppp;
124 /* Strip trailing white space from subst text */
125 len = strlen(ppp->subst);
126 while(len && strchr(" \t\r\n", ppp->subst[len-1]))
127 {
128 ppp->subst[--len] = '\0';
129 }
130 /* Strip leading white space from subst text */
131 for(cptr = ppp->subst; *cptr && strchr(" \t\r", *cptr); cptr++)
132 ;
133 if(ppp->subst != cptr)
134 memmove(ppp->subst, cptr, strlen(cptr)+1);
135 if(yydebug)
136 printf("Added (%s, %d) <%s> to <%s>\n", input_name, line_number, ppp->ident, ppp->subst);
137}
138
139void add_cmdline_define(char *set)
140{
141 char *cpy = xstrdup(set); /* Because gcc passes a R/O string */
142 char *cptr = strchr(cpy, '=');
143 if(cptr)
144 *cptr = '\0';
145 set_define(cpy);
146 add_define(cptr ? cptr+1 : "");
147 free(cpy);
148}
149
150#if defined(_Windows) || defined(__MSDOS__) || defined(__WIN32OS2__)
151#define INCLUDESEPARATOR ";"
152#else
153#define INCLUDESEPARATOR ":"
154#endif
155
156static char **includepath;
157static int nincludepath = 0;
158
159void add_include_path(char *path)
160{
161 char *tok;
162 char *cpy = xstrdup(path);
163
164 tok = strtok(cpy, INCLUDESEPARATOR);
165 while(tok)
166 {
167 char *dir;
168 char *cptr;
169 if(strlen(tok) == 0)
170 continue;
171 dir = xstrdup(tok);
172 for(cptr = dir; *cptr; cptr++)
173 {
174 /* Convert to forward slash */
175 if(*cptr == '\\')
176 *cptr = '/';
177 }
178 /* Kill eventual trailing '/' */
179 if(*(cptr = dir + strlen(dir)-1) == '/')
180 *cptr = '\0';
181
182 /* Add to list */
183 nincludepath++;
184 includepath = (char **)xrealloc(includepath, nincludepath * sizeof(*includepath));
185 includepath[nincludepath-1] = dir;
186 tok = strtok(NULL, INCLUDESEPARATOR);
187 }
188 free(cpy);
189}
190
191FILE *open_include(const char *name, int search)
192{
193 char *cpy = xstrdup(name);
194 char *cptr;
195 FILE *fp;
196 int i;
197
198 for(cptr = cpy; *cptr; cptr++)
199 {
200 /* kill double backslash */
201 if(*cptr == '\\' && *(cptr+1) == '\\')
202 memmove(cptr, cptr+1, strlen(cptr));
203 /* Convert to forward slash */
204 if(*cptr == '\\')
205 *cptr = '/';
206 }
207
208 if(search)
209 {
210 /* Search current dir and then -I path */
211 fp = fopen(name, "rt");
212 if(fp)
213 {
214 if(yydebug)
215 printf("Going to include <%s>\n", name);
216 free(cpy);
217 return fp;
218 }
219 }
220 /* Search -I path */
221 for(i = 0; i < nincludepath; i++)
222 {
223 char *path;
224 path = (char *)xmalloc(strlen(includepath[i]) + strlen(cpy) + 2);
225 strcpy(path, includepath[i]);
226 strcat(path, "/");
227 strcat(path, cpy);
228 fp = fopen(path, "rt");
229 if(fp && yydebug)
230 printf("Going to include <%s>\n", path);
231 free(path);
232 if(fp)
233 {
234 free(cpy);
235 return fp;
236 }
237
238 }
239 free(cpy);
240 return NULL;
241}
242
243void push_if(int truecase, int wastrue, int nevertrue)
244{
245 if(ifstackidx >= MAXIFSTACK-1)
246 internal_error(__FILE__, __LINE__, "#if stack overflow");
247 ifstack[ifstackidx].current = truecase && !wastrue;
248 ifstack[ifstackidx].hasbeentrue = wastrue;
249 ifstack[ifstackidx].nevertrue = nevertrue;
250 if(nevertrue || !(truecase && !wastrue))
251 set_pp_ignore(1);
252 if(yydebug)
253 printf("push_if: %d %d %d (%d %d %d)\n",
254 truecase,
255 wastrue,
256 nevertrue,
257 ifstack[ifstackidx].current,
258 ifstack[ifstackidx].hasbeentrue,
259 ifstack[ifstackidx].nevertrue);
260 ifstackidx++;
261}
262
263int pop_if(void)
264{
265 if(ifstackidx <= 0)
266 yyerror("#endif without #if|#ifdef|#ifndef (#if stack underflow)");
267 ifstackidx--;
268 if(yydebug)
269 printf("pop_if: %d %d %d\n",
270 ifstack[ifstackidx].current,
271 ifstack[ifstackidx].hasbeentrue,
272 ifstack[ifstackidx].nevertrue);
273 if(ifstack[ifstackidx].nevertrue || !ifstack[ifstackidx].current)
274 set_pp_ignore(0);
275 return ifstack[ifstackidx].hasbeentrue || ifstack[ifstackidx].current;
276}
277
278int isnevertrue_if(void)
279{
280 return ifstackidx > 0 && ifstack[ifstackidx-1].nevertrue;
281}
282
Note: See TracBrowser for help on using the repository browser.