From cacac0ba12074dab75918e08c53a07b6fc65cc83 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 10 Dec 2005 09:00:55 +0000 Subject: [PATCH] interpret menu statements in isolinux configuration file to hide menu items and set human-readable labels --- boot.config | 1 + common.inc | 31 +++----- install.config | 1 + menuconfig.inc | 188 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 198 insertions(+), 23 deletions(-) create mode 100644 menuconfig.inc diff --git a/boot.config b/boot.config index 8dde58f..56373d5 100644 --- a/boot.config +++ b/boot.config @@ -10,6 +10,7 @@ %% include button.inc %% include help.inc %% include main.inc +%% include menuconfig.inc %% include xmenu.inc %% include dia_video.inc %% include dia_lang.inc diff --git a/common.inc b/common.inc index 79e8025..97c8375 100644 --- a/common.inc +++ b/common.inc @@ -399,7 +399,9 @@ /menu.dentry exch def /menu.args exch def + menuconfig.init /menu.texts exch def + /menu.humans exch def window.main dup window.init @@ -872,30 +874,13 @@ % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - % ( text ) == > ( new_text ) +% If text is in menu.texts (it should be), return the corresponding item +% from menu.humans. Otherwise, return text as-is. /menuitemmap { - translate - dup "memtest" eq over "memtest86" eq or { pop txt_memtest return } if - syslinux { - livecd { - dup "linux" eq { pop "SUSE Linux 10.1 LiveCD (english)" return } if - dup "failsafe" eq { pop "LiveCD - Safe Settings" return } if - dup "linux2" eq { pop "SUSE Linux 10.1 LiveCD (deutsch)" return } if - dup "failsaf2" eq { pop "LiveCD - Sichere Einstellungen" return } if - } { - dup "linux" eq { pop txt_install return } if - dup "failsafe" eq { pop txt_safe_install return } if - } ifelse - dup "live" eq { pop "SUSE Linux 10.1 LiveCD" return } if - dup "noacpi" eq { pop txt_noacpi_install return } if - dup "manual" eq { pop txt_manual_install return } if - dup "rescue" eq { pop txt_rescue return } if - dup "hwcheck" eq { pop "Hardware Check" return } if - dup "harddisk" eq { pop txt_boot_harddisk return } if - } { - dup "linux" eq { pop "Linux" return } if - dup "failsafe" eq { pop txt_safe_linux return } if - dup "windows" eq { pop "Windows" return } if - } ifelse + 0 menu.texts { + 2 index eq { menu.humans over get exch pop return } if + 1 add + } forall pop } def diff --git a/install.config b/install.config index 88775bd..68981b4 100644 --- a/install.config +++ b/install.config @@ -10,6 +10,7 @@ %% include button.inc %% include help.inc %% include main.inc +%% include menuconfig.inc %% include xmenu.inc %% include dia_video.inc %% include dia_lang.inc diff --git a/menuconfig.inc b/menuconfig.inc new file mode 100644 index 0000000..b17cb4f --- /dev/null +++ b/menuconfig.inc @@ -0,0 +1,188 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% Read syslinux configuration to get human-readable names for menu items, and +% to decide whether to hide menu items. The configuration used is the same as +% that used by the syslinux simple menu system, so you can use the same +% configuration file for both. +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +/menuconfig.find { + % TODO: isolinux-specific + [ "/isolinux.cfg" "/isolinux/isolinux.cfg" "/boot/isolinux/isolinux.cfg" ] { + dup filesize .undef ne { findfile return } if + pop + } forall + .undef +} def + +% Duplicate len bytes of string. +% ( string len -- string ) +/strndup { + /strndup.len exch def + /strndup.src exch cvp def + /strndup.dst strndup.len string cvp def + strndup.dst strndup.src strndup.len memcpy + strndup.dst strndup.len 0 put + strndup.dst cvs +} def + +% Force to lower case. Overwrites string. +% ( string -- string ) +/tolower { + dup length 0 eq { return } if + dup length 1 sub 0 1 rot { + over over get 32 or 2 index 3 1 roll put + } for +} def + +% Skip whitespace. Advances string. +% ( string -- string ) +/menuconfig.skipspace { + { + dup 0 get + dup 0 eq exch ' ' gt or { exit } if + 1 add + } loop +} def + +% Find the next word boundary (NUL or whitespace). +% ( string -- pos ) +/menuconfig.nextspace { + 0 { + over over get + dup 0 eq exch ' ' le or { exit } if + 1 add + } loop + exch pop +} def + +% Extract a keyword (always forced to lowercase). keyword_str must be freed. +% ( config_str -- trailing_str keyword_str ) +/menuconfig.keyword { + dup menuconfig.nextspace + over over add % get trailing string + 3 1 roll strndup tolower % get lowercase keyword string +} def + +% Extract a word. word_str must be freed. +% ( config_str -- trailing_str word_str ) +/menuconfig.word { + dup menuconfig.nextspace + over over add % get trailing string + 3 1 roll strndup % get word string +} def + +% Set the human-readable text for the current menu item. +% ( string -- ) +/menuconfig.sethuman { + menuconfig.curlabel .undef eq { pop return } if + + /menuconfig.human exch def + /menuconfig.idx 0 def + menuconfig.entries { + menuconfig.curlabel eq { + menuconfig.humans menuconfig.idx menuconfig.human put + return + } if + /menuconfig.idx inc + } forall +} def + +% Remove the current menu item from the menu. +% ( -- ) +/menuconfig.hidelabel { + menuconfig.curlabel .undef eq { return } if + + /menuconfig.idx 0 def + menuconfig.entries { + menuconfig.curlabel eq { + % Copy everything up to here into a new array. + /menuconfig.newentries menuconfig.entries length 1 sub array def + /menuconfig.newhumans menuconfig.humans length 1 sub array def + menuconfig.idx 0 ne { + 0 1 menuconfig.idx 1 sub { + menuconfig.entries over get + menuconfig.newentries 2 index rot put + menuconfig.humans over get + menuconfig.newhumans 3 1 roll put + } for + } if + + % Slide everything else down one place. + menuconfig.idx 1 menuconfig.entries length 2 sub { + menuconfig.entries over 1 add get + menuconfig.newentries 2 index rot put + menuconfig.humans over 1 add get + menuconfig.newhumans 3 1 roll put + } for + + /menuconfig.entries menuconfig.newentries def + /menuconfig.humans menuconfig.newhumans def + + return + } if + /menuconfig.idx inc + } forall +} def + +% ( menu_entries_array -- menu_humans_array menu_entries_array ) +% The returned menu_entries_array (identifiers) and menu_humans_array +% (human-readable names) will have any hidden entries removed. +/menuconfig.init { + dup length array /menuconfig.entries exch def + dup length array /menuconfig.humans exch def + + % copy input array into menuconfig.entries; initialise menuconfig.humans + /menuconfig.idx 0 def + { + dup menuconfig.entries menuconfig.idx rot put + menuconfig.humans menuconfig.idx rot put + /menuconfig.idx inc + } forall + + % we only understand syslinux configuration + syslinux not { + menuconfig.humans menuconfig.entries return + } if + + % load configuration file; return if not found + menuconfig.find dup .undef eq { + menuconfig.humans menuconfig.entries return + } if + /menuconfig.file exch cvs def + + /menuconfig.curlabel .undef def + + menuconfig.file { + % skip over any NULs we've left behind; exit if there's really no more + % memory left to go + { + dup cvp length 0 eq { exit } if + dup 0 get 0 ne { exit } if + 1 add + } loop + dup cvp length 0 eq { exit } if + + % break lines at \r or \n + dup "\x0d" strstr dup 0 ne { 1 sub over exch 0 put } { pop } ifelse + dup "\n" strstr dup 0 ne { 1 sub over exch 0 put } { pop } ifelse + + menuconfig.skipspace menuconfig.keyword + dup "label" eq { + over menuconfig.skipspace /menuconfig.curlabel exch def + } if + dup "menu" eq { + over menuconfig.skipspace menuconfig.keyword + dup "label" eq { over menuconfig.skipspace menuconfig.sethuman } if + dup "hide" eq { menuconfig.hidelabel } if + free rot pop exch + } if + free + + % skip to end of line + dup length add + } loop free + + menuconfig.humans menuconfig.entries +} def