% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - % % 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. % % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - % ( str2 str1 -- str ) /menuconfig.append { over length over length add string /menuconfig.append.tmp exch def "%s%s" menuconfig.append.tmp sprintf menuconfig.append.tmp } def % Read a configuration file. If file_name is .undef, look in some standard % places. % ( file_name -- file_contents ) /menuconfig.find { /menuconfig.find.tmp exch def menuconfig.find.tmp { [ menuconfig.find.tmp menuconfig.find.tmp "/" menuconfig.append menuconfig.find.tmp "/syslinux/" menuconfig.append menuconfig.find.tmp "/isolinux/" menuconfig.append menuconfig.find.tmp "/boot/isolinux/" menuconfig.append ] } { [ "syslinux.cfg" "/syslinux.cfg" "/syslinux/syslinux.cfg" "isolinux.cfg" "/isolinux.cfg" "/isolinux/isolinux.cfg" "/boot/isolinux/isolinux.cfg" ] } ifelse { dup filesize .undef ne { findfile cvs return } if pop } forall .undef } 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 % The gfxboot com32 module in syslinux parses the configuration file for % us, but only gives us the human-readable labels, so we may need to % translate them back. /menuconfig.idx 0 def menuconfig.humans { menuconfig.human eq { menuconfig.entries menuconfig.idx menuconfig.curlabel 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 new arrays. /menuconfig.newargs menuconfig.args length 1 sub array def /menuconfig.newentries menuconfig.entries length 1 sub array def /menuconfig.newhumans menuconfig.humans length 1 sub array def /menuconfig.newindices menuconfig.indices length 1 sub array def menuconfig.idx 0 ne { 0 1 menuconfig.idx 1 sub { menuconfig.args over get menuconfig.newargs 2 index rot put menuconfig.entries over get menuconfig.newentries 2 index rot put menuconfig.humans over get menuconfig.newhumans 2 index rot put menuconfig.indices over get menuconfig.newindices 3 1 roll put } for } if menuconfig.idx menuconfig.entries length 1 sub lt { % Slide everything else down one place. menuconfig.idx 1 menuconfig.entries length 2 sub { menuconfig.args over 1 add get menuconfig.newargs 2 index rot put menuconfig.entries over 1 add get menuconfig.newentries 2 index rot put menuconfig.humans over 1 add get menuconfig.newhumans 2 index rot put menuconfig.indices over 1 add get menuconfig.newindices 3 1 roll put } for } if /menuconfig.args menuconfig.newargs def /menuconfig.entries menuconfig.newentries def /menuconfig.humans menuconfig.newhumans def /menuconfig.indices menuconfig.newindices def return } if /menuconfig.idx inc } forall } def % ( file_name -- ) /menuconfig.parse { % load configuration file; return if not found menuconfig.find dup .undef eq { pop return } if dup { % 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 0 1 2 index length 1 sub { over over get dup '\x0d' eq exch '\n' eq or { over exch 0 put exit } { pop } ifelse } for skipspace getword tolower dup "include" eq { over skipspace getword dup menuconfig.parse } if dup "label" eq { over skipspace strdup /menuconfig.curlabel exch def } if dup "menu" eq { over skipspace getword tolower dup "label" eq { over skipspace strdup menuconfig.sethuman } if dup "hide" eq { menuconfig.hidelabel } if % items that switch between syslinux menus are unlikely to be useful % in gfxboot dup "goto" eq { menuconfig.hidelabel } if dup "exit" eq { menuconfig.hidelabel } if free rot pop exch } if dup "config" eq { % used for help menu item, not useful in gfxboot menuconfig.hidelabel } if free % skip to end of line dup length add } loop pop free } def % ( menu_entries_array menu_args_array -- menu_indices_array menu_humans_array menu_entries_array menu_args_array ) % The returned menu_args_array (kernel parameters), menu_entries_array % (identifiers), menu_humans_array (human-readable names), and % menu_indices_array (original indices) will have any hidden entries % removed. /menuconfig.init { dup length array /menuconfig.args exch def over length array /menuconfig.entries exch def over length array /menuconfig.humans exch def over length array /menuconfig.indices exch def % copy input arrays; initialise menuconfig.humans /menuconfig.idx 0 def { menuconfig.args menuconfig.idx rot put /menuconfig.idx inc } forall /menuconfig.idx 0 def { dup menuconfig.entries menuconfig.idx rot put menuconfig.humans menuconfig.idx rot put menuconfig.indices menuconfig.idx dup put /menuconfig.idx inc } forall % we only understand syslinux configuration syslinux not { menuconfig.humans menuconfig.entries menuconfig.args return } if /menuconfig.curlabel .undef def .undef menuconfig.parse menuconfig.indices menuconfig.humans menuconfig.entries menuconfig.args } def