diff options
author | Murali Krishnan Ganapathy <gmurali@cs.uchicago.edu> | 2006-01-08 15:29:11 -0600 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2006-01-09 11:21:51 -0800 |
commit | aad150e5df7c229962d16fb5936901b9ea970b59 (patch) | |
tree | 927e77156dd38f8dce9b4f8eb3ffb0d41913d3b4 /menu | |
parent | becc57991cb724d7888f0d6fefd368f5a4c1815b (diff) | |
download | syslinux-aad150e5df7c229962d16fb5936901b9ea970b59.tar.gz |
Add missing files to menu subdirectory
Just realised that the patch I sent before did not contain the new files added. I am attaching the new files (to be put in "menu" subdirectory).
- Murali
Diffstat (limited to 'menu')
-rw-r--r-- | menu/CHANGES | 10 | ||||
-rw-r--r-- | menu/MENU_FORMAT | 68 | ||||
-rw-r--r-- | menu/TODO | 9 | ||||
-rw-r--r-- | menu/menugen.py | 241 | ||||
-rw-r--r-- | menu/test.menu | 61 |
5 files changed, 379 insertions, 10 deletions
diff --git a/menu/CHANGES b/menu/CHANGES index da7fc90f..ede6a4fc 100644 --- a/menu/CHANGES +++ b/menu/CHANGES @@ -1,10 +1,10 @@ Changes in v1.2 --------------- -* Allowed menu's to have names. Submenu's can be referred to by names instead - of their index in the menu system. This allows user to refer to submenus - which are not yet part of the menusystem. -* menugen.py: Python script for converting menu's specified in a given format - to corresponding C source code +* Allowed menu's to have names. Submenu's can be referred to by names + instead of their index in the menu system. This allows user to refer + to submenus which are not yet part of the menusystem. +* menugen.py: Python script for converting .menu files to C source code + See MENU_FORMAT for the format of .menu files Changes in v1.1 --------------- diff --git a/menu/MENU_FORMAT b/menu/MENU_FORMAT new file mode 100644 index 00000000..e34ebf4e --- /dev/null +++ b/menu/MENU_FORMAT @@ -0,0 +1,68 @@ +A .menu file can be used to describe basic menu structures which can be converted into +C code which can then be compiled into a .c32 file for use with SYSLINUX. The format +of a .menu file is similar to an ini file, but with important differences. + +COMMENTS and Blank lines +------------------------ +Lines starting with # and ; are treated as comments. +Blank lines are used to separate the attributes of one menu item +from another. Multiple blank lines are equivalent to a single one. +In other contexts Blank lines are not significant. + +Menus +----- +Each menu declaration starts with a line containing the name of menu in [ ]. +This name is used for internal purposes only and is not visible to the user of +the system. + +The menu declaration is followed by lines which set the attributes of the menu. +This is followed by a blank line and followed by declaration of menu items in +that menu. + +Currently supported menu attributes are +title: the title of this menu +row,col: position where menu should be displayed (defaults to system choosing optimal place) + + +Global Settings +--------------- +All lines which occur before the first menu declaration is considered as +a global declaration. Currently supported global settings are + +title: the title of the whole menu system +top,left,bot,right: limits of the window in which menu system should use to display + menu. Defaults to 1,1,23,78 + +Menu item +--------- +Each menu item is declared by setting the following attributes + +item: The string displayed to the user +info: Additional information displayed in the status bar +type: exitmenu,submenu or run indicating whether this item represents + an entry which exits this menu, goes to a sub menu or + executes something in SYSLINUX +data: In case of exitmenu, this has no meaning + In case of submenu, this is the name of the submenu + In case of run, this is string to be passed to SYSLINUX for execution + +-------------------------------------------------------- + +GLOBAL SETTINGS + +[menuname1] + +MENUSETTINGS + +ITEMATTR + +... + +[menuname2] + +MENUSETTINGS + +ITEMATTR + +ITEMATTR + @@ -1,8 +1,7 @@ -* Read menu structure from config files - - This will eliminate the need for recompiling the code, especially - for the simple menus -* Features to add - - Parse commandline arguments +* Write COMBOOT code to read .menu files and parse them directly + - take the name of menu file to parse from commandline +* menugen.py is still useful as user can see what the C code will + be and modify that as required. * Help support - Beef up help.c so that the text file can be larger than one page, and user can scroll down page to view extra text. diff --git a/menu/menugen.py b/menu/menugen.py new file mode 100644 index 00000000..a868d2a3 --- /dev/null +++ b/menu/menugen.py @@ -0,0 +1,241 @@ +#!/usr/bin/env python + +import sys, string + +TEMPLATE_HEADER=""" +/* -*- c -*- ------------------------------------------------------------- * + * + * Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved + * + * 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, Inc., 53 Temple Place Ste 330, + * Boston MA 02111-1307, USA; either version 2 of the License, or + * (at your option) any later version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#include "menu.h" +#include "com32io.h" +#include <string.h> + +int main(void) +{ + t_menuitem * curr; + + // Change the video mode here + // setvideomode(0) + + // Set the title and window size + +""" + + +TEMPLATE_FOOTER=""" + curr = showmenus(find_menu_num("main")); // Initial menu is the one called "main" + + if (curr) + { + if (curr->action == OPT_RUN) + { + if (issyslinux()) runsyslinuxcmd(curr->data); + else csprint(curr->data,0x07); + return 1; + } + csprint("Error in programming!",0x07); + } + return 0; +} +""" + +class Menusystem: + def __init__(self): + self.menus = [] + self.types = {"run" : "OPT_RUN","exitmenu":"OPT_EXITMENU","submenu":"OPT_SUBMENU"} + self.init_entry() + self.init_menu() + self.init_system() + self.vtypes = string.join(self.types.keys()," OR ") + self.vattrs = string.join(filter(lambda x: x[0] != "_", self.entry.keys())," OR ") + self.mattrs = string.join(filter(lambda x: x[0] != "_", self.menu.keys())," OR ") + self.itemtemplate = ' add_item("%(item)s","%(info)s",%(type)s,"%(data)s",0);\n' + self.menutemplate = '\n add_named_menu("%(name)s","%(title)s",-1);\n' + self.systemplate = '\n init_menusystem(%(title)s);\n set_window_size(%(top)s,%(left)s,%(bot)s,%(right)s);\n' + + def init_entry(self): + self.entry = { "item" : "", + "info" : "", + "data" : "", + "_updated" : None, # has this dictionary been updated + "type" : "run" } + + def init_menu(self): + self.menu = {"title" : "", + "row" : "0xFF", # let system decide position + "col" : "0xFF", + "_updated" : None, + "name" : "" } + + def init_system(self): + self.system = { "title" : "", + "top" : "1", "left" : "1" , "bot" : "23", "right":"79" } + + def add_menu(self,name): + self.add_item() + self.init_menu() + self.menu["name"] = name + self.menu["_updated"] = 1 + self.menus.append( (self.menu,[]) ) + + def add_item(self): + if self.menu["_updated"]: # menu details have changed + self.menus[-1][0].update(self.menu) + self.init_menu() + if self.entry["_updated"]: + if not self.entry["info"]: + self.entry["info"] = self.entry["data"] + if not self.menus: + print "Error before line %d" % self.lineno + print "REASON: menu must be declared before a menu item is declared" + sys.exit(1) + self.menus[-1][1].append(self.entry) + self.init_entry() + + # remove quotes if reqd + def rm_quote(self,str): + str = str .strip() + if (str[0] == str[-1]) and (str[0] in ['"',"'"]): # remove quotes + str = str[1:-1] + return str + + def set_item(self,name,value): + if not self.entry.has_key(name): + msg = ["Unknown attribute %s in line %d" % (name,self.lineno)] + msg.append("REASON: Attribute must be one of %s" % self.vattrs) + return string.join(msg,"\n") + if name=="type" and not self.types.has_key(value): + msg = [ "Unrecognized type %s in line %d" % (value,self.lineno)] + msg.append("REASON: Valid types are %s" % self.vtypes) + return string.join(msg,"\n") + self.entry[name] = self.rm_quote(value) + self.entry["_updated"] = 1 + return "" + + def set_menu(self,name,value): + # no current menu yet. We are probably in global section + if not self.menus: return "Error" + if not self.menu.has_key(name): + return "Error" + self.menu[name] = self.rm_quote(value) + self.menu["_updated"] = 1 + return "" + + def set_system(self,name,value): + if not self.system.has_key(name): + return "Error" + self.system[name] = self.rm_quote(value) + + def set(self,name,value): + msg = self.set_item(name,value) + # if valid item attrbute done + if not msg: return + + # check if attr is of menu + err = self.set_menu(name,value) + if not err: return + + # check if global attribute + err = self.set_system(name,value) + if not err: return + + # all errors so return item's error message + print msg + sys.exit(1) + + def print_entry(self,entry,fd): + entry["type"] = self.types[entry["type"]] + fd.write(self.itemtemplate % entry) + + def print_menu(self,menu,fd): + if menu["name"] == "main": self.foundmain = 1 + fd.write(self.menutemplate % menu) + if (menu["row"] != "0xFF") or (menu["col"] != "0xFF"): + fd.write(' set_menu_pos(%(row)s,%(col)s);\n' % menu) + + # parts of C code which set attrs for entire menu system + def print_system(self,fd): + if self.system["title"]: + self.system["title"] = '"%s"' % self.system["title"] + else: self.system["title"] = "NULL" + fd.write(self.systemplate % self.system) + + def output(self,filename): + fd = open(filename,"w") + self.foundmain = None + fd.write(TEMPLATE_HEADER) + self.print_system(fd) + for (menu,items) in self.menus: + self.print_menu(menu,fd) + for entry in items: self.print_entry(entry,fd) + fd.write(TEMPLATE_FOOTER) + fd.close() + if not self.foundmain: + print "main menu not found" + sys.exit(1) + + def input(self,filename): + fd = open(filename,"r") + self.lineno = 0 + for line in fd.readlines(): + self.lineno = self.lineno + 1 + if line and line[-1] in ["\r","\n"]: line = line[:-1] + if line and line[-1] in ["\r","\n"]: line = line[:-1] + if line and line[0] in ["#",";"]: continue + + try: + # blank line -> starting a new entry + if not line: + self.add_item() + continue + + # starting a new section? + if line[0] == "[" and line[-1] == "]": + self.add_menu(line[1:-1]) + continue + + # add property of current entry + pos = line.find("=") # find the first = in string + if pos < 0: + print "Syntax error in line %d" % self.lineno + print "REASON: non-section lines must be of the form ATTRIBUTE=VALUE" + sys.exit(1) + attr = line[:pos].strip().lower() + value = line[pos+1:].strip() + self.set(attr,value) + except: + print "Error while parsing line %d: %s" % (self.lineno,line) + raise + fd.close() + self.add_item() + + +def usage(): + print sys.argv[0]," inputfile outputfile" + print "inputfile is the ini-like file declaring menu structure" + print "outputfile is the C source which can be compiled" + sys.exit(1) + +def main(): + if len(sys.argv) <> 3: usage() + inst = Menusystem() + inst.input(sys.argv[1]) + inst.output(sys.argv[2]) + +if __name__ == "__main__": + main() + + diff --git a/menu/test.menu b/menu/test.menu new file mode 100644 index 00000000..66b26584 --- /dev/null +++ b/menu/test.menu @@ -0,0 +1,61 @@ +# choose default title +title = "A test of the test.menu file" +top = 1 +left = 1 +bot = 23 +right = 78 + +[testing] +title = " Testing " + +item="Self Loop" +info="Go to Testing" +type=submenu +data=testing + +item="Memory Test" +info="Perform extensive memory testing" +data="memtest" + +item="Exit this menu" +info="Go one level up" +type=exitmenu + +[rescue] +title = " Rescue Options " +row = 10 +col = 10 + +item="Linux Rescue" +data="linresc" + +item="Dos Rescue" +data="dosresc" + +item="Windows Rescue" +data="winresc" + +item="Exit this menu" +info="Go one level up" +type=exitmenu + +[main] +title = " Main Menu " + +item="Prepare" +data="prep" + +item="Rescue options..." +info="Troubleshoot a system" +type=submenu +data="rescue" + +item="Testing..." +info="Options to test hardware" +type=submenu +data="testing" + +item="Exit this menu" +info="Go one level up" +type=exitmenu + |