### General targets.
CLEANFILES += $(pkglib_DATA) $(pkgdata_DATA) po/*.mo
-pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst
+pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst
moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep.awk
cat $(DEFSYMFILES) /dev/null \
| $(AWK) -f $(srcdir)/genmoddep.awk $(UNDSYMFILES) > $@ \
handler.lst: $(HANDLERFILES)
cat $^ /dev/null | sort > $@
+terminal.lst: $(TERMINALFILES)
+ cat $^ /dev/null | sort > $@
+
parttool.lst: $(PARTTOOLFILES)
cat $^ /dev/null | sort | uniq > $@
#include <grub/i18n.h>
#include <grub/misc.h>
+struct grub_term_autoload *grub_term_input_autoload = NULL;
+struct grub_term_autoload *grub_term_output_autoload = NULL;
+
grub_err_t
grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
int i;
grub_term_input_t term;
+ struct grub_term_autoload *aut;
if (argc == 0)
{
grub_puts_ (N_ ("Available input terminals:"));
FOR_DISABLED_TERM_INPUTS(term)
grub_printf ("%s ", term->name);
+ /* This is quadratic but we don't expect mode than 30 terminal
+ modules ever. */
+ for (aut = grub_term_input_autoload; aut; aut = aut->next)
+ {
+ FOR_DISABLED_TERM_INPUTS(term)
+ if (grub_strcmp (term->name, aut->name) == 0)
+ break;
+ if (!term)
+ FOR_ACTIVE_TERM_INPUTS(term)
+ if (grub_strcmp (term->name, aut->name) == 0)
+ break;
+ if (!term)
+ grub_printf ("%s ", aut->name);
+ }
grub_printf ("\n");
return GRUB_ERR_NONE;
}
for (; i < argc; i++)
{
- FOR_DISABLED_TERM_INPUTS(term)
- if (grub_strcmp (args[i], term->name) == 0)
- break;
- if (term == 0)
- FOR_ACTIVE_TERM_INPUTS(term)
- if (grub_strcmp (args[i], term->name) == 0)
+ int again = 0;
+ while (1)
+ {
+ FOR_DISABLED_TERM_INPUTS(term)
+ if (grub_strcmp (args[i], term->name) == 0)
+ break;
+ if (term == 0)
+ FOR_ACTIVE_TERM_INPUTS(term)
+ if (grub_strcmp (args[i], term->name) == 0)
+ break;
+ if (term)
break;
- if (term == 0)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
- args[i]);
+ if (again)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
+ args[i]);
+ for (aut = grub_term_input_autoload; aut; aut = aut->next)
+ if (grub_strcmp (args[i], aut->name) == 0)
+ {
+ grub_dl_t mod;
+ mod = grub_dl_load (aut->modname);
+ if (mod)
+ grub_dl_ref (mod);
+ grub_errno = GRUB_ERR_NONE;
+ break;
+ }
+ if (!aut)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
+ args[i]);
+ again = 1;
+ }
}
if (grub_strcmp (args[0], "--append") == 0)
{
int i;
grub_term_output_t term;
+ struct grub_term_autoload *aut;
if (argc == 0)
{
grub_puts_ (N_ ("Available output terminals:"));
FOR_DISABLED_TERM_OUTPUTS(term)
grub_printf ("%s ", term->name);
+ /* This is quadratic but we don't expect mode than 30 terminal
+ modules ever. */
+ for (aut = grub_term_output_autoload; aut; aut = aut->next)
+ {
+ FOR_DISABLED_TERM_OUTPUTS(term)
+ if (grub_strcmp (term->name, aut->name) == 0)
+ break;
+ if (!term)
+ FOR_ACTIVE_TERM_OUTPUTS(term)
+ if (grub_strcmp (term->name, aut->name) == 0)
+ break;
+ if (!term)
+ grub_printf ("%s ", aut->name);
+ }
grub_printf ("\n");
return GRUB_ERR_NONE;
}
for (; i < argc; i++)
{
- FOR_DISABLED_TERM_OUTPUTS(term)
- if (grub_strcmp (args[i], term->name) == 0)
- break;
- if (term == 0)
- FOR_ACTIVE_TERM_OUTPUTS(term)
- if (grub_strcmp (args[i], term->name) == 0)
+ int again = 0;
+ while (1)
+ {
+ FOR_DISABLED_TERM_OUTPUTS(term)
+ if (grub_strcmp (args[i], term->name) == 0)
+ break;
+ if (term == 0)
+ FOR_ACTIVE_TERM_OUTPUTS(term)
+ if (grub_strcmp (args[i], term->name) == 0)
+ break;
+ if (term)
break;
- if (term == 0)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
- args[i]);
+ if (again)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
+ args[i]);
+ for (aut = grub_term_output_autoload; aut; aut = aut->next)
+ if (grub_strcmp (args[i], aut->name) == 0)
+ {
+ grub_dl_t mod;
+ mod = grub_dl_load (aut->modname);
+ if (mod)
+ grub_dl_ref (mod);
+ grub_errno = GRUB_ERR_NONE;
+ break;
+ }
+ if (!aut)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
+ args[i]);
+ again = 1;
+ }
}
if (grub_strcmp (args[0], "--append") == 0)
fs = 'fs-' + obj.suffix('lst')
partmap = 'partmap-' + obj.suffix('lst')
handler = 'handler-' + obj.suffix('lst')
+ terminal = 'terminal-' + obj.suffix('lst')
parttool = 'parttool-' + obj.suffix('lst')
video = 'video-' + obj.suffix('lst')
dep = deps[i]
PARTTOOLFILES += #{parttool}
PARTMAPFILES += #{partmap}
HANDLERFILES += #{handler}
+TERMINALFILES += #{terminal}
VIDEOFILES += #{video}
#{command}: #{src} $(#{src}_DEPENDENCIES) gencmdlist.sh
$(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)
+#{terminal}: #{src} $(#{src}_DEPENDENCIES) genterminlist.sh
+ set -e; \
+ $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
+ | sh $(srcdir)/genterminallist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
+
#{video}: #{src} $(#{src}_DEPENDENCIES) genvideolist.sh
set -e; \
$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
--- /dev/null
+#! /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_term_register_input *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $module/;p;}" \
+ -e "/grub_term_register_input_active *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $module/;p;}" \
+ -e "/grub_term_register_output *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $module/;p;}" \
+ -e "/grub_term_register_output_active *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $module/;p;}"
void read_crypto_list (void);
+void read_terminal_list (void);
+
void grub_set_more (int onoff);
#ifdef GRUB_UTIL
extern void (*EXPORT_VAR (grub_newline_hook)) (void);
+struct grub_term_autoload
+{
+ struct grub_term_autoload *next;
+ char *name;
+ char *modname;
+};
+
+extern struct grub_term_autoload *grub_term_input_autoload;
+extern struct grub_term_autoload *grub_term_output_autoload;
+
/* For convenience. */
#define GRUB_TERM_ASCII_CHAR(c) ((c) & 0xff)
read_fs_list ();
read_handler_list ();
read_crypto_list ();
+ read_terminal_list ();
grub_command_execute ("parser.grub", 0, 0);
reader_nested = nested;
#include <grub/term.h>
#include <grub/misc.h>
#include <grub/mm.h>
+#include <grub/file.h>
+#include <grub/dl.h>
+#include <grub/env.h>
+#include <grub/normal.h>
/* The amount of lines counted by the pager. */
static unsigned grub_more_lines;
ptr++;
}
}
+
+static void
+grub_terminal_autoload_free (void)
+{
+ struct grub_term_autoload *cur, *next;
+ unsigned i;
+ for (i = 0; i < 2; i++)
+ for (cur = i ? grub_term_input_autoload : grub_term_output_autoload;
+ cur; cur = next)
+ {
+ next = cur->next;
+ grub_free (cur->name);
+ grub_free (cur->modname);
+ grub_free (cur);
+ }
+ grub_term_input_autoload = NULL;
+ grub_term_output_autoload = NULL;
+}
+
+
+/* Read the file terminal.lst for auto-loading. */
+void
+read_terminal_list (void)
+{
+ const char *prefix;
+ char *filename;
+ grub_file_t file;
+ char *buf = NULL;
+
+ prefix = grub_env_get ("prefix");
+ if (!prefix)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ return;
+ }
+
+ filename = grub_malloc (grub_strlen (prefix) + sizeof ("/crypto.lst"));
+ if (!filename)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ return;
+ }
+
+ grub_sprintf (filename, "%s/terminal.lst", prefix);
+ file = grub_file_open (filename);
+ if (!file)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ return;
+ }
+
+ /* Override previous terminal.lst. */
+ grub_terminal_autoload_free ();
+
+ for (;; grub_free (buf))
+ {
+ char *p, *name;
+ struct grub_term_autoload *cur;
+ struct grub_term_autoload **target = NULL;
+
+ buf = grub_file_getline (file);
+
+ if (! buf)
+ break;
+
+ switch (buf[0])
+ {
+ case 'i':
+ target = &grub_term_input_autoload;
+ break;
+
+ case 'o':
+ target = &grub_term_output_autoload;
+ break;
+ }
+ if (!target)
+ continue;
+
+ name = buf + 1;
+
+ p = grub_strchr (name, ':');
+ if (! p)
+ continue;
+
+ *p = '\0';
+ while (*++p == ' ')
+ ;
+
+ cur = grub_malloc (sizeof (*cur));
+ if (!cur)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ continue;
+ }
+
+ cur->name = grub_strdup (name);
+ if (! name)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ grub_free (cur);
+ continue;
+ }
+
+ cur->modname = grub_strdup (p);
+ if (! cur->modname)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ grub_free (cur);
+ grub_free (cur->name);
+ continue;
+ }
+ cur->next = *target;
+ *target = cur;
+ }
+
+ grub_file_close (file);
+
+ grub_errno = GRUB_ERR_NONE;
+}