Part three of my nested functions patch set. Size changes: DOWN: obj/amd64-efi/grub-core/kernel.img (96968 > 96960) - change: -8 DOWN: obj/i386-coreboot/grub-core/kernel.img (27976 > 27960) - change: -16 DOWN: obj/i386-efi/grub-core/kernel.img (59560 > 59536) - change: -24 DOWN: obj/i386-ieee1275/grub-core/kernel.img (48392 > 48376) - change: -16 DOWN: obj/i386-pc/grub-core/kernel.img (28952 > 28936) - change: -16 DOWN: obj/amd64-efi/grub-core/normal.mod (174712 > 174608) - change: -104 DOWN: obj/i386-coreboot/grub-core/normal.mod (110540 > 110512) - change: -28 DOWN: obj/i386-efi/grub-core/normal.mod (115060 > 115020) - change: -40 DOWN: obj/i386-ieee1275/grub-core/normal.mod (110532 > 110504) - change: -28 UP: obj/i386-pc/grub-core/legacycfg.mod (28624 < 28628) - change: 4 DOWN: obj/i386-pc/grub-core/normal.mod (110512 > 110484) - change: -28 DOWN: i386-pc core image (biosdisk ext2 part_msdos) (26740 > 26729) - change: -11 DOWN: i386-pc core image (biosdisk ext2 part_msdos lvm mdraid1x) (34115 > 34092) - change: -23
=== modified file 'ChangeLog' --- ChangeLog 2013-01-13 21:45:16 +0000 +++ ChangeLog 2013-01-15 10:49:28 +0000 @@ -1,3 +1,49 @@ +2013-01-15 Colin Watson <cjwat...@ubuntu.com> + + Remove nested functions from script reading and parsing. + + * grub-core/kern/parser.c (grub_parser_split_cmdline): Add + getline_data argument, passed to getline. + * grub-core/kern/rescue_parser.c (grub_rescue_parse_line): Add + getline_data argument, passed to grub_parser_split_cmdline. + * grub-core/script/lexer.c (grub_script_lexer_yywrap): Pass + lexerstate->getline_data to lexerstate->getline. + (grub_script_lexer_init): Add getline_data argument, saved in + lexerstate->getline_data. + * grub-core/script/main.c (grub_normal_parse_line): Add getline_data + argument, passed to grub_script_parse. + * grub-core/script/script.c (grub_script_parse): Add getline_data + argument, passed to grub_script_lexer_init. + * include/grub/parser.h (grub_parser_split_cmdline): Update + prototype. Update all callers to pass appropriate getline data. + (struct grub_parser.parse_line): Likewise. + (grub_rescue_parse_line): Likewise. + * include/grub/reader.h (grub_reader_getline_t): Add void * + argument. + * include/grub/script_sh.h (struct grub_lexer_param): Add + getline_data member. + (grub_script_parse): Update prototype. Update all callers to pass + appropriate getline data. + (grub_script_lexer_init): Likewise. + (grub_normal_parse_line): Likewise. + + * grub-core/commands/legacycfg.c (legacy_file_getline): Add unused + data argument. + * grub-core/kern/parser.c (grub_parser_execute: getline): Make + static instead of nested. Rename to ... + (grub_parser_execute_getline): ... this. + * grub-core/kern/rescue_reader.c (grub_rescue_read_line): Add unused + data argument. + * grub-core/normal/main.c (read_config_file: getline): Make static + instead of nested. Rename to ... + (read_config_file_getline): ... this. + (grub_normal_read_line): Add unused data argument. + * grub-core/script/execute.c (grub_script_execute_sourcecode: + getline): Make static instead of nested. Rename to ... + (grub_script_execute_sourcecode_getline): ... this. + * util/grub-script-check.c (main: get_config_line): Make static + instead of nested. + 2013-01-13 Vladimir Serbinenko <phco...@gmail.com> * grub-core/kern/emu/hostdisk.c (read_device_map): Explicitly === modified file 'grub-core/commands/legacycfg.c' --- grub-core/commands/legacycfg.c 2012-12-31 17:31:38 +0000 +++ grub-core/commands/legacycfg.c 2013-01-14 22:55:48 +0000 @@ -37,7 +37,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); /* Helper for legacy_file. */ static grub_err_t -legacy_file_getline (char **line, int cont __attribute__ ((unused))) +legacy_file_getline (char **line, int cont __attribute__ ((unused)), + void *data __attribute__ ((unused))) { *line = 0; return GRUB_ERR_NONE; @@ -134,7 +135,7 @@ legacy_file (const char *filename) if (parsed && !entryname) { - grub_normal_parse_line (parsed, legacy_file_getline); + grub_normal_parse_line (parsed, legacy_file_getline, NULL); grub_print_error (); grub_free (parsed); parsed = NULL; @@ -180,7 +181,7 @@ legacy_file (const char *filename) grub_free (args); } - grub_normal_parse_line (suffix, legacy_file_getline); + grub_normal_parse_line (suffix, legacy_file_getline, NULL); grub_print_error (); grub_free (suffix); grub_free (entrysrc); === modified file 'grub-core/kern/parser.c' --- grub-core/kern/parser.c 2012-12-31 17:31:38 +0000 +++ grub-core/kern/parser.c 2013-01-15 10:50:01 +0000 @@ -107,7 +107,8 @@ check_varstate (grub_parser_state_t s) } grub_err_t -grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, +grub_parser_split_cmdline (const char *cmdline, + grub_reader_getline_t getline, void *getline_data, int *argc, char ***argv) { grub_parser_state_t state = GRUB_PARSER_STATE_TEXT; @@ -149,7 +150,7 @@ grub_parser_split_cmdline (const char *c if (!rd || !*rd) { if (getline) - getline (&rd, 1); + getline (&rd, 1, getline_data); else break; } @@ -232,36 +233,39 @@ grub_parser_split_cmdline (const char *c return 0; } -grub_err_t -grub_parser_execute (char *source) +/* Helper for grub_parser_execute. */ +static grub_err_t +grub_parser_execute_getline (char **line, int cont __attribute__ ((unused)), + void *data) { - auto grub_err_t getline (char **line, int cont); - grub_err_t getline (char **line, int cont __attribute__ ((unused))) - { - char *p; + char **source = data; + char *p; - if (!source) - { - *line = 0; - return 0; - } - - p = grub_strchr (source, '\n'); - - if (p) - *line = grub_strndup (source, p - source); - else - *line = grub_strdup (source); - source = p ? p + 1 : 0; - return 0; - } + if (!*source) + { + *line = 0; + return 0; + } + + p = grub_strchr (*source, '\n'); + if (p) + *line = grub_strndup (*source, p - *source); + else + *line = grub_strdup (*source); + *source = p ? p + 1 : 0; + return 0; +} + +grub_err_t +grub_parser_execute (char *source) +{ while (source) { char *line; - getline (&line, 0); - grub_rescue_parse_line (line, getline); + grub_parser_execute_getline (&line, 0, &source); + grub_rescue_parse_line (line, grub_parser_execute_getline, &source); grub_free (line); } === modified file 'grub-core/kern/rescue_parser.c' --- grub-core/kern/rescue_parser.c 2012-02-12 14:25:25 +0000 +++ grub-core/kern/rescue_parser.c 2013-01-14 22:55:48 +0000 @@ -26,14 +26,16 @@ #include <grub/i18n.h> grub_err_t -grub_rescue_parse_line (char *line, grub_reader_getline_t getline) +grub_rescue_parse_line (char *line, + grub_reader_getline_t getline, void *getline_data) { char *name; int n; grub_command_t cmd; char **args; - if (grub_parser_split_cmdline (line, getline, &n, &args) || n < 0) + if (grub_parser_split_cmdline (line, getline, getline_data, &n, &args) + || n < 0) return grub_errno; if (n == 0) === modified file 'grub-core/kern/rescue_reader.c' --- grub-core/kern/rescue_reader.c 2011-12-13 14:13:51 +0000 +++ grub-core/kern/rescue_reader.c 2013-01-14 22:55:48 +0000 @@ -30,7 +30,8 @@ static char linebuf[GRUB_RESCUE_BUF_SIZE /* Prompt to input a command and read the line. */ static grub_err_t -grub_rescue_read_line (char **line, int cont) +grub_rescue_read_line (char **line, int cont, + void *data __attribute__ ((unused))) { int c; int pos = 0; @@ -87,11 +88,11 @@ grub_rescue_run (void) grub_print_error (); grub_errno = GRUB_ERR_NONE; - grub_rescue_read_line (&line, 0); + grub_rescue_read_line (&line, 0, NULL); if (! line || line[0] == '\0') continue; - grub_rescue_parse_line (line, grub_rescue_read_line); + grub_rescue_parse_line (line, grub_rescue_read_line, NULL); grub_free (line); } } === modified file 'grub-core/normal/completion.c' --- grub-core/normal/completion.c 2012-02-12 02:52:17 +0000 +++ grub-core/normal/completion.c 2013-01-14 22:55:48 +0000 @@ -418,7 +418,7 @@ grub_normal_do_completion (char *buf, in *restore = 1; - if (grub_parser_split_cmdline (buf, 0, &argc, &argv)) + if (grub_parser_split_cmdline (buf, 0, 0, &argc, &argv)) return 0; if (argc == 0) === modified file 'grub-core/normal/main.c' --- grub-core/normal/main.c 2012-06-28 00:06:36 +0000 +++ grub-core/normal/main.c 2013-01-14 22:55:48 +0000 @@ -134,33 +134,37 @@ grub_normal_free_menu (grub_menu_t menu) grub_env_unset_menu (); } -static grub_menu_t -read_config_file (const char *config) +/* Helper for read_config_file. */ +static grub_err_t +read_config_file_getline (char **line, int cont __attribute__ ((unused)), + void *data) { - grub_file_t file; - const char *old_file, *old_dir; - char *config_dir, *ptr = 0; + grub_file_t file = data; - auto grub_err_t getline (char **line, int cont); - grub_err_t getline (char **line, int cont __attribute__ ((unused))) + while (1) { - while (1) - { - char *buf; + char *buf; - *line = buf = grub_file_getline (file); - if (! buf) - return grub_errno; - - if (buf[0] == '#') - grub_free (*line); - else - break; - } + *line = buf = grub_file_getline (file); + if (! buf) + return grub_errno; - return GRUB_ERR_NONE; + if (buf[0] == '#') + grub_free (*line); + else + break; } + return GRUB_ERR_NONE; +} + +static grub_menu_t +read_config_file (const char *config) +{ + grub_file_t file; + const char *old_file, *old_dir; + char *config_dir, *ptr = 0; + grub_menu_t newmenu; newmenu = grub_env_get_menu (); @@ -199,10 +203,10 @@ read_config_file (const char *config) grub_print_error (); grub_errno = GRUB_ERR_NONE; - if ((getline (&line, 0)) || (! line)) + if ((read_config_file_getline (&line, 0, file)) || (! line)) break; - grub_normal_parse_line (line, getline); + grub_normal_parse_line (line, read_config_file_getline, file); grub_free (line); } @@ -427,7 +431,8 @@ grub_normal_read_line_real (char **line, } static grub_err_t -grub_normal_read_line (char **line, int cont) +grub_normal_read_line (char **line, int cont, + void *data __attribute__ ((unused))) { return grub_normal_read_line_real (line, cont, 0); } @@ -463,7 +468,7 @@ grub_cmdline_run (int nested) if (! line) break; - grub_normal_parse_line (line, grub_normal_read_line); + grub_normal_parse_line (line, grub_normal_read_line, NULL); grub_free (line); } } === modified file 'grub-core/script/execute.c' --- grub-core/script/execute.c 2012-06-21 20:02:09 +0000 +++ grub-core/script/execute.c 2013-01-14 22:55:48 +0000 @@ -783,6 +783,31 @@ grub_script_function_call (grub_script_f return ret; } +/* Helper for grub_script_execute_sourcecode. */ +static grub_err_t +grub_script_execute_sourcecode_getline (char **line, + int cont __attribute__ ((unused)), + void *data) +{ + const char **source = data; + const char *p; + + if (! *source) + { + *line = 0; + return 0; + } + + p = grub_strchr (*source, '\n'); + + if (p) + *line = grub_strndup (*source, p - *source); + else + *line = grub_strdup (*source); + *source = p ? p + 1 : 0; + return 0; +} + /* Execute a source script. */ grub_err_t grub_script_execute_sourcecode (const char *source, int argc, char **args) @@ -792,27 +817,6 @@ grub_script_execute_sourcecode (const ch struct grub_script_scope new_scope; struct grub_script_scope *old_scope; - auto grub_err_t getline (char **line, int cont); - grub_err_t getline (char **line, int cont __attribute__ ((unused))) - { - const char *p; - - if (! source) - { - *line = 0; - return 0; - } - - p = grub_strchr (source, '\n'); - - if (p) - *line = grub_strndup (source, p - source); - else - *line = grub_strdup (source); - source = p ? p + 1 : 0; - return 0; - } - new_scope.argv.argc = argc; new_scope.argv.args = args; new_scope.flags = 0; @@ -824,8 +828,9 @@ grub_script_execute_sourcecode (const ch { char *line; - getline (&line, 0); - parsed_script = grub_script_parse (line, getline); + grub_script_execute_sourcecode_getline (&line, 0, &source); + parsed_script = grub_script_parse + (line, grub_script_execute_sourcecode_getline, &source); if (! parsed_script) { ret = grub_errno; === modified file 'grub-core/script/lexer.c' --- grub-core/script/lexer.c 2012-02-12 20:33:48 +0000 +++ grub-core/script/lexer.c 2013-01-14 22:55:48 +0000 @@ -147,7 +147,7 @@ grub_script_lexer_yywrap (struct grub_pa line = 0; if (! input) - lexerstate->getline (&line, 1); + lexerstate->getline (&line, 1, lexerstate->getline_data); else line = grub_strdup (input); @@ -216,7 +216,7 @@ grub_script_lexer_yywrap (struct grub_pa struct grub_lexer_param * grub_script_lexer_init (struct grub_parser_param *parser, char *script, - grub_reader_getline_t arg_getline) + grub_reader_getline_t getline, void *getline_data) { struct grub_lexer_param *lexerstate; @@ -232,7 +232,10 @@ grub_script_lexer_init (struct grub_pars return 0; } - lexerstate->getline = arg_getline; /* rest are all zeros already */ + lexerstate->getline = getline; + lexerstate->getline_data = getline_data; + /* The other elements of lexerstate are all zeros already. */ + if (yylex_init (&lexerstate->yyscanner)) { grub_free (lexerstate->text); === modified file 'grub-core/script/main.c' --- grub-core/script/main.c 2012-03-10 12:19:46 +0000 +++ grub-core/script/main.c 2013-01-14 22:55:48 +0000 @@ -22,12 +22,13 @@ #include <grub/script_sh.h> grub_err_t -grub_normal_parse_line (char *line, grub_reader_getline_t getline) +grub_normal_parse_line (char *line, + grub_reader_getline_t getline, void *getline_data) { struct grub_script *parsed_script; /* Parse the script. */ - parsed_script = grub_script_parse (line, getline); + parsed_script = grub_script_parse (line, getline, getline_data); if (parsed_script) { === modified file 'grub-core/script/script.c' --- grub-core/script/script.c 2010-11-25 13:26:20 +0000 +++ grub-core/script/script.c 2013-01-14 22:55:48 +0000 @@ -340,7 +340,8 @@ grub_script_create (struct grub_script_c /* Parse the script passed in SCRIPT and return the parsed datastructure that is ready to be interpreted. */ struct grub_script * -grub_script_parse (char *script, grub_reader_getline_t getline) +grub_script_parse (char *script, + grub_reader_getline_t getline, void *getline_data) { struct grub_script *parsed; struct grub_script_mem *membackup; @@ -359,7 +360,8 @@ grub_script_parse (char *script, grub_re } /* Initialize the lexer. */ - lexstate = grub_script_lexer_init (parsestate, script, getline); + lexstate = grub_script_lexer_init (parsestate, script, + getline, getline_data); if (!lexstate) { grub_free (parsed); === modified file 'include/grub/parser.h' --- include/grub/parser.h 2010-06-28 10:42:50 +0000 +++ include/grub/parser.h 2013-01-14 22:55:48 +0000 @@ -63,6 +63,7 @@ EXPORT_FUNC (grub_parser_cmdline_state) grub_err_t EXPORT_FUNC (grub_parser_split_cmdline) (const char *cmdline, grub_reader_getline_t getline, + void *getline_data, int *argc, char ***argv); struct grub_parser @@ -79,13 +80,15 @@ struct grub_parser /* Clean up the parser. */ grub_err_t (*fini) (void); - grub_err_t (*parse_line) (char *line, grub_reader_getline_t getline); + grub_err_t (*parse_line) (char *line, + grub_reader_getline_t getline, void *getline_data); }; typedef struct grub_parser *grub_parser_t; grub_err_t grub_parser_execute (char *source); grub_err_t -grub_rescue_parse_line (char *line, grub_reader_getline_t getline); +grub_rescue_parse_line (char *line, + grub_reader_getline_t getline, void *getline_data); #endif /* ! GRUB_PARSER_HEADER */ === modified file 'include/grub/reader.h' --- include/grub/reader.h 2011-12-13 14:13:51 +0000 +++ include/grub/reader.h 2013-01-14 22:55:48 +0000 @@ -22,7 +22,7 @@ #include <grub/err.h> -typedef grub_err_t (*grub_reader_getline_t) (char **, int); +typedef grub_err_t (*grub_reader_getline_t) (char **, int, void *); void grub_rescue_run (void) __attribute__ ((noreturn)); === modified file 'include/grub/script_sh.h' --- include/grub/script_sh.h 2012-06-08 20:54:21 +0000 +++ include/grub/script_sh.h 2013-01-14 22:55:48 +0000 @@ -161,6 +161,9 @@ struct grub_lexer_param expected, but not available. */ grub_reader_getline_t getline; + /* Caller-supplied data passed to `getline'. */ + void *getline_data; + /* A reference counter. If this is >0 it means that the parser expects more tokens and `getline' should be called to fetch more. Otherwise the lexer can stop processing if the current buffer is @@ -287,14 +290,16 @@ grub_script_arg_add (struct grub_parser_ grub_script_arg_type_t type, char *str); struct grub_script *grub_script_parse (char *script, - grub_reader_getline_t getline); + grub_reader_getline_t getline, + void *getline_data); void grub_script_free (struct grub_script *script); struct grub_script *grub_script_create (struct grub_script_cmd *cmd, struct grub_script_mem *mem); struct grub_lexer_param *grub_script_lexer_init (struct grub_parser_param *parser, char *script, - grub_reader_getline_t getline); + grub_reader_getline_t getline, + void *getline_data); 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 *); @@ -380,7 +385,8 @@ char ** grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count); grub_err_t -grub_normal_parse_line (char *line, grub_reader_getline_t getline); +grub_normal_parse_line (char *line, + grub_reader_getline_t getline, void *getline_data); static inline struct grub_script * grub_script_ref (struct grub_script *script) === modified file 'util/grub-script-check.c' --- util/grub-script-check.c 2012-03-06 11:02:38 +0000 +++ util/grub-script-check.c 2013-01-15 10:50:38 +0000 @@ -85,81 +85,92 @@ static struct argp argp = { NULL, NULL, NULL }; +/* Context for main. */ +struct main_ctx +{ + int lineno; + FILE *file; + struct arguments arguments; +}; + +/* Helper for main. */ +static grub_err_t +get_config_line (char **line, int cont __attribute__ ((unused)), void *data) +{ + struct main_ctx *ctx = data; + int i; + char *cmdline = 0; + size_t len = 0; + ssize_t curread; + + curread = getline (&cmdline, &len, (ctx->file ?: stdin)); + if (curread == -1) + { + *line = 0; + grub_errno = GRUB_ERR_READ_ERROR; + + if (cmdline) + free (cmdline); + return grub_errno; + } + + if (ctx->arguments.verbose) + grub_printf ("%s", cmdline); + + for (i = 0; cmdline[i] != '\0'; i++) + { + /* Replace tabs and carriage returns with spaces. */ + if (cmdline[i] == '\t' || cmdline[i] == '\r') + cmdline[i] = ' '; + + /* Replace '\n' with '\0'. */ + if (cmdline[i] == '\n') + cmdline[i] = '\0'; + } + + ctx->lineno++; + *line = grub_strdup (cmdline); + + free (cmdline); + return 0; +} + int main (int argc, char *argv[]) { + struct main_ctx ctx = { + .lineno = 0, + .file = 0 + }; char *input; - int lineno = 0; - FILE *file = 0; - struct arguments arguments; int found_input = 0; struct grub_script *script = NULL; - auto grub_err_t get_config_line (char **line, int cont); - grub_err_t get_config_line (char **line, int cont __attribute__ ((unused))) - { - int i; - char *cmdline = 0; - size_t len = 0; - ssize_t curread; - - curread = getline(&cmdline, &len, (file ?: stdin)); - if (curread == -1) - { - *line = 0; - grub_errno = GRUB_ERR_READ_ERROR; - - if (cmdline) - free (cmdline); - return grub_errno; - } - - if (arguments.verbose) - grub_printf("%s", cmdline); - - for (i = 0; cmdline[i] != '\0'; i++) - { - /* Replace tabs and carriage returns with spaces. */ - if (cmdline[i] == '\t' || cmdline[i] == '\r') - cmdline[i] = ' '; - - /* Replace '\n' with '\0'. */ - if (cmdline[i] == '\n') - cmdline[i] = '\0'; - } - - lineno++; - *line = grub_strdup (cmdline); - - free (cmdline); - return 0; - } - set_program_name (argv[0]); grub_util_init_nls (); - memset (&arguments, 0, sizeof (struct arguments)); + memset (&ctx.arguments, 0, sizeof (struct arguments)); /* Check for options. */ - if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0) + if (argp_parse (&argp, argc, argv, 0, 0, &ctx.arguments) != 0) { fprintf (stderr, "%s", _("Error in parsing command line arguments\n")); exit(1); } /* Obtain ARGUMENT. */ - if (!arguments.filename) + if (!ctx.arguments.filename) { - file = 0; /* read from stdin */ + ctx.file = 0; /* read from stdin */ } else { - file = fopen (arguments.filename, "r"); - if (! file) + ctx.file = fopen (ctx.arguments.filename, "r"); + if (! ctx.file) { char *program = xstrdup(program_name); fprintf (stderr, "%s: %s: %s\n", program_name, - arguments.filename, strerror(errno)); + ctx.arguments.filename, strerror (errno)); argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program); free(program); exit(1); @@ -169,12 +180,12 @@ main (int argc, char *argv[]) do { input = 0; - get_config_line(&input, 0); + get_config_line (&input, 0, &ctx); if (! input) break; found_input = 1; - script = grub_script_parse (input, get_config_line); + script = grub_script_parse (input, get_config_line, &ctx); if (script) { grub_script_execute (script); @@ -184,11 +195,11 @@ main (int argc, char *argv[]) grub_free (input); } while (script != 0); - if (file) fclose (file); + if (ctx.file) fclose (ctx.file); if (found_input && script == 0) { - fprintf (stderr, _("Syntax error at line %u\n"), lineno); + fprintf (stderr, _("Syntax error at line %u\n"), ctx.lineno); return 1; } Thanks, -- Colin Watson [cjwat...@ubuntu.com] _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel