3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2005,2007,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/>.
20 #ifndef GRUB_NORMAL_PARSER_HEADER
21 #define GRUB_NORMAL_PARSER_HEADER 1
23 #include <grub/types.h>
25 #include <grub/parser.h>
26 #include <grub/command.h>
28 struct grub_script_mem
;
30 /* The generic header for each scripting command or structure. */
31 struct grub_script_cmd
33 /* This function is called to execute the command. */
34 grub_err_t (*exec
) (struct grub_script_cmd
*cmd
);
36 /* The next command. This can be used by the parent to form a chain
38 struct grub_script_cmd
*next
;
44 struct grub_script_mem
*mem
;
45 struct grub_script_cmd
*cmd
;
47 /* grub_scripts from block arguments. */
48 struct grub_script
*next_siblings
;
49 struct grub_script
*children
;
54 GRUB_SCRIPT_ARG_TYPE_VAR
,
55 GRUB_SCRIPT_ARG_TYPE_TEXT
,
56 GRUB_SCRIPT_ARG_TYPE_GETTEXT
,
57 GRUB_SCRIPT_ARG_TYPE_DQVAR
,
58 GRUB_SCRIPT_ARG_TYPE_DQSTR
,
59 GRUB_SCRIPT_ARG_TYPE_SQSTR
,
60 GRUB_SCRIPT_ARG_TYPE_BLOCK
61 } grub_script_arg_type_t
;
63 /* A part of an argument. */
64 struct grub_script_arg
66 grub_script_arg_type_t type
;
70 /* Parsed block argument. */
71 struct grub_script
*script
;
73 /* Next argument part. */
74 struct grub_script_arg
*next
;
77 /* An argument vector. */
78 struct grub_script_argv
82 struct grub_script
*script
;
85 /* Pluggable wildcard translator. */
86 struct grub_script_wildcard_translator
88 grub_err_t (*expand
) (const char *str
, char ***expansions
);
90 extern struct grub_script_wildcard_translator
*grub_wildcard_translator
;
91 extern struct grub_script_wildcard_translator grub_filename_translator
;
93 /* A complete argument. It consists of a list of one or more `struct
95 struct grub_script_arglist
97 struct grub_script_arglist
*next
;
98 struct grub_script_arg
*arg
;
99 /* Only stored in the first link. */
103 /* A single command line. */
104 struct grub_script_cmdline
106 struct grub_script_cmd cmd
;
108 /* The arguments for this command. */
109 struct grub_script_arglist
*arglist
;
112 /* An if statement. */
113 struct grub_script_cmdif
115 struct grub_script_cmd cmd
;
117 /* The command used to check if the 'if' is true or false. */
118 struct grub_script_cmd
*exec_to_evaluate
;
120 /* The code executed in case the result of 'if' was true. */
121 struct grub_script_cmd
*exec_on_true
;
123 /* The code executed in case the result of 'if' was false. */
124 struct grub_script_cmd
*exec_on_false
;
127 /* A for statement. */
128 struct grub_script_cmdfor
130 struct grub_script_cmd cmd
;
132 /* The name used as looping variable. */
133 struct grub_script_arg
*name
;
135 /* The words loop iterates over. */
136 struct grub_script_arglist
*words
;
138 /* The command list executed in each loop. */
139 struct grub_script_cmd
*list
;
142 /* A while/until command. */
143 struct grub_script_cmdwhile
145 struct grub_script_cmd cmd
;
147 /* The command list used as condition. */
148 struct grub_script_cmd
*cond
;
150 /* The command list executed in each loop. */
151 struct grub_script_cmd
*list
;
153 /* The flag to indicate this as "until" loop. */
157 /* State of the lexer as passed to the lexer. */
158 struct grub_lexer_param
160 /* Function used by the lexer to get a new line when more input is
161 expected, but not available. */
162 grub_reader_getline_t getline
;
164 /* Caller-supplied data passed to `getline'. */
167 /* A reference counter. If this is >0 it means that the parser
168 expects more tokens and `getline' should be called to fetch more.
169 Otherwise the lexer can stop processing if the current buffer is
173 /* While walking through the databuffer, `record' the characters to
174 this other buffer. It can be used to edit the menu entry at a
177 /* If true, recording is enabled. */
180 /* Points to the recording. */
183 /* index in the RECORDING. */
186 /* Size of RECORDING. */
189 /* End of file reached. */
192 /* Merge multiple word tokens. */
196 /* Part of a multi-part token. */
202 grub_script_arg_type_t type
;
204 /* Flag to indicate resplit in progres. */
207 /* Text that is unput. */
213 /* Flex scanner buffer. */
217 #define GRUB_LEXER_INITIAL_TEXT_SIZE 32
218 #define GRUB_LEXER_INITIAL_RECORD_SIZE 256
220 /* State of the parser as passes to the parser. */
221 struct grub_parser_param
223 /* Keep track of the memory allocated for this specific
225 struct grub_script_mem
*func_mem
;
227 /* When set to 0, no errors have occurred during parsing. */
230 /* The memory that was used while parsing and scanning. */
231 struct grub_script_mem
*memused
;
233 /* The block argument scripts. */
234 struct grub_script
*scripts
;
236 /* The result of the parser. */
237 struct grub_script_cmd
*parsed
;
239 struct grub_lexer_param
*lexerstate
;
242 void grub_script_init (void);
243 void grub_script_fini (void);
245 void grub_script_mem_free (struct grub_script_mem
*mem
);
247 void grub_script_argv_free (struct grub_script_argv
*argv
);
248 int grub_script_argv_make (struct grub_script_argv
*argv
, int argc
, char **args
);
249 int grub_script_argv_next (struct grub_script_argv
*argv
);
250 int grub_script_argv_append (struct grub_script_argv
*argv
, const char *s
,
252 int grub_script_argv_split_append (struct grub_script_argv
*argv
, const char *s
);
254 struct grub_script_arglist
*
255 grub_script_create_arglist (struct grub_parser_param
*state
);
257 struct grub_script_arglist
*
258 grub_script_add_arglist (struct grub_parser_param
*state
,
259 struct grub_script_arglist
*list
,
260 struct grub_script_arg
*arg
);
261 struct grub_script_cmd
*
262 grub_script_create_cmdline (struct grub_parser_param
*state
,
263 struct grub_script_arglist
*arglist
);
265 struct grub_script_cmd
*
266 grub_script_create_cmdif (struct grub_parser_param
*state
,
267 struct grub_script_cmd
*exec_to_evaluate
,
268 struct grub_script_cmd
*exec_on_true
,
269 struct grub_script_cmd
*exec_on_false
);
271 struct grub_script_cmd
*
272 grub_script_create_cmdfor (struct grub_parser_param
*state
,
273 struct grub_script_arg
*name
,
274 struct grub_script_arglist
*words
,
275 struct grub_script_cmd
*list
);
277 struct grub_script_cmd
*
278 grub_script_create_cmdwhile (struct grub_parser_param
*state
,
279 struct grub_script_cmd
*cond
,
280 struct grub_script_cmd
*list
,
281 int is_an_until_loop
);
283 struct grub_script_cmd
*
284 grub_script_append_cmd (struct grub_parser_param
*state
,
285 struct grub_script_cmd
*list
,
286 struct grub_script_cmd
*last
);
287 struct grub_script_arg
*
288 grub_script_arg_add (struct grub_parser_param
*state
,
289 struct grub_script_arg
*arg
,
290 grub_script_arg_type_t type
, char *str
);
292 struct grub_script
*grub_script_parse (char *script
,
293 grub_reader_getline_t getline_func
,
294 void *getline_func_data
);
295 void grub_script_free (struct grub_script
*script
);
296 struct grub_script
*grub_script_create (struct grub_script_cmd
*cmd
,
297 struct grub_script_mem
*mem
);
299 struct grub_lexer_param
*grub_script_lexer_init (struct grub_parser_param
*parser
,
301 grub_reader_getline_t getline_func
,
302 void *getline_func_data
);
303 void grub_script_lexer_fini (struct grub_lexer_param
*);
304 void grub_script_lexer_ref (struct grub_lexer_param
*);
305 void grub_script_lexer_deref (struct grub_lexer_param
*);
306 unsigned grub_script_lexer_record_start (struct grub_parser_param
*);
307 char *grub_script_lexer_record_stop (struct grub_parser_param
*, unsigned);
308 int grub_script_lexer_yywrap (struct grub_parser_param
*, const char *input
);
309 void grub_script_lexer_record (struct grub_parser_param
*, char *);
311 /* Functions to track allocated memory. */
312 struct grub_script_mem
*grub_script_mem_record (struct grub_parser_param
*state
);
313 struct grub_script_mem
*grub_script_mem_record_stop (struct grub_parser_param
*state
,
314 struct grub_script_mem
*restore
);
315 void *grub_script_malloc (struct grub_parser_param
*state
, grub_size_t size
);
317 /* Functions used by bison. */
319 int grub_script_yylex (union YYSTYPE
*, struct grub_parser_param
*);
320 int grub_script_yyparse (struct grub_parser_param
*);
321 void grub_script_yyerror (struct grub_parser_param
*, char const *);
323 /* Commands to execute, don't use these directly. */
324 grub_err_t
grub_script_execute_cmdline (struct grub_script_cmd
*cmd
);
325 grub_err_t
grub_script_execute_cmdlist (struct grub_script_cmd
*cmd
);
326 grub_err_t
grub_script_execute_cmdif (struct grub_script_cmd
*cmd
);
327 grub_err_t
grub_script_execute_cmdfor (struct grub_script_cmd
*cmd
);
328 grub_err_t
grub_script_execute_cmdwhile (struct grub_script_cmd
*cmd
);
330 /* Execute any GRUB pre-parsed command or script. */
331 grub_err_t
grub_script_execute (struct grub_script
*script
);
332 grub_err_t
grub_script_execute_sourcecode (const char *source
);
333 grub_err_t
grub_script_execute_new_scope (const char *source
, int argc
, char **args
);
335 /* Break command for loops. */
336 grub_err_t
grub_script_break (grub_command_t cmd
, int argc
, char *argv
[]);
338 /* SHIFT command for GRUB script. */
339 grub_err_t
grub_script_shift (grub_command_t cmd
, int argc
, char *argv
[]);
341 /* SETPARAMS command for GRUB script functions. */
342 grub_err_t
grub_script_setparams (grub_command_t cmd
, int argc
, char *argv
[]);
344 /* RETURN command for functions. */
345 grub_err_t
grub_script_return (grub_command_t cmd
, int argc
, char *argv
[]);
347 /* This variable points to the parsed command. This is used to
348 communicate with the bison code. */
349 extern struct grub_script_cmd
*grub_script_parsed
;
353 /* The function description. */
354 struct grub_script_function
359 /* The script function. */
360 struct grub_script
*func
;
365 /* The next element. */
366 struct grub_script_function
*next
;
370 typedef struct grub_script_function
*grub_script_function_t
;
372 extern grub_script_function_t grub_script_function_list
;
374 #define FOR_SCRIPT_FUNCTIONS(var) for((var) = grub_script_function_list; \
375 (var); (var) = (var)->next)
377 grub_script_function_t
grub_script_function_create (struct grub_script_arg
*functionname
,
378 struct grub_script
*cmd
);
379 void grub_script_function_remove (const char *name
);
380 grub_script_function_t
grub_script_function_find (char *functionname
);
382 grub_err_t
grub_script_function_call (grub_script_function_t func
,
383 int argc
, char **args
);
386 grub_script_execute_arglist_to_argv (struct grub_script_arglist
*arglist
, int *count
);
389 grub_normal_parse_line (char *line
,
390 grub_reader_getline_t getline_func
,
391 void *getline_func_data
);
393 static inline struct grub_script
*
394 grub_script_ref (struct grub_script
*script
)
402 grub_script_unref (struct grub_script
*script
)
407 if (script
->refcnt
== 0)
408 grub_script_free (script
);
413 #endif /* ! GRUB_NORMAL_PARSER_HEADER */