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