1 /* grub-script-check.c - check grub script file for syntax errors */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2009,2010 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
21 #include <grub/types.h>
23 #include <grub/misc.h>
24 #include <grub/emu/misc.h>
25 #include <grub/util/misc.h>
26 #include <grub/i18n.h>
27 #include <grub/parser.h>
28 #include <grub/script_sh.h>
37 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
38 #pragma GCC diagnostic ignored "-Wmissing-declarations"
40 #pragma GCC diagnostic error "-Wmissing-prototypes"
41 #pragma GCC diagnostic error "-Wmissing-declarations"
51 static struct argp_option options
[] = {
52 {"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
57 argp_parser (int key
, char *arg
, struct argp_state
*state
)
59 /* Get the input argument from argp_parse, which we
60 know is a pointer to our arguments structure. */
61 struct arguments
*arguments
= state
->input
;
66 arguments
->verbose
= 1;
70 if (state
->arg_num
== 0)
71 arguments
->filename
= xstrdup (arg
);
74 /* Too many arguments. */
75 fprintf (stderr
, _("Unknown extra argument `%s'."), arg
);
76 fprintf (stderr
, "\n");
81 return ARGP_ERR_UNKNOWN
;
86 static struct argp argp
= {
87 options
, argp_parser
, N_("[PATH]"),
88 N_("Checks GRUB script configuration file for syntax errors."),
92 /* Context for main. */
97 struct arguments arguments
;
100 /* Helper for main. */
102 get_config_line (char **line
, int cont
__attribute__ ((unused
)), void *data
)
104 struct main_ctx
*ctx
= data
;
110 curread
= getline (&cmdline
, &len
, (ctx
->file
?: stdin
));
114 grub_errno
= GRUB_ERR_READ_ERROR
;
121 if (ctx
->arguments
.verbose
)
122 grub_printf ("%s", cmdline
);
124 for (i
= 0; cmdline
[i
] != '\0'; i
++)
126 /* Replace tabs and carriage returns with spaces. */
127 if (cmdline
[i
] == '\t' || cmdline
[i
] == '\r')
130 /* Replace '\n' with '\0'. */
131 if (cmdline
[i
] == '\n')
136 *line
= grub_strdup (cmdline
);
143 main (int argc
, char *argv
[])
145 struct main_ctx ctx
= {
150 int found_input
= 0, found_cmd
= 0;
151 struct grub_script
*script
= NULL
;
153 grub_util_host_init (&argc
, &argv
);
155 memset (&ctx
.arguments
, 0, sizeof (struct arguments
));
157 /* Check for options. */
158 if (argp_parse (&argp
, argc
, argv
, 0, 0, &ctx
.arguments
) != 0)
160 fprintf (stderr
, "%s", _("Error in parsing command line arguments\n"));
164 /* Obtain ARGUMENT. */
165 if (!ctx
.arguments
.filename
)
167 ctx
.file
= 0; /* read from stdin */
171 ctx
.file
= grub_util_fopen (ctx
.arguments
.filename
, "r");
174 char *program
= xstrdup(program_name
);
175 fprintf (stderr
, _("cannot open `%s': %s"),
176 ctx
.arguments
.filename
, strerror (errno
));
177 argp_help (&argp
, stderr
, ARGP_HELP_STD_USAGE
, program
);
186 get_config_line (&input
, 0, &ctx
);
191 script
= grub_script_parse (input
, get_config_line
, &ctx
);
196 grub_script_execute (script
);
197 grub_script_free (script
);
201 } while (script
!= 0);
203 if (ctx
.file
) fclose (ctx
.file
);
205 if (found_input
&& script
== 0)
207 fprintf (stderr
, _("Syntax error at line %u\n"), ctx
.lineno
);
212 fprintf (stderr
, _("Script `%s' contains no commands and will do nothing\n"),
213 ctx
.arguments
.filename
);