From 0993355a68b5e954c26184a4fb19310c15eef701 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 29 Apr 2010 18:10:22 +0530 Subject: [PATCH] nested recording support --- include/grub/script_sh.h | 4 +-- script/lexer.c | 68 +++++++++++++++++----------------------- script/parser.y | 11 ++++--- 3 files changed, 37 insertions(+), 46 deletions(-) diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index b55b6a806..17b1c5a5a 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -282,8 +282,8 @@ struct grub_lexer_param *grub_script_lexer_init (struct grub_parser_param *parse void grub_script_lexer_fini (struct grub_lexer_param *); void grub_script_lexer_ref (struct grub_lexer_param *); void grub_script_lexer_deref (struct grub_lexer_param *); -void grub_script_lexer_record_start (struct grub_parser_param *); -char *grub_script_lexer_record_stop (struct grub_parser_param *); +unsigned grub_script_lexer_record_start (struct grub_parser_param *); +char *grub_script_lexer_record_stop (struct grub_parser_param *, unsigned); int grub_script_lexer_yywrap (struct grub_parser_param *); void grub_script_lexer_record (struct grub_parser_param *, char *); diff --git a/script/lexer.c b/script/lexer.c index 42a570348..73adf627f 100644 --- a/script/lexer.c +++ b/script/lexer.c @@ -38,68 +38,57 @@ grub_script_lexer_deref (struct grub_lexer_param *state) } /* Start recording all characters passing through the lexer. */ -void +unsigned grub_script_lexer_record_start (struct grub_parser_param *parser) { struct grub_lexer_param *lexer = parser->lexerstate; - lexer->record = 1; - lexer->recordpos = 0; - if (lexer->recording) /* reuse last record */ - return; + lexer->record++; + if (lexer->recording) + return lexer->recordpos; + lexer->recordpos = 0; lexer->recordlen = GRUB_LEXER_INITIAL_RECORD_SIZE; lexer->recording = grub_malloc (lexer->recordlen); if (!lexer->recording) { grub_script_yyerror (parser, 0); - lexer->record = 0; lexer->recordlen = 0; } + return lexer->recordpos; } char * -grub_script_lexer_record_stop (struct grub_parser_param *parser) +grub_script_lexer_record_stop (struct grub_parser_param *parser, unsigned offset) { - char *ptr; + int count; char *result; struct grub_lexer_param *lexer = parser->lexerstate; - auto char *compact (char *start, char *end); - char *compact (char *start, char *end) - { - /* Delete '{' and '}' characters and whitespaces. */ - while (*start && grub_isspace (*start)) start++; - if (*start == '{') start++; - while (*start && grub_isspace (*start)) start++; - - while (*end && grub_isspace (*end)) end--; - if (*end == '}') end--; - while (*end && grub_isspace (*end)) end--; - end[1] = '\0'; - - return start; - } - - if (!lexer->record || !lexer->recording) + if (!lexer->record) return 0; - /* XXX This is not necessary in BASH. */ + lexer->record--; + if (!lexer->recording) + return 0; - ptr = compact (lexer->recording, lexer->recording + lexer->recordpos - 1); - lexer->record = 0; - lexer->recordpos = 0; - - /* This memory would be freed by, grub_script_free. */ - result = grub_script_malloc (parser, grub_strlen (ptr) + 1); - if (result) - grub_strcpy (result, ptr); + count = lexer->recordpos - offset; + result = grub_script_malloc (parser, count + 1); + if (result) { + grub_strncpy (result, lexer->recording + offset, count); + result[count] = '\0'; + } + if (lexer->record == 0) + { + grub_free (lexer->recording); + lexer->recording = 0; + lexer->recordlen = 0; + lexer->recordpos = 0; + } return result; } -#define MAX(a,b) ((a) < (b) ? (b) : (a)) - /* Record STR if input recording is enabled. */ void grub_script_lexer_record (struct grub_parser_param *parser, char *str) @@ -108,21 +97,20 @@ grub_script_lexer_record (struct grub_parser_param *parser, char *str) char *old; struct grub_lexer_param *lexer = parser->lexerstate; - if (!lexer->record) + if (!lexer->record || !lexer->recording) return; len = grub_strlen (str); if (lexer->recordpos + len + 1 > lexer->recordlen) { old = lexer->recording; - lexer->recordlen = MAX (len, lexer->recordlen) * 2; + lexer->recordlen = grub_max (len, lexer->recordlen) * 2; lexer->recording = grub_realloc (lexer->recording, lexer->recordlen); if (!lexer->recording) { grub_free (old); - lexer->record = 0; lexer->recordpos = 0; - lexer->recordlen /= 2; + lexer->recordlen = 0; grub_script_yyerror (parser, 0); return; } diff --git a/script/parser.y b/script/parser.y index b5815ea8d..e5de35cf4 100644 --- a/script/parser.y +++ b/script/parser.y @@ -33,6 +33,7 @@ struct grub_script_arglist *arglist; struct grub_script_arg *arg; char *string; + unsigned offset; } %token GRUB_PARSER_TOKEN_BAD @@ -217,14 +218,16 @@ menuentry: "menuentry" } arguments1 { - grub_script_lexer_record_start (state); + $$ = grub_script_lexer_record_start (state); } delimiters0 "{" commands1 delimiters1 "}" { - char *menu_entry; - menu_entry = grub_script_lexer_record_stop (state); + char *def; + def = grub_script_lexer_record_stop (state, $4); + *grub_strrchr(def, '}') = '\0'; + grub_script_lexer_deref (state->lexerstate); - $$ = grub_script_create_cmdmenu (state, $3, menu_entry, 0); + $$ = grub_script_create_cmdmenu (state, $3, def, 0); } ;