script_sh.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. /* normal_parser.h */
  2. /*
  3. * GRUB -- GRand Unified Bootloader
  4. * Copyright (C) 2005,2007,2009,2010 Free Software Foundation, Inc.
  5. *
  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.
  10. *
  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.
  15. *
  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/>.
  18. */
  19. #ifndef GRUB_NORMAL_PARSER_HEADER
  20. #define GRUB_NORMAL_PARSER_HEADER 1
  21. #include <grub/types.h>
  22. #include <grub/err.h>
  23. #include <grub/parser.h>
  24. #include <grub/command.h>
  25. struct grub_script_mem;
  26. /* The generic header for each scripting command or structure. */
  27. struct grub_script_cmd
  28. {
  29. /* This function is called to execute the command. */
  30. grub_err_t (*exec) (struct grub_script_cmd *cmd);
  31. /* The next command. This can be used by the parent to form a chain
  32. of commands. */
  33. struct grub_script_cmd *next;
  34. };
  35. struct grub_script
  36. {
  37. unsigned refcnt;
  38. struct grub_script_mem *mem;
  39. struct grub_script_cmd *cmd;
  40. /* grub_scripts from block arguments. */
  41. struct grub_script *next_siblings;
  42. struct grub_script *children;
  43. };
  44. typedef enum
  45. {
  46. GRUB_SCRIPT_ARG_TYPE_VAR,
  47. GRUB_SCRIPT_ARG_TYPE_TEXT,
  48. GRUB_SCRIPT_ARG_TYPE_GETTEXT,
  49. GRUB_SCRIPT_ARG_TYPE_DQVAR,
  50. GRUB_SCRIPT_ARG_TYPE_DQSTR,
  51. GRUB_SCRIPT_ARG_TYPE_SQSTR,
  52. GRUB_SCRIPT_ARG_TYPE_BLOCK
  53. } grub_script_arg_type_t;
  54. /* A part of an argument. */
  55. struct grub_script_arg
  56. {
  57. grub_script_arg_type_t type;
  58. char *str;
  59. /* Parsed block argument. */
  60. struct grub_script *script;
  61. /* Next argument part. */
  62. struct grub_script_arg *next;
  63. };
  64. /* An argument vector. */
  65. struct grub_script_argv
  66. {
  67. unsigned argc;
  68. char **args;
  69. struct grub_script *script;
  70. };
  71. /* Pluggable wildcard translator. */
  72. struct grub_script_wildcard_translator
  73. {
  74. grub_err_t (*expand) (const char *str, char ***expansions);
  75. };
  76. extern struct grub_script_wildcard_translator *grub_wildcard_translator;
  77. extern struct grub_script_wildcard_translator grub_filename_translator;
  78. /* A complete argument. It consists of a list of one or more `struct
  79. grub_script_arg's. */
  80. struct grub_script_arglist
  81. {
  82. struct grub_script_arglist *next;
  83. struct grub_script_arg *arg;
  84. /* Only stored in the first link. */
  85. int argcount;
  86. };
  87. /* A single command line. */
  88. struct grub_script_cmdline
  89. {
  90. struct grub_script_cmd cmd;
  91. /* The arguments for this command. */
  92. struct grub_script_arglist *arglist;
  93. };
  94. /* An if statement. */
  95. struct grub_script_cmdif
  96. {
  97. struct grub_script_cmd cmd;
  98. /* The command used to check if the 'if' is true or false. */
  99. struct grub_script_cmd *exec_to_evaluate;
  100. /* The code executed in case the result of 'if' was true. */
  101. struct grub_script_cmd *exec_on_true;
  102. /* The code executed in case the result of 'if' was false. */
  103. struct grub_script_cmd *exec_on_false;
  104. };
  105. /* A for statement. */
  106. struct grub_script_cmdfor
  107. {
  108. struct grub_script_cmd cmd;
  109. /* The name used as looping variable. */
  110. struct grub_script_arg *name;
  111. /* The words loop iterates over. */
  112. struct grub_script_arglist *words;
  113. /* The command list executed in each loop. */
  114. struct grub_script_cmd *list;
  115. };
  116. /* A while/until command. */
  117. struct grub_script_cmdwhile
  118. {
  119. struct grub_script_cmd cmd;
  120. /* The command list used as condition. */
  121. struct grub_script_cmd *cond;
  122. /* The command list executed in each loop. */
  123. struct grub_script_cmd *list;
  124. /* The flag to indicate this as "until" loop. */
  125. int until;
  126. };
  127. /* State of the lexer as passed to the lexer. */
  128. struct grub_lexer_param
  129. {
  130. /* Function used by the lexer to get a new line when more input is
  131. expected, but not available. */
  132. grub_reader_getline_t getline;
  133. /* Caller-supplied data passed to `getline'. */
  134. void *getline_data;
  135. /* A reference counter. If this is >0 it means that the parser
  136. expects more tokens and `getline' should be called to fetch more.
  137. Otherwise the lexer can stop processing if the current buffer is
  138. depleted. */
  139. int refs;
  140. /* While walking through the databuffer, `record' the characters to
  141. this other buffer. It can be used to edit the menu entry at a
  142. later moment. */
  143. /* If true, recording is enabled. */
  144. int record;
  145. /* Points to the recording. */
  146. char *recording;
  147. /* index in the RECORDING. */
  148. int recordpos;
  149. /* Size of RECORDING. */
  150. int recordlen;
  151. /* End of file reached. */
  152. int eof;
  153. /* Merge multiple word tokens. */
  154. int merge_start;
  155. int merge_end;
  156. /* Part of a multi-part token. */
  157. char *text;
  158. unsigned used;
  159. unsigned size;
  160. /* Type of text. */
  161. grub_script_arg_type_t type;
  162. /* Flag to indicate resplit in progres. */
  163. unsigned resplit;
  164. /* Text that is unput. */
  165. char *prefix;
  166. /* Flex scanner. */
  167. void *yyscanner;
  168. /* Flex scanner buffer. */
  169. void *buffer;
  170. };
  171. #define GRUB_LEXER_INITIAL_TEXT_SIZE 32
  172. #define GRUB_LEXER_INITIAL_RECORD_SIZE 256
  173. /* State of the parser as passes to the parser. */
  174. struct grub_parser_param
  175. {
  176. /* Keep track of the memory allocated for this specific
  177. function. */
  178. struct grub_script_mem *func_mem;
  179. /* When set to 0, no errors have occurred during parsing. */
  180. int err;
  181. /* The memory that was used while parsing and scanning. */
  182. struct grub_script_mem *memused;
  183. /* The block argument scripts. */
  184. struct grub_script *scripts;
  185. /* The result of the parser. */
  186. struct grub_script_cmd *parsed;
  187. struct grub_lexer_param *lexerstate;
  188. };
  189. void grub_script_init (void);
  190. void grub_script_fini (void);
  191. void grub_script_mem_free (struct grub_script_mem *mem);
  192. void grub_script_argv_free (struct grub_script_argv *argv);
  193. int grub_script_argv_make (struct grub_script_argv *argv, int argc, char **args);
  194. int grub_script_argv_next (struct grub_script_argv *argv);
  195. int grub_script_argv_append (struct grub_script_argv *argv, const char *s,
  196. grub_size_t slen);
  197. int grub_script_argv_split_append (struct grub_script_argv *argv, const char *s);
  198. struct grub_script_arglist *
  199. grub_script_create_arglist (struct grub_parser_param *state);
  200. struct grub_script_arglist *
  201. grub_script_add_arglist (struct grub_parser_param *state,
  202. struct grub_script_arglist *list,
  203. struct grub_script_arg *arg);
  204. struct grub_script_cmd *
  205. grub_script_create_cmdline (struct grub_parser_param *state,
  206. struct grub_script_arglist *arglist);
  207. struct grub_script_cmd *
  208. grub_script_create_cmdif (struct grub_parser_param *state,
  209. struct grub_script_cmd *exec_to_evaluate,
  210. struct grub_script_cmd *exec_on_true,
  211. struct grub_script_cmd *exec_on_false);
  212. struct grub_script_cmd *
  213. grub_script_create_cmdfor (struct grub_parser_param *state,
  214. struct grub_script_arg *name,
  215. struct grub_script_arglist *words,
  216. struct grub_script_cmd *list);
  217. struct grub_script_cmd *
  218. grub_script_create_cmdwhile (struct grub_parser_param *state,
  219. struct grub_script_cmd *cond,
  220. struct grub_script_cmd *list,
  221. int is_an_until_loop);
  222. struct grub_script_cmd *
  223. grub_script_append_cmd (struct grub_parser_param *state,
  224. struct grub_script_cmd *list,
  225. struct grub_script_cmd *last);
  226. struct grub_script_arg *
  227. grub_script_arg_add (struct grub_parser_param *state,
  228. struct grub_script_arg *arg,
  229. grub_script_arg_type_t type, char *str);
  230. struct grub_script *grub_script_parse (char *script,
  231. grub_reader_getline_t getline_func,
  232. void *getline_func_data);
  233. void grub_script_free (struct grub_script *script);
  234. struct grub_script *grub_script_create (struct grub_script_cmd *cmd,
  235. struct grub_script_mem *mem);
  236. struct grub_lexer_param *grub_script_lexer_init (struct grub_parser_param *parser,
  237. char *script,
  238. grub_reader_getline_t getline_func,
  239. void *getline_func_data);
  240. void grub_script_lexer_fini (struct grub_lexer_param *);
  241. void grub_script_lexer_ref (struct grub_lexer_param *);
  242. void grub_script_lexer_deref (struct grub_lexer_param *);
  243. unsigned grub_script_lexer_record_start (struct grub_parser_param *);
  244. char *grub_script_lexer_record_stop (struct grub_parser_param *, unsigned);
  245. int grub_script_lexer_yywrap (struct grub_parser_param *, const char *input);
  246. void grub_script_lexer_record (struct grub_parser_param *, char *);
  247. /* Functions to track allocated memory. */
  248. struct grub_script_mem *grub_script_mem_record (struct grub_parser_param *state);
  249. struct grub_script_mem *grub_script_mem_record_stop (struct grub_parser_param *state,
  250. struct grub_script_mem *restore);
  251. void *grub_script_malloc (struct grub_parser_param *state, grub_size_t size);
  252. /* Functions used by bison. */
  253. union YYSTYPE;
  254. int grub_script_yylex (union YYSTYPE *, struct grub_parser_param *);
  255. int grub_script_yyparse (struct grub_parser_param *);
  256. void grub_script_yyerror (struct grub_parser_param *, const char *);
  257. /* Commands to execute, don't use these directly. */
  258. grub_err_t grub_script_execute_cmdline (struct grub_script_cmd *cmd);
  259. grub_err_t grub_script_execute_cmdlist (struct grub_script_cmd *cmd);
  260. grub_err_t grub_script_execute_cmdif (struct grub_script_cmd *cmd);
  261. grub_err_t grub_script_execute_cmdfor (struct grub_script_cmd *cmd);
  262. grub_err_t grub_script_execute_cmdwhile (struct grub_script_cmd *cmd);
  263. /* Execute any GRUB pre-parsed command or script. */
  264. grub_err_t grub_script_execute (struct grub_script *script);
  265. grub_err_t grub_script_execute_sourcecode (const char *source);
  266. grub_err_t grub_script_execute_new_scope (const char *source, int argc, char **args);
  267. /* Break command for loops. */
  268. grub_err_t grub_script_break (grub_command_t cmd, int argc, char *argv[]);
  269. /* SHIFT command for GRUB script. */
  270. grub_err_t grub_script_shift (grub_command_t cmd, int argc, char *argv[]);
  271. /* SETPARAMS command for GRUB script functions. */
  272. grub_err_t grub_script_setparams (grub_command_t cmd, int argc, char *argv[]);
  273. /* RETURN command for functions. */
  274. grub_err_t grub_script_return (grub_command_t cmd, int argc, char *argv[]);
  275. /* This variable points to the parsed command. This is used to
  276. communicate with the bison code. */
  277. extern struct grub_script_cmd *grub_script_parsed;
  278. /* The function description. */
  279. struct grub_script_function
  280. {
  281. /* The name. */
  282. char *name;
  283. /* The script function. */
  284. struct grub_script *func;
  285. /* The next element. */
  286. struct grub_script_function *next;
  287. unsigned executing;
  288. };
  289. typedef struct grub_script_function *grub_script_function_t;
  290. extern grub_script_function_t grub_script_function_list;
  291. #define FOR_SCRIPT_FUNCTIONS(var) for((var) = grub_script_function_list; \
  292. (var); (var) = (var)->next)
  293. grub_script_function_t grub_script_function_create (struct grub_script_arg *functionname,
  294. struct grub_script *cmd);
  295. void grub_script_function_remove (const char *name);
  296. grub_script_function_t grub_script_function_find (char *functionname);
  297. grub_err_t grub_script_function_call (grub_script_function_t func,
  298. int argc, char **args);
  299. char **
  300. grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count);
  301. grub_err_t
  302. grub_normal_parse_line (char *line,
  303. grub_reader_getline_t getline_func,
  304. void *getline_func_data);
  305. static inline struct grub_script *
  306. grub_script_ref (struct grub_script *script)
  307. {
  308. if (script)
  309. script->refcnt++;
  310. return script;
  311. }
  312. static inline void
  313. grub_script_unref (struct grub_script *script)
  314. {
  315. if (! script)
  316. return;
  317. if (script->refcnt == 0)
  318. grub_script_free (script);
  319. else
  320. script->refcnt--;
  321. }
  322. #endif /* ! GRUB_NORMAL_PARSER_HEADER */