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