chiark / gitweb /
Import upstream sources.
[cparse] / parse.c
1 #include "cparse.h"
2 #include <sys/types.h>
3 #include <unistd.h>
4 #include <sys/wait.h>
5
6 static const char *cpp = "cc";
7 static const char **options;
8 static int noptions = 2;
9
10 static void cc_option(const char *s) {
11   options = xrealloc(options, ++noptions * sizeof(char *));
12   options[noptions - 1] = s;
13 }
14
15 int commandline(int argc, char **argv) {
16   int n = 1;
17   
18   yy_flex_debug = 0;
19   while(n < argc && strcmp(argv[n], "--")) {
20     if(!strcmp(argv[n], "--cpp") && n + 1 < argc)
21       cpp = argv[++n];
22     else if(!strcmp(argv[n], "--no-cpp"))
23       cpp = 0;
24     else if(!strcmp(argv[n], "--yydebug"))
25       yydebug = 1;
26     else if(!strcmp(argv[n], "--flexdebug"))
27       yy_flex_debug = 1;
28     else
29       cc_option(argv[n]);
30     ++n;
31   }
32   if(n < argc)
33     ++n;
34   return n;
35 }
36
37 struct external_declaration *parse(const char *filename) {
38   FILE *fp;
39   pid_t pid = -1, r;
40   int p[2], w;
41   struct external_declaration *tu;
42
43   if(cpp) {
44     if(pipe(p) < 0) fatal(errno, "pipe");
45     if((pid = fork()) < 0) fatal(errno, "fork");
46     if(!pid) {
47       exiter = _exit;
48       if(close(p[0]) < 0) fatal(errno, "close");
49       if(p[1] != 1) {
50         if(dup2(p[1], 1) < 0) fatal(errno, "dup2");
51         if(close(p[1]) < 0) fatal(errno, "close");
52       }
53       cc_option(filename);
54       cc_option(0);
55       options[0] = cpp;
56       options[1] = "-E";
57       execvp(options[0], (char **)options);
58       fatal(errno, "execve %s", cpp);
59     }
60     if(close(p[1]) < 0) fatal(errno, "close");
61     if(!(fp = fdopen(p[0], "r"))) fatal(errno, "fdopen");
62   } else
63     if(!(fp = fopen(filename, "r"))) fatal(errno, "opening %s", filename);
64   parser_init(fp);
65   yyparse();
66   yyin = 0;
67   if(fclose(fp) < 0) fatal(errno, "fclose");
68   if(cpp) {
69     while((r = waitpid(pid, &w, 0)) < 0 && errno == EINTR)
70       ;
71     if(r < 0) fatal(errno, "waitpid");
72     if(w) fatal(0, "%s exited with status %d", cpp, w);
73   }
74   tu = translation_unit;
75   translation_unit = 0;
76   return tu;
77 }
78
79 /*
80 Local Variables:
81 c-basic-offset:2
82 comment-column:40
83 End:
84 */