Hi,

This patch generate handler.lst using the register functions. In
normal.mod, it reads handler.lst and register commands like:

terminal_output.gfxterm
...

It also rename static function get_line in normal/main.c to grub_file_getline.

-- 
Bean
diff --git a/Makefile.in b/Makefile.in
index d6e55e7..b24ee2e 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -139,7 +139,7 @@ include $(srcdir)/conf/$(target_cpu)-$(platform).mk
 ### General targets.
 
 CLEANFILES += $(pkglib_DATA) $(pkgdata_DATA)
-pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst
+pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst handler.lst
 moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep.awk
 	cat $(DEFSYMFILES) /dev/null \
 	  | $(AWK) -f $(srcdir)/genmoddep.awk $(UNDSYMFILES) > $@ \
@@ -154,6 +154,9 @@ fs.lst: $(FSFILES)
 partmap.lst: $(PARTMAPFILES)
 	cat $^ /dev/null | sort > $@
 
+handler.lst: $(HANDLERFILES)
+	cat $^ /dev/null | sort > $@
+
 ifeq (, $(UNIFONT_BDF))
 else
 
diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
index 7dfb854..bd20238 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -206,7 +206,7 @@ linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
 # keep it simpler to update to different architectures.
 #
 normal_mod_SOURCES = normal/cmdline.c normal/command.c normal/datetime.c \
-	normal/completion.c normal/execute.c		 		\
+	normal/completion.c normal/execute.c normal/handler.c 		\
 	normal/function.c normal/lexer.c normal/main.c normal/menu.c	\
 	normal/menu_text.c						\
 	normal/color.c							\
diff --git a/config.h.in b/config.h.in
index 1a9ed68..e825f7c 100644
--- a/config.h.in
+++ b/config.h.in
@@ -4,9 +4,6 @@
    prefixed with an asterisk */
 #undef ABSOLUTE_WITHOUT_ASTERISK
 
-/* Define if building universal (internal helper macro) */
-#undef AC_APPLE_UNIVERSAL_BUILD
-
 /* Define it to \"addr32\" or \"addr32;\" to make GAS happy */
 #undef ADDR32
 
@@ -121,52 +118,17 @@
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 
-/* Enable extensions on AIX 3, Interix.  */
-#ifndef _ALL_SOURCE
-# undef _ALL_SOURCE
-#endif
+/* Define to 1 if your processor stores words with the most significant byte
+   first (like Motorola and SPARC, unlike Intel and VAX). */
+#undef WORDS_BIGENDIAN
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
 /* Enable GNU extensions on systems that have them.  */
 #ifndef _GNU_SOURCE
 # undef _GNU_SOURCE
 #endif
-/* Enable threading extensions on Solaris.  */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# undef _POSIX_PTHREAD_SEMANTICS
-#endif
-/* Enable extensions on HP NonStop.  */
-#ifndef _TANDEM_SOURCE
-# undef _TANDEM_SOURCE
-#endif
-/* Enable general extensions on Solaris.  */
-#ifndef __EXTENSIONS__
-# undef __EXTENSIONS__
-#endif
-
-
-/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
-   significant byte first (like Motorola and SPARC, unlike Intel). */
-#if defined AC_APPLE_UNIVERSAL_BUILD
-# if defined __BIG_ENDIAN__
-#  define WORDS_BIGENDIAN 1
-# endif
-#else
-# ifndef WORDS_BIGENDIAN
-#  undef WORDS_BIGENDIAN
-# endif
-#endif
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-#undef _FILE_OFFSET_BITS
 
 /* Define for large files, on AIX-style hosts. */
 #undef _LARGE_FILES
-
-/* Define to 1 if on MINIX. */
-#undef _MINIX
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
-   this defined. */
-#undef _POSIX_1_SOURCE
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-#undef _POSIX_SOURCE
diff --git a/genhandlerlist.sh b/genhandlerlist.sh
new file mode 100644
index 0000000..6446a98
--- /dev/null
+++ b/genhandlerlist.sh
@@ -0,0 +1,23 @@
+#! /bin/sh
+#
+# Copyright (C) 2009  Free Software Foundation, Inc.
+#
+# This script is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Read source code from stdin and detect command names.
+
+module=$1
+
+grep -v "^#" | sed -n \
+ -e "/grub_parser_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/parser.\1: $module/;p;}" \
+ -e "/grub_reader_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/reader.\1: $module/;p;}" \
+ -e "/grub_term_register_input *( *\"/{s/.*( *\"\([^\"]*\)\".*/terminal_input.\1: $module/;p;}" \
+ -e "/grub_term_register_output *( *\"/{s/.*( *\"\([^\"]*\)\".*/terminal_output.\1: $module/;p;}" \
+ -e "/grub_menu_viewer_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/menu_viewer.\1: $module/;p;}"
diff --git a/genmk.rb b/genmk.rb
index 62e5066..c676a67 100644
--- a/genmk.rb
+++ b/genmk.rb
@@ -143,6 +143,7 @@ endif
       command = 'cmd-' + obj.suffix('lst')
       fs = 'fs-' + obj.suffix('lst')
       partmap = 'partmap-' + obj.suffix('lst')
+      handler = 'handler-' + obj.suffix('lst')
       dep = deps[i]
       flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end
       extra_flags = if /\.S$/ =~ src then '-DASM_FILE=1' else '' end
@@ -152,10 +153,11 @@ endif
 	$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -MD -c -o $@ $<
 -include #{dep}
 
-CLEANFILES += #{command} #{fs} #{partmap}
+CLEANFILES += #{command} #{fs} #{partmap} #{handler}
 COMMANDFILES += #{command}
 FSFILES += #{fs}
 PARTMAPFILES += #{partmap}
+HANDLERFILES += #{handler}
 
 #{command}: #{src} $(#{src}_DEPENDENCIES) gencmdlist.sh
 	set -e; \
@@ -172,6 +174,10 @@ PARTMAPFILES += #{partmap}
 	  $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
 	  | sh $(srcdir)/genpartmaplist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
 
+#{handler}: #{src} $(#{src}_DEPENDENCIES) genhandlerlist.sh
+	set -e; \
+	  $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
+	  | sh $(srcdir)/genhandlerlist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
 
 "
     end.join('')
diff --git a/include/grub/normal.h b/include/grub/normal.h
index 27978dc..e62e433 100644
--- a/include/grub/normal.h
+++ b/include/grub/normal.h
@@ -26,6 +26,7 @@
 #include <grub/env.h>
 #include <grub/menu.h>
 #include <grub/command.h>
+#include <grub/file.h>
 
 /* The maximum size of a command-line.  */
 #define GRUB_MAX_CMDLINE	1600
@@ -103,6 +104,10 @@ char *grub_env_write_color_highlight (struct grub_env_var *var, const char *val)
 void grub_parse_color_name_pair (grub_uint8_t *ret, const char *name);
 void grub_wait_after_message (void);
 
+char *grub_file_getline (grub_file_t file);
+void read_handler_list (void);
+void free_handler_list (void);
+
 #ifdef GRUB_UTIL
 void grub_normal_init (void);
 void grub_normal_fini (void);
diff --git a/include/grub/term.h b/include/grub/term.h
index 6a35664..d12d0f0 100644
--- a/include/grub/term.h
+++ b/include/grub/term.h
@@ -219,13 +219,15 @@ extern struct grub_handler_class EXPORT_VAR(grub_term_input_class);
 extern struct grub_handler_class EXPORT_VAR(grub_term_output_class);
 
 static inline void
-grub_term_register_input (grub_term_input_t term)
+grub_term_register_input (const char *name __attribute__ ((unused)),
+			  grub_term_input_t term)
 {
   grub_handler_register (&grub_term_input_class, GRUB_AS_HANDLER (term));
 }
 
 static inline void
-grub_term_register_output (grub_term_output_t term)
+grub_term_register_output (const char *name __attribute__ ((unused)),
+			   grub_term_output_t term)
 {
   grub_handler_register (&grub_term_output_class, GRUB_AS_HANDLER (term));
 }
diff --git a/normal/handler.c b/normal/handler.c
new file mode 100755
index 0000000..f9c2bd6
--- /dev/null
+++ b/normal/handler.c
@@ -0,0 +1,229 @@
+/* handler.c - support handler loading */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+#include <grub/handler.h>
+#include <grub/normal.h>
+
+struct grub_handler_list
+{
+  struct grub_handler_list *next;
+  char *name;
+  grub_command_t cmd;
+};
+
+static grub_list_t handler_list;
+
+static grub_err_t
+grub_handler_cmd (struct grub_command *cmd,
+		  int argc __attribute__ ((unused)),
+		  char **args __attribute__ ((unused)))
+{
+  char *p;
+  grub_handler_class_t class;
+  grub_handler_t handler;
+
+  p = grub_strchr (cmd->name, '.');
+  if (! p)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid command name");
+
+  if (cmd->data)
+    {
+      if (! grub_dl_get (cmd->data))
+	{
+	  grub_dl_t mod;
+
+	  mod = grub_dl_load (cmd->data);
+	  if (mod)
+	    grub_dl_ref (mod);
+	  else
+	    return grub_errno;
+	}
+      grub_free (cmd->data);
+      cmd->data = 0;
+    }
+
+  *p = 0;
+  class = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_handler_class_list),
+				cmd->name);
+  *p = '.';
+
+  if (! class)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found");
+
+
+  handler = grub_named_list_find (GRUB_AS_NAMED_LIST (class->handler_list),
+				  p + 1);
+  if (! handler)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found");
+
+  grub_handler_set_current (class, handler);
+
+  return 0;
+}
+
+static void
+insert_handler (char *name, char *module)
+{
+  struct grub_handler_list *item;
+  char *data;
+
+  item = grub_malloc (sizeof (*item));
+  if (! item)
+    return;
+
+  item->name = grub_strdup (name);
+  if (! item->name)
+    {
+      grub_free (item);
+      return;
+    }
+
+  if (module)
+    {
+      data = grub_strdup (module);
+      if (! data)
+	{
+	  grub_free (item->name);
+	  grub_free (item);
+	  return;
+	}
+    }
+  else
+    data = 0;
+
+  item->cmd = grub_register_command (item->name, grub_handler_cmd, 0,
+				     "Set active handler");
+  if (! item->cmd)
+    {
+      grub_free (data);
+      grub_free (item->name);
+      grub_free (item);
+      return;
+    }
+
+  item->cmd->data = data;
+  grub_list_push (&handler_list, GRUB_AS_LIST (item));
+}
+
+/* Read the file handler.lst for auto-loading.  */
+void
+read_handler_list (void)
+{
+  const char *prefix;
+  static int first_time = 1;
+  const char *class_name;
+
+  auto int iterate_handler (grub_handler_t handler);
+  int iterate_handler (grub_handler_t handler)
+    {
+      char name[grub_strlen (class_name) + grub_strlen (handler->name) + 2];
+
+      grub_strcpy (name, class_name);
+      grub_strcat (name, ".");
+      grub_strcat (name, handler->name);
+
+      insert_handler (name, 0);
+      return 0;
+    }
+
+  auto int iterate_class (grub_handler_class_t class);
+  int iterate_class (grub_handler_class_t class)
+    {
+      class_name = class->name;
+      grub_list_iterate (GRUB_AS_LIST (class->handler_list),
+			 (grub_list_hook_t) iterate_handler);
+
+      return 0;
+    }
+
+  /* Make sure that this function does not get executed twice.  */
+  if (! first_time)
+    return;
+  first_time = 0;
+
+  prefix = grub_env_get ("prefix");
+  if (prefix)
+    {
+      char *filename;
+
+      filename = grub_malloc (grub_strlen (prefix) + sizeof ("/handler.lst"));
+      if (filename)
+	{
+	  grub_file_t file;
+
+	  grub_sprintf (filename, "%s/handler.lst", prefix);
+	  file = grub_file_open (filename);
+	  if (file)
+	    {
+	      char *buf = 0;
+	      for (;; grub_free(buf))
+		{
+		  char *p;
+
+		  buf = grub_file_getline (file);
+
+		  if (! buf)
+		    break;
+
+		  if (! grub_isgraph (buf[0]))
+		    continue;
+
+		  p = grub_strchr (buf, ':');
+		  if (! p)
+		    continue;
+
+		  *p = '\0';
+		  while (*++p == ' ')
+		    ;
+
+		  insert_handler (buf, p);
+		}
+
+	      grub_file_close (file);
+	    }
+	  else
+	    grub_list_iterate (GRUB_AS_LIST (grub_handler_class_list),
+			       (grub_list_hook_t) iterate_class);
+	  grub_free (filename);
+	}
+    }
+
+  /* Ignore errors.  */
+  grub_errno = GRUB_ERR_NONE;
+}
+
+void
+free_handler_list (void)
+{
+  struct grub_handler_list *item;
+
+  while ((item = grub_list_pop (&handler_list)) != 0)
+    {
+      grub_free (item->cmd->data);
+      grub_unregister_command (item->cmd);
+      grub_free (item->name);
+      grub_free (item);
+    }
+}
diff --git a/normal/main.c b/normal/main.c
index 9f906d8..5aaeb5f 100644
--- a/normal/main.c
+++ b/normal/main.c
@@ -37,8 +37,8 @@ static grub_fs_module_list_t fs_module_list = 0;
 #define GRUB_DEFAULT_HISTORY_SIZE	50
 
 /* Read a line from the file FILE.  */
-static char *
-get_line (grub_file_t file)
+char *
+grub_file_getline (grub_file_t file)
 {
   char c;
   int pos = 0;
@@ -310,7 +310,7 @@ read_config_file (const char *config, int nested)
     {
       currline++;
 
-      *line = get_line (file);
+      *line = grub_file_getline (file);
       if (! *line)
 	return grub_errno;
 
@@ -343,7 +343,7 @@ read_config_file (const char *config, int nested)
       int startline;
       char *cmdline;
 
-      cmdline = get_line (file);
+      cmdline = grub_file_getline (file);
       if (!cmdline)
 	break;
 
@@ -475,7 +475,7 @@ read_command_list (void)
 		  grub_command_t cmd;
 		  int prio = 0;
 
-		  buf = get_line (file);
+		  buf = grub_file_getline (file);
 
 		  if (! buf)
 		    break;
@@ -594,7 +594,7 @@ read_fs_list (void)
 		  char *q;
 		  grub_fs_module_list_t fs_mod;
 		  
-		  buf = get_line (file);
+		  buf = grub_file_getline (file);
 		  if (! buf)
 		    break;
 
@@ -650,6 +650,7 @@ grub_normal_execute (const char *config, int nested, int batch)
 
   read_command_list ();
   read_fs_list ();
+  read_handler_list ();
   
   if (config)
     {
@@ -754,4 +755,5 @@ GRUB_MOD_FINI(normal)
 {
   grub_set_history (0);
   grub_unregister_command (cmd_normal);
+  free_handler_list ();
 }
diff --git a/term/efi/console.c b/term/efi/console.c
index 0bf2449..3322b8f 100644
--- a/term/efi/console.c
+++ b/term/efi/console.c
@@ -366,8 +366,8 @@ grub_console_init (void)
       return;
     }
 
-  grub_term_register_input (&grub_console_term_input);
-  grub_term_register_output (&grub_console_term_output);
+  grub_term_register_input ("console", &grub_console_term_input);
+  grub_term_register_output ("console", &grub_console_term_output);
 }
 
 void
diff --git a/term/gfxterm.c b/term/gfxterm.c
index dacecf4..4f74346 100644
--- a/term/gfxterm.c
+++ b/term/gfxterm.c
@@ -1155,7 +1155,7 @@ static grub_command_t cmd;
 GRUB_MOD_INIT(term_gfxterm)
 {
   my_mod = mod;
-  grub_term_register_output (&grub_video_term);
+  grub_term_register_output ("gfxterm", &grub_video_term);
   cmd = grub_register_command ("background_image",
 			       grub_gfxterm_background_image_cmd,
 			       0, "Load background image for active terminal");
diff --git a/term/i386/pc/at_keyboard.c b/term/i386/pc/at_keyboard.c
index ff5246d..0b2a06d 100644
--- a/term/i386/pc/at_keyboard.c
+++ b/term/i386/pc/at_keyboard.c
@@ -226,7 +226,7 @@ static struct grub_term_input grub_at_keyboard_term =
 
 GRUB_MOD_INIT(at_keyboard)
 {
-  grub_term_register_input (&grub_at_keyboard_term);
+  grub_term_register_input ("at_keyboard", &grub_at_keyboard_term);
 }
 
 GRUB_MOD_FINI(at_keyboard)
diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c
index 6c6be46..c880595 100644
--- a/term/i386/pc/console.c
+++ b/term/i386/pc/console.c
@@ -46,8 +46,8 @@ static struct grub_term_output grub_console_term_output =
 void
 grub_console_init (void)
 {
-  grub_term_register_output (&grub_console_term_output);
-  grub_term_register_input (&grub_console_term_input);
+  grub_term_register_output ("console", &grub_console_term_output);
+  grub_term_register_input ("console", &grub_console_term_input);
 }
 
 void
diff --git a/term/i386/pc/serial.c b/term/i386/pc/serial.c
index eacff06..757a06c 100644
--- a/term/i386/pc/serial.c
+++ b/term/i386/pc/serial.c
@@ -577,8 +577,8 @@ grub_cmd_serial (grub_extcmd_t cmd,
       /* Register terminal if not yet registered.  */
       if (registered == 0)
 	{
-	  grub_term_register_input (&grub_serial_term_input);
-	  grub_term_register_output (&grub_serial_term_output);
+	  grub_term_register_input ("serial", &grub_serial_term_input);
+	  grub_term_register_output ("serial", &grub_serial_term_output);
 	  registered = 1;
 	}
     }
diff --git a/term/i386/pc/vesafb.c b/term/i386/pc/vesafb.c
index 75cbd75..edd0b1a 100644
--- a/term/i386/pc/vesafb.c
+++ b/term/i386/pc/vesafb.c
@@ -599,7 +599,7 @@ static struct grub_term_output grub_vesafb_term =
 GRUB_MOD_INIT(vesafb)
 {
   my_mod = mod;
-  grub_term_register_output (&grub_vesafb_term);
+  grub_term_register_output ("vesafb", &grub_vesafb_term);
 }
 
 GRUB_MOD_FINI(vesafb)
diff --git a/term/i386/pc/vga.c b/term/i386/pc/vga.c
index af880d5..dd2e25c 100644
--- a/term/i386/pc/vga.c
+++ b/term/i386/pc/vga.c
@@ -25,7 +25,6 @@
 #include <grub/types.h>
 #include <grub/dl.h>
 #include <grub/misc.h>
-#include <grub/normal.h>
 #include <grub/font.h>
 
 #define DEBUG_VGA	0
@@ -509,7 +508,7 @@ GRUB_MOD_INIT(vga)
 #ifndef GRUB_UTIL
   my_mod = mod;
 #endif
-  grub_term_register_output (&grub_vga_term);
+  grub_term_register_output ("vga", &grub_vga_term);
 }
 
 GRUB_MOD_FINI(vga)
diff --git a/term/i386/pc/vga_text.c b/term/i386/pc/vga_text.c
index e067ed6..170f74d 100644
--- a/term/i386/pc/vga_text.c
+++ b/term/i386/pc/vga_text.c
@@ -168,7 +168,7 @@ static struct grub_term_output grub_vga_text_term =
 
 GRUB_MOD_INIT(vga_text)
 {
-  grub_term_register_output (&grub_vga_text_term);
+  grub_term_register_output ("vga_text", &grub_vga_text_term);
 }
 
 GRUB_MOD_FINI(vga_text)
diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c
index 70fda9a..0cc0924 100644
--- a/term/ieee1275/ofconsole.c
+++ b/term/ieee1275/ofconsole.c
@@ -420,8 +420,8 @@ static struct grub_term_output grub_ofconsole_term_output =
 void
 grub_console_init (void)
 {
-  grub_term_register_input (&grub_ofconsole_term_input);
-  grub_term_register_output (&grub_ofconsole_term_output);
+  grub_term_register_input ("ofconsole", &grub_ofconsole_term_input);
+  grub_term_register_output ("ofconsole", &grub_ofconsole_term_output);
 }
 
 void
diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c
index 07f7d08..6caa2ff 100644
--- a/term/usb_keyboard.c
+++ b/term/usb_keyboard.c
@@ -248,7 +248,7 @@ GRUB_MOD_INIT(usb_keyboard)
   (void) mod;			/* To stop warning. */
 
   grub_usb_hid ();
-  grub_term_register_input (&grub_usb_keyboard_term);
+  grub_term_register_input ("usb_keyboard", &grub_usb_keyboard_term);
 }
 
 GRUB_MOD_FINI(usb_keyboard)
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to