#!/usr/bin/env python ''' * Copyright (C) 1999 Bill Allen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. glc.py - compile glade to python version 0.2 usage: python glc.py test.glade test.py Takes test.glade as an input file and produces test.py as an output. Additionally, if signals are defined it will produce a file named by concatenatinge the name of the top level widget and "Handlers.py". Thus if the top level widget is window1, a file called "window1Handlers.py" will be produced if it does not already exist. As each handler is encountered, the handler file will be searched for a handler of the given name. If found, nothing more is done. Otherwise, if not found a function of the proper signature that does nothing will be produced. One can thus implement each signal handler in the handlers file. This implementation will never be overwritten. For a signal like: add on_combo1_add window1 the following code will be generated in the handlers file: def on_combo1_add(widget, mainObj): pass mainObj is a reference to the class produced in test.py. Each widget defined in test.glade is an attribute of mainObj. For example, given a glade definition: GtkSpinButton spinbutton1 ... one can refer to this widget like this: def on_hscale1_value_changed(widget, mainObj): mainObj.spinbutton1.set_value(30) Option Menus are a slight variation on this notion. For the following glade xml: GtkOptionMenu SetVariableMenu 2 0 False False True Display Market Sector Maturity Quality 0 The following code is generated in the handlers file: def on_SetVariableMenu_menu_activate(widget, mainObj): pass in which the mainObj is a list with two elements the first being a reference to the main class produced in the generated as the mainObj scalar in other signals, the second of which is the menu item number. Thus: def on_SetVariableMenu_menu_activate(widget, mainObj): mainObj[0].SetVariableMenuState = mainObj[1] assigns the selected menu item to an attribute variable of the main GUI object. Note on this implementation: Many widgets are not yet handled. I have been implementing them on an as needed basis. Styles are not handled. I have yet to figure out how to create one using pygtk. Patches are accepted and requests for new widgets will also be gladly accepted. ''' from xmllib import TestXMLParser from string import strip,join,split,atoi from gtk import * import sys import re fo = sys.stdout indentlevel = 0 handler = "" handlername = "" gtkpy_main = "" gtkpy_window = "" #gtkpy_styles = {} debug = 0 def setindentlevel(lev): global indentlevel indentlevel = lev def getindentlevel(): global indentlevel return indentlevel def readHandler(): global handlername global handler try: f = open(handlername, 'r') lines = f.readlines() handler = join(lines, '') f.close() except IOError, msg: print "handler file: " + handlername + " does not exist, will create" def writeHandler(): global handlername global handler try: f = open(handlername, 'w') f.write(handler) f.close except IOError, msg: print "handler file: " + handlername + " could not write" def updateHandler(name): global handler pattern = "def " + name if (re.compile(pattern).search(handler) == None): handler = handler + "\n" + pattern + "(widget, mainObj):\n" + " pass" + "\n" def doMain(name): global handler global gtkpy_main global gtkpy_window gtkpy_main = name + "Widget" gtkpy_window = name pattern = "def mainfunc" if (re.compile(pattern).search(handler) == None): handler = "from gtk import mainquit" + handler handler = handler + "\n" + pattern + "(" + gtkpy_main + "):\n" + " " + gtkpy_main + "." + name + ".connect(\"delete_event\", mainquit)\n" def quote(s): return "\"" + s + "\"" def indent(level): global fo s = map(lambda x: " ", range(0, level)) fo.write(join(s, '')) def putline(line = ""): global fo indent(getindentlevel()) fo.write(line + "\n") def buggerarg(arg): rval = "" if (arg == "True"): rval = "TRUE" elif (arg == "False"): rval = "FALSE" elif (arg[0:4] == "GTK_"): rval = arg[4:] else: rval = arg return rval def putparams(args): rlist = map(buggerarg, args) return join(rlist, ", ") def putfunc(obj, funcname, args): rval = obj + "." + funcname + "(" rval = rval + putparams(args) rval = rval + ")" putline(rval) class WidgetStack: def __init__(self): self.stack = [] def push(self, widget): self.stack.append(widget); def top(self): l = len(self.stack) if (l == 0): raise OverflowError, "Badly formed xml" rval = self.stack[l - 1] return rval def pop(self): l = len(self.stack) if (l == 0): raise OverflowError, "Badly formed xml" rval = self.stack[l - 1] del self.stack[l - 1] return rval class gObject: def __init__(self): self.children = [] self.attribs = {} self.parent = self def add(self, child): self.children.append(child) child.parent = self def attrib(self, attrib, value): self.attribs[strip(attrib)] = strip(value) def dump(self, level): indent(level) print "=====",self.otype,"=====" for attrib in self.attribs.keys(): indent(level) print attrib, " = ", self.attribs[attrib] for child in self.children: child.dump(level + 1) def generate(self): for child in self.children: child.generate() def getattrib(self, attrib, default): rval = default if (self.attribs.has_key(attrib)): rval = self.attribs[attrib] return rval class gWidget(gObject): def __init__(self): gObject.__init__(self) self.otype = "gWidget" def generateHeader(self, name): global handlername handlername = name + "Handlers.py" readHandler() putline("from " + name + "Handlers import *") # putline(name + "Styles = {}") putline("class " + name + "Widget:") setindentlevel(4) putline("def __init__(self):") setindentlevel(8) # putline("global " + name + "Styles") doMain(name) def generateTest(self, name): setindentlevel(0) putline("if __name__ == '__main__':") setindentlevel(4) putline(name + "=" + name + "Widget()") putline("mainfunc(" + name + ")") putline("mainloop()") def makeGtkAdjustment(self, name): return "GtkAdjustment(" + putparams([self.getattrib("hvalue", "1"), self.getattrib("hlower", "0"), self.getattrib("hupper", "100"), self.getattrib("hstep", "1"), self.getattrib("hpage", "10"), self.getattrib("hpage_size", "10")]) + ")" def doTableChildOptions(self, expand, shrink, fill): numdone = 0 outs = "" if (expand == "True"): outs = "EXPAND" numdone = 1 if (shrink == "True"): if (numdone > 0): outs = outs + "|" outs = outs + "SHRINK" numdone = 1 if (fill == "True"): if (numdone > 0): outs = outs + "|" outs = outs + "FILL" numdone = 1 if (numdone == 0): outs = "0" return outs def generate(self): ''' The code generation for a widget includes 3 steps. The following glade definition segment will be used to illustrate these steps: GtkCombo combo1 5 0 False True add on_combo1_add window1 False True False 1. generating the widget instantiation code. In the example we will generate: combo1=GtkCombo() 2. generate code to add this object to a parent object. In the example generate: vbox1.pack_start(combo1, FALSE, TRUE, 0) 3. generate code to implement the various attributes specified for this widget: combo1.set_usize(-1, -1) combo1.set_homogeneous(FALSE) combo1.set_spacing(0) combo1.set_border_width(5) combo1.set_case_sensitive(FALSE) combo1.set_use_arrows(TRUE) combo1.set_use_arrows_always(FALSE) combo1.connect("add", on_combo1_add, self) combo1.GTKPY_MAIN = window2Widget combo1.show() ''' klass = self.attribs["class"] if (klass == "Placeholder"): return name = self.attribs["name"] # print name thisClass = eval(klass) # build the widget creation parameters into 'type' variable type = buggerarg(self.getattrib("type", "")) if (issubclass(thisClass, GtkWindow)): if (type == 'WINDOW_TOPLEVEL'): self.generateHeader(name) elif (issubclass(thisClass, GtkRadioButton)): group = self.getattrib("group", "None") if (self.parent.attribs.has_key(group)): group = self.parent.attribs[group] else: self.parent.attribs[group] = name group = "None" type = putparams([group, quote(self.attribs["label"])]) elif (issubclass(thisClass, GtkOptionMenu)): type = "" elif (issubclass(thisClass, GtkButton)): type = quote(self.attribs["label"]) elif (issubclass(thisClass, GtkMenuItem)): type = quote(self.attribs["label"]) elif (issubclass(thisClass, GtkTable)): type = putparams([self.getattrib("rows", "1"), self.getattrib("columns", "1")]) elif (issubclass(thisClass, GtkArrow)): type = putparams([self.getattrib("arrow_type", "GTK_ARROW_DOWN"), self.getattrib("shadow_type", "GTK_SHADOW_OUT")]) elif (issubclass(thisClass, GtkPixmap)): pmdirectory = "project[\"pixmaps_directory\"] + " + quote("/" + self.getattrib("filename", "")) putline("pix, mask = create_pixmap_from_xpm(" + gtkpy_window + ", None, " + pmdirectory + ")") type = putparams(["pix", "mask"]) elif (issubclass(thisClass, GtkSpinButton)): type = putparams([self.makeGtkAdjustment(name), self.getattrib("climb_rate", "1"), self.getattrib("digits", "0")]) elif (issubclass(thisClass, GtkAlignment)): type = putparams([self.getattrib("xalign", "0.5"), self.getattrib("yalign", "0.5"), self.getattrib("xscale", "1"), self.getattrib("yscale", "1")]) elif (issubclass(thisClass, GtkToolbar)): type = putparams([self.getattrib("orientation", "GTK_ORIENTATION_HORIZONTAL")]) # generate widget instantiation code if (issubclass(thisClass, GtkCList)): putline("headers = []") numcolumns = self.getattrib("columns", "1") putline(name + "=" + klass + "(" + numcolumns + ")") else: line = name + "=" + klass + "(" + type + ")" putline(line) if (self.attribs.has_key("title")): line = name + ".set_title(\"" + self.attribs["title"] + "\")" putline(line) if (debug): putline("print " + klass + "(" + type + ")") # # add this object to a parent object, if any. Each parent has it's own adding method. # note that if a child class parent has a different adding method than its parent, it # must appear first in this chain, since the parent would resolve first otherwise. # if (self.parent.attribs.has_key("name")): #print name pname = self.parent.attribs["name"] parentclass = self.parent.attribs["class"] pclass = eval(parentclass) if (issubclass(pclass, GtkBox)): padding = "0" fill = "True" expand = "True" for child in self.children: if (child.attribs.has_key("padding")): padding = child.getattrib("padding", padding) fill = child.getattrib("fill", fill) expand = child.getattrib("expand", expand) putfunc(pname, "pack_start", [name, expand, fill, padding]) elif (issubclass(pclass, GtkTable)): for child in self.children: if (child.attribs.has_key("left_attach")): left_attach = child.getattrib("left_attach", "1") right_attach = child.getattrib("right_attach", "2") top_attach = child.getattrib("top_attach", "1") bottom_attach = child.getattrib("bottom_attach", "2") xpad = child.getattrib("xpad", "0") ypad = child.getattrib("ypad", "0") xexpand = child.getattrib("xexpand", "True") yexpand = child.getattrib("yexpand", "True") xshrink = child.getattrib("xshrink", "False") yshrink = child.getattrib("yshrink", "False") xfill = child.getattrib("xfill", "True") yfill = child.getattrib("yfill", "True") xoptions = self.doTableChildOptions(xexpand, xshrink, xfill) yoptions = self.doTableChildOptions(yexpand, yshrink, yfill) putfunc(pname, "attach", [name, left_attach, right_attach, top_attach, bottom_attach, xoptions, yoptions, xpad, ypad]) elif (issubclass(pclass, GtkCList)): colnum = self.parent.getattrib("colnum", "0") putfunc(pname, "set_column_widget", [colnum, name]) self.parent.attribs["colnum"] = "%d" % (atoi(colnum) + 1) elif (issubclass(pclass, GtkNotebook)): if (self.attribs.has_key("child_name")): colnum = self.parent.getattrib("colnum", "0") label = self.getattrib("label", "label" + colnum) child = pname + ".get_nth_page(" + colnum + ")" putfunc(pname, "set_tab_label", [child, label]) self.parent.attribs["colnum"] = "%d" % (atoi(colnum) + 1) else: putfunc(pname, "add", [name]) elif (issubclass(pclass, GtkFixed)): putfunc(pname, "put", [name, self.getattrib("x", "0"), self.getattrib("y", "0")]) elif (issubclass(pclass, GtkMenuShell)): putfunc(pname, "append", [name]) elif (issubclass(pclass, GtkToolbar)): tooltip = self.getattrib("tooltip", "\"\"") putfunc(pname, "append_widget", [name, tooltip, "\"\""]) elif (issubclass(pclass, GtkScrolledWindow)): # non-scrollable widgets must be added with add_with_viewport. I'm not sure how # one can determine if a widget is scrollable other than apriori knowlege. if (issubclass(thisClass, GtkCList) or issubclass(thisClass, GtkText)): putfunc(pname, "add", [name]) else: putfunc(pname, "add_with_viewport", [name]) elif (issubclass(pclass, GtkContainer)): putfunc(pname, "add", [name]) else: print "Don't know how to add", klass, "to", parentclass # # do attributes for this object. Note that an object can have attributes set by # zero or more items below. It might have attributes set by its class, and each # of its parental classes. The evaluation order shouldn't matter. # if (issubclass(thisClass, GtkWidget)): if (self.attribs.has_key("style_name")): pass if (self.getattrib("can_focus", "FALSE") == "True"): putfunc(name, "set_flags", ["GTK_CAN_FOCUS"]) putfunc(name, "set_usize", [self.getattrib("width", "-1"), self.getattrib("height", "-1")]) if (issubclass(thisClass, GtkWindow)): shrink = self.getattrib("allow_shrink", "FALSE") grow = self.getattrib("allow_grow", "TRUE") autoshrink = self.getattrib("auto_shrink", "TRUE") putfunc(name, "set_policy", [shrink, grow, autoshrink]) position = self.getattrib("position", "GTK_WIN_POS_NONE") putfunc(name, "set_position", [position]) if (issubclass(thisClass, GtkBox)): homogeneous = self.getattrib("homogeneous", "False") putfunc(name, "set_homogeneous", [homogeneous]) spacing = self.getattrib("spacing", "0") putfunc(name, "set_spacing", [spacing]) if (issubclass(thisClass, GtkTable)): row_spacing = self.getattrib("row_spacing", "2") putfunc(name, "set_row_spacings", [row_spacing]) column_spacing = self.getattrib("column_spacing", "2") putfunc(name, "set_col_spacings", [column_spacing]) if (issubclass(thisClass, GtkNotebook)): putfunc(name, "set_tab_pos", [self.getattrib("tab_pos", "GTK_POS_TOP")]) putfunc(name, "set_scrollable", [self.getattrib("scrollable", "False")]) putfunc(name, "set_show_border", [self.getattrib("show_border", "True")]) putfunc(name, "set_show_tabs", [self.getattrib("show_tabs", "True")]) putfunc(name, "set_tab_border", [self.getattrib("tab_border", "3")]) if (self.getattrib("popup_enable", "True") == "True"): putfunc(name, "popup_enable", []) else: putfunc(name, "popup_disable", []) if (issubclass(thisClass, GtkContainer)): if (self.attribs.has_key("border_width")): putfunc(name, "set_border_width", [self.getattrib("border_width", "0")]) if (issubclass(thisClass, GtkCombo)): case_sensitive = self.getattrib("case_sensitive", "False") putfunc(name, "set_case_sensitive", [case_sensitive]) use_arrows = self.getattrib("use_arrows", "True") putfunc(name, "set_use_arrows", [use_arrows]) use_arrows_always = self.getattrib("use_arrows_always", "False") putfunc(name, "set_use_arrows_always", [use_arrows_always]) if (issubclass(thisClass, GtkRuler)): metric = self.getattrib("metric", "GTK_PIXELS") putfunc(name, "set_metric", [metric]) lower = self.getattrib("lower", "0") upper = self.getattrib("upper", "10") position = self.getattrib("position", "0") max_size = self.getattrib("max_size", "10") putfunc(name, "set_range", [lower, upper, position, max_size]) if (issubclass(thisClass, GtkRange)): putfunc(name, "set_update_policy", [self.getattrib("policy", "GTK_UPDATE_CONTINUOUS")]) if (issubclass(thisClass, GtkScale)): putfunc(name, "set_draw_value", [self.getattrib("draw_value", "True")]) putfunc(name, "set_value_pos", [self.getattrib("value_pos", "GTK_POS_TOP")]) putfunc(name, "set_digits", [self.getattrib("digits", "1")]) if (issubclass(thisClass, GtkRange)): putfunc(name, "set_adjustment", [self.makeGtkAdjustment(name)]) if (issubclass(thisClass, GtkButtonBox)): putfunc(name, "set_child_size_default", [self.getattrib("child_min_width", "-1"), self.getattrib("child_min_height", "-1")]) putfunc(name, "set_child_ipadding_default", [self.getattrib("child_ipad_x", "0"), self.getattrib("child_ipad_y", "0")]) putfunc(name, "set_spacing", [self.getattrib("spacing", "30")]) putfunc(name, "set_layout", [self.getattrib("layout_style", "GTK_BUTTONBOX_DEFAULT_STYLE")]) if (issubclass(thisClass, GtkSpinButton)): putfunc(name, "set_numeric", [self.getattrib("numeric", "False")]) putfunc(name, "set_update_policy", [self.getattrib("update_policy", "GTK_UPDATE_IF_VALID")]) if (self.getattrib("snap", "False") == "True"): putfunc(name, "set_snap_to_ticks", []) if (issubclass(thisClass, GtkCList)): column_widths = self.getattrib("column_widths", "") cws = split(column_widths, ',') col = 0 for cw in cws: putfunc(name, "set_column_width", ["%d" % col, cw]) col = col + 1 selection = self.getattrib("selection_mode", "GTK_SELECTION_SINGLE") putfunc(name, "set_selection_mode", [selection]) show_titles = self.getattrib("show_titles", "True") if (show_titles == "True"): putfunc(name, "column_titles_show", []) else: putfunc(name, "column_titles_hide", []) shadow_type = self.getattrib("shadow_type", "GTK_SHADOW_IN") putfunc(name, "set_shadow_type", [selection]) if (issubclass(thisClass, GtkLabel)): putfunc(name, "set_text", [quote(self.getattrib("label", "label"))]) putfunc(name, "set_justify", [self.getattrib("justify", "GTK_JUSTIFY_CENTER")]) if (issubclass(thisClass, GtkFrame)): putfunc(name, "set_shadow_type", [quote(self.getattrib("shadow_type", "GTK_SHADOW_ETCHED_IN"))]) if (self.attribs.has_key("label")): putfunc(name, "set_label", [quote(self.getattrib("label", ""))]) putfunc(name, "set_label_align", [self.getattrib("label_xalign", "-1"), self.getattrib("label_yalign", "-1")]) if (issubclass(thisClass, GtkCurve)): putfunc(name, "set_curve_type", [self.getattrib("curve_type", "GTK_CURVE_TYPE_SPLINE")]) putfunc(name, "set_range", [self.getattrib("min_x", "0"), self.getattrib("max_x", "1"), self.getattrib("min_y", "0"), self.getattrib("max_y", "1")]) if (issubclass(thisClass, GtkText)): putfunc(name, "set_editable", [self.getattrib("editable", "True")]) if (issubclass(thisClass, GtkEntry)): putfunc(name, "set_editable", [self.getattrib("editable", "True")]) putfunc(name, "set_visibility", [self.getattrib("text_visible", "True")]) if (self.attribs.has_key("text_max_length")): putfunc(name, "set_max_length", [self.getattrib("text_max_length", "0")]) putfunc(name, "set_text", [quote(self.getattrib("text", ""))]) if (issubclass(thisClass, GtkScrolledWindow)): putfunc(name, "set_policy", [self.getattrib("hscrollbar_policy", "GTK_POLICY_AUTOMATIC"), self.getattrib("vscrollbar_policy", "GTK_POLICY_AUTOMATIC")]) if (issubclass(thisClass, GtkToolbar)): putfunc(name, "set_orientation", [self.getattrib("orientation", "GTK_ORIENTATION_HORIZONTAL")]) if (issubclass(thisClass, GtkOptionMenu)): putline("menu = GtkMenu()") menuitems = split(self.getattrib("items", "item 1\nitem 2\item3\n"), '\n') putline("menulist = []") num = 0 for item in menuitems: putline("menuitem = GtkMenuItem(\"" + item + "\")") putline("menuitemdata = [self, " + "%d" % num + "]") num = num + 1 handler = "on_" + name + "_menu_activate" putline("menuitem.connect(\"activate\", " + handler + ", menuitemdata)") updateHandler(handler) putline("menulist.append(\"" + item + "\")") putline("menu.append(menuitem)") putline("menuitem.show()") putline(name + ".menulist = menulist") putfunc(name, "set_menu", ["menu"]) putfunc(name, "set_history", [self.getattrib("initial_choice", "0")]) if (issubclass(thisClass, GtkMisc)): putfunc(name, "set_alignment", [self.getattrib("xalign", "0.5"), self.getattrib("yalign", "0.5")]) putfunc(name, "set_padding", [self.getattrib("xpad", "0"), self.getattrib("ypad", "0")]) gObject.generate(self) putfunc(name, "show", []) putline("self." + name + "=" + name) if (issubclass(thisClass, GtkWindow)): if (type == 'WINDOW_TOPLEVEL'): self.generateTest(name) class gProject(gObject): def __init__(self): gObject.__init__(self) self.otype = "gProject" def generate(self): putline("project = {}") for attrib in self.attribs.keys(): putline("project[" + quote(attrib) + "] = " + quote(self.attribs[attrib])) class gChild(gObject): def __init__(self): gObject.__init__(self) self.otype = "gChild" class gSignal(gObject): def __init__(self): gObject.__init__(self) self.otype = "gSignal" def generate(self): if (self.parent.otype != "gAccelerator"): name = self.attribs["name"] handler = self.attribs["handler"] parent = self.parent.attribs["name"] putfunc(parent, "connect", [quote(name), handler, "self"]) putline(parent + ".GTKPY_MAIN = " + gtkpy_main) updateHandler(handler) class gAccelerator(gObject): def __init__(self): gObject.__init__(self) self.otype = "gAccelerator" def generate(self): gObject.generate(self) class gStyle(gObject): def __init__(self): gObject.__init__(self) self.otype = "style" def generate(self): # name = self.getattrib("style_name", "") # if (not gtkpy_styles.has_key(name)): # gtkpy_styles[name] = self gObject.generate(self) class gGTKInterface(gObject): def __init__(self): gObject.__init__(self) self.otype = "GTK-Interface" class gTop(gObject): def __init__(self): gObject.__init__(self) self.otype = "Top" def generate(self): putline( "import sys") putline( "from gtk import *") putline( "import GtkExtra") putline() gObject.generate(self) class GladeParser(TestXMLParser): def __init__(self): TestXMLParser.__init__(self) self.wStack = WidgetStack() self.top = gTop() self.wStack.push(self.top) self.data = "" def dump(self): self.top.dump(0) def generate(self): self.top.generate() writeHandler() def handle_data(self, data): self.data = self.data + data def flush(self): data = self.data if data: self.data = "" def start_thingy(self, w): self.flush() self.wStack.top().add(w) self.wStack.push(w) def end_thingy(self): self.flush() self.wStack.pop() def start_project(self, attrs): self.start_thingy(gProject()) def end_project(self): self.end_thingy() def start_widget(self, attrs): self.start_thingy(gWidget()) def end_widget(self): self.end_thingy() def start_Signal(self, attrs): self.start_thingy(gSignal()) def end_Signal(self): self.end_thingy() def start_signal(self, attrs): self.start_thingy(gSignal()) def end_signal(self): self.end_thingy() def start_child(self, attrs): self.start_thingy(gChild()) def end_child(self): self.end_thingy() def start_Accelerator(self, attrs): self.start_thingy(gAccelerator()) def end_Accelerator(self): self.end_thingy() def start_style(self, attrs): self.start_thingy(gStyle()) def end_style(self): self.end_thingy() def start_GTKInterface(self, attrs): self.start_thingy(gGTKInterface()) def end_GTKInterface(self): self.end_thingy() def unknown_starttag(self, tag, attrs): if (tag == "GTK-Interface"): self.start_GTKInterface(attrs) else: self.flush() def unknown_endtag(self, tag): if (tag == "GTK-Interface"): self.end_GTKInterface() else: self.wStack.top().attrib(tag, self.data) self.flush() #testdoc = """\ # # # #]> #Hello, world! #""" import xmllib def test(args = None): outfile = 'testglc.py' global fo if not args: args = sys.argv[1:] if args: file = args[0] else: file = 'test.glade' if file == '-': f = sys.stdin else: try: f = open(file, 'r') except IOError, msg: print file, ":", msg sys.exit(1) if (len(args) > 1): outfile = args[1] if outfile != '-': try: fo = open(outfile, 'w') except IOError, msg: print file, ":", msg sys.exit(1) data = f.read() if f is not sys.stdin: f.close() x = GladeParser() print "#", try: for c in data: x.feed(c) x.close() except RuntimeError, msg: print msg sys.exit(1) #x.dump() x.generate() if __name__ == '__main__': test()