From: Samuel Mendoza-Jonas Date: Tue, 30 Oct 2018 04:26:04 +0000 (+1100) Subject: discover: Reimplement native-parser as a Bison parser X-Git-Tag: v1.9.2~2 X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=commitdiff_plain;h=646d77d8156ad72da1c24f734a029a525ba4bed9;hp=638f16c7683db165154bbe53772c4b864f9dc90d discover: Reimplement native-parser as a Bison parser Occasionally you look at some code and realise that a) this never gets built, and b) even if it did it would never compile. Today's example is native-parser.c which we must have just assumed worked for quite a while. The native parser has bitrotted entirely and needs to be brought up to date. While we're here, lets take the chance to implement a proper grammar for it. This helps us reason more effectively about the parser, lets us extend it easily in the future, and.. I wanted to write a Bison parser too. This implements most of the old functionality, but drops off some smaller details like settings icons which needs some separate attention to bring up to date. Signed-off-by: Samuel Mendoza-Jonas --- diff --git a/Makefile.am b/Makefile.am index c0ad839..63456ca 100644 --- a/Makefile.am +++ b/Makefile.am @@ -50,6 +50,7 @@ CLEANFILES = include lib/Makefile.am include discover/grub2/Makefile.am +include discover/native/Makefile.am include discover/Makefile.am include test/Makefile.am include test/lib/Makefile.am diff --git a/discover/Makefile.am b/discover/Makefile.am index d98ebec..bfe33fa 100644 --- a/discover/Makefile.am +++ b/discover/Makefile.am @@ -55,6 +55,7 @@ discover_pb_discover_SOURCES = \ discover_pb_discover_LDADD = \ discover/grub2/grub2-parser.ro \ + discover/native/native-parser.ro \ discover/platform.ro \ $(core_lib) \ $(UDEV_LIBS) diff --git a/discover/native-parser.c b/discover/native-parser.c deleted file mode 100644 index 08309d1..0000000 --- a/discover/native-parser.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "parser.h" -#include "params.h" -#include "paths.h" - -#include -#include -#include - -static const char *conf_filename = "/boot/petitboot.conf"; - -static struct boot_option *cur_opt; -static struct device *dev; -static const char *devpath; -static int device_added; - -static int check_and_add_device(struct device *dev) -{ - if (!dev->icon_file) - dev->icon_file = strdup(generic_icon_file(guess_device_type())); - - return !add_device(dev); -} - -static int section(char *section_name) -{ - if (!device_added++ && !check_and_add_device(dev)) - return 0; - - if (cur_opt) { - add_boot_option(cur_opt); - free_boot_option(cur_opt); - } - - cur_opt = malloc(sizeof(*cur_opt)); - memset(cur_opt, 0, sizeof(*cur_opt)); - return 1; -} - - -static void set_boot_option_parameter(struct boot_option *opt, - const char *name, const char *value) -{ - if (streq(name, "name")) - opt->name = strdup(value); - - else if (streq(name, "description")) - opt->description = strdup(value); - - else if (streq(name, "image")) - opt->boot_image_file = resolve_path(value, devpath); - - else if (streq(name, "icon")) - opt->icon_file = resolve_path(value, devpath); - - else if (streq(name, "initrd")) - opt->initrd_file =resolve_path(value, devpath); - - else if (streq(name, "args")) - opt->boot_args = strdup(value); - - else - fprintf(stderr, "Unknown parameter %s\n", name); -} - -static void set_device_parameter(struct device *dev, - const char *name, const char *value) -{ - if (streq(name, "name")) - dev->name = strdup(value); - - else if (streq(name, "description")) - dev->description = strdup(value); - - else if (streq(name, "icon")) - dev->icon_file = resolve_path(value, devpath); -} - -static int parameter(char *param_name, char *param_value) -{ - if (cur_opt) - set_boot_option_parameter(cur_opt, param_name, param_value); - else - set_device_parameter(dev, param_name, param_value); - return 1; -} - - -static int native_parse(const char *device) -{ - char *filepath; - int rc; - - filepath = resolve_path(conf_filename, device); - - cur_opt = NULL; - dev = malloc(sizeof(*dev)); - memset(dev, 0, sizeof(*dev)); - dev->id = strdup(device); - - rc = pm_process(filepath, section, parameter); - if (!rc) - return 0; - - if (cur_opt) { - add_boot_option(cur_opt); - free_boot_option(cur_opt); - } - - cur_opt = NULL; - - free(filepath); - - return 1; -} - -define_parser(native, native_parse); diff --git a/discover/native/Makefile.am b/discover/native/Makefile.am new file mode 100644 index 0000000..f120e70 --- /dev/null +++ b/discover/native/Makefile.am @@ -0,0 +1,54 @@ +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +noinst_PROGRAMS += discover/native/native-parser.ro + +discover_native_native_parser_ro_SOURCES = \ + discover/native/native.h \ + discover/native/native.c \ + discover/native/native-lexer.l \ + discover/native/native-parser.y + +BUILT_SOURCES += \ + discover/native/native-parser.c \ + discover/native/native-parser.h \ + discover/native/native-lexer.h \ + discover/native/native-lexer.c + +CLEANFILES += \ + discover/native/native-parser.c \ + discover/native/native-parser.h \ + discover/native/native-lexer.c \ + discover/native/native-lexer.h + +discover_native_native_parser_ro_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -I$(top_srcdir)/discover/native \ + -I$(top_builddir)/discover/native + +discover_native_native_parser_ro_LINK = \ + $(LD) -r -o $@ + +# ylwrap doesn't handle flex header files well; use our own rule here. +discover/native/native-lexer.h discover/native/native-lexer.c: \ + $(top_srcdir)/discover/native/native-lexer.l + $(AM_V_LEX)$(LEXCOMPILE) --header-file=discover/native/native-lexer.h \ + -o discover/native/native-lexer.c $^ + +# We need to loosen our warnings for the generated lexer code. +discover/native/%native-lexer.o discover/native/native-lexer.o: \ + AM_CFLAGS += -Wno-unused-parameter -Wno-missing-prototypes \ + -Wno-missing-declarations -Wno-sign-compare + +$(discover_native_native_parser_ro_OBJECTS): discover/native/native-parser.h diff --git a/discover/native/native-lexer.l b/discover/native/native-lexer.l new file mode 100644 index 0000000..bf1408a --- /dev/null +++ b/discover/native/native-lexer.l @@ -0,0 +1,65 @@ +%{ +#include "native.h" +#include "native-parser.h" +#include + +#define YYSTYPE NSTYPE + +void yyerror(struct native_parser *parser, const char *fmt, ...); +%} + +%option nounput noinput +%option batch never-interactive +%option warn +%option noyywrap +%option reentrant +%option bison-bridge +%option yylineno +%option noyyalloc noyyfree noyyrealloc +%option extra-type="struct native_parser *" +%option prefix="n" + +%x label +%x args + +DELIM [ \t]+ +NUMBER 0|[1-9][0-9]* +WORDS [^\n]+ +NEWLINE [\n]+ + +%% + +name { BEGIN(label); return TOKEN_NAME; } +image { BEGIN(label); return TOKEN_IMAGE; } +initrd { BEGIN(label); return TOKEN_INITRD; } +args { BEGIN(label); return TOKEN_ARGS; } +dtb { BEGIN(label); return TOKEN_DTB; } +description { BEGIN(label); return TOKEN_DESCRIPTION; } +default { BEGIN(label); return TOKEN_DEFAULT; } +dev_description { BEGIN(label); return TOKEN_DEV_DESCRIPTION; } +{DELIM} { ; } +{NEWLINE} { ; } +