Annotation of embedaddon/confuse/src/lexer.l, revision 1.1

1.1     ! misho       1: %{
        !             2: /*
        !             3:  * Copyright (c) 2002,2003,2007 Martin Hedenfalk <martin@bzero.se>
        !             4:  *
        !             5:  * Permission to use, copy, modify, and distribute this software for any
        !             6:  * purpose with or without fee is hereby granted, provided that the above
        !             7:  * copyright notice and this permission notice appear in all copies.
        !             8:  *
        !             9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            16:  */
        !            17: 
        !            18: #ifdef HAVE_CONFIG_H
        !            19: # include <config.h>
        !            20: #endif
        !            21: 
        !            22: #include <assert.h>
        !            23: 
        !            24: #ifdef HAVE_STRING_H
        !            25: # include <string.h>
        !            26: #endif
        !            27: #include "confuse.h"
        !            28: 
        !            29: #include <errno.h>
        !            30: 
        !            31: #if defined(ENABLE_NLS) && defined(HAVE_GETTEXT)
        !            32: # include <libintl.h>
        !            33: # define _(str) dgettext(PACKAGE, str)
        !            34: #else
        !            35: # define _(str) str
        !            36: #endif
        !            37: #define N_(str) str
        !            38: 
        !            39: /*
        !            40:  * Prevent compilation of static input() function in generated code
        !            41:  * This function is never used but GCC 4.3 will warn about it.
        !            42:  */
        !            43: #define YY_NO_INPUT
        !            44: 
        !            45: typedef char * YYSTYPE;
        !            46: extern YYSTYPE cfg_yylval;
        !            47: 
        !            48: #define YY_DECL int cfg_yylex ( cfg_t *cfg )
        !            49: 
        !            50: /* temporary buffer for the quoted strings scanner
        !            51:  */
        !            52: char *cfg_qstring = NULL;
        !            53: static unsigned int qstring_index = 0;
        !            54: static unsigned int qstring_len = 0;
        !            55: static void qputc(char ch);
        !            56: #define CFG_QSTRING_BUFSIZ 32
        !            57: 
        !            58: #define MAX_INCLUDE_DEPTH 10
        !            59: struct {
        !            60:     YY_BUFFER_STATE state;
        !            61:     char *filename;
        !            62:     unsigned int line;
        !            63: } cfg_include_stack[MAX_INCLUDE_DEPTH];
        !            64: int cfg_include_stack_ptr = 0;
        !            65: 
        !            66: static YY_BUFFER_STATE pre_string_scan_state = 0;
        !            67: static YY_BUFFER_STATE string_scan_state = 0;
        !            68: 
        !            69: %}
        !            70: 
        !            71: %option noyywrap
        !            72: 
        !            73:  /* start conditions
        !            74:   */
        !            75: %x comment
        !            76: %x dq_str
        !            77: %x sq_str
        !            78: 
        !            79: %%
        !            80: 
        !            81: [ \t]+    /* eat up whitespace */
        !            82: 
        !            83: \n   cfg->line++; /* keep track of line number */
        !            84: 
        !            85: ("#"|"//")[^\n]*     /* eat up one-line comments */
        !            86: 
        !            87:  /* special keywords/symbols
        !            88:   */
        !            89: "{"         { cfg_yylval = yytext; return '{'; }
        !            90: "}"         { cfg_yylval = yytext; return '}'; }
        !            91: "("         { cfg_yylval = yytext; return '('; }
        !            92: ")"         { cfg_yylval = yytext; return ')'; }
        !            93: "="         { cfg_yylval = yytext; return '='; }
        !            94: "+="        { cfg_yylval = yytext; return '+'; }
        !            95: ","         { cfg_yylval = yytext; return ','; }
        !            96: 
        !            97:  /* handle multi-line C-style comments
        !            98:   */
        !            99: "/*"         BEGIN(comment);
        !           100: <comment>[^*\n]*        /* eat anything that's not a '*' */
        !           101: <comment>"*"+[^*/\n]*   /* eat up '*'s not followed by '/'s */
        !           102: <comment>\n             cfg->line++;
        !           103: <comment>"*"+"/"        BEGIN(INITIAL);
        !           104: 
        !           105:  /* handle C-style strings
        !           106:   */
        !           107: "\""    {
        !           108:     qstring_index = 0;
        !           109:     BEGIN(dq_str);
        !           110: }
        !           111: <dq_str>\"  { /* saw closing quote - all done */
        !           112:     BEGIN(INITIAL);
        !           113:     qputc('\0');
        !           114:     cfg_yylval = cfg_qstring;
        !           115:     return CFGT_STR;
        !           116:  }
        !           117: <dq_str>$\{[^}]*\} { /* environment variable substitution */
        !           118:     char *var;
        !           119:     char *e;
        !           120:     yytext[strlen(yytext) - 1] = 0;
        !           121:     e = strchr(yytext+2, ':');
        !           122:     if(e && e[1] == '-')
        !           123:         *e = 0;
        !           124:     else
        !           125:         e = 0;
        !           126:     var = getenv(yytext+2);
        !           127:     if(!var && e)
        !           128:         var = e+2;
        !           129:     while(var && *var)
        !           130:         qputc(*var++);
        !           131: }
        !           132: <dq_str>\n   {
        !           133:     qputc('\n');
        !           134:     cfg->line++;
        !           135: }
        !           136: <dq_str>\\\n { /* allow continuing on next line */
        !           137:     /* no-op */
        !           138:     cfg->line++;
        !           139: }
        !           140: <dq_str>\\[0-7]{1,3} {  /* octal escape sequence */
        !           141:     unsigned int result;
        !           142:     sscanf(yytext + 1, "%o", &result);
        !           143:     if(result > 0xFF) {
        !           144:         cfg_error(cfg, _("invalid octal number '%s'"), yytext);
        !           145:         return 0;
        !           146:     }
        !           147:     qputc(result);
        !           148:  }
        !           149: <dq_str>\\[0-9]+   {
        !           150:     cfg_error(cfg, _("bad escape sequence '%s'"), yytext);
        !           151:     return 0;
        !           152: }
        !           153: <dq_str>"\\x"[0-9A-Fa-f]{1,2} { /* hexadecimal escape sequence */
        !           154:     unsigned int result;
        !           155:     sscanf(yytext + 2, "%x", &result);
        !           156:     qputc(result);
        !           157: }
        !           158: <dq_str>\\n  {
        !           159:     qputc('\n');
        !           160: }
        !           161: <dq_str>\\r  {
        !           162:     qputc('\r');
        !           163: }
        !           164: <dq_str>\\b  {
        !           165:     qputc('\b');
        !           166: }
        !           167: <dq_str>\\f  {
        !           168:     qputc('\f');
        !           169: }
        !           170: <dq_str>\\a  {
        !           171:     qputc('\007');
        !           172: }
        !           173: <dq_str>\\e  {
        !           174:     qputc('\033');
        !           175: }
        !           176: <dq_str>\\t  {
        !           177:     qputc('\t');
        !           178: }
        !           179: <dq_str>\\v  {
        !           180:     qputc('\v');
        !           181: }
        !           182: <dq_str>\\.  {
        !           183:     qputc(yytext[1]);
        !           184: }
        !           185: <dq_str>[^\\\"\n]+  {
        !           186:     char *yptr = yytext;
        !           187:     while(*yptr) {
        !           188:         qputc(*yptr++);
        !           189:     }
        !           190: }
        !           191: 
        !           192:     /* single-quoted string ('...') */
        !           193: "\'" {
        !           194:     qstring_index = 0;
        !           195:     BEGIN(sq_str);
        !           196: }
        !           197: <sq_str>\' { /* saw closing quote - all done */
        !           198:     BEGIN(INITIAL);
        !           199:     qputc('\0');
        !           200:     cfg_yylval = cfg_qstring;
        !           201:     return CFGT_STR;
        !           202: }
        !           203: <sq_str>\n   {
        !           204:     qputc('\n');
        !           205:     cfg->line++;
        !           206: }
        !           207: <sq_str>\\\n { /* allow continuing on next line */
        !           208:     /* no-op */
        !           209:     cfg->line++;
        !           210: }
        !           211: <sq_str>\\[\\\'] {
        !           212:     qputc(yytext[1]);
        !           213: }
        !           214: <sq_str>\\[^\\\'] {
        !           215:     qputc(yytext[0]);
        !           216:     qputc(yytext[1]);
        !           217: }
        !           218: <sq_str>[^\\\'\n]+ {
        !           219:     char *cp = yytext;
        !           220:     while(*cp != '\0') {
        !           221:         qputc(*cp++);
        !           222:     }
        !           223: }
        !           224: <sq_str><<EOF>> {
        !           225:     cfg_error(cfg, _("unterminated string constant"));
        !           226:     return 0;
        !           227: }
        !           228: 
        !           229: <<EOF>> {
        !           230:              if (cfg_include_stack_ptr <= 0)
        !           231:              {
        !           232:                  return EOF;
        !           233:              }
        !           234:              else
        !           235:              {
        !           236:                  yy_delete_buffer( YY_CURRENT_BUFFER );
        !           237:                  fclose(cfg_yyin);
        !           238:                  cfg_yyin = 0;
        !           239:                  --cfg_include_stack_ptr;
        !           240:                  yy_switch_to_buffer(
        !           241:                       cfg_include_stack[cfg_include_stack_ptr].state );
        !           242:                  free(cfg->filename);
        !           243:                  cfg->filename = cfg_include_stack[cfg_include_stack_ptr].filename;
        !           244:                  cfg->line = cfg_include_stack[cfg_include_stack_ptr].line;
        !           245:              }
        !           246: }
        !           247: 
        !           248: $\{[^}]*\} {
        !           249:     char *var;
        !           250:     char *e;
        !           251:     yytext[strlen(yytext) - 1] = 0;
        !           252:     e = strchr(yytext+2, ':');
        !           253:     if(e && e[1] == '-')
        !           254:         *e = 0;
        !           255:     else
        !           256:         e = 0;
        !           257:     var = getenv(yytext+2);
        !           258:     if(!var && e)
        !           259:         var = e+2;
        !           260:     if(!var)
        !           261:         var = "";
        !           262:     cfg_yylval = var;
        !           263:     return CFGT_STR;
        !           264: }
        !           265: 
        !           266:  /* an unquoted string
        !           267:   * a slash can't be followed by another slash (c++
        !           268:   * comment) or an asterisk (C multi-line comment)
        !           269:   */
        !           270: (\/[^ #\"\'\t\n\r={}()+,\/*]|[^ #\"\'\t\n\r={}()+,\*])+ {
        !           271:     cfg_yylval = yytext;
        !           272:     return CFGT_STR;
        !           273:  }
        !           274: 
        !           275: . /* eat any non-matching characters */
        !           276: 
        !           277: %%
        !           278: 
        !           279: void cfg_dummy_function(void)
        !           280: {
        !           281:     /* please compiler :-)
        !           282:      * otherwise "defined but not used" warning
        !           283:      */
        !           284:     yyunput(0, 0);
        !           285: }
        !           286: 
        !           287: int cfg_lexer_include(cfg_t *cfg, const char *filename)
        !           288: {
        !           289:     char *xfilename;
        !           290: 
        !           291:     if(cfg_include_stack_ptr >= MAX_INCLUDE_DEPTH) {
        !           292:         cfg_error(cfg, _("includes nested too deeply"));
        !           293:         return 1;
        !           294:     }
        !           295: 
        !           296:     cfg_include_stack[cfg_include_stack_ptr].state = YY_CURRENT_BUFFER;
        !           297:     cfg_include_stack[cfg_include_stack_ptr].filename = cfg->filename;
        !           298:     cfg_include_stack[cfg_include_stack_ptr].line = cfg->line;
        !           299:     cfg_include_stack_ptr++;
        !           300: 
        !           301:     xfilename = cfg_tilde_expand(filename);
        !           302: 
        !           303:     cfg_yyin = fopen(xfilename, "r");
        !           304: 
        !           305:     if(!cfg_yyin) {
        !           306:         cfg_error(cfg, "%s: %s", xfilename, strerror(errno));
        !           307:         free(xfilename);
        !           308:         return 1;
        !           309:     }
        !           310: 
        !           311:     cfg->filename = xfilename;
        !           312:     cfg->line = 1;
        !           313: 
        !           314:     yy_switch_to_buffer(yy_create_buffer(cfg_yyin, YY_BUF_SIZE));
        !           315:     return 0;
        !           316: }
        !           317: 
        !           318: /* write a character to the quoted string buffer, and reallocate as
        !           319:  * necessary
        !           320:  */
        !           321: static void qputc(char ch)
        !           322: {
        !           323:     if(qstring_index >= qstring_len) {
        !           324:         qstring_len += CFG_QSTRING_BUFSIZ;
        !           325:         cfg_qstring = (char *)realloc(cfg_qstring, qstring_len);
        !           326:         assert(cfg_qstring);
        !           327:         memset(cfg_qstring + qstring_index, 0, CFG_QSTRING_BUFSIZ);
        !           328:     }
        !           329:     cfg_qstring[qstring_index++] = ch;
        !           330: }
        !           331: 
        !           332: void cfg_scan_string_begin(const char *buf)
        !           333: {
        !           334:     pre_string_scan_state = YY_CURRENT_BUFFER;
        !           335: 
        !           336:     /* yy_scan_string does a yy_switch_to_buffer call for us
        !           337:      */
        !           338:     string_scan_state = yy_scan_string(buf);
        !           339: }
        !           340: 
        !           341: void cfg_scan_string_end(void)
        !           342: {
        !           343:     /* restore to previous state
        !           344:      */
        !           345:     yy_delete_buffer(string_scan_state);
        !           346:     if (pre_string_scan_state)
        !           347:         yy_switch_to_buffer(pre_string_scan_state);
        !           348:     free(cfg_qstring);
        !           349:     cfg_qstring = 0;
        !           350:     qstring_index = qstring_len = 0;
        !           351:     string_scan_state = 0;
        !           352: }
        !           353: 
        !           354: static YY_BUFFER_STATE pre_fp_scan_state;
        !           355: static YY_BUFFER_STATE fp_scan_state;
        !           356: 
        !           357: void cfg_scan_fp_begin(FILE *fp)
        !           358: {
        !           359:     pre_fp_scan_state = YY_CURRENT_BUFFER;
        !           360:     fp_scan_state = yy_create_buffer(fp, YY_BUF_SIZE);
        !           361:     yy_switch_to_buffer(fp_scan_state);
        !           362: }
        !           363: 
        !           364: void cfg_scan_fp_end(void)
        !           365: {
        !           366:     /* restore to previous state
        !           367:      */
        !           368:     yy_delete_buffer(fp_scan_state);
        !           369:     if(pre_fp_scan_state)
        !           370:         yy_switch_to_buffer(pre_fp_scan_state);
        !           371:     free(cfg_qstring);
        !           372:     cfg_qstring = 0;
        !           373:     qstring_index = qstring_len = 0;
        !           374: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>