aboutsummaryrefslogtreecommitdiff
path: root/src/preproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/preproc.c')
-rw-r--r--src/preproc.c812
1 files changed, 0 insertions, 812 deletions
diff --git a/src/preproc.c b/src/preproc.c
deleted file mode 100644
index 4d69602..0000000
--- a/src/preproc.c
+++ /dev/null
@@ -1,812 +0,0 @@
1/* grecs - Gray's Extensible Configuration System
2 Copyright (C) 2007-2016 Sergey Poznyakoff
3
4 Grecs is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 3 of the License, or (at your
7 option) any later version.
8
9 Grecs is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with Grecs. If not, see <http://www.gnu.org/licenses/>. */
16
17#ifdef HAVE_CONFIG_H
18# include <config.h>
19#endif
20#include <grecs.h>
21#include <wordsplit.h>
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <sys/wait.h>
25#include <ctype.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <stdarg.h>
29#include <string.h>
30#include <errno.h>
31#include <signal.h>
32#include <glob.h>
33#include <unistd.h>
34
35
36int grecs_log_to_stderr = 1;
37void (*grecs_log_setup_hook) () = NULL;
38
39struct input_file_ident {
40 ino_t i_node;
41 dev_t device;
42};
43
44struct buffer_ctx {
45 struct buffer_ctx *prev; /* Pointer to previous context */
46 grecs_locus_t locus; /* Current input location */
47 size_t namelen; /* Length of the file name */
48 size_t xlines; /* Number of #line directives output so far */
49 struct input_file_ident id;
50 FILE *infile;
51};
52
53extern int grecs_grecs__flex_debug;
54static struct buffer_ctx *context_stack;
55static char *linebufbase = NULL;
56static size_t linebufsize = 0;
57
58#define INFILE context_stack->infile
59#define LOCUS context_stack->locus
60#define POINT context_stack->locus.beg
61
62static char *linebuf;
63static size_t bufsize;
64static char *putback_buffer;
65static size_t putback_size;
66static size_t putback_max;
67static glob_t include_glob;
68static size_t include_pos;
69static int include_once;
70
71static int push_source (const char *name, int once);
72static int pop_source (void);
73static int parse_include (const char *text, int once);
74
75ssize_t
76grecs_getline(char **pbuf, size_t *psize, FILE *fp)
77{
78 char *buf = *pbuf;
79 size_t size = *psize;
80 ssize_t off = 0;
81
82 if (!buf) {
83 size = 1;
84 buf = grecs_malloc(size);
85 }
86
87 do {
88 if (off == size - 1) {
89 size_t nsize = 2 * size;
90 if (nsize < size)
91 grecs_alloc_die();
92 buf = grecs_realloc(buf, nsize);
93 size = nsize;
94 }
95 if (!fgets(buf + off, size - off, fp)) {
96 if (off == 0)
97 off = -1;
98 break;
99 }
100 off += strlen(buf + off);
101 } while (buf[off - 1] != '\n');
102
103 *pbuf = buf;
104 *psize = size;
105 return off;
106}
107
108static void
109putback(const char *str)
110{
111 size_t len;
112
113 if (!*str)
114 return;
115 len = strlen(str) + 1;
116 if (len > putback_max) {
117 putback_max = len;
118 putback_buffer = grecs_realloc(putback_buffer, putback_max);
119 }
120 strcpy(putback_buffer, str);
121 putback_size = len - 1;
122}
123
124static void
125pp_line_stmt()
126{
127 size_t ls_size;
128 size_t pb_size;
129
130 if (grecs_asprintf(&linebufbase, &linebufsize,
131 "#line %lu \"%s\" %lu\n",
132 (unsigned long) POINT.line,
133 POINT.file, (unsigned long) context_stack->xlines))
134 grecs_alloc_die();
135
136 ls_size = strlen(linebufbase);
137 pb_size = putback_size + ls_size + 1;
138
139 if (pb_size > putback_max) {
140 putback_max = pb_size;
141 putback_buffer = grecs_realloc(putback_buffer, putback_max);
142 }
143
144 context_stack->xlines++;
145 strcpy(putback_buffer + putback_size, linebufbase);
146 putback_size += ls_size;
147}
148
149#define STRMATCH(p, len, s) (len >= sizeof(s) \
150 && memcmp(p, s, sizeof(s) - 1) == 0 \
151 && isspace(p[sizeof(s) - 1]))
152
153static int
154next_line()
155{
156 ssize_t rc;
157
158 do {
159 if (putback_size) {
160 if (putback_size + 1 > bufsize) {
161 bufsize = putback_size + 1;
162 linebuf = grecs_realloc(linebuf, bufsize);
163 }
164 strcpy(linebuf, putback_buffer);
165 rc = putback_size;
166 putback_size = 0;
167 }
168 else if (!context_stack)
169 return 0;
170 else
171 rc = grecs_getline(&linebuf, &bufsize, INFILE);
172 } while (rc == -1 && pop_source() == 0);
173 return rc;
174}
175
176size_t
177grecs_preproc_fill_buffer(char *buf, size_t size)
178{
179 size_t bufsize = size;
180
181 while (next_line() > 0) {
182 char *p;
183 size_t len;
184 int is_line = 0;
185
186 for (p = linebuf; *p && isspace(*p); p++)
187 ;
188 if (*p == '#') {
189 size_t l;
190 for (p++; *p && isspace(*p); p++)
191 ;
192 l = strlen(p);
193 if (STRMATCH(p, l, "include_once")) {
194 if (parse_include(linebuf, 1))
195 putback("/*include_once*/\n");
196 continue;
197 } else if (STRMATCH(p, l, "include")) {
198 if (parse_include(linebuf, 0))
199 putback("/*include*/\n");
200 continue;
201 } else if (STRMATCH(p, l, "line"))
202 is_line = 1;
203 }
204
205 len = strlen(linebuf);
206
207 if (len > size)
208 len = size;
209
210 memcpy(buf, linebuf, len);
211 buf += len;
212 size -= len;
213
214 if (size == 0) {
215 putback(linebuf + len);
216 break;
217 }
218
219 if (!is_line && len > 0 && linebuf[len - 1] == '\n')
220 POINT.line++;
221 }
222 return bufsize - size;
223}
224
225#define STAT_ID_EQ(st,id) ((id).i_node == (st).st_ino \
226 && (id).device == (st).st_dev)
227
228static struct buffer_ctx *
229ctx_lookup(struct stat *st)
230{
231 struct buffer_ctx *ctx;
232
233 if (!context_stack)
234 return NULL;
235
236 for (ctx = context_stack->prev; ctx; ctx = ctx->prev)
237 if (STAT_ID_EQ(*st, ctx->id))
238 break;
239 return ctx;
240}
241
242const char *grecs_preprocessor = NULL;
243static struct grecs_list *grecs_usr_include_path;
244static struct grecs_list *grecs_std_include_path;
245
246size_t
247grecs_include_path_count(int flag)
248{
249 size_t count = 0;
250 if (flag & GRECS_STD_INCLUDE)
251