[apparmor] [PATCH 01/10] clean up the lexer
Seth Arnold
seth.arnold at canonical.com
Wed Jul 24 07:33:13 UTC 2013
On Sun, Jul 21, 2013 at 10:32:44PM -0700, John Johansen wrote:
> - Make indenting consistent
> - Move common match + fn patterns into a single shared entry with mulitstate
> headers
> - add names table to convert lexer state #s to state names used in the code
> - Create/use macros for common patterns of DUMP, DEBUG, return ...
> this fixes a few places where preprocess or DEBUG output was not
> available
> - update RE patterns for bugs eg. {WS} inside a character class [] does
> not match whitespace
>
> all told despite adding code to provide better support to debug and
> preprocessing, the code is about 150 lines shorter, and has few corner
> cases cleaned up.
Oh man, this is beautiful. Lovely. Thanks. :)
A few comments inline..
> Signed-off-by: John Johansen <john.johansen at canonical.com>
> ---
> parser/parser_lex.l | 661 +++++++++++++++++++--------------------------------
> parser/parser_yacc.y | 1 +
> 2 files changed, 251 insertions(+), 411 deletions(-)
>
> diff --git a/parser/parser_lex.l b/parser/parser_lex.l
> index 539e16a..1b14625 100644
> --- a/parser/parser_lex.l
> +++ b/parser/parser_lex.l
> @@ -46,7 +46,8 @@
> #endif
> /* #define DEBUG */
> #ifdef DEBUG
> -#define PDEBUG(fmt, args...) printf("Lexer (state %d): " fmt, YY_START, ## args)
> +static int yy_top_state(void);
> +#define PDEBUG(fmt, args...) printf("Lexer (Line %d) (state %s): " fmt, current_lineno, state_names[YY_START], ## args)
> #else
> #define PDEBUG(fmt, args...) /* Do nothing */
> #endif
> @@ -54,8 +55,44 @@
>
> #define DUMP_PREPROCESS do { if (preprocess_only) ECHO; } while (0)
>
> +#
> +#define RETURN_TOKEN(X) \
> +do { \
> + DUMP_PREPROCESS; \
> + PDEBUG("Matched: %s\n", yytext); \
> + return (X); \
> +} while (0)
> +
> +#define POP_AND_RETURN(X) \
> +do { \
> + DUMP_PREPROCESS; \
> + PDEBUG(" (ret_to(%s)): Matched: %s\n", state_names[yy_top_state()], yytext); \
> + yy_pop_state(); \
> + return (X); \
> +} while (0)
> +
> +#define PUSH_AND_RETURN(X, Y) \
> +do { \
> + DUMP_PREPROCESS; \
> + PDEBUG(" (push(%s)): Matched: %s\n", state_names[(X)], yytext); \
> + yy_push_state(X); \
> + return (Y); \
> +} while (0)
> +
> +#define BEGIN_AND_RETURN(X, Y) \
> +do { \
> + DUMP_PREPROCESS; \
> + PDEBUG(" (begin(%s)): Matched: %s\n", state_names[(X)], yytext); \
> + BEGIN(X); \
> + return (Y); \
> +} while (0)
> +
> +
> #define YY_NO_INPUT
>
> +#define STATE_TABLE_ENT(X) [(X)] = #X
> +static const char *const state_names[];
> +
> struct ignored_suffix_t {
> char * text;
> int len;
> @@ -199,8 +236,9 @@ POST_VAR_ID {POST_VAR_ID_CHARS}|(,{POST_VAR_ID_CHARS})
> LIST_VALUE_ID_CHARS [^ \t\n"!,]{-}[()]
> LIST_VALUE_ID {LIST_VALUE_ID_CHARS}+
> ID_CHARS_NOEQ [^ \t\n"!,]{-}[=]
> +LEADING_ID_CHARS_NOEQ [^ \t\n"!,]{-}[=()+&]
> ID_NOEQ {ID_CHARS_NOEQ}|(,{ID_CHARS_NOEQ})
> -IDS_NOEQ {ID_NOEQ}+
> +IDS_NOEQ {LEADING_ID_CHARS_NOEQ}{ID_NOEQ}*
> ALLOWED_QUOTED_ID [^\0"]|\\\"
> QUOTED_ID \"{ALLOWED_QUOTED_ID}*\"
>
> @@ -221,10 +259,12 @@ OPEN_PAREN \(
> CLOSE_PAREN \)
> COMMA \,
> EQUALS =
> +NOTEQUALS !=
Not used...
> ADD_ASSIGN \+=
> ARROW ->
> LT_EQUAL <=
>
> +/* IF adding new state please update state_names table at eof */
> %x SUB_ID
> %x SUB_VALUE
> %x EXTCOND_MODE
> @@ -247,483 +287,282 @@ LT_EQUAL <=
> }
> %}
>
> -<INCLUDE>{
> - {WS}+ { /* Eat whitespace */ }
> - \<([^\> \t\n]+)\> { /* <filename> */
> - char *filename = strdup(yytext);
> - filename[strlen(filename) - 1] = '\0';
> - include_filename(filename + 1, 1);
> - free(filename);
> - yy_pop_state();
> - }
> +<INITIAL,INCLUDE,LIST_VAL_MODE,EXTCOND_MODE,ASSIGN_MODE,NETWORK_MODE,CHANGE_PROFILE_MODE,RLIMIT_MODE,MOUNT_MODE>{
> + {WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ }
> +}
>
> - \"([^\" \t\n]+)\" { /* "filename" */
> +<INCLUDE>{
> + (\<([^\> \t\n]+)\>|\"([^\" \t\n]+)\") { /* <filename> */
> char *filename = strdup(yytext);
> filename[strlen(filename) - 1] = '\0';
> - include_filename(filename + 1, 0);
> + include_filename(filename + 1, *filename == '<');
> free(filename);
> yy_pop_state();
> - }
> + }
>
> - [^\<\>\"{WS}]+ { /* filename */
> + [^\<\>\" \t\n]+ { /* filename */
> include_filename(yytext, 0);
> yy_pop_state();
> - }
> + }
> }
>
> <<EOF>> {
> fclose(yyin);
> pop_include_stack();
> yypop_buffer_state();
> - if ( !YY_CURRENT_BUFFER ) yyterminate();
> + if ( !YY_CURRENT_BUFFER )
> + yyterminate();
> }
>
> <INITIAL,MOUNT_MODE>{
> {VARIABLE_NAME}/{WS}*= {
> - /* we match to the = in the lexer so that
> - * can switch scanner state. By the time
> - * the parser see the = it may be to late
> - * as bison may have requested the next
> - * token from the scanner
> - */
> - DUMP_PREPROCESS;
> - PDEBUG("conditional %s=\n", yytext);
> - yylval.id = processid(yytext, yyleng);
> - yy_push_state(EXTCOND_MODE);
> - return TOK_CONDID;
> - }
> + /* we match to the = in the lexer so that can switch scanner
> + * state. By the time the parser see the = it may be to late
> + * as bison may have requested the next token from the scanner
> + */
While we're making drastic changes, some of these comment errors that
have grated on me for years are finally fair game :) "so that we can",
and "too late", please.
> + DUMP_PREPROCESS;
> + yylval.id = processid(yytext, yyleng);
> + PUSH_AND_RETURN(EXTCOND_MODE, TOK_CONDID);
PUSH_AND_RETURN() already includes the DUMP_PREPROCESS.
> + }
> +
> {VARIABLE_NAME}/{WS}+in{WS}*\( {
> - /* we match to 'in' in the lexer so that
> - * we can switch scanner state. By the time
> - * the parser see the 'in' it may be to late
> - * as bison may have requested the next
> - * token from the scanner
> - */
> - DUMP_PREPROCESS;
> - PDEBUG("conditional %s=\n", yytext);
> - yylval.id = processid(yytext, yyleng);
> - yy_push_state(EXTCOND_MODE);
> - return TOK_CONDID;
> - }
> + /* we match to 'in' in the lexer so that we can switch scanner
> + * state. By the time the parser see the 'in' it may be to
> + * late as bison may have requested the next token from the
> + * scanner
> + */
Again, "too late".
> + DUMP_PREPROCESS;
> + yylval.id = processid(yytext, yyleng);
> + PUSH_AND_RETURN(EXTCOND_MODE, TOK_CONDID);
PUSH_AND_RETURN() already includes the DUMP_PREPROCESS.
> + }
> }
>
> <SUB_ID>{
> - ({IDS}|{QUOTED_ID}) {
> - /* Ugh, this is a gross hack. I used to use
> - * {IDS} to match all TOK_IDs, but that would
> - * also match TOK_MODE + TOK_END_OF_RULE
> - * without any spaces in between (because it's
> - * a longer match). So now, when I want to
> - * match any random string, I go into a
> - * separate state. */
> - DUMP_PREPROCESS;
> - yylval.id = processid(yytext, yyleng);
> - PDEBUG("Found sub name: \"%s\"\n", yylval.id);
> - yy_pop_state();
> - return TOK_ID;
> - }
> -
> - [^\n] {
> - DUMP_PREPROCESS;
> - /* Something we didn't expect */
> - yyerror(_("Found unexpected character: '%s'"), yytext);
> - }
> + ({IDS}|{QUOTED_ID}) {
> + /* Go into separate state to match generic ID strings */
> + yylval.id = processid(yytext, yyleng);
> + POP_AND_RETURN(TOK_ID);
> + }
> }
>
> <SUB_VALUE>{
> - ({IDS}|{QUOTED_ID}) {
> - /* Ugh, this is a gross hack. I used to use
> - * {IDS} to match all TOK_IDs, but that would
> - * also match TOK_MODE + TOK_END_OF_RULE
> - * without any spaces in between (because it's
> - * a longer match). So now, when I want to
> - * match any random string, I go into a
> - * separate state. */
> - DUMP_PREPROCESS;
> - yylval.id = processid(yytext, yyleng);
> - PDEBUG("Found sub value: \"%s\"\n", yylval.id);
> - yy_pop_state();
> - return TOK_VALUE;
> - }
> -
> - [^\n] {
> - DUMP_PREPROCESS;
> - /* Something we didn't expect */
> - yyerror(_("Found unexpected character: '%s'"), yytext);
> - }
> + ({IDS}|{QUOTED_ID}) {
> + /* Go into separate state to match generic VALUE strings */
> + yylval.id = processid(yytext, yyleng);
> + POP_AND_RETURN(TOK_VALUE);
> + }
> }
Can <SUB_ID> and <SUB_VALUE> be combined here? Is the clarity increased
if they are combined?
>
> <LIST_VAL_MODE>{
> - {CLOSE_PAREN} {
> - DUMP_PREPROCESS;
> - PDEBUG("listval: )\n");
> - yy_pop_state();
> - return TOK_CLOSEPAREN;
> - }
> -
> - {WS}+ { DUMP_PREPROCESS; /* Eat whitespace */ }
> + {CLOSE_PAREN} { POP_AND_RETURN(TOK_CLOSEPAREN); }
>
> {COMMA} {
> - DUMP_PREPROCESS;
> - PDEBUG("listval: , \n");
> - /* East comma, its an optional separator */
> - }
> -
> - ({LIST_VALUE_ID}|{QUOTED_ID}) {
> - DUMP_PREPROCESS;
> - yylval.id = processid(yytext, yyleng);
> - PDEBUG("listval: \"%s\"\n", yylval.id);
> - return TOK_VALUE;
> - }
> -
> - [^\n] {
> - DUMP_PREPROCESS;
> - /* Something we didn't expect */
> - yyerror(_("Found unexpected character: '%s'"), yytext);
> - }
> + DUMP_PREPROCESS;
> + PDEBUG("listval: , \n");
> + /* Eat comma, its an optional separator */
> + }
> +
> + ({LIST_VALUE_ID}|{QUOTED_ID}) {
> + yylval.id = processid(yytext, yyleng);
> + RETURN_TOKEN(TOK_VALUE);
> + }
> }
>
> <EXTCOND_MODE>{
> - {WS}+ { DUMP_PREPROCESS; /* Eat whitespace */ }
> -
> - {EQUALS}{WS}*/[^(\n]{-}{WS} {
> - DUMP_PREPROCESS;
> - BEGIN(SUB_VALUE);
> - return TOK_EQUALS;
> - }
> -
> - {EQUALS} {
> - DUMP_PREPROCESS;
> - return TOK_EQUALS;
> - }
> -
> - {OPEN_PAREN} {
> - DUMP_PREPROCESS;
> - PDEBUG("extcond listv\n");
> - /* Don't push state here as this is a transition
> - * start condition and we want to return to the start
> - * condition that invoked <EXTCOND_MODE> when
> - * LIST_VAL_ID is done
> - */
> - BEGIN(LIST_VAL_MODE);
> - return TOK_OPENPAREN;
> - }
> + {EQUALS}{WS}*/[^(\n]{-}{WS} { BEGIN_AND_RETURN(SUB_VALUE, TOK_EQUALS);}
>
> - in {
> - DUMP_PREPROCESS;
> - return TOK_IN;
> - }
> + {EQUALS} { RETURN_TOKEN(TOK_EQUALS); }
>
> - [^\n] {
> - DUMP_PREPROCESS;
> - /* Something we didn't expect */
> - yyerror(_("Found unexpected character: '%s' %d"), yytext, *yytext);
> - }
> + /* Don't push state here as this is a transition start condition and
> + * we want to return to the start condition that invoked <EXTCOND_MODE>
> + * when LIST_VAL_ID is done
> + */
> + {OPEN_PAREN} { BEGIN_AND_RETURN(LIST_VAL_MODE, TOK_OPENPAREN); }
>
> + in { RETURN_TOKEN(TOK_IN); }
> }
>
> <ASSIGN_MODE>{
> - {WS}+ { DUMP_PREPROCESS; /* Eat whitespace */ }
> -
> - ({IDS}|{QUOTED_ID}) {
> - DUMP_PREPROCESS;
> - yylval.var_val = processid(yytext, yyleng);
> - PDEBUG("Found assignment value: \"%s\"\n", yylval.var_val);
> - return TOK_VALUE;
> - }
> + ({IDS}|{QUOTED_ID}) {
> + yylval.var_val = processid(yytext, yyleng);
> + RETURN_TOKEN(TOK_VALUE);
> + }
>
> - {END_OF_RULE} {
> - DUMP_PREPROCESS;
> - yylval.id = strdup(yytext);
> - yyerror(_("Variable declarations do not accept trailing commas"));
> - }
> + {END_OF_RULE} {
> + yylval.id = strdup(yytext);
> + DUMP_PREPROCESS;
> + yyerror(_("Variable declarations do not accept trailing commas"));
> + }
It wasn't introduced here, but I don't understand the strdup(),
yyerror() is going to exit anyway.
>
> - \\\n { DUMP_PREPROCESS; current_lineno++ ; }
> + \\\n { DUMP_PREPROCESS; current_lineno++ ; }
>
> - \r?\n {
> - DUMP_PREPROCESS;
> - current_lineno++;
> - yy_pop_state();
> - }
> - [^\n] {
> - DUMP_PREPROCESS;
> - /* Something we didn't expect */
> - yyerror(_("Found unexpected character: '%s'"), yytext);
> - }
> + \r?\n {
> + DUMP_PREPROCESS;
> + current_lineno++;
> + yy_pop_state();
> + }
> }
>
> <NETWORK_MODE>{
> - {WS}+ { DUMP_PREPROCESS; /* Eat whitespace */ }
> -
> - {IDS} {
> - DUMP_PREPROCESS;
> - yylval.id = strdup(yytext);
> - return TOK_ID;
> - }
> - {END_OF_RULE} {
> - DUMP_PREPROCESS;
> - yy_pop_state();
> - return TOK_END_OF_RULE;
> - }
> - [^\n] {
> - DUMP_PREPROCESS;
> - /* Something we didn't expect */
> - yylval.id = strdup(yytext);
> - yyerror(_("(network_mode) Found unexpected character: '%s'"), yylval.id);
> - }
> -
> - \r?\n {
> - DUMP_PREPROCESS;
> - current_lineno++;
> - }
> + {IDS} {
> + yylval.id = strdup(yytext);
> + RETURN_TOKEN(TOK_ID);
> + }
> }
>
> <CHANGE_PROFILE_MODE>{
> - {ARROW} {
> - DUMP_PREPROCESS;
> - PDEBUG("Matched a change profile arrow\n");
> - return TOK_ARROW;
> - }
> -
> - ({IDS}|{QUOTED_ID}) {
> - /* Ugh, this is a gross hack. I used to use
> - * {IDS} to match all TOK_IDs, but that would
> - * also match TOK_MODE + TOK_END_OF_RULE
> - * without any spaces in between (because it's
> - * a longer match). So now, when I want to
> - * match any random string, I go into a
> - * separate state. */
> - DUMP_PREPROCESS;
> - yylval.id = processid(yytext, yyleng);
> - PDEBUG("Found change profile name: \"%s\"\n", yylval.id);
> - yy_pop_state();
> - return TOK_ID;
> - }
> + {ARROW} { RETURN_TOKEN(TOK_ARROW); }
>
> - {WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ }
> - [^\n] {
> - DUMP_PREPROCESS;
> - /* Something we didn't expect */
> - yyerror(_("Found unexpected character: '%s'"), yytext);
> - }
> + ({IDS}|{QUOTED_ID}) {
> + yylval.id = processid(yytext, yyleng);
> + POP_AND_RETURN(TOK_ID);
> + }
> }
>
> <RLIMIT_MODE>{
> - {WS}+ { DUMP_PREPROCESS; /* Eat whitespace */ }
> -
> -
> -?{NUMBER}[[:alpha:]]* {
Not introduced in this patch, but can we use a more-specific set of
chars here to give better error messages? Or would errors get worse? At
least line number is easily available here...
> - DUMP_PREPROCESS;
> - yylval.var_val = strdup(yytext);
> - return TOK_VALUE;
> - }
> + yylval.var_val = strdup(yytext);
> + RETURN_TOKEN(TOK_VALUE);
> + }
>
> {KEYWORD} {
> - DUMP_PREPROCESS;
> - yylval.id = strdup(yytext);
> - if (strcmp(yytext, "infinity") == 0)
> - return TOK_VALUE;
> - return TOK_ID;
> - }
> + yylval.id = strdup(yytext);
> + if (strcmp(yytext, "infinity") == 0)
> + RETURN_TOKEN(TOK_VALUE);
> + RETURN_TOKEN(TOK_ID);
> + }
>
> - {LT_EQUAL} { DUMP_PREPROCESS; return TOK_LE; }
> + {LT_EQUAL} { RETURN_TOKEN(TOK_LE); }
> +}
>
> - {END_OF_RULE} {
> - DUMP_PREPROCESS;
> - yy_pop_state();
> - return TOK_END_OF_RULE;
> - }
> +<MOUNT_MODE>{
> + {ARROW} { RETURN_TOKEN(TOK_ARROW); }
>
> - \\\n {
> - DUMP_PREPROCESS;
> - current_lineno++;
> - yy_pop_state();
> - }
> + ({IDS_NOEQ}|{PATHNAME}|{QUOTED_ID}) {
> + yylval.id = processid(yytext, yyleng);
> + RETURN_TOKEN(TOK_ID);
> + }
> +}
>
> - \r?\n {
> - DUMP_PREPROCESS;
> - current_lineno++;
> - yy_pop_state();
> - }
> +#include/.*\r?\n {
Hunh, I don't think I knew that "# include" wouldn't include a file. Now I
do know. :)
> + DUMP_PREPROCESS;
> + PDEBUG("Matched: %s\n", yytext);
> + yy_push_state(INCLUDE);
> }
>
> -<MOUNT_MODE>{
> - {WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ }
> +#.*\r?\n { /* normal comment */
> + DUMP_PREPROCESS;
> + PDEBUG("comment(%d): %s\n", current_lineno, yytext);
> + current_lineno++;
> +}
>
> - {ARROW} {
> - DUMP_PREPROCESS;
> - PDEBUG("Matched arrow\n");
> - return TOK_ARROW;
> - }
> +{CARET} { PUSH_AND_RETURN(SUB_ID, TOK_CARET); }
>
> - ({IDS_NOEQ}|{PATHNAME}|{QUOTED_ID}) {
> - DUMP_PREPROCESS;
> - yylval.id = processid(yytext, yyleng);
> - PDEBUG("Found ID: \"%s\"\n", yylval.id);
> - return TOK_ID;
> - }
> +{ARROW} { RETURN_TOKEN(TOK_ARROW); }
>
> +{EQUALS} { PUSH_AND_RETURN(ASSIGN_MODE, TOK_EQUALS); }
> +
> +{ADD_ASSIGN} { PUSH_AND_RETURN(ASSIGN_MODE, TOK_ADD_ASSIGN); }
> +
> +{SET_VARIABLE} {
> + yylval.set_var = strdup(yytext);
> + RETURN_TOKEN(TOK_SET_VAR);
> +}
> +
> +{BOOL_VARIABLE} {
> + yylval.bool_var = strdup(yytext);
> + RETURN_TOKEN(TOK_BOOL_VAR);
> +}
> +
> +{OPEN_BRACE} { RETURN_TOKEN(TOK_OPEN); }
> +
> +{CLOSE_BRACE} { RETURN_TOKEN(TOK_CLOSE); }
> +
> +({PATHNAME}|{QPATHNAME}) {
> + yylval.id = processid(yytext, yyleng);
> + RETURN_TOKEN(TOK_ID);
> +}
> +
> +({MODES})/([[:space:],]) {
> + yylval.mode = strdup(yytext);
> + RETURN_TOKEN(TOK_MODE);
> +}
> +
> +{HAT} { PUSH_AND_RETURN(SUB_ID, TOK_HAT); }
> +
> +{PROFILE} { PUSH_AND_RETURN(SUB_ID, TOK_PROFILE); }
> +
> +{COLON} { RETURN_TOKEN(TOK_COLON); }
> +
> +{OPEN_PAREN} { PUSH_AND_RETURN(LIST_VAL_MODE, TOK_OPENPAREN); }
> +
> +{VARIABLE_NAME} {
> + DUMP_PREPROCESS;
> + int token = get_keyword_token(yytext);
> + int state = INITIAL;
> +
> + /* special cases */
> + switch (token) {
> + case -1:
> + /* no token found */
> + yylval.id = processunquoted(yytext, yyleng);
> + RETURN_TOKEN(TOK_ID);
> + break;
> + case TOK_RLIMIT:
> + state = RLIMIT_MODE;
> + break;
> + case TOK_NETWORK:
> + state = NETWORK_MODE;
> + break;
> + case TOK_CHANGE_PROFILE:
> + state = CHANGE_PROFILE_MODE;
> + break;
> + case TOK_MOUNT:
> + case TOK_REMOUNT:
> + case TOK_UMOUNT:
> + state = MOUNT_MODE;
> + break;
> + default: /* nothing */
> + break;
> + }
> + PUSH_AND_RETURN(state, token);
> +}
> +
> +<INITIAL,NETWORK_MODE,RLIMIT_MODE,MOUNT_MODE>{
> {END_OF_RULE} {
> - DUMP_PREPROCESS;
> + if (YY_START != INITIAL)
> yy_pop_state();
> - return TOK_END_OF_RULE;
> - }
> -
> - [^\n] {
> - DUMP_PREPROCESS;
> - /* Something we didn't expect */
> - yyerror(_("Found unexpected character: '%s'"), yytext);
> - }
> + RETURN_TOKEN(TOK_END_OF_RULE);
> + }
>
> \r?\n {
> - DUMP_PREPROCESS;
> - current_lineno++;
> - yy_pop_state();
> - }
> + DUMP_PREPROCESS;
> + current_lineno++;
> + }
> }
>
> -#include/.*\r?\n { /* include */
> - PDEBUG("Matched #include\n");
> - yy_push_state(INCLUDE);
> - }
> -
> -#.*\r?\n { /* normal comment */
> - DUMP_PREPROCESS;
> - PDEBUG("comment(%d): %s\n", current_lineno, yytext);
> - current_lineno++;
> - }
> -
> -{END_OF_RULE} { DUMP_PREPROCESS; return TOK_END_OF_RULE; }
> -
> -{CARET} {
> - DUMP_PREPROCESS;
> - PDEBUG("Matched hat ^\n");
> - yy_push_state(SUB_ID);
> - return TOK_CARET;
> - }
> -{ARROW} {
> - DUMP_PREPROCESS;
> - PDEBUG("Matched a arrow\n");
> - return TOK_ARROW;
> - }
> -{EQUALS} {
> - DUMP_PREPROCESS;
> - PDEBUG("Matched equals for assignment\n");
> - yy_push_state(ASSIGN_MODE);
> - return TOK_EQUALS;
> - }
> -{ADD_ASSIGN} {
> - DUMP_PREPROCESS;
> - PDEBUG("Matched additive value assignment\n");
> - yy_push_state(ASSIGN_MODE);
> - return TOK_ADD_ASSIGN;
> - }
> -{SET_VARIABLE} {
> - DUMP_PREPROCESS;
> - yylval.set_var = strdup(yytext);
> - PDEBUG("Found set variable %s\n", yylval.set_var);
> - return TOK_SET_VAR;
> - }
> -
> -{BOOL_VARIABLE} {
> - DUMP_PREPROCESS;
> - yylval.bool_var = strdup(yytext);
> - PDEBUG("Found boolean variable %s\n", yylval.bool_var);
> - return TOK_BOOL_VAR;
> - }
> -
> -{OPEN_BRACE} {
> - DUMP_PREPROCESS;
> - PDEBUG("Open Brace\n");
> - return TOK_OPEN;
> - }
> -{CLOSE_BRACE} {
> - DUMP_PREPROCESS;
> - PDEBUG("Close Brace\n");
> - return TOK_CLOSE;
> - }
> -
> -({PATHNAME}|{QPATHNAME}) {
> - DUMP_PREPROCESS;
> - yylval.id = processid(yytext, yyleng);
> - PDEBUG("Found id: \"%s\"\n", yylval.id);
> - return TOK_ID;
> - }
> -
> -({MODES})/([[:space:],]) {
> - DUMP_PREPROCESS;
> - yylval.mode = strdup(yytext);
> - PDEBUG("Found modes: %s\n", yylval.mode);
> - return TOK_MODE;
> - }
> -
> -{HAT} {
> - DUMP_PREPROCESS;
> - yy_push_state(SUB_ID);
> - return TOK_HAT;
> - }
> -
> -{PROFILE} {
> - DUMP_PREPROCESS;
> - yy_push_state(SUB_ID);
> - return TOK_PROFILE;
> - }
> -
> -{COLON} {
> - DUMP_PREPROCESS;
> - PDEBUG("Found a colon\n");
> - return TOK_COLON;
> - }
> -
> -{OPEN_PAREN} {
> - DUMP_PREPROCESS;
> - PDEBUG("listval (\n");
> - yy_push_state(LIST_VAL_MODE);
> - return TOK_OPENPAREN;
> - }
> -
> -{VARIABLE_NAME} {
> - DUMP_PREPROCESS;
> - int token = get_keyword_token(yytext);
> -
> - /* special cases */
> - switch (token) {
> - case -1:
> - /* no token found */
> - yylval.id = processunquoted(yytext, yyleng);
> - PDEBUG("Found (var) id: \"%s\"\n", yylval.id);
> - return TOK_ID;
> - break;
> - case TOK_RLIMIT:
> - yy_push_state(RLIMIT_MODE);
> - break;
> - case TOK_NETWORK:
> - yy_push_state(NETWORK_MODE);
> - break;
> - case TOK_CHANGE_PROFILE:
> - yy_push_state(CHANGE_PROFILE_MODE);
> - break;
> - case TOK_MOUNT:
> - case TOK_REMOUNT:
> - case TOK_UMOUNT:
> - PDEBUG("Entering mount\n");
> - yy_push_state(MOUNT_MODE);
> - break;
> - default: /* nothing */
> - break;
> - }
> - return token;
> - }
> -
> -{WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ }
> -
> -\r?\n { DUMP_PREPROCESS; current_lineno++ ; }
> -
> -[^\n] {
> - DUMP_PREPROCESS;
> -
> - /* Something we didn't expect */
> - yyerror(_("Found unexpected character: '%s'"), yytext);
> - }
> -
> +<INITIAL,SUB_ID,SUB_VALUE,LIST_VAL_MODE,EXTCOND_MODE,ASSIGN_MODE,NETWORK_MODE,CHANGE_PROFILE_MODE,RLIMIT_MODE,MOUNT_MODE>{
> + [^\n] {
> + DUMP_PREPROCESS;
> + /* Something we didn't expect */
> + yyerror(_("Found unexpected character: '%s'"), yytext);
> + }
> +}
> %%
> +
> +/* Create a table mapping lexer state number to the name used in the
> + * in the code. This allows for better debug output
> + */
> +static const char *const state_names[] = {
> + STATE_TABLE_ENT(INITIAL),
> + STATE_TABLE_ENT(SUB_ID),
> + STATE_TABLE_ENT(SUB_VALUE),
> + STATE_TABLE_ENT(EXTCOND_MODE),
> + STATE_TABLE_ENT(NETWORK_MODE),
> + STATE_TABLE_ENT(LIST_VAL_MODE),
> + STATE_TABLE_ENT(ASSIGN_MODE),
> + STATE_TABLE_ENT(RLIMIT_MODE),
> + STATE_TABLE_ENT(MOUNT_MODE),
> + STATE_TABLE_ENT(CHANGE_PROFILE_MODE),
> + STATE_TABLE_ENT(INCLUDE),
> +};
> diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y
> index 351a173..433bb6d 100644
> --- a/parser/parser_yacc.y
> +++ b/parser/parser_yacc.y
> @@ -87,6 +87,7 @@ void add_local_entry(struct codomain *cod);
> %token TOK_MODE
> %token TOK_END_OF_RULE
> %token TOK_EQUALS
> +%token TOK_NOTEQUALS
.. Well, okay, used here, but not used _much_. :)
> %token TOK_ARROW
> %token TOK_ADD_ASSIGN
> %token TOK_LE
> --
Man, what an awesome cleanup. Thanks. :)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: Digital signature
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20130724/5946f7e5/attachment-0001.pgp>
More information about the AppArmor
mailing list