summaryrefslogtreecommitdiffabout
path: root/src/preproc.c
authorSergey Poznyakoff <gray@gnu.org.ua>2011-05-01 18:13:32 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2011-05-03 18:23:16 (GMT)
commit24ec67c9f6375d34d88e79981ed8abbe15a78169 (patch) (unidiff)
tree6e68b1b409b10b48581422df05cfac9caedb0af2 /src/preproc.c
parentda56e338d346e358de864d18ca42f574305d8dfc (diff)
downloadgrecs-24ec67c9f6375d34d88e79981ed8abbe15a78169.tar.gz
grecs-24ec67c9f6375d34d88e79981ed8abbe15a78169.tar.bz2
Reindent all, except wordsplit, which is shared with MU.
Diffstat (limited to 'src/preproc.c') (more/less context) (ignore whitespace changes)
-rw-r--r--src/preproc.c1050
1 files changed, 504 insertions, 546 deletions
diff --git a/src/preproc.c b/src/preproc.c
index 7ea9442..06924c1 100644
--- a/src/preproc.c
+++ b/src/preproc.c
@@ -34,20 +34,18 @@
34int grecs_log_to_stderr = 1; 34int grecs_log_to_stderr = 1;
35void (*grecs_log_setup_hook) () = NULL; 35void (*grecs_log_setup_hook) () = NULL;
36 36
37struct input_file_ident 37struct input_file_ident {
38{ 38 ino_t i_node;
39 ino_t i_node; 39 dev_t device;
40 dev_t device;
41}; 40};
42 41
43struct buffer_ctx 42struct buffer_ctx {
44{ 43 struct buffer_ctx *prev;/* Pointer to previous context */
45 struct buffer_ctx *prev;/* Pointer to previous context */ 44 grecs_locus_t locus; /* Current input location */
46 grecs_locus_t locus; /* Current input location */ 45 size_t namelen; /* Length of the file name */
47 size_t namelen; /* Length of the file name */ 46 size_t xlines; /* Number of #line directives output so far */
48 size_t xlines; /* Number of #line directives output so far */ 47 struct input_file_ident id;
49 struct input_file_ident id; 48 FILE *infile;
50 FILE *infile;
51}; 49};
52 50
53extern int yy_grecs_flex_debug; 51extern int yy_grecs_flex_debug;
@@ -69,669 +67,629 @@ static int pop_source (void);
69static int parse_include (const char *text, int once); 67static int parse_include (const char *text, int once);
70 68
71static ssize_t 69static ssize_t
72pp_getline (char **pbuf, size_t *psize, FILE *fp) 70pp_getline(char **pbuf, size_t *psize, FILE *fp)
73{ 71{
74 char *buf = *pbuf; 72 char *buf = *pbuf;
75 size_t size = *psize; 73 size_t size = *psize;
76 ssize_t off = 0; 74 ssize_t off = 0;
77 75
78 do 76 do {
79 { 77 if (off == size - 1) {
80 size_t len; 78 if (!buf) {
81 79 size = 1;
82 if (off == size - 1) 80 buf = grecs_malloc(size);
83 { 81 } else {
84 if (!buf) 82 size_t nsize = 2 * size;
85 { 83 if (nsize < size)
86 size = 1; 84 grecs_alloc_die();
87 buf = grecs_malloc (size); 85 buf = grecs_realloc(buf, nsize);
88 } 86 size = nsize;
89 else 87 }
90 { 88 }
91 size_t nsize = 2 * size; 89 if (!fgets(buf + off, size - off, fp)) {
92 if (nsize < size) 90 if (off == 0)
93 grecs_alloc_die (); 91 off = -1;
94 buf = grecs_realloc (buf, nsize); 92 break;
95 size = nsize; 93 }
96 } 94 off += strlen(buf + off);
97 }
98 if (!fgets (buf + off, size - off, fp))
99 {
100 if (off == 0)
101 off = -1;
102 break;
103 } 95 }
104 off += strlen (buf + off); 96 while (buf[off - 1] != '\n');
105 }
106 while (buf[off - 1] != '\n');
107 97
108 *pbuf = buf; 98 *pbuf = buf;
109 *psize = size; 99 *psize = size;
110 return off; 100 return off;
111} 101}
112 102
113
114static void 103static void
115putback (const char *str) 104putback(const char *str)
116{ 105{
117 size_t len; 106 size_t len;
118 107
119 if (!*str) 108 if (!*str)
120 return; 109 return;
121 len = strlen (str) + 1; 110 len = strlen(str) + 1;
122 if (len > putback_max) 111 if (len > putback_max) {
123 { 112 putback_max = len;
124 putback_max = len; 113 putback_buffer = grecs_realloc(putback_buffer, putback_max);
125 putback_buffer = grecs_realloc (putback_buffer, putback_max); 114 }
126 } 115 strcpy(putback_buffer, str);
127 strcpy (putback_buffer, str); 116 putback_size = len - 1;
128 putback_size = len - 1;
129} 117}
130 118
131static void 119static void
132pp_line_stmt () 120pp_line_stmt()
133{ 121{
134 size_t ls_size; 122 size_t ls_size;
135 size_t pb_size; 123 size_t pb_size;
136 124
137 if (grecs_asprintf (&linebufbase, &linebufsize, "#line %lu \"%s\" %lu\n", 125 if (grecs_asprintf(&linebufbase, &linebufsize,
138 (unsigned long) LOCUS.line, 126 "#line %lu \"%s\" %lu\n",
139 LOCUS.file, (unsigned long) context_stack->xlines)) 127 (unsigned long) LOCUS.line,
140 grecs_alloc_die (); 128 LOCUS.file, (unsigned long) context_stack->xlines))
141 129 grecs_alloc_die();
142 ls_size = strlen (linebufbase); 130
143 pb_size = putback_size + ls_size + 1; 131 ls_size = strlen(linebufbase);
144 132 pb_size = putback_size + ls_size + 1;
145 if (pb_size > putback_max) 133
146 { 134 if (pb_size > putback_max) {
147 putback_max = pb_size; 135 putback_max = pb_size;
148 putback_buffer = grecs_realloc (putback_buffer, putback_max); 136 putback_buffer = grecs_realloc(putback_buffer, putback_max);
149 } 137 }
150 138
151 context_stack->xlines++; 139 context_stack->xlines++;
152 strcpy (putback_buffer + putback_size, linebufbase); 140 strcpy(putback_buffer + putback_size, linebufbase);
153 putback_size += ls_size; 141 putback_size += ls_size;
154} 142}
155 143
156 #define STRMATCH(p, len, s) (len >= sizeof(s) \ 144 #define STRMATCH(p, len, s) (len >= sizeof(s) \
157 && memcmp (p, s, sizeof(s) - 1) == 0 \ 145 && memcmp(p, s, sizeof(s) - 1) == 0 \
158 && isspace(p[sizeof(s) - 1])) 146 && isspace(p[sizeof(s) - 1]))
159 147
160static int 148static int
161next_line () 149next_line()
162{ 150{
163 ssize_t rc; 151 ssize_t rc;
164 152
165 do 153 do {
166 { 154 if (putback_size) {
167 if (putback_size) 155 if (putback_size + 1 > bufsize) {
168 { 156 bufsize = putback_size + 1;
169 if (putback_size + 1 > bufsize) 157 linebuf = grecs_realloc(linebuf, bufsize);
170 { 158 }
171 bufsize = putback_size + 1; 159 strcpy(linebuf, putback_buffer);
172 linebuf = grecs_realloc (linebuf, bufsize); 160 rc = putback_size;
173 } 161 putback_size = 0;
174 strcpy (linebuf, putback_buffer); 162 }
175 rc = putback_size; 163 else if (!context_stack)
176 putback_size = 0; 164 return 0;
177 } 165 else
178 else if (!context_stack) 166 rc = pp_getline(&linebuf, &bufsize, INFILE);
179 return 0; 167 } while (rc == -1 && pop_source() == 0);
180 else 168 return rc;
181 rc = pp_getline (&linebuf, &bufsize, INFILE);
182 }
183 while (rc == -1 && pop_source () == 0);
184 return rc;
185} 169}
186 170
187size_t 171size_t
188grecs_preproc_fill_buffer (char *buf, size_t size) 172grecs_preproc_fill_buffer(char *buf, size_t size)
189{ 173{
190 size_t bufsize = size; 174 size_t bufsize = size;
191 175
192 while (next_line () > 0) 176 while (next_line() > 0) {
193 { 177 char *p;
194 char *p; 178 size_t len;
195 size_t len; 179 int is_line = 0;
196 int is_line = 0; 180
197 181 for (p = linebuf; *p && isspace(*p); p++)
198 for (p = linebuf; *p && isspace (*p); p++) 182 ;
199 ; 183 if (*p == '#') {
200 if (*p == '#') 184 size_t l;
201 { 185 for (p++; *p && isspace(*p); p++)
202 size_t l; 186 ;
203 for (p++; *p && isspace (*p); p++) 187 l = strlen(p);
204 ; 188 if (STRMATCH(p, l, "include_once")) {
205 l = strlen (p); 189 if (parse_include(linebuf, 1))
206 if (STRMATCH (p, l, "include_once")) 190 putback("/*include_once*/\n");
207 { 191 continue;
208 if (parse_include (linebuf, 1)) 192 } else if (STRMATCH(p, l, "include")) {
209 putback ("/*include_once*/\n"); 193 if (parse_include(linebuf, 0))
210 continue; 194 putback("/*include*/\n");
211 } 195 continue;
212 else if (STRMATCH (p, l, "include")) 196 } else if (STRMATCH(p, l, "line"))
213 { 197 is_line = 1;
214 if (parse_include (linebuf, 0)) 198 }
215 putback ("/*include*/\n");
216 continue;
217 }
218 else if (STRMATCH (p, l, "line"))
219 is_line = 1;
220 }
221
222 len = strlen (linebuf);
223
224 if (len > size)
225 len = size;
226 199
227 memcpy (buf, linebuf, len); 200 len = strlen(linebuf);
228 buf += len; 201
229 size -= len; 202 if (len > size)
203 len = size;
204
205 memcpy(buf, linebuf, len);
206 buf += len;
207 size -= len;
208
209 if (size == 0) {
210 putback(linebuf + len);
211 break;
212 }
230 213
231 if (size == 0) 214 if (!is_line && len > 0 && linebuf[len - 1] == '\n')
232 { 215 LOCUS.line++;
233 putback (linebuf + len);
234 break;
235 } 216 }
236 217 return bufsize - size;
237 if (!is_line && len > 0 && linebuf[len - 1] == '\n')
238 LOCUS.line++;
239 }
240 return bufsize - size;
241} 218}
242 219
243#define STAT_ID_EQ(st,id) ((id).i_node == (st).st_ino \ 220#define STAT_ID_EQ(st,id) ((id).i_node == (st).st_ino \
244 && (id).device == (st).st_dev) 221 && (id).device == (st).st_dev)
245 222
246static struct buffer_ctx * 223static struct buffer_ctx *
247ctx_lookup (struct stat *st) 224ctx_lookup(struct stat *st)
248{ 225{
249 struct buffer_ctx *ctx; 226 struct buffer_ctx *ctx;
250 227
251 if (!context_stack) 228 if (!context_stack)
252 return NULL; 229 return NULL;
253 230
254 for (ctx = context_stack->prev; ctx; ctx = ctx->prev) 231 for (ctx = context_stack->prev; ctx; ctx = ctx->prev)
255 if (STAT_ID_EQ (*st, ctx->id)) 232 if (STAT_ID_EQ(*st, ctx->id))
256 break; 233 break;
257 return ctx; 234 return ctx;
258} 235}
259 236
260const char *grecs_preprocessor = NULL; 237const char *grecs_preprocessor = NULL;
261static struct grecs_list *include_path; 238static struct grecs_list *include_path;
262static struct grecs_list *std_include_path; 239static struct grecs_list *std_include_path;
263 240
264struct file_data 241struct file_data {
265{ 242 const char *name;
266 const char *name; 243 size_t namelen;
267 size_t namelen; 244 char *buf;
268 char *buf; 245 size_t buflen;
269 size_t buflen; 246 int found;
270 int found;
271}; 247};
272 248
273static int 249static int
274pp_list_find (struct grecs_list *list, struct file_data *dptr) 250pp_list_find(struct grecs_list *list, struct file_data *dptr)
275{ 251{
276 struct grecs_list_entry *ep; 252 struct grecs_list_entry *ep;
277 253
278 for (ep = list->head; !dptr->found && ep; ep = ep->next) 254 for (ep = list->head; !dptr->found && ep; ep = ep->next) {
279 { 255 const char *dir = ep->data;
280 const char *dir = ep->data; 256 size_t size = strlen (dir) + 1 + dptr->namelen + 1;
281 size_t size = strlen (dir) + 1 + dptr->namelen + 1; 257 if (size > dptr->buflen) {
282 if (size > dptr->buflen) 258 dptr->buflen = size;
283 { 259 dptr->buf = grecs_realloc(dptr->buf, dptr->buflen);
284 dptr->buflen = size; 260 }
285 dptr->buf = grecs_realloc (dptr->buf, dptr->buflen); 261 strcpy(dptr->buf, dir);
262 strcat(dptr->buf, "/");
263 strcat(dptr->buf, dptr->name);
264 dptr->found = access(dptr->buf, F_OK) == 0;
286 } 265 }
287 strcpy (dptr->buf, dir); 266 return dptr->found;
288 strcat (dptr->buf, "/"); 267}
289 strcat (dptr->buf, dptr->name); 268
290 dptr->found = access (dptr->buf, F_OK) == 0; 269static void
291 } 270incl_free(void *data)
292 return dptr->found; 271{
272 free(data);
293} 273}
294 274
295void 275void
296grecs_include_path_setup_v (char **dirs) 276grecs_include_path_setup_v(char **dirs)
297{ 277{
298 if (!include_path) 278 if (!include_path) {
299 include_path = grecs_list_create (); 279 include_path = grecs_list_create();
300 std_include_path = grecs_list_create (); 280 include_path->free_entry = incl_free;
301 if (dirs) 281 }
302 { 282 std_include_path = grecs_list_create();
303 int i; 283 std_include_path->free_entry = incl_free;
304 for (i = 0; dirs[i]; i++) 284 if (dirs) {
305 /* FIXME: Element never freed */ 285 int i;
306 grecs_list_append (std_include_path, grecs_strdup (dirs[i])); 286 for (i = 0; dirs[i]; i++)
307 } 287 /* FIXME: Element never freed */
288 grecs_list_append(std_include_path,
289 grecs_strdup(dirs[i]));
290 }
308} 291}
309 292
310void 293void
311grecs_include_path_setup (const char *dir, ...) 294grecs_include_path_setup(const char *dir, ...)
312{ 295{
313 const char *p; 296 const char *p;
314 char **argv = NULL; 297 char **argv = NULL;
315 size_t argc = 0; 298 size_t argc = 0;
316 size_t argi = 0; 299 size_t argi = 0;
317 va_list ap; 300 va_list ap;
318 301
319 va_start (ap, dir); 302 va_start(ap, dir);
320 p = dir; 303 p = dir;
321 while (1) 304 while (1) {
322 { 305 if (argi == argc) {
323 if (argi == argc) 306 if (argc == 0)
324 { 307 argc = 16;
325 if (argc == 0) 308 else
326 argc = 16; 309 argc += 16;
327 else 310 argv = grecs_realloc(argv, argc * sizeof(argv[0]));
328 argc += 16; 311 }
329 argv = grecs_realloc (argv, argc * sizeof (argv[0])); 312 argv[argi++] = (char*) p;
313 if (!p)
314 break;
315 p = va_arg(ap, const char*);
330 } 316 }
331 argv[argi++] = (char*) p; 317 grecs_include_path_setup_v(argv);
332 if (!p) 318 free(argv);
333 break; 319 va_end(ap);
334 p = va_arg (ap, const char*);
335 }
336 grecs_include_path_setup_v (argv);
337 free (argv);
338 va_end (ap);
339} 320}
340 321
341void 322void
342grecs_preproc_add_include_dir (char *dir) 323grecs_preproc_add_include_dir(char *dir)
343{ 324{
344 if (!include_path) 325 if (!include_path) {
345 include_path = grecs_list_create (); 326 include_path = grecs_list_create();
346 grecs_list_append (include_path, dir); 327 include_path->free_entry = incl_free;
328 }
329 grecs_list_append(include_path, grecs_strdup(dir));
347} 330}
348 331
349static struct grecs_symtab *incl_sources; 332static struct grecs_symtab *incl_sources;
350 333
351/* Calculate the hash of a struct input_file_ident. */ 334/* Calculate the hash of a struct input_file_ident. */
352static unsigned 335static unsigned
353incl_hasher (void *data, unsigned long n_buckets) 336incl_hasher(void *data, unsigned long n_buckets)
354{ 337{
355 const struct input_file_ident *id = data; 338 const struct input_file_ident *id = data;
356 return (id->i_node + id->device) % n_buckets; 339 return (id->i_node + id->device) % n_buckets;
357} 340}
358 341
359/* Compare two input_file_idents for equality. */ 342/* Compare two input_file_idents for equality. */
360static int 343static int
361incl_compare (void const *data1, void const *data2) 344incl_compare(void const *data1, void const *data2)
362{ 345{
363 const struct input_file_ident *id1 = data1; 346 const struct input_file_ident *id1 = data1;
364 const struct input_file_ident *id2 = data2; 347 const struct input_file_ident *id2 = data2;
365 return !(id1->device == id2->device && id1->i_node == id2->i_node); 348 return !(id1->device == id2->device && id1->i_node == id2->i_node);
366}
367
368static void
369incl_free (void *data)
370{
371 free (data);
372} 349}
373 350
374static int 351static int
375source_lookup (struct stat *st) 352source_lookup(struct stat *st)
376{ 353{
377 struct input_file_ident key; 354 struct input_file_ident key;
378 int install = 1; 355 int install = 1;
379
380 if (!incl_sources)
381 {
382 incl_sources = grecs_symtab_create(sizeof (struct input_file_ident),
383 incl_hasher,
384 incl_compare,
385 NULL,
386 NULL,/*FIXME: alloc*/
387 NULL);
388 if (!incl_sources)
389 grecs_alloc_die ();
390 }
391 356
392 key.i_node = st->st_ino; 357 if (!incl_sources) {
393 key.device = st->st_dev; 358 incl_sources = grecs_symtab_create(
394 if (!grecs_symtab_lookup_or_install(incl_sources, &key, &install)) 359 sizeof(struct input_file_ident),
395 grecs_alloc_die (); 360 incl_hasher,
396 return !install; 361 incl_compare,
362 NULL,
363 NULL,/*FIXME: alloc*/
364 NULL);
365 if (!incl_sources)
366 grecs_alloc_die();
367 }
368
369 key.i_node = st->st_ino;
370 key.device = st->st_dev;
371 if (!grecs_symtab_lookup_or_install(incl_sources, &key, &install))
372 grecs_alloc_die();
373 return !install;
397} 374}
398 375
399 376
400static int 377static int
401push_source (const char *name, int once) 378push_source(const char *name, int once)
402{ 379{
403 FILE *fp; 380 FILE *fp;
404 struct buffer_ctx *ctx; 381 struct buffer_ctx *ctx;
405 struct stat st; 382 struct stat st;
406 int rc = stat (name, &st); 383 int rc = stat(name, &st);
407 384
408 if (context_stack) 385 if (context_stack) {
409 { 386 if (rc) {
410 if (rc) 387 grecs_error(&LOCUS, errno,
411 { 388 _("Cannot stat `%s'"), name);
412 grecs_error (&LOCUS, errno, _("Cannot stat `%s'"), name); 389 return 1;
413 return 1; 390 }
414 }
415 391
416 if (LOCUS.file && STAT_ID_EQ (st, context_stack->id)) 392 if (LOCUS.file && STAT_ID_EQ(st, context_stack->id)) {
417 { 393 grecs_error(&LOCUS, 0, _("Recursive inclusion"));
418 grecs_error (&LOCUS, 0, _("Recursive inclusion")); 394 return 1;
419 return 1; 395 }
396
397 if ((ctx = ctx_lookup(&st))) {
398 grecs_error(&LOCUS, 0, _("Recursive inclusion"));
399 if (ctx->prev)
400 grecs_error(&ctx->prev->locus, 0,
401 _("`%s' already included here"),
402 name);
403 else
404 grecs_error(&LOCUS, 0,
405 _("`%s' already included at top level"),
406 name);
407 return 1;
408 }
409 } else if (rc) {
410 grecs_error(NULL, errno, _("Cannot stat `%s'"), name);
411 return 1;
420 } 412 }
421 413
422 if ((ctx = ctx_lookup (&st))) 414 if (once && source_lookup(&st))
423 { 415 return -1;
424 grecs_error (&LOCUS, 0, _("Recursive inclusion")); 416
425 if (ctx->prev) 417 fp = fopen(name, "r");
426 grecs_error (&ctx->prev->locus, 0, 418 if (!fp) {
427 _("`%s' already included here"), name); 419 grecs_error(&LOCUS, errno, _("Cannot open `%s'"), name);
428 else 420 return 1;
429 grecs_error (&LOCUS, 0,
430 _("`%s' already included at top level"), name);
431 return 1;
432 } 421 }
433 }
434 else if (rc)
435 {
436 grecs_error (NULL, errno, _("Cannot stat `%s'"), name);
437 return 1;
438 }
439
440 if (once && source_lookup (&st))
441 return -1;
442
443 fp = fopen (name, "r");
444 if (!fp)
445 {
446 grecs_error (&LOCUS, errno, _("Cannot open `%s'"), name);
447 return 1;
448 }
449
450 /* Push current context */
451 ctx = grecs_malloc (sizeof (*ctx));
452 ctx->locus.file = grecs_install_text (name);
453 ctx->locus.line = 1;
454 ctx->xlines = 0;
455 ctx->namelen = strlen (ctx->locus.file);
456 ctx->id.i_node = st.st_ino;
457 ctx->id.device = st.st_dev;
458 ctx->infile = fp;
459 ctx->prev = context_stack;
460 context_stack = ctx;
461
462 if (yy_grecs_flex_debug)
463 fprintf (stderr, "Processing file `%s'\n", name);
464
465 pp_line_stmt ();
466
467 return 0;
468}
469 422
470static int 423 /* Push current context */
471pop_source () 424 ctx = grecs_malloc(sizeof(*ctx));
472{ 425 ctx->locus.file = grecs_install_text(name);
473 struct buffer_ctx *ctx; 426 ctx->locus.line = 1;
427 ctx->xlines = 0;
428 ctx->namelen = strlen(ctx->locus.file);
429 ctx->id.i_node = st.st_ino;
430 ctx->id.device = st.st_dev;
431 ctx->infile = fp;
432 ctx->prev = context_stack;
433 context_stack = ctx;
474 434
475 if (!context_stack) 435 if (yy_grecs_flex_debug)
476 return 1; 436 fprintf (stderr, "Processing file `%s'\n", name);
477 437
478 fclose (INFILE); 438 pp_line_stmt();
479 439
480 /* Restore previous context */ 440 return 0;
481 ctx = context_stack->prev; 441}
482 free (context_stack);
483 context_stack = ctx;
484 442
485 if (!context_stack) 443static int
486 { 444pop_source()
487 if (yy_grecs_flex_debug) 445{
488 fprintf (stderr, "End of input\n"); 446 struct buffer_ctx *ctx;
489 return 1; 447
490 } 448 if (!context_stack)
449 return 1;
450
451 fclose(INFILE);
452
453 /* Restore previous context */
454 ctx = context_stack->prev;
455 free(context_stack);
456 context_stack = ctx;
457
458 if (!context_stack) {
459 if (yy_grecs_flex_debug)
460 fprintf (stderr, "End of input\n");
461 return 1;
462 }
491 463
492 LOCUS.line++; 464 LOCUS.line++;
493 465
494 if (yy_grecs_flex_debug) 466 if (yy_grecs_flex_debug)
495 fprintf (stderr, "Resuming file `%s' at line %lu\n", 467 fprintf (stderr, "Resuming file `%s' at line %lu\n",
496 LOCUS.file, (unsigned long) LOCUS.line); 468 LOCUS.file, (unsigned long) LOCUS.line);
497 469
498 pp_line_stmt (); 470 pp_line_stmt();
499 471
500 return 0; 472 return 0;
501} 473}
502 474
503static int 475static int
504try_file (const char *name, int allow_cwd, int err_not_found, char **newp) 476try_file(const char *name, int allow_cwd, int err_not_found, char **newp)
505{ 477{
506 static char *cwd = "."; 478 static char *cwd = ".";
507 struct file_data fd; 479 struct file_data fd;
508 480
509 fd.name = name; 481 fd.name = name;
510 fd.namelen = strlen (name); 482 fd.namelen = strlen(name);
511 fd.buf = NULL; 483 fd.buf = NULL;
512 fd.buflen = 0; 484 fd.buflen = 0;
513 fd.found = 0; 485 fd.found = 0;
514 486
515 if (!include_path) 487 if (!include_path)
516 grecs_include_path_setup (NULL); 488 grecs_include_path_setup(NULL);
517 if (allow_cwd) 489 if (allow_cwd) {
518 { 490 grecs_list_append(include_path, cwd);
519 grecs_list_append (include_path, cwd); 491 pp_list_find(include_path, &fd);
520 pp_list_find (include_path, &fd); 492 grecs_list_remove_tail(include_path);
521 grecs_list_remove_tail (include_path); 493 } else
522 } 494 pp_list_find(include_path, &fd);
523 else 495
524 pp_list_find (include_path, &fd); 496 if (!fd.found) {
525 497 pp_list_find(std_include_path, &fd);
526 if (!fd.found) 498
527 { 499 if (!fd.found && err_not_found) {
528 pp_list_find (std_include_path, &fd); 500 grecs_error(&LOCUS, 0,
529 501 _("%s: No such file or directory"), name);
530 if (!fd.found && err_not_found) 502 *newp = NULL;
531 { 503 }
532 grecs_error (&LOCUS, 0, _("%s: No such file or directory"), name);
533 *newp = NULL;
534 } 504 }
535 } 505 if (fd.found)
536 if (fd.found) 506 *newp = fd.buf;
537 *newp = fd.buf; 507 return fd.found;
538 return fd.found;
539} 508}
540 509
541static int 510static int
542parse_include (const char *text, int once) 511parse_include(const char *text, int once)
543{ 512{
544 struct wordsplit ws; 513 struct wordsplit ws;
545 char *tmp = NULL; 514 char *tmp = NULL;
546 char *p = NULL; 515 char *p = NULL;
547 int rc = 1; 516 int rc = 1;
548 517
549 if (wordsplit (text, &ws, WRDSF_DEFFLAGS)) 518 if (wordsplit(text, &ws, WRDSF_DEFFLAGS))
550 grecs_error (&LOCUS, 0, _("Cannot parse include line")); 519 grecs_error(&LOCUS, 0, _("Cannot parse include line"));
551 else if (ws.ws_wordc != 2) 520 else if (ws.ws_wordc != 2) {
552 { 521 wordsplit_free(&ws);
553 wordsplit_free (&ws); 522 grecs_error(&LOCUS, 0, _("invalid include statement"));
554 grecs_error (&LOCUS, 0, _("invalid include statement")); 523 } else {
555 } 524 size_t len;
556 else 525 int allow_cwd;
557 { 526
558 size_t len; 527 p = ws.ws_wordv[1];
559 int allow_cwd; 528 len = strlen (p);
560 529
561 p = ws.ws_wordv[1]; 530 if (p[0] == '<' && p[len - 1] == '>') {
562 len = strlen (p); 531 allow_cwd = 0;
563 532 p[len - 1] = 0;
564 if (p[0] == '<' && p[len - 1] == '>') 533 p++;
565 { 534 }
566 allow_cwd = 0; 535 else
567 p[len - 1] = 0; 536 allow_cwd = 1;
568 p++; 537
538 if (p[0] != '/' && try_file(p, allow_cwd, 1, &tmp))
539 p = tmp;
569 } 540 }
570 else
571 allow_cwd = 1;
572
573 if (p[0] != '/' && try_file (p, allow_cwd, 1, &tmp))
574 p = tmp;
575 }
576 541
577 if (p) 542 if (p)
578 rc = push_source (p, once); 543 rc = push_source(p, once);
579 free (tmp); 544 free(tmp);
580 wordsplit_free (&ws); 545 wordsplit_free(&ws);
581 return rc; 546 return rc;
582} 547}
583 548
584int 549int
585grecs_preproc_init (const char *name) 550grecs_preproc_init(const char *name)
586{ 551{
587 return push_source (name, 0); 552 return push_source(name, 0);
588} 553}
589 554
590void 555void
591grecs_preproc_done () 556grecs_preproc_done()
592{ 557{
593 grecs_symtab_free (incl_sources); 558 grecs_symtab_free(incl_sources);
594 free (linebuf); 559 free(linebuf);
595 free (putback_buffer); 560 free(putback_buffer);
596 free (linebufbase); 561 free(linebufbase);
597} 562}
598 563
599int 564int
600grecs_preproc_run (const char *config_file, const char *extpp) 565grecs_preproc_run(const char *config_file, const char *extpp)
601{ 566{
602 size_t i; 567 size_t i;
603 char buffer[512]; 568 char buffer[512];
604 569
605 if (grecs_preproc_init (config_file)) 570 if (grecs_preproc_init(config_file))
606 return 1; 571 return 1;
607 if (extpp) 572 if (extpp) {
608 { 573 FILE *outfile;
609 FILE *outfile; 574 char *setup_file;
610 char *setup_file; 575 char *cmd = NULL;
611 char *cmd; 576
612 577 if (try_file("pp-setup", 1, 0, &setup_file)) {
613 if (try_file ("pp-setup", 1, 0, &setup_file)) 578 size_t size = 0;
614 { 579 if (grecs_asprintf(&cmd, &size,
615 asprintf (&cmd, "%s %s -", extpp, setup_file); 580 "%s %s -", extpp, setup_file))
616 free (setup_file); 581 grecs_alloc_die();
617 } 582 free(setup_file);
618 else 583 } else
619 cmd = grecs_strdup (extpp); 584 cmd = grecs_strdup (extpp);
620 /*FIXME_DEBUG_F1 (2, "Running preprocessor: `%s'", cmd);*/ 585 /*FIXME_DEBUG_F1 (2, "Running preprocessor: `%s'", cmd);*/
621 outfile = popen (cmd, "w"); 586 outfile = popen(cmd, "w");
622 if (!outfile) 587 if (!outfile){
623 { 588 grecs_error(NULL, errno,
624 grecs_error (NULL, errno, 589 _("Unable to start external preprocessor `%s'"),
625 _("Unable to start external preprocessor `%s'"), cmd); 590 cmd);
626 free (cmd); 591 free(cmd);
627 return 1; 592 return 1;
628 } 593 }
629 594
630 while ((i = grecs_preproc_fill_buffer (buffer, sizeof buffer))) 595 while ((i = grecs_preproc_fill_buffer(buffer, sizeof buffer)))
631 fwrite (buffer, 1, i, outfile); 596 fwrite(buffer, 1, i, outfile);
632 pclose (outfile); 597 pclose(outfile);
633 free (cmd); 598 free(cmd);
634 } 599 } else {
635 else 600 while ((i = grecs_preproc_fill_buffer(buffer, sizeof buffer)))
636 { 601 fwrite(buffer, 1, i, stdout);
637 while ((i = grecs_preproc_fill_buffer (buffer, sizeof buffer))) 602 }
638 fwrite (buffer, 1, i, stdout); 603 grecs_preproc_done();
639 } 604 return 0;
640 grecs_preproc_done ();
641 return 0;
642} 605}
643 606
644FILE * 607FILE *
645grecs_preproc_extrn_start (const char *file_name, pid_t *ppid) 608grecs_preproc_extrn_start(const char *file_name, pid_t *ppid)
646{ 609{
647 int pout[2]; 610 int pout[2];
648 pid_t pid; 611 pid_t pid;
649 int i; 612 int i;
650 FILE *fp = NULL; 613 FILE *fp = NULL;
651 614
652 /*FIXME_DEBUG_F1 (2, "Running preprocessor: `%s'", ppcmd);*/ 615 /*FIXME_DEBUG_F1 (2, "Running preprocessor: `%s'", ppcmd);*/
653 616
654 pipe (pout); 617 pipe(pout);
655 switch (pid = fork ()) 618 switch (pid = fork()) {
656 { 619 /* The child branch. */
657 /* The child branch. */ 620 case 0:
658 case 0: 621 if (pout[1] != 1) {
659 if (pout[1] != 1) 622 close(1);
660 { 623 dup2(pout[1], 1);
661 close (1); 624 }
662 dup2 (pout[1], 1);
663 }
664 625
665 /* Close unneeded descripitors */ 626 /* Close unneeded descripitors */
666 for (i = getdtablesize (); i > 2; i--) 627 for (i = getdtablesize(); i > 2; i--)
667 close (i); 628 close(i);
668 629
669 if (!grecs_log_to_stderr) 630 if (!grecs_log_to_stderr) {
670 { 631 int p[2];
671 int p[2]; 632 char *buf = NULL;
672 char *buf = NULL; 633 size_t size = 0;
673 size_t size = 0; 634 FILE *fp;
674 FILE *fp;
675 635
676 signal (SIGCHLD, SIG_DFL); 636 signal(SIGCHLD, SIG_DFL);
677 pipe (p); 637 pipe(p);
678 switch (pid = fork ()) 638 switch (pid = fork()) {
679 { 639 /* Grandchild */
680 /* Grandchild */ 640 case 0:
681 case 0: 641 if (p[1] != 2) {
682 if (p[1] != 2) 642 close(2);
683 { 643 dup2(p[1], 2);
684 close (2); 644 }
685 dup2 (p[1], 2); 645 close(p[0]);
646
647 if (grecs_preproc_run(file_name,
648 grecs_preprocessor))
649 exit(127);
650 exit(0);
651
652 case -1:
653 /* Fork failed */
654 if (grecs_log_setup_hook)
655 grecs_log_setup_hook();
656 grecs_error(NULL, errno, _("Cannot run `%s'"),
657 grecs_preprocessor);
658 exit(127);
659
660 default:
661 /* Sub-master */
662 close (p[1]);
663 fp = fdopen(p[0], "r");
664 if (grecs_log_setup_hook)
665 grecs_log_setup_hook();
666 while (pp_getline(&buf, &size, fp) > 0)
667 grecs_error(NULL, 0, "%s", buf);
668 }
669 } else {
670 grecs_preproc_run(file_name, grecs_preprocessor);
686 } 671 }
687 close (p[0]); 672 exit (0);
688 673
689 if (grecs_preproc_run (file_name, grecs_preprocessor)) 674 case -1:
690 exit (127); 675 /* Fork failed */
691 exit (0); 676 grecs_error(NULL, errno, _("Cannot run `%s'"),
692 677 grecs_preprocessor);
693 case -1: 678 break;
694 /* Fork failed */ 679
695 if (grecs_log_setup_hook) 680 default:
696 grecs_log_setup_hook (); 681 close(pout[1]);
697 grecs_error (NULL, errno, _("Cannot run `%s'"), 682 fp = fdopen(pout[0], "r");
698 grecs_preprocessor); 683 break;
699 exit (127);
700
701 default:
702 /* Sub-master */
703 close (p[1]);
704 fp = fdopen (p[0], "r");
705 if (grecs_log_setup_hook)
706 grecs_log_setup_hook ();
707 while (pp_getline (&buf, &size, fp) > 0)
708 grecs_error (NULL, 0, "%s", buf);
709 }
710 }
711 else
712 {
713 grecs_preproc_run (file_name, grecs_preprocessor);
714 } 684 }
715 exit (0); 685 *ppid = pid;
716 686 return fp;
717 case -1:
718 /* Fork failed */
719 grecs_error (NULL, errno, _("Cannot run `%s'"), grecs_preprocessor);
720 break;
721
722 default:
723 close (pout[1]);
724 fp = fdopen (pout[0], "r");
725 break;
726 }
727 *ppid = pid;
728 return fp;
729} 687}
730 688
731void 689void
732grecs_preproc_extrn_shutdown (pid_t pid) 690grecs_preproc_extrn_shutdown(pid_t pid)
733{ 691{
734 int status; 692 int status;
735 waitpid (pid, &status, 0); 693 waitpid(pid, &status, 0);
736} 694}
737 695

Return to:

Send suggestions and report system problems to the System administrator.