Source code for excentury.lang.cpp.aux

"""AUX CPP

Auxilary file for the cpp converter.

"""

import os
from excentury.command import error, trace, exec_cmd, date
from excentury.lang import format_input, format_return, gen_cmd
from excentury.lang import write_file
from datetime import datetime

TEMPLATE = """// File generated on {date} by xcpp.
#define XC_CPP
{preamble}{funcpre}void xc_help() {{
    fprintf(stderr,
{help});
}}
void xc_input() {{
    xc_help();
    excentury::TextInterface<excentury::dump_mode> XC_DI_(stdout);
{param}    XC_DI_.close();
}}
int main(int argc, char** argv) {{
    /*{doc}*/
    excentury::check_inputs(argc);
    excentury::print_help(argv, xc_help);
    excentury::print_inputs(argv, xc_input);
    excentury::S{load}Interface<excentury::load_mode> XC_LI_(argv[1]);
{input}    XC_LI_.close();
{body}
    excentury::{dump}Interface<excentury::dump_mode> XC_DI_({out});
    {output}
    XC_DI_.close();
}}
{funcepi}{epilog}
"""


def _format_help(func, fname):
    """Generate the help string. """
    msg = '    "program: %s-%s\\n"\n' % (fname, func.name)
    msg += '    "\\ndescription:\\n"\n    "    '
    msg += '\\n"\n    "'.join(func.doc.split('\n'))
    if func.param:
        msg += '\\n"\n    "\\nparameters:\\n"\n'
        tmp = '    "    {0}: {1}\\n"\n'
        for par in func.param:
            msg += tmp.format(par['name'], par['desc'])
        msg += '    "\\n"'
    else:
        msg += '\\n"\n    "\\n"'
    return msg


def _format_input(param):
    """Return a string with all the inputs property formatted. """
    inputs = ''
    for par in param:
        tmp = '    {type} {var}{ctor}; XC_DI_.dump({var}, "{var}"'
        if 'sample' in par:
            tmp += ', %s);\n' % par['sample']
        else:
            tmp += ');\n'
        inputs += tmp.format(type=par['type'], var=par['name'][1:-1],
                             ctor=par['ctor'])
    return inputs


def _write_file(contents, func, cfg):
    """Helper function for process_function. """
    root = cfg['xcpp']['root']
    cppdir = cfg['cpp']['dir']
    if cppdir[0] == '/' or cppdir == '.':
        base = cppdir
    else:
        base = '%s/%s' % (root, cppdir)
    filename = cfg['xcpp']['filename']
    in_fname = '%s/%s-%s.cpp' % (base, filename, func.name)
    msg = '[%d] inspecting %s-%s.cpp ... '
    trace(msg % (func.num, filename, func.name))
    write_file(in_fname, contents)
    return in_fname


def _get_exec_name(func, cfg):
    """Helper function to process_function. """
    filename = cfg['xcpp']['filename']
    root = cfg['xcpp']['root']
    bindir = cfg['cpp']['bin']
    if bindir[0] == '/' or bindir == '.':
        base = bindir
    else:
        base = '%s/%s' % (root, bindir)
    dbg = cfg['cpp']['debug'] if cfg['cpp']['debug'] != '0' else ''
    ext = cfg['cpp']['ext']
    if ext == '':
        out_fname = '%s/%s-%s%s' % (base, filename, func.name, dbg)
    else:
        out_fname = '%s/%s-%s.%s%s' % (base, filename, func.name, ext, dbg)
    return out_fname


[docs]def process_function(xcf, cfg, func): """Given a Function object from .xcpp it will create the contents of a valid cpp file that can be compiled for a valid executable. """ in_fname = cfg['xcpp']['filename'] epilog = func.epilog if epilog != '': epilog += '\n' contents = TEMPLATE.format(date=date(), pre_xc=xcf.pre_xc, preamble=xcf.preamble, help=_format_help(func, in_fname), param=_format_input(func.param), doc=func.doc, body=func.body, load=cfg['cpp']['load'].capitalize(), dump=cfg['cpp']['dump'].capitalize(), input=format_input(func.param), output=format_return(func.ret), out=func.out, funcpre=func.preamble, funcepi=epilog, epilog=xcf.epilog) in_fname = _write_file(contents, func, cfg) out_fname = _get_exec_name(func, cfg) force = cfg['cpp']['force'] make_new = True if isinstance(force, list) and (len(force) == 0 or func.num in force): pass elif force in ['True', 'true']: pass elif os.path.exists(out_fname): date_in = datetime.fromtimestamp(os.path.getmtime(in_fname)) date_out = datetime.fromtimestamp(os.path.getmtime(out_fname)) if date_in < date_out: make_new = False trace(' - skipping compilation\n') if make_new: cmd = gen_cmd(cfg, 'cpp', int(cfg['cpp']['debug'])) cmd = '%s%s -o %s' % (cmd, in_fname, out_fname) trace(' - compiling %s ... ' % in_fname) _, err, _ = exec_cmd(cmd) if err != '': msg = "\nERROR: The command\n%s\n\nreturned the following " \ "error:\n%s" % (str(cmd), str(err)) error(msg) trace('done\n')