]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
nested recording support
authorBVK Chaitanya <bvk.groups@gmail.com>
Thu, 29 Apr 2010 12:40:22 +0000 (18:10 +0530)
committerBVK Chaitanya <bvk.groups@gmail.com>
Thu, 29 Apr 2010 12:40:22 +0000 (18:10 +0530)
include/grub/script_sh.h
script/lexer.c
script/parser.y

index b55b6a806bdf338c41ec67df6b3b62975dc98051..17b1c5a5a79ddf0e7092727c6f888d559a897098 100644 (file)
@@ -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 *);
 
index 42a570348081544f196e1015aeae843a5e38c34f..73adf627fb93ffadbc46d55fb49f932f6db3d559 100644 (file)
@@ -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.  */
-
-  ptr = compact (lexer->recording, lexer->recording + lexer->recordpos - 1);
-  lexer->record = 0;
-  lexer->recordpos = 0;
+  lexer->record--;
+  if (!lexer->recording)
+    return 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;
        }
index b5815ea8de809e076b5e3a67087c83ca639eadbf..e5de35cf453892967b5767ef17c5311170235dde 100644 (file)
@@ -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);
+             $<offset>$ = 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, $<offset>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);
            }
 ;