File:  [CENS] / python / pyGiNaC / tools / strip_ginac_h.py
Revision 1.2: download - view: text, annotated - select for diffs - revision graph
Sat Mar 10 06:04:31 2001 UTC (16 years, 8 months ago) by pearu
Branches: MAIN
CVS tags: HEAD
Created automatic wrapper generator

#!/usr/bin/env python
# Extracts:
#    public members/methods of the ginac classes and struct's.
#    functions
#    type definitions
# and saves them in a simpler format.
# Pearu Peterson, 8 March 2001

import sys,os,re,tempfile,glob

ginac_headers = '/usr/local/include/ginac/*.h'

match_class = re.compile(r'class')
match_struct = re.compile(r'struct')
match_eofclass = re.compile(r'};')
match_enum = re.compile(r'\s*(typedef|)\s+enum')
match_eofenum = re.compile(r'\s+};')
match_public = re.compile(r'public:')
match_nonpublic = re.compile(r'(private|protected):')

fout = open('strip_ginac_rest.txt','w')
f_cl = open('strip_ginac_class.txt','w')
f_cln = open('strip_ginac_classnames.txt','w')
flog = open('strip_ginac_h.log','w')

for fn in glob.glob(ginac_headers):
    fn = os.path.abspath(fn)
    if not os.path.isfile(fn):
        print >> flog, 'Nonexisting file:',fn
        continue
    fn1 = tempfile.mktemp()
    fn2 = tempfile.mktemp()
    ofn = os.path.basename(fn)+'.cl'
    #ofn2 = os.path.basename(fn)+'.ncl'
    tf = open(fn1,'w')
    f = open(fn,'r')
    pl = ''
    for l in f.xreadlines():
        l = l.rstrip()
        if not l: continue
        if l[-1] in ['\\'] or l in ['inline']:
            pl = pl + l + ' '
            continue
        else:
            l = pl + l
            pl = ''
        if l.strip() in ['class ex;','class symbol;','class lst;',
                         'class scalar_products;','namespace GiNaC {',
                         'class archive;','class numeric;','class relational;',
                         'class archive_node;','class function;',
                         'namespace cln { class cl_N; }',
                         'class add;','class registered_class_info;']:
            print >> flog, 'skipping:',l
            continue
        if l.lstrip()[0]=='#':
            print >> flog, 'skipping:',l
            continue
        tf.write(l+'\n')
    f.close()
    tf.close()
    os.system('/lib/cpp %s %s'%(fn1,fn2))
    
    tf = open(fn2,'r')
    print >> flog, 'Creating file:',ofn
    f = fout
    fl = 0
    fl2 = 0
    fl3 = 0
    fl4 = 0 # enum
    pl = ''
    for l in tf.xreadlines():
        l = l.rstrip()
        if not l: continue
        if not fl4:
            if l[-1] == ',':
                if pl:
                    pl = pl + l.lstrip() + ' '
                else:
                    pl = pl + l + ' '
                continue
            else:
                if pl:
                    l = pl + l.lstrip()
                pl = ''
        m = match_class.match(l)
        if m and l[-1]!=';':
            f = f_cl
            fl = 1
            fl3 = 1
            if l[-1]=='{': l = l[:-1]
            f.write(l+'\n')
            f_cln.write(l+'\n')
            continue
        elif match_struct.match(l):
            if l[-1]=='{': l = l[:-1]
            f = f_cl
            fl = 2
            fl3 = 1
            f.write(l+'\n')
            f_cln.write(l+'\n')
            continue
        if fl:
            m = match_eofclass.match(l)
            if m:
                fl = 0
                f = fout
            if fl==1:
                m = match_public.match(l)
                if not m:
                    print >> flog, 'Not yet public:',l
                    continue
                fl = 2
            elif fl==2:
                m = match_nonpublic.match(l)
                if m:
                    fl = 1
                    print >> flog, 'Leaving public:',l
                    continue
        else:
            print >> flog, 'Not yet class:',l
            #if not fl3:
            #    print >> flog, '     skipping'
            #    continue
        if match_public.match(l):
            print >> flog, 'Skipping:',l
            continue
        i = l.find('{')
        if i>-1 and l.strip()[0].isalpha():
            print >> flog, 'Not proto:',l
            i = l.find('{')
            if i>0:
                print >> flog, '  keeping:',l[:i]
                l = l[:i].rstrip()
        sl = l.strip()
        if sl[0]=='{':
            fl2 = 1
            print >> flog, 'Skipping block:',l
            if not l.count('{')==l.count('}'):
                continue
        if sl[-1]=='}':
            fl2 = 0
            print >> flog, 'Leaving skipping block:',l
            continue
        if fl2:
            print >> flog, 'Skipping block:',l
            continue
        m = match_enum.match(l)
        if m:
            print >> flog, 'Enum start:',l
            fl4 = 1
            enum = []
        if fl4:
            #m = match_eofenum.match(l)
            print >> flog, 'Enum:',l
            if l[-1]==';':
                enum.append(l)
                print >> flog, 'Enum block end:',l
                fl4 = 0
                print >> flog, 'Enum:',enum
                l = enum[0]+' { '+' '.join(map(lambda s:s.strip(),enum[1:]))
            else:
                enum.append(l)
                continue
        i = l.find(') :')
        if i>-1:
            print >> flog, 'Removing init:',l
            l = l[:i+1]
            print >> flog, '      keeping:',l[:i+1]
        if l[-1]!=';':
            print >> flog, 'Adding `;\' to:',l
            l = l + ';'
        if l.lstrip()[0] in [':',',','#'] or re.match(r'\s*return ',l):
            print >> flog, 'Skipping init:',l
            continue
        if l=='};':
            print >> flog, 'Skipping init:',l
            continue
        f.write(l+'\n')
    tf.close()

fout.close()
f_cl.close()
f_cln.close()
flog.close()

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>