yann@2836
|
1 |
%option backup nostdinit noyywrap never-interactive full ecs
|
yann@2836
|
2 |
%option 8bit backup nodefault perf-report perf-report
|
yann@2836
|
3 |
%option noinput
|
yann@2836
|
4 |
%x COMMAND HELP STRING PARAM
|
yann@2836
|
5 |
%{
|
yann@2836
|
6 |
/*
|
yann@2836
|
7 |
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
|
yann@2836
|
8 |
* Released under the terms of the GNU GPL v2.0.
|
yann@2836
|
9 |
*/
|
yann@2836
|
10 |
|
yann@2836
|
11 |
#include <limits.h>
|
yann@2836
|
12 |
#include <stdio.h>
|
yann@2836
|
13 |
#include <stdlib.h>
|
yann@2836
|
14 |
#include <string.h>
|
yann@2836
|
15 |
#include <unistd.h>
|
yann@2836
|
16 |
|
yann@2836
|
17 |
#define LKC_DIRECT_LINK
|
yann@2836
|
18 |
#include "lkc.h"
|
yann@2836
|
19 |
|
yann@2836
|
20 |
#define START_STRSIZE 16
|
yann@2836
|
21 |
|
yann@2836
|
22 |
static struct {
|
yann@2836
|
23 |
struct file *file;
|
yann@2836
|
24 |
int lineno;
|
yann@2836
|
25 |
} current_pos;
|
yann@2836
|
26 |
|
yann@2836
|
27 |
static char *text;
|
yann@2836
|
28 |
static int text_size, text_asize;
|
yann@2836
|
29 |
|
yann@2836
|
30 |
struct buffer {
|
yann@2836
|
31 |
struct buffer *parent;
|
yann@2836
|
32 |
YY_BUFFER_STATE state;
|
yann@2836
|
33 |
};
|
yann@2836
|
34 |
|
yann@2836
|
35 |
struct buffer *current_buf;
|
yann@2836
|
36 |
|
yann@2836
|
37 |
static int last_ts, first_ts;
|
yann@2836
|
38 |
|
yann@2836
|
39 |
static void zconf_endhelp(void);
|
yann@2836
|
40 |
static void zconf_endfile(void);
|
yann@2836
|
41 |
|
yann@2836
|
42 |
static void new_string(void)
|
yann@2836
|
43 |
{
|
yann@2836
|
44 |
text = malloc(START_STRSIZE);
|
yann@2836
|
45 |
text_asize = START_STRSIZE;
|
yann@2836
|
46 |
text_size = 0;
|
yann@2836
|
47 |
*text = 0;
|
yann@2836
|
48 |
}
|
yann@2836
|
49 |
|
yann@2836
|
50 |
static void append_string(const char *str, int size)
|
yann@2836
|
51 |
{
|
yann@2836
|
52 |
int new_size = text_size + size + 1;
|
yann@2836
|
53 |
if (new_size > text_asize) {
|
yann@2836
|
54 |
new_size += START_STRSIZE - 1;
|
yann@2836
|
55 |
new_size &= -START_STRSIZE;
|
yann@2836
|
56 |
text = realloc(text, new_size);
|
yann@2836
|
57 |
text_asize = new_size;
|
yann@2836
|
58 |
}
|
yann@2836
|
59 |
memcpy(text + text_size, str, size);
|
yann@2836
|
60 |
text_size += size;
|
yann@2836
|
61 |
text[text_size] = 0;
|
yann@2836
|
62 |
}
|
yann@2836
|
63 |
|
yann@2836
|
64 |
static void alloc_string(const char *str, int size)
|
yann@2836
|
65 |
{
|
yann@2836
|
66 |
text = malloc(size + 1);
|
yann@2836
|
67 |
memcpy(text, str, size);
|
yann@2836
|
68 |
text[size] = 0;
|
yann@2836
|
69 |
}
|
yann@2836
|
70 |
%}
|
yann@2836
|
71 |
|
yann@2836
|
72 |
ws [ \n\t]
|
yann@2836
|
73 |
n [A-Za-z0-9_]
|
yann@2836
|
74 |
|
yann@2836
|
75 |
%%
|
yann@2836
|
76 |
int str = 0;
|
yann@2836
|
77 |
int ts, i;
|
yann@2836
|
78 |
|
yann@2836
|
79 |
[ \t]*#.*\n |
|
yann@2836
|
80 |
[ \t]*\n {
|
yann@2836
|
81 |
current_file->lineno++;
|
yann@2836
|
82 |
return T_EOL;
|
yann@2836
|
83 |
}
|
yann@2836
|
84 |
[ \t]*#.*
|
yann@2836
|
85 |
|
yann@2836
|
86 |
|
yann@2836
|
87 |
[ \t]+ {
|
yann@2836
|
88 |
BEGIN(COMMAND);
|
yann@2836
|
89 |
}
|
yann@2836
|
90 |
|
yann@2836
|
91 |
. {
|
yann@2836
|
92 |
unput(yytext[0]);
|
yann@2836
|
93 |
BEGIN(COMMAND);
|
yann@2836
|
94 |
}
|
yann@2836
|
95 |
|
yann@2836
|
96 |
|
yann@2836
|
97 |
<COMMAND>{
|
yann@2836
|
98 |
{n}+ {
|
yann@2836
|
99 |
struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
|
yann@2836
|
100 |
BEGIN(PARAM);
|
yann@2836
|
101 |
current_pos.file = current_file;
|
yann@2836
|
102 |
current_pos.lineno = current_file->lineno;
|
yann@2836
|
103 |
if (id && id->flags & TF_COMMAND) {
|
yann@2836
|
104 |
zconflval.id = id;
|
yann@2836
|
105 |
return id->token;
|
yann@2836
|
106 |
}
|
yann@2836
|
107 |
alloc_string(yytext, yyleng);
|
yann@2836
|
108 |
zconflval.string = text;
|
yann@2836
|
109 |
return T_WORD;
|
yann@2836
|
110 |
}
|
yann@2836
|
111 |
.
|
yann@2836
|
112 |
\n {
|
yann@2836
|
113 |
BEGIN(INITIAL);
|
yann@2836
|
114 |
current_file->lineno++;
|
yann@2836
|
115 |
return T_EOL;
|
yann@2836
|
116 |
}
|
yann@2836
|
117 |
}
|
yann@2836
|
118 |
|
yann@2836
|
119 |
<PARAM>{
|
yann@2836
|
120 |
"&&" return T_AND;
|
yann@2836
|
121 |
"||" return T_OR;
|
yann@2836
|
122 |
"(" return T_OPEN_PAREN;
|
yann@2836
|
123 |
")" return T_CLOSE_PAREN;
|
yann@2836
|
124 |
"!" return T_NOT;
|
yann@2836
|
125 |
"=" return T_EQUAL;
|
yann@2836
|
126 |
"!=" return T_UNEQUAL;
|
yann@2836
|
127 |
\"|\' {
|
yann@2836
|
128 |
str = yytext[0];
|
yann@2836
|
129 |
new_string();
|
yann@2836
|
130 |
BEGIN(STRING);
|
yann@2836
|
131 |
}
|
yann@2836
|
132 |
\n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
|
yann@2836
|
133 |
--- /* ignore */
|
yann@2836
|
134 |
({n}|[-/.])+ {
|
yann@2836
|
135 |
struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
|
yann@2836
|
136 |
if (id && id->flags & TF_PARAM) {
|
yann@2836
|
137 |
zconflval.id = id;
|
yann@2836
|
138 |
return id->token;
|
yann@2836
|
139 |
}
|
yann@2836
|
140 |
alloc_string(yytext, yyleng);
|
yann@2836
|
141 |
zconflval.string = text;
|
yann@2836
|
142 |
return T_WORD;
|
yann@2836
|
143 |
}
|
yann@2836
|
144 |
#.* /* comment */
|
yann@2836
|
145 |
\\\n current_file->lineno++;
|
yann@2836
|
146 |
.
|
yann@2836
|
147 |
<<EOF>> {
|
yann@2836
|
148 |
BEGIN(INITIAL);
|
yann@2836
|
149 |
}
|
yann@2836
|
150 |
}
|
yann@2836
|
151 |
|
yann@2836
|
152 |
<STRING>{
|
yann@2836
|
153 |
[^'"\\\n]+/\n {
|
yann@2836
|
154 |
append_string(yytext, yyleng);
|
yann@2836
|
155 |
zconflval.string = text;
|
yann@2836
|
156 |
return T_WORD_QUOTE;
|
yann@2836
|
157 |
}
|
yann@2836
|
158 |
[^'"\\\n]+ {
|
yann@2836
|
159 |
append_string(yytext, yyleng);
|
yann@2836
|
160 |
}
|
yann@2836
|
161 |
\\.?/\n {
|
yann@2836
|
162 |
append_string(yytext + 1, yyleng - 1);
|
yann@2836
|
163 |
zconflval.string = text;
|
yann@2836
|
164 |
return T_WORD_QUOTE;
|
yann@2836
|
165 |
}
|
yann@2836
|
166 |
\\.? {
|
yann@2836
|
167 |
append_string(yytext + 1, yyleng - 1);
|
yann@2836
|
168 |
}
|
yann@2836
|
169 |
\'|\" {
|
yann@2836
|
170 |
if (str == yytext[0]) {
|
yann@2836
|
171 |
BEGIN(PARAM);
|
yann@2836
|
172 |
zconflval.string = text;
|
yann@2836
|
173 |
return T_WORD_QUOTE;
|
yann@2836
|
174 |
} else
|
yann@2836
|
175 |
append_string(yytext, 1);
|
yann@2836
|
176 |
}
|
yann@2836
|
177 |
\n {
|
yann@2836
|
178 |
printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
|
yann@2836
|
179 |
current_file->lineno++;
|
yann@2836
|
180 |
BEGIN(INITIAL);
|
yann@2836
|
181 |
return T_EOL;
|
yann@2836
|
182 |
}
|
yann@2836
|
183 |
<<EOF>> {
|
yann@2836
|
184 |
BEGIN(INITIAL);
|
yann@2836
|
185 |
}
|
yann@2836
|
186 |
}
|
yann@2836
|
187 |
|
yann@2836
|
188 |
<HELP>{
|
yann@2836
|
189 |
[ \t]+ {
|
yann@2836
|
190 |
ts = 0;
|
yann@2836
|
191 |
for (i = 0; i < yyleng; i++) {
|
yann@2836
|
192 |
if (yytext[i] == '\t')
|
yann@2836
|
193 |
ts = (ts & ~7) + 8;
|
yann@2836
|
194 |
else
|
yann@2836
|
195 |
ts++;
|
yann@2836
|
196 |
}
|
yann@2836
|
197 |
last_ts = ts;
|
yann@2836
|
198 |
if (first_ts) {
|
yann@2836
|
199 |
if (ts < first_ts) {
|
yann@2836
|
200 |
zconf_endhelp();
|
yann@2836
|
201 |
return T_HELPTEXT;
|
yann@2836
|
202 |
}
|
yann@2836
|
203 |
ts -= first_ts;
|
yann@2836
|
204 |
while (ts > 8) {
|
yann@2836
|
205 |
append_string(" ", 8);
|
yann@2836
|
206 |
ts -= 8;
|
yann@2836
|
207 |
}
|
yann@2836
|
208 |
append_string(" ", ts);
|
yann@2836
|
209 |
}
|
yann@2836
|
210 |
}
|
yann@2836
|
211 |
[ \t]*\n/[^ \t\n] {
|
yann@2836
|
212 |
current_file->lineno++;
|
yann@2836
|
213 |
zconf_endhelp();
|
yann@2836
|
214 |
return T_HELPTEXT;
|
yann@2836
|
215 |
}
|
yann@2836
|
216 |
[ \t]*\n {
|
yann@2836
|
217 |
current_file->lineno++;
|
yann@2836
|
218 |
append_string("\n", 1);
|
yann@2836
|
219 |
}
|
yann@2836
|
220 |
[^ \t\n].* {
|
yann@2836
|
221 |
while (yyleng) {
|
yann@2836
|
222 |
if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t'))
|
yann@2836
|
223 |
break;
|
yann@2836
|
224 |
yyleng--;
|
yann@2836
|
225 |
}
|
yann@2836
|
226 |
append_string(yytext, yyleng);
|
yann@2836
|
227 |
if (!first_ts)
|
yann@2836
|
228 |
first_ts = last_ts;
|
yann@2836
|
229 |
}
|
yann@2836
|
230 |
<<EOF>> {
|
yann@2836
|
231 |
zconf_endhelp();
|
yann@2836
|
232 |
return T_HELPTEXT;
|
yann@2836
|
233 |
}
|
yann@2836
|
234 |
}
|
yann@2836
|
235 |
|
yann@2836
|
236 |
<<EOF>> {
|
yann@2836
|
237 |
if (current_file) {
|
yann@2836
|
238 |
zconf_endfile();
|
yann@2836
|
239 |
return T_EOL;
|
yann@2836
|
240 |
}
|
yann@2836
|
241 |
fclose(yyin);
|
yann@2836
|
242 |
yyterminate();
|
yann@2836
|
243 |
}
|
yann@2836
|
244 |
|
yann@2836
|
245 |
%%
|
yann@2836
|
246 |
void zconf_starthelp(void)
|
yann@2836
|
247 |
{
|
yann@2836
|
248 |
new_string();
|
yann@2836
|
249 |
last_ts = first_ts = 0;
|
yann@2836
|
250 |
BEGIN(HELP);
|
yann@2836
|
251 |
}
|
yann@2836
|
252 |
|
yann@2836
|
253 |
static void zconf_endhelp(void)
|
yann@2836
|
254 |
{
|
yann@2836
|
255 |
zconflval.string = text;
|
yann@2836
|
256 |
BEGIN(INITIAL);
|
yann@2836
|
257 |
}
|
yann@2836
|
258 |
|
yann@2836
|
259 |
|
yann@2836
|
260 |
/*
|
yann@2836
|
261 |
* Try to open specified file with following names:
|
yann@2836
|
262 |
* ./name
|
yann@2836
|
263 |
* $(srctree)/name
|
yann@2836
|
264 |
* The latter is used when srctree is separate from objtree
|
yann@2836
|
265 |
* when compiling the kernel.
|
yann@2836
|
266 |
* Return NULL if file is not found.
|
yann@2836
|
267 |
*/
|
yann@2836
|
268 |
FILE *zconf_fopen(const char *name)
|
yann@2836
|
269 |
{
|
yann@2836
|
270 |
char *env, fullname[PATH_MAX+1];
|
yann@2836
|
271 |
FILE *f;
|
yann@2836
|
272 |
|
yann@2836
|
273 |
f = fopen(name, "r");
|
yann@2836
|
274 |
if (!f && name != NULL && name[0] != '/') {
|
yann@2836
|
275 |
env = getenv(SRCTREE);
|
yann@2836
|
276 |
if (env) {
|
yann@2836
|
277 |
sprintf(fullname, "%s/%s", env, name);
|
yann@2836
|
278 |
f = fopen(fullname, "r");
|
yann@2836
|
279 |
}
|
yann@2836
|
280 |
}
|
yann@2836
|
281 |
return f;
|
yann@2836
|
282 |
}
|
yann@2836
|
283 |
|
yann@2836
|
284 |
void zconf_initscan(const char *name)
|
yann@2836
|
285 |
{
|
yann@2836
|
286 |
yyin = zconf_fopen(name);
|
yann@2836
|
287 |
if (!yyin) {
|
yann@2836
|
288 |
printf("can't find file %s\n", name);
|
yann@2836
|
289 |
exit(1);
|
yann@2836
|
290 |
}
|
yann@2836
|
291 |
|
yann@2836
|
292 |
current_buf = malloc(sizeof(*current_buf));
|
yann@2836
|
293 |
memset(current_buf, 0, sizeof(*current_buf));
|
yann@2836
|
294 |
|
yann@2836
|
295 |
current_file = file_lookup(name);
|
yann@2836
|
296 |
current_file->lineno = 1;
|
yann@2836
|
297 |
}
|
yann@2836
|
298 |
|
yann@2836
|
299 |
void zconf_nextfile(const char *name)
|
yann@2836
|
300 |
{
|
yann@2836
|
301 |
struct file *iter;
|
yann@2836
|
302 |
struct file *file = file_lookup(name);
|
yann@2836
|
303 |
struct buffer *buf = malloc(sizeof(*buf));
|
yann@2836
|
304 |
memset(buf, 0, sizeof(*buf));
|
yann@2836
|
305 |
|
yann@2836
|
306 |
current_buf->state = YY_CURRENT_BUFFER;
|
yann@2836
|
307 |
yyin = zconf_fopen(file->name);
|
yann@2836
|
308 |
if (!yyin) {
|
yann@2836
|
309 |
printf("%s:%d: can't open file \"%s\"\n",
|
yann@2836
|
310 |
zconf_curname(), zconf_lineno(), file->name);
|
yann@2836
|
311 |
exit(1);
|
yann@2836
|
312 |
}
|
yann@2836
|
313 |
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
|
yann@2836
|
314 |
buf->parent = current_buf;
|
yann@2836
|
315 |
current_buf = buf;
|
yann@2836
|
316 |
|
yann@2836
|
317 |
for (iter = current_file->parent; iter; iter = iter->parent ) {
|
yann@2836
|
318 |
if (!strcmp(current_file->name,iter->name) ) {
|
yann@2836
|
319 |
printf("%s:%d: recursive inclusion detected. "
|
yann@2836
|
320 |
"Inclusion path:\n current file : '%s'\n",
|
yann@2836
|
321 |
zconf_curname(), zconf_lineno(),
|
yann@2836
|
322 |
zconf_curname());
|
yann@2836
|
323 |
iter = current_file->parent;
|
yann@2836
|
324 |
while (iter && \
|
yann@2836
|
325 |
strcmp(iter->name,current_file->name)) {
|
yann@2836
|
326 |
printf(" included from: '%s:%d'\n",
|
yann@2836
|
327 |
iter->name, iter->lineno-1);
|
yann@2836
|
328 |
iter = iter->parent;
|
yann@2836
|
329 |
}
|
yann@2836
|
330 |
if (iter)
|
yann@2836
|
331 |
printf(" included from: '%s:%d'\n",
|
yann@2836
|
332 |
iter->name, iter->lineno+1);
|
yann@2836
|
333 |
exit(1);
|
yann@2836
|
334 |
}
|
yann@2836
|
335 |
}
|
yann@2836
|
336 |
file->lineno = 1;
|
yann@2836
|
337 |
file->parent = current_file;
|
yann@2836
|
338 |
current_file = file;
|
yann@2836
|
339 |
}
|
yann@2836
|
340 |
|
yann@2836
|
341 |
static void zconf_endfile(void)
|
yann@2836
|
342 |
{
|
yann@2836
|
343 |
struct buffer *parent;
|
yann@2836
|
344 |
|
yann@2836
|
345 |
current_file = current_file->parent;
|
yann@2836
|
346 |
|
yann@2836
|
347 |
parent = current_buf->parent;
|
yann@2836
|
348 |
if (parent) {
|
yann@2836
|
349 |
fclose(yyin);
|
yann@2836
|
350 |
yy_delete_buffer(YY_CURRENT_BUFFER);
|
yann@2836
|
351 |
yy_switch_to_buffer(parent->state);
|
yann@2836
|
352 |
}
|
yann@2836
|
353 |
free(current_buf);
|
yann@2836
|
354 |
current_buf = parent;
|
yann@2836
|
355 |
}
|
yann@2836
|
356 |
|
yann@2836
|
357 |
int zconf_lineno(void)
|
yann@2836
|
358 |
{
|
yann@2836
|
359 |
return current_pos.lineno;
|
yann@2836
|
360 |
}
|
yann@2836
|
361 |
|
yann@2836
|
362 |
const char *zconf_curname(void)
|
yann@2836
|
363 |
{
|
yann@2836
|
364 |
return current_pos.file ? current_pos.file->name : "<none>";
|
yann@2836
|
365 |
}
|