⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flp.py

📁 minimal python variant for small footprint apps like embedded apps
💻 PY
字号:
## flp - Module to load fl forms from fd files## Jack Jansen, December 1991#import stringimport osimport sysimport FLSPLITLINE = '--------------------'FORMLINE = '=============== FORM ==============='ENDLINE = '=============================='error = 'flp.error'###################################################################    Part 1 - The parsing routines                               ##################################################################### Externally visible function. Load form.#def parse_form(filename, formname):    forms = checkcache(filename)    if forms is None:        forms = parse_forms(filename)    if forms.has_key(formname):        return forms[formname]    else:        raise error, 'No such form in fd file'## Externally visible function. Load all forms.#def parse_forms(filename):    forms = checkcache(filename)    if forms != None: return forms    fp = _open_formfile(filename)    nforms = _parse_fd_header(fp)    forms = {}    for i in range(nforms):        form = _parse_fd_form(fp, None)        forms[form[0].Name] = form    writecache(filename, forms)    return forms## Internal: see if a cached version of the file exists#MAGIC = '.fdc'_internal_cache = {}                    # Used by frozen scripts onlydef checkcache(filename):    if _internal_cache.has_key(filename):        altforms = _internal_cache[filename]        return _unpack_cache(altforms)    import marshal    fp, filename = _open_formfile2(filename)    fp.close()    cachename = filename + 'c'    try:        fp = open(cachename, 'r')    except IOError:        #print 'flp: no cache file', cachename        return None    try:        if fp.read(4) != MAGIC:            print 'flp: bad magic word in cache file', cachename            return None        cache_mtime = rdlong(fp)        file_mtime = getmtime(filename)        if cache_mtime != file_mtime:            #print 'flp: outdated cache file', cachename            return None        #print 'flp: valid cache file', cachename        altforms = marshal.load(fp)        return _unpack_cache(altforms)    finally:        fp.close()def _unpack_cache(altforms):        forms = {}        for name in altforms.keys():            altobj, altlist = altforms[name]            obj = _newobj()            obj.make(altobj)            list = []            for altobj in altlist:                nobj = _newobj()                nobj.make(altobj)                list.append(nobj)            forms[name] = obj, list        return formsdef rdlong(fp):    s = fp.read(4)    if len(s) != 4: return None    a, b, c, d = s[0], s[1], s[2], s[3]    return ord(a)<<24 | ord(b)<<16 | ord(c)<<8 | ord(d)def wrlong(fp, x):    a, b, c, d = (x>>24)&0xff, (x>>16)&0xff, (x>>8)&0xff, x&0xff    fp.write(chr(a) + chr(b) + chr(c) + chr(d))def getmtime(filename):    import os    from stat import ST_MTIME    try:        return os.stat(filename)[ST_MTIME]    except os.error:        return None## Internal: write cached version of the form (parsing is too slow!)#def writecache(filename, forms):    import marshal    fp, filename = _open_formfile2(filename)    fp.close()    cachename = filename + 'c'    try:        fp = open(cachename, 'w')    except IOError:        print 'flp: can\'t create cache file', cachename        return # Never mind    fp.write('\0\0\0\0') # Seek back and write MAGIC when done    wrlong(fp, getmtime(filename))    altforms = _pack_cache(forms)    marshal.dump(altforms, fp)    fp.seek(0)    fp.write(MAGIC)    fp.close()    #print 'flp: wrote cache file', cachename## External: print some statements that set up the internal cache.# This is for use with the "freeze" script.  You should call# flp.freeze(filename) for all forms used by the script, and collect# the output on a file in a module file named "frozenforms.py".  Then# in the main program of the script import frozenforms.# (Don't forget to take this out when using the unfrozen version of# the script!)#def freeze(filename):    forms = parse_forms(filename)    altforms = _pack_cache(forms)    print 'import flp'    print 'flp._internal_cache[', `filename`, '] =', altforms## Internal: create the data structure to be placed in the cache#def _pack_cache(forms):    altforms = {}    for name in forms.keys():        obj, list = forms[name]        altobj = obj.__dict__        altlist = []        for obj in list: altlist.append(obj.__dict__)        altforms[name] = altobj, altlist    return altforms## Internal: Locate form file (using PYTHONPATH) and open file#def _open_formfile(filename):    return _open_formfile2(filename)[0]def _open_formfile2(filename):    if filename[-3:] <> '.fd':        filename = filename + '.fd'    if filename[0] == '/':        try:            fp = open(filename,'r')        except IOError:            fp = None    else:        for pc in sys.path:            pn = os.path.join(pc, filename)            try:                fp = open(pn, 'r')                filename = pn                break            except IOError:                fp = None    if fp == None:        raise error, 'Cannot find forms file ' + filename    return fp, filename## Internal: parse the fd file header, return number of forms#def _parse_fd_header(file):    # First read the magic header line    datum = _parse_1_line(file)    if datum <> ('Magic', 12321):        raise error, 'Not a forms definition file'    # Now skip until we know number of forms    while 1:        datum = _parse_1_line(file)        if type(datum) == type(()) and datum[0] == 'Numberofforms':            break    return datum[1]## Internal: parse fd form, or skip if name doesn't match.# the special value None means 'allways parse it'.#def _parse_fd_form(file, name):    datum = _parse_1_line(file)    if datum <> FORMLINE:        raise error, 'Missing === FORM === line'    form = _parse_object(file)    if form.Name == name or name == None:        objs = []        for j in range(form.Numberofobjects):            obj = _parse_object(file)            objs.append(obj)        return (form, objs)    else:        for j in range(form.Numberofobjects):            _skip_object(file)    return None## Internal class: a convient place to store object info fields#class _newobj:    def add(self, name, value):        self.__dict__[name] = value    def make(self, dict):        for name in dict.keys():            self.add(name, dict[name])## Internal parsing routines.#def _parse_string(str):    if '\\' in str:        s = '\'' + str + '\''        try:            return eval(s)        except:            pass    return strdef _parse_num(str):    return eval(str)def _parse_numlist(str):    slist = string.split(str)    nlist = []    for i in slist:        nlist.append(_parse_num(i))    return nlist# This dictionary maps item names to parsing routines.# If no routine is given '_parse_num' is default._parse_func = { \        'Name':         _parse_string, \        'Box':          _parse_numlist, \        'Colors':       _parse_numlist, \        'Label':        _parse_string, \        'Name':         _parse_string, \        'Callback':     _parse_string, \        'Argument':     _parse_string }# This function parses a line, and returns either# a string or a tuple (name,value)import reprog = re.compile('^([^:]*): *(.*)')def _parse_line(line):    match = prog.match(line)    if not match:        return line    name, value = match.group(1, 2)    if name[0] == 'N':            name = string.join(string.split(name),'')            name = string.lower(name)    name = string.capitalize(name)    try:        pf = _parse_func[name]    except KeyError:        pf = _parse_num    value = pf(value)    return (name, value)def _readline(file):    line = file.readline()    if not line:        raise EOFError    return line[:-1]        def _parse_1_line(file):    line = _readline(file)    while line == '':        line = _readline(file)    return _parse_line(line)def _skip_object(file):    line = ''    while not line in (SPLITLINE, FORMLINE, ENDLINE):        pos = file.tell()        line = _readline(file)    if line == FORMLINE:        file.seek(pos)def _parse_object(file):    obj = _newobj()    while 1:        pos = file.tell()        datum = _parse_1_line(file)        if datum in (SPLITLINE, FORMLINE, ENDLINE):            if datum == FORMLINE:                file.seek(pos)            return obj        if type(datum) <> type(()) or len(datum) <> 2:            raise error, 'Parse error, illegal line in object: '+datum        obj.add(datum[0], datum[1])##################################################################   Part 2 - High-level object/form creation routines            #################################################################### External - Create a form an link to an instance variable.#def create_full_form(inst, (fdata, odatalist)):    form = create_form(fdata)    exec 'inst.'+fdata.Name+' = form\n'    for odata in odatalist:        create_object_instance(inst, form, odata)## External - Merge a form into an existing form in an instance# variable.#def merge_full_form(inst, form, (fdata, odatalist)):    exec 'inst.'+fdata.Name+' = form\n'    if odatalist[0].Class <> FL.BOX:        raise error, 'merge_full_form() expects FL.BOX as first obj'    for odata in odatalist[1:]:        create_object_instance(inst, form, odata)##################################################################   Part 3 - Low-level object/form creation routines            #################################################################### External Create_form - Create form from parameters#def create_form(fdata):    import fl    return fl.make_form(FL.NO_BOX, fdata.Width, fdata.Height)## External create_object - Create an object. Make sure there are# no callbacks. Returns the object created.#def create_object(form, odata):    obj = _create_object(form, odata)    if odata.Callback:        raise error, 'Creating free object with callback'    return obj## External create_object_instance - Create object in an instance.#def create_object_instance(inst, form, odata):    obj = _create_object(form, odata)    if odata.Callback:        cbfunc = eval('inst.'+odata.Callback)        obj.set_call_back(cbfunc, odata.Argument)    if odata.Name:        exec 'inst.' + odata.Name + ' = obj\n'## Internal _create_object: Create the object and fill options#def _create_object(form, odata):    crfunc = _select_crfunc(form, odata.Class)    obj = crfunc(odata.Type, odata.Box[0], odata.Box[1], odata.Box[2], \            odata.Box[3], odata.Label)    if not odata.Class in (FL.BEGIN_GROUP, FL.END_GROUP):        obj.boxtype = odata.Boxtype        obj.col1 = odata.Colors[0]        obj.col2 = odata.Colors[1]        obj.align = odata.Alignment        obj.lstyle = odata.Style        obj.lsize = odata.Size        obj.lcol = odata.Lcol    return obj## Internal crfunc: helper function that returns correct create function#def _select_crfunc(fm, cl):    if cl == FL.BEGIN_GROUP: return fm.bgn_group    elif cl == FL.END_GROUP: return fm.end_group    elif cl == FL.BITMAP: return fm.add_bitmap    elif cl == FL.BOX: return fm.add_box    elif cl == FL.BROWSER: return fm.add_browser    elif cl == FL.BUTTON: return fm.add_button    elif cl == FL.CHART: return fm.add_chart    elif cl == FL.CHOICE: return fm.add_choice    elif cl == FL.CLOCK: return fm.add_clock    elif cl == FL.COUNTER: return fm.add_counter    elif cl == FL.DIAL: return fm.add_dial    elif cl == FL.FREE: return fm.add_free    elif cl == FL.INPUT: return fm.add_input    elif cl == FL.LIGHTBUTTON: return fm.add_lightbutton    elif cl == FL.MENU: return fm.add_menu    elif cl == FL.POSITIONER: return fm.add_positioner    elif cl == FL.ROUNDBUTTON: return fm.add_roundbutton    elif cl == FL.SLIDER: return fm.add_slider    elif cl == FL.VALSLIDER: return fm.add_valslider    elif cl == FL.TEXT: return fm.add_text    elif cl == FL.TIMER: return fm.add_timer    else:        raise error, 'Unknown object type: ' + `cl`def test():    import time    t0 = time.time()    if len(sys.argv) == 2:        forms = parse_forms(sys.argv[1])        t1 = time.time()        print 'parse time:', 0.001*(t1-t0), 'sec.'        keys = forms.keys()        keys.sort()        for i in keys:            _printform(forms[i])    elif len(sys.argv) == 3:        form = parse_form(sys.argv[1], sys.argv[2])        t1 = time.time()        print 'parse time:', round(t1-t0, 3), 'sec.'        _printform(form)    else:        print 'Usage: test fdfile [form]'def _printform(form):    f = form[0]    objs = form[1]    print 'Form ', f.Name, ', size: ', f.Width, f.Height, ' Nobj ', f.Numberofobjects    for i in objs:        print '  Obj ', i.Name, ' type ', i.Class, i.Type        print '    Box ', i.Box, ' btype ', i.Boxtype        print '    Label ', i.Label, ' size/style/col/align ', i.Size,i.Style, i.Lcol, i.Alignment        print '    cols ', i.Colors        print '    cback ', i.Callback, i.Argument

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -