diff options
Diffstat (limited to 'src/preproc.c')
-rw-r--r-- | src/preproc.c | 1050 |
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 @@ | |||
34 | int grecs_log_to_stderr = 1; | 34 | int grecs_log_to_stderr = 1; |
35 | void (*grecs_log_setup_hook) () = NULL; | 35 | void (*grecs_log_setup_hook) () = NULL; |
36 | 36 | ||
37 | struct input_file_ident | 37 | struct 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 | ||
43 | struct buffer_ctx | 42 | struct 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 | ||
53 | extern int yy_grecs_flex_debug; | 51 | extern int yy_grecs_flex_debug; |
@@ -69,669 +67,629 @@ static int pop_source (void); | |||
69 | static int parse_include (const char *text, int once); | 67 | static int parse_include (const char *text, int once); |
70 | 68 | ||
71 | static ssize_t | 69 | static ssize_t |
72 | pp_getline (char **pbuf, size_t *psize, FILE *fp) | 70 | pp_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 | |||
114 | static void | 103 | static void |
115 | putback (const char *str) | 104 | putback(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 | ||
131 | static void | 119 | static void |
132 | pp_line_stmt () | 120 | pp_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 | ||
160 | static int | 148 | static int |
161 | next_line () | 149 | next_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 | ||
187 | size_t | 171 | size_t |
188 | grecs_preproc_fill_buffer (char *buf, size_t size) | 172 | grecs_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)) |