File:  [CENS] / python / pyGiNaC / tools / wrap_typedefs.py
Revision 1.4: download - view: text, annotated - select for diffs - revision graph
Sun Mar 18 23:40:42 2001 UTC (16 years, 8 months ago) by pearu
Branches: MAIN
CVS tags: HEAD
Impl.lots of code

#!/usr/bin/env python

import re

ok_types = [
    'int','unsigned int','long','unsigned long','double const','const std::string &',
    'bool','unsigned','double','const char *','const cln::cl_N &','void',
    'std::ostream &','std::string const &'
    ]

def fix_type(a):
    if a in ok_types:
        return a
    m = re.match(r'(?P<before>.*?)\b(?P<type>symbol|ex|numeric|expairseq|exprseq|basic|exvector|epvector|exlist|evalffunctype|matrix|lst|scalar_products|pseries|relational|expair|epplist)\b(?P<rest>.*)',a)
    if m:
        return m.group('before')+'GiNaC::'+m.group('type')+m.group('rest')
    if a == 'malloc_alloc':
        return a # ignore it
    m = re.match(r'(?P<before>.*?)\b(?P<type>series_funcp_\d+|derivative_funcp_\d+|evalf_funcp_\d+|eval_funcp_\d+|(eval|evalf|derivative|series)_funcp|)\b(?P<rest>.*)',a)
    if m:
        return m.group('before')+'GiNaC::'+m.group('type')+m.group('rest')
    print 'Not fixed:',a
    return a

def construct_vector_wrapper(name,ft,t):
    return '''\
// typedef #name# wrapper
struct #name#_wrapper: #ftype# {
\t#name#_wrapper(PyObject*, const #ftype#& v) : #ftype#(v) {}
\t#name#_wrapper(PyObject* self) : #ftype#() {}
\t#name#_wrapper(PyObject* self, const std::size_t n) : #ftype#(n) {}
\t#name#_wrapper(PyObject* self, const python::tuple seq) : #ftype#()
\t{
\t\tfor (std::size_t i = 0; i < seq.size(); i++)
\t\t\tthis->push_back(BOOST_PYTHON_CONVERSION::from_python(seq[i].get(), python::type< #type# >()));
\t}
};
void #name#_throw_index_error_if(const #ftype#& v, const std::size_t key)
{
\tif ((key >= v.size()) || (key < 0))
\t{
\t\tPyErr_SetObject(PyExc_IndexError, BOOST_PYTHON_CONVERSION::to_python(key));
\t\tthrow python::error_already_set();
\t}
}
#type# #name#_getitem (const #ftype#& v, const std::size_t key)
{
\t#name#_throw_index_error_if(v, key);
\treturn v[key];
}
void #name#_setitem(#ftype#& v, const std::size_t key, const #type# &d)
{
\t#ftype#::iterator viter = v.begin();
\t#name#_throw_index_error_if(v, key);
\tviter[key] = d;
}
void #name#_delitem(#ftype# & v, const std::size_t key)
{
\t#ftype#::iterator viter = v.begin();
\t#name#_throw_index_error_if(v, key);
\tv.erase(&viter[key]);
}
'''.replace('#name#',name).replace('#ftype#',ft).replace('#type#',t)
def construct_list_wrapper(name,ft,t):
    return '''\
// typedef #name# wrapper
struct #name#_wrapper: #ftype# {
\t#name#_wrapper(PyObject*, const #ftype#& v) : #ftype#(v) {}
\t#name#_wrapper(PyObject* self) : #ftype#() {}
\t#name#_wrapper(PyObject* self, const std::size_t n) : #ftype#(n) {}
\t#name#_wrapper(PyObject* self, const python::tuple seq) : #ftype#()
\t{
\t\tfor (std::size_t i = 0; i < seq.size(); i++)
\t\t\tthis->push_back(BOOST_PYTHON_CONVERSION::from_python(seq[i].get(),python::type< #type# >()));
\t}
};
void #name#_throw_index_error_if(const #ftype#& v, const std::size_t key)
{
\tif ((key >= v.size()) || (key < 0))
\t{
\t\tPyErr_SetObject(PyExc_IndexError, BOOST_PYTHON_CONVERSION::to_python(key));
\t\tthrow python::error_already_set();
\t}
}
#type# #name#_getitem (const #ftype#& v, const std::size_t key)
{
\t#ftype#::const_iterator viter = v.begin();
\t#name#_throw_index_error_if(v, key);
\tfor(unsigned int i = 0; i < key; i++,viter++);
\treturn *viter;
}
void #name#_setitem(#ftype#& v, const std::size_t key, const #type# &d)
{
\t#ftype#::iterator viter = v.begin();
\t#name#_throw_index_error_if(v, key);
\tfor(unsigned int i = 0; i < key; i++,viter++);
\tv.insert(viter,d);
\tviter = v.begin();
\tfor(unsigned int i = 0; i < key; i++,viter++);
\tviter++;
\tv.erase(viter);
}
void #name#_delitem(#ftype# & v, const std::size_t key)
{
\t#ftype#::iterator viter = v.begin();
\t#name#_throw_index_error_if(v, key);
\tfor(unsigned int i = 0; i < key; i++,viter++);
\tv.erase(viter);
}
'''.replace('#name#',name).replace('#ftype#',ft).replace('#type#',t)

def construct_func_wrapper(name,ft,t):
    return '''
// typedef #name# wrapper
struct #name#_wrapper: #ftype# {
\t#name#_wrapper(PyObject* self) {cout << "#name#_wrapper_constructor" << endl ;}
};
    '''.replace('#name#',name).replace('#ftype#',ft).replace('#type#',t)

fin = open('strip_ginac_rest.txt','r')
ftodo = open('todo_wtf.txt','w')
def todo(l):
    ftodo.write(l)

td_m = re.compile(r'typedef\s+(?P<type>.*?)\s+\b(?P<name>\w+)\b\s*;')
tdf_m = re.compile(r'typedef\s+(?P<type>.*?)\s*[(]\s*[*]\s*\b(?P<name>\w+)\b\s*[)]\s*[(]\s*(?P<args>.*?)\s*[)]\s*;')
#typedef ex (*evalffunctype)(void);

defs = {'classes':[],'defs':[],'wrappers':[],'proto':['\t// prototypes of typedef ... wrappers']}
ignore = []
for l in fin.xreadlines():
    m = td_m.match(l.strip())
    if m:
        n,t = m.group('name'),m.group('type').strip()
        if (n,t) in ignore: continue
        ignore.append((n,t))
        if 1 and (t[:11]=='std::vector' or t[:9]=='std::list') and n in ['exvector','epvector','exlist']:
            if t[:11]=='std::vector':
                args = [fix_type(a.strip()) for a in t[12:-1].split(',')]
                ft = 'std::vector<'+', '.join(args)+'>'
                ft = fix_type(n)
                if n=='exvector' and len(args)==2:
                    continue
            elif t[:9]=='std::list':
                args = [fix_type(a.strip()) for a in t[10:-1].split(',')]
                ft = 'std::list<'+', '.join(args)+'>'
                ft = fix_type(n)
                if n=='exlist' and len(args)==2:
                    continue
            else:
                assert 0,'unimpl.'
            r = '\tpython::class_builder<%s, %s_wrapper> %s_class(this_module, "%s");'%(ft,n,n,n)
            defs['classes'].append('\t// typedef %s'%(n))
            defs['classes'].append(r)
            defs['defs'].append('\t// typedef %s constructors'%(n))
            defs['defs'].append('\t%s_class.def(python::constructor<>());'%(n))
            defs['defs'].append('\t%s_class.def(python::constructor<const int>());'%(n))
            defs['defs'].append('\t%s_class.def(python::constructor<python::tuple>());'%(n))
            defs['defs'].append('\t// typedef %s methods'%(n))
            defs['defs'].append('\t%s_class.def(&%s::size, "__len__");'%(n,ft))
            assert len(args)==1
            if t[:11]=='std::vector':
                defs['wrappers'].append(construct_vector_wrapper(n,ft,args[0]))
            elif t[:9]=='std::list':
                defs['wrappers'].append(construct_list_wrapper(n,ft,args[0]))
            else:
                assert 0,'unimpl.'
            defs['proto'].append('\tstruct %s_wrapper;'%n)
            defs['proto'].append('\t%s %s_getitem(const %s &, const std::size_t);'%(args[0],n,ft))
            defs['proto'].append('\tvoid %s_setitem(%s &, const std::size_t, const %s &);'%(n,ft,args[0]))
            defs['proto'].append('\tvoid %s_delitem(%s &, const std::size_t);'%(n,ft))
            defs['defs'].append('\t%s_class.def(%s_getitem, "__getitem__");'%(n,n))
            defs['defs'].append('\t%s_class.def(%s_setitem, "__setitem__");'%(n,n))
            defs['defs'].append('\t%s_class.def(%s_delitem, "__delitem__");'%(n,n))
            continue
        if n in ['epp','epplist','epplistvector','epviter','spmapkey','spmap',
                 'archive_node_id','archive_atom']:
            # no need to interface
            continue
        print 'Skipped typedef:',t,n
    m = tdf_m.match(l.strip())
    if m:
        rt = m.group('type')
        n = m.group('name')
        ft = fix_type(n)
        args = [fix_type(a.strip()) for a in m.group('name').split(',')]
        if n == 'evalffunctype':
            print 'n=',n
            print 'ft=',ft
            print 'rt=',rt
            print 'args=',args
            defs['classes'].append('\t// typedef (*%s)()'%(n))
            defs['classes'].append('\tpython::class_builder<%s, %s_wrapper> %s_class(this_module, "%s");'%(ft,n,n,n))
            print defs['classes'][-1]
            defs['defs'].append('\t// typedef %s constructors'%(n))
            defs['defs'].append('\t%s_class.def(python::constructor<>());'%(n))
            defs['proto'].append('\tstruct %s_wrapper;'%n)
            defs['wrappers'].append(construct_func_wrapper(n,ft,args[0]))
    todo(l)
    
fin.close()
ftodo.close()

open('../src/typedef_class._cpp','w').write('\n'.join(defs['classes'])+'\n')
open('../src/typedef_method._cpp','w').write('\n'.join(defs['defs'])+'\n')
open('../src/typedef_wrapper._cpp','w').write('\n'.join(defs['wrappers'])+'\n')
open('../src/typedef_proto._cpp','w').write('\n'.join(defs['proto'])+'\n')

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