From stefan at synopsis.fresco.org Fri Jan 2 03:58:09 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:22 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/Synopsis/Parsers/Cpp Makefile.in,1.11,1.12 cpp-posix.cc,1.2,1.3 cpp-win32.cc,1.1,1.2 cpp.cc,1.1,1.2 Message-ID: Update of /cvs/synopsis/Synopsis/Synopsis/Parsers/Cpp In directory frida:/tmp/cvs-serv28361/Synopsis/Parsers/Cpp Modified Files: Makefile.in cpp-posix.cc cpp-win32.cc cpp.cc Log Message: first working version of standalone ucpp parser Index: Makefile.in =================================================================== RCS file: /cvs/synopsis/Synopsis/Synopsis/Parsers/Cpp/Makefile.in,v retrieving revision 1.11 retrieving revision 1.12 diff -u -p -d -r1.11 -r1.12 --- Makefile.in 31 Dec 2003 16:35:38 -0000 1.11 +++ Makefile.in 2 Jan 2004 03:58:05 -0000 1.12 @@ -62,7 +62,7 @@ ucpp: $(AOBJ) $(CC) -o $@ $^ $(UCPP_SO): $(OBJ) - $(CC) -shared $(LDFLAGS) -o $@ $^ $(LIBS) + $(CXX) -shared $(LDFLAGS) -o $@ $^ $(LIBS) clean : rm -f *~ ucpp/*.o ucpp/*.go ucpp/*.a ucpp/*.ga \ Index: cpp-posix.cc =================================================================== RCS file: /cvs/synopsis/Synopsis/Synopsis/Parsers/Cpp/cpp-posix.cc,v retrieving revision 1.2 retrieving revision 1.3 diff -u -p -d -r1.2 -r1.3 --- cpp-posix.cc 18 Dec 2003 03:36:52 -0000 1.2 +++ cpp-posix.cc 2 Jan 2004 03:58:05 -0000 1.3 @@ -10,119 +10,3 @@ # include # include -#include -#include -#include -#include - -// ucpp_main is the renamed main() func of ucpp, since it is included in this -// module -extern "C" int ucpp_main(int argc, char** argv); - -const char * -RunPreprocessor(const char *preprocessor, - const char *src, const std::vector &flags, - bool verbose) -{ - static char cppfile[1024]; - strcpy(cppfile, "/tmp/synopsis-XXXXXX"); - int temp_fd = mkstemp(cppfile); - if (temp_fd == -1) - { - std::perror("RunPreprocessor"); - exit(1); - } - // Not interested in the open file, just the unique filename - close(temp_fd); - - if (preprocessor) - { - switch(fork()) - { - case 0: - { - std::vector args; - char *cc = getenv("CC"); - if (cc) - { - // separate command and arguments - do - { - args.push_back(cc); - cc = strchr(cc, ' '); // find next whitespace... - while (cc && *cc == ' ') *cc++ = '\0'; // ...and skip to next non-ws - } - while (cc && *cc != '\0'); - } - else - { - args.push_back("cpp"); - } - args.insert(args.end(), flags.begin(), flags.end()); - args.push_back("-C"); // keep comments - args.push_back("-E"); // stop after preprocessing - args.push_back("-o"); // output to... - args.push_back(cppfile); - args.push_back("-x"); // language c++ - args.push_back("c++"); - args.push_back(src); - if (verbose) - { - std::cout << "calling external preprocessor\n" << args[0]; - for (std::vector::iterator i = args.begin(); i != args.end(); ++i) - std::cout << ' ' << *i; - std::cout << std::endl; - } - args.push_back(0); - execvp(args[0], (char **)&*args.begin()); - std::perror("cannot invoke compiler"); - exit(-1); - break; - } - case -1: - std::perror("RunPreprocessor"); - exit(-1); - break; - default: - { - int status; - wait(&status); - if (status != 0) - { - if (WIFEXITED(status)) - std::cout << "exited with status " << WEXITSTATUS(status) << std::endl; - else if (WIFSIGNALED(status)) - std::cout << "stopped with status " << WTERMSIG(status) << std::endl; - exit(1); - } - } - } // switch - - } - else - { // else use ucpp - // Create argv vector - std::vector args = flags; - char *cc = getenv("CC"); - args.insert(args.begin(), cc ? cc : "ucpp"); - args.push_back("-C"); // keep comments - args.push_back("-lg"); // gcc-like line numbers - args.push_back("-o"); // output to... - args.push_back(cppfile); - args.push_back(src); - if (verbose) - { - std::cout << "calling ucpp\n"; - for (std::vector::iterator i = args.begin(); i != args.end(); ++i) - std::cout << ' ' << *i; - std::cout << std::endl; - } - - // Call ucpp - int status = ucpp_main(args.size(), (char **)&*args.begin()); - if (status != 0) - std::cerr << "ucpp returned error flag. ignoring error." << std::endl; - } - return cppfile; -} - Index: cpp-win32.cc =================================================================== RCS file: /cvs/synopsis/Synopsis/Synopsis/Parsers/Cpp/cpp-win32.cc,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- cpp-win32.cc 17 Dec 2003 15:07:24 -0000 1.1 +++ cpp-win32.cc 2 Jan 2004 03:58:05 -0000 1.2 @@ -34,42 +34,6 @@ RunPreprocessor(const char *preprocessor _splitpath(src, drive, dir, fname, ext); _makepath(cppfile, drive, dir, fname, ".i"); - if (preprocessor) - { - - std::vector args; - args.push_back("-nologo"); - args.insert(args.end(), flags.begin(), flags.end()); - args.push_back("-E"); // Use -EP if you don't want the directives #line - args.push_back("-C"); // Don't strip comments - args.push_back("-P"); // Preprocessor output to .i - args.push_back("-Tp"); // Consider source file as C++ file, - // whatever extension. -// args.push_back("-Fp"); // Preprocessor output -// args.push_back(dest); - args.push_back(src); - args.push_back((char*)0); - - if (verbose) - { - std::cout << "calling external preprocessor 'cl'\n"; - for (std::vector::iterator i = args.begin(); i != args.end(); ++i) - std::cout << ' ' << *i; - std::cout << std::endl; - } - - - int status = _spawnvp(_P_WAIT, "cl", (char **)&*args.begin()); - if(status != 0) - { - if(status == -1) perror("cannot invoke the preprocessor"); - // VIC Feb 20 1998 - // MSVC 5.0 returns non-zero exit code on normal input - if (status != 2) exit(status); - } - - } - else { // else use ucpp // Create argv vector std::vector args = flags; Index: cpp.cc =================================================================== RCS file: /cvs/synopsis/Synopsis/Synopsis/Parsers/Cpp/cpp.cc,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- cpp.cc 17 Dec 2003 15:07:24 -0000 1.1 +++ cpp.cc 2 Jan 2004 03:58:05 -0000 1.2 @@ -6,12 +6,147 @@ // see the file COPYING for details. // -#ifdef __WIN32__ +#include +#include +#include +#include +#include -# include "cpp-win32.cc" +int verbose = 0; +int debug = 0; -#else +extern "C" +{ + // ucpp_main is the renamed main() func of ucpp, since it is included in this + // module + int ucpp_main(int argc, char** argv); -# include "cpp-posix.cc" + //. This function is a callback from the ucpp code to store macro + //. expansions + void synopsis_macro_hook(const char *name, int line, int start, int end, int diff) + { + if (debug) + std::cout << "macro : " << name << ' ' << line << ' ' << start << ' ' << end << ' ' << diff << std::endl; +#if 0 + LinkMap::instance()->add(name, line, start, end, diff); +#endif + } + + //. This function is a callback from the ucpp code to store includes + void synopsis_include_hook(const char *source_file, const char *target_file, int is_macro, int is_next) + { + if (debug) + std::cout << "include : " << source_file << ' ' << target_file << ' ' << is_macro << ' ' << is_next << std::endl; +#if 0 + // There is not enough code here to make another class.. + FileFilter *filter = FileFilter::instance(); + if (!filter) return; + // Add another Include to the source's SourceFile + // We don't deal with duplicates here. The Linker's Unduplicator will + // take care of that. + //std::cout << "Include: " << source_file << " -> " << target_file << std::endl; + AST::SourceFile *file = filter->get_sourcefile(source_file); + AST::SourceFile *target = filter->get_sourcefile(target_file); + AST::Include *include = new AST::Include(target, is_macro, is_next); + file->includes().push_back(include); #endif + } + + //. This function is a callback from the ucpp code to store macro + //. definitions + void synopsis_define_hook(const char* filename, int line, const char *name, int num_args, const char **args, int vaarg, const char *text) + { + if (debug) + std::cout << "define : " << filename << ' ' << line << ' ' << name << ' ' << num_args << ' ' << text << std::endl; +#if 0 + FileFilter *filter = FileFilter::instance(); + if (!filter) return; + AST::SourceFile *file = filter->get_sourcefile(filename); + if (!file->is_main()) return; + if (!syn_macro_defines) syn_macro_defines = new std::vector; + AST::Macro::Parameters *params = 0; + if (args) + { + params = new AST::Macro::Parameters; + for (int i = 0; i < num_args; i++) + params->push_back(args[i]); + if (vaarg) params->push_back("..."); + } + ScopedName macro_name; + macro_name.push_back(name); + AST::Macro* macro = new AST::Macro(file, line, macro_name, params, text); + //. Don't know global NS yet.. Will have to extract these later + file->declarations().push_back(macro); + syn_macro_defines->push_back(macro); +#endif + } +}; + +namespace +{ + +bool extract(PyObject *list, std::vector &out) +{ + size_t argsize = PyList_Size(list); + for (size_t i = 0; i != argsize; ++i) + { + const char *value = PyString_AsString(PyList_GetItem(list, i)); + if (!value) return false; + out.push_back(value); + } + return true; +} + +PyObject *ucpp_parse(PyObject *self, PyObject *args) +{ + PyObject *ast; + char *input, *output; + PyObject *py_cppflags; + std::vector cppflags; + if (!PyArg_ParseTuple(args, "OszO!ii", + &ast, + &input, + &output, + &PyList_Type, &py_cppflags, + &verbose, + &debug) + || !extract(py_cppflags, cppflags)) + return 0; + + Py_INCREF(ast); + + + cppflags.insert(cppflags.begin(), "ucpp"); + cppflags.push_back("-C"); // keep comments + cppflags.push_back("-lg"); // gcc-like line numbers + if (output) + { + cppflags.push_back("-o"); // output to... + cppflags.push_back(output); + } + cppflags.push_back(input); + if (verbose) + { + std::cout << "calling ucpp\n"; + for (std::vector::iterator i = cppflags.begin(); + i != cppflags.end(); ++i) + std::cout << ' ' << *i; + std::cout << std::endl; + } + + int status = ucpp_main(cppflags.size(), (char **)&*cppflags.begin()); + if (status != 0) + std::cerr << "ucpp returned error flag. ignoring error." << std::endl; + return ast; +} + +PyMethodDef ucpp_methods[] = {{(char*)"parse", ucpp_parse, METH_VARARGS}, + {0, 0}}; +}; + +extern "C" void initucpp() +{ + PyObject* m = Py_InitModule((char*)"ucpp", ucpp_methods); + PyObject_SetAttrString(m, (char*)"version", PyString_FromString("0.1")); +} From stefan at synopsis.fresco.org Fri Jan 2 03:58:49 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:22 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/Synopsis/Parsers/Cpp Parser.py,NONE,1.1 __init__.py,NONE,1.1 Message-ID: Update of /cvs/synopsis/Synopsis/Synopsis/Parsers/Cpp In directory frida:/tmp/cvs-serv28392/Synopsis/Parsers/Cpp Added Files: Parser.py __init__.py Log Message: first working version of standalone ucpp parser --- NEW FILE: Parser.py --- # $Id: Parser.py,v 1.1 2004/01/02 03:58:47 stefan Exp $ # # Copyright (C) 2003 Stefan Seefeld # All rights reserved. # Licensed to the public under the terms of the GNU LGPL (>= 2), # see the file COPYING for details. # """Preprocessor for C, C++, IDL """ from Synopsis.Processor import Processor, Parameter from Synopsis import AST class Parser(Processor): preprocessor = Parameter(None, 'the preprocessor to use') emulate_compiler = Parameter('c++', 'a compiler to emulate') flags = Parameter([], 'list of preprocessor flags such as -I or -D') def process(self, ast, **kwds): self.set_parameters(kwds) self.ast = ast flags = self.flags if not self.preprocessor: import ucpp info = self.get_compiler_info(self.emulate_compiler) flags += map(lambda x:'-I%s'%x, info.include_paths) flags += map(lambda x:'-D%s=%s'%(x[0], x[1]), info.macros) for file in self.input: self.ast = ucpp.parse(self.ast, file, self.output, flags, self.verbose, self.debug) else: print 'not implemented yet: spawn external preprocessor' return self.output_and_return_ast() def get_compiler_info(self, compiler): import emul return emul.get_compiler_info(compiler) --- NEW FILE: __init__.py --- # $Id: __init__.py,v 1.1 2004/01/02 03:58:47 stefan Exp $ # # Copyright (C) 2003 Stefan Seefeld # All rights reserved. # Licensed to the public under the terms of the GNU LGPL (>= 2), # see the file COPYING for details. # from Parser import * From stefan at synopsis.fresco.org Sun Jan 4 02:08:34 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:22 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/Synopsis/Parsers/Cpp Parser.py,1.1,1.2 cpp.cc,1.2,1.3 Message-ID: Update of /cvs/synopsis/Synopsis/Synopsis/Parsers/Cpp In directory frida:/tmp/cvs-serv29668/Synopsis/Parsers/Cpp Modified Files: Parser.py cpp.cc Log Message: create SourceFile, Macro, Include nodes, as well as a macro map store. Index: Parser.py =================================================================== RCS file: /cvs/synopsis/Synopsis/Synopsis/Parsers/Cpp/Parser.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- Parser.py 2 Jan 2004 03:58:47 -0000 1.1 +++ Parser.py 4 Jan 2004 02:08:26 -0000 1.2 @@ -17,6 +17,10 @@ class Parser(Processor): preprocessor = Parameter(None, 'the preprocessor to use') emulate_compiler = Parameter('c++', 'a compiler to emulate') flags = Parameter([], 'list of preprocessor flags such as -I or -D') + cpp_output = Parameter(None, 'filename for preprocessed file') + cpp_mmap = Parameter(None, 'output macro calls for the given file') + prefix = Parameter(None, 'prefix to strip off from the filename') + language = Parameter('C', 'source code programming language of the given input file') def process(self, ast, **kwds): @@ -30,7 +34,9 @@ class Parser(Processor): flags += map(lambda x:'-I%s'%x, info.include_paths) flags += map(lambda x:'-D%s=%s'%(x[0], x[1]), info.macros) for file in self.input: - self.ast = ucpp.parse(self.ast, file, self.output, flags, self.verbose, self.debug) + self.ast = ucpp.parse(self.ast, file, self.prefix, + self.cpp_output, self.cpp_mmap, + self.language, flags, self.verbose, self.debug) else: print 'not implemented yet: spawn external preprocessor' return self.output_and_return_ast() Index: cpp.cc =================================================================== RCS file: /cvs/synopsis/Synopsis/Synopsis/Parsers/Cpp/cpp.cc,v retrieving revision 1.2 retrieving revision 1.3 diff -u -p -d -r1.2 -r1.3 --- cpp.cc 2 Jan 2004 03:58:05 -0000 1.2 +++ cpp.cc 4 Jan 2004 02:08:26 -0000 1.3 @@ -8,83 +8,171 @@ #include #include +#include +#include +#include #include +#include #include #include +namespace +{ + int verbose = 0; int debug = 0; +PyObject *ast; +const char *prefix = 0; +PyObject *language = 0; +PyObject *source_file = 0; +const char *input = 0; -extern "C" +//. MacroMap is a map from preprocessed file positions to input file positions. +//. This may eventually be part of the AST (if more than just declarations are +//. supported), but for now it is persisted into a file in parallel so it can be +//. read in by C/C++ parsers for correct symbol cross referencing. +struct MacroMap { - // ucpp_main is the renamed main() func of ucpp, since it is included in this - // module - int ucpp_main(int argc, char** argv); - - //. This function is a callback from the ucpp code to store macro - //. expansions - void synopsis_macro_hook(const char *name, int line, int start, int end, int diff) + struct Node { - if (debug) - std::cout << "macro : " << name << ' ' << line << ' ' << start << ' ' << end << ' ' << diff << std::endl; -#if 0 - LinkMap::instance()->add(name, line, start, end, diff); -#endif - } + std::string name; + int start; + int end; + enum Type { START, END } type; + int diff; + bool operator <(const Node &other) const + { + return start < other.start; + } + }; + typedef std::set Line; + typedef std::map LineMap; - //. This function is a callback from the ucpp code to store includes - void synopsis_include_hook(const char *source_file, const char *target_file, int is_macro, int is_next) + //. Adds a map at the given line. out_{start,end} define the start and + //. past-the-end markers for the macro in the output file. diff defines + //. the signed difference to add to the pos. + void add(const char *name, int linenum, int start, int end, int diff) { - if (debug) - std::cout << "include : " << source_file << ' ' << target_file << ' ' << is_macro << ' ' << is_next << std::endl; -#if 0 - // There is not enough code here to make another class.. - FileFilter *filter = FileFilter::instance(); - if (!filter) return; - - // Add another Include to the source's SourceFile - // We don't deal with duplicates here. The Linker's Unduplicator will - // take care of that. - //std::cout << "Include: " << source_file << " -> " << target_file << std::endl; - AST::SourceFile *file = filter->get_sourcefile(source_file); - AST::SourceFile *target = filter->get_sourcefile(target_file); - AST::Include *include = new AST::Include(target, is_macro, is_next); - file->includes().push_back(include); -#endif + Line &line = lines[linenum]; + Node node; + node.name = name; // name isn't really needed. For now keep it for debugging... + node.start = start; + node.end = end; + node.type = Node::START; + node.diff = diff; + line.insert(node); } - - //. This function is a callback from the ucpp code to store macro - //. definitions - void synopsis_define_hook(const char* filename, int line, const char *name, int num_args, const char **args, int vaarg, const char *text) + void write(const char *filename) { - if (debug) - std::cout << "define : " << filename << ' ' << line << ' ' << name << ' ' << num_args << ' ' << text << std::endl; -#if 0 - FileFilter *filter = FileFilter::instance(); - if (!filter) return; - AST::SourceFile *file = filter->get_sourcefile(filename); - if (!file->is_main()) return; - if (!syn_macro_defines) syn_macro_defines = new std::vector; - AST::Macro::Parameters *params = 0; - if (args) - { - params = new AST::Macro::Parameters; - for (int i = 0; i < num_args; i++) - params->push_back(args[i]); - if (vaarg) params->push_back("..."); - } - ScopedName macro_name; - macro_name.push_back(name); - AST::Macro* macro = new AST::Macro(file, line, macro_name, params, text); - //. Don't know global NS yet.. Will have to extract these later - file->declarations().push_back(macro); - syn_macro_defines->push_back(macro); -#endif + std::ofstream ofs(filename); + for (LineMap::iterator i = lines.begin(); + i != lines.end(); ++i) + for (MacroMap::Line::iterator j = (*i).second.begin(); + j != (*i).second.end(); ++j) + ofs << (*i).first << ' ' + << (*j).name << ' ' + << (*j).start << ' ' + << (*j).end << ' ' + << (*j).type << ' ' + << (*j).diff << '\n'; } -}; -namespace + LineMap lines; +} mmap; + +const char *strip_prefix(const char *filename, const char *prefix) { + if (!prefix) return filename; + size_t length = strlen(prefix); + if (length > strlen(filename)) return filename; // ?? + if (strncmp(filename, prefix, length) == 0) + return filename + length; + return filename; +} + +//. creates new SourceFile object +PyObject *create_source_file(const char *filename, bool is_main) +{ + PyObject *short_filename = PyString_FromString(strip_prefix(filename, prefix)); + PyObject *long_filename = PyString_FromString(filename); + PyObject *ast_module = PyImport_ImportModule("Synopsis.AST"); + PyObject *source_file = PyObject_CallMethod(ast_module, "SourceFile", "OOO", + short_filename, long_filename, language); + Py_DECREF(ast_module); + if (is_main) PyObject_CallMethod(source_file, "set_is_main", "i", 1); + PyObject *pyfiles = PyObject_CallMethod(ast, "files", 0); + PyDict_SetItem(pyfiles, short_filename, source_file); + Py_DECREF(short_filename); + Py_DECREF(long_filename); + Py_DECREF(pyfiles); + return source_file; +} + +//. creates new or returns existing SourceFile object +//. with the given filename +PyObject *lookup_source_file(const char *filename) +{ + PyObject *short_filename = PyString_FromString(strip_prefix(filename, prefix)); + PyObject *pyfiles = PyObject_CallMethod(ast, "files", 0); + PyObject *source_file = PyDict_GetItem(pyfiles, short_filename); + if (source_file) Py_INCREF(source_file); + Py_DECREF(pyfiles); + Py_DECREF(short_filename); + return source_file ? source_file : create_source_file(filename, false); +} + +void create_include(PyObject *source, PyObject *target, + bool is_macro, bool is_next) +{ + PyObject *ast_module = PyImport_ImportModule("Synopsis.AST"); + PyObject *include = PyObject_CallMethod(ast_module, "Include", "Oii", + target, is_macro, is_next); + Py_DECREF(ast_module); + PyObject *includes = PyObject_CallMethod(source, "includes", 0); + PyObject_CallMethod(includes, "append", "O", include); + Py_DECREF(includes); + Py_DECREF(include); +} + +//. creates new Macro object +void create_macro(const char *filename, int line, + const char *macro_name, int num_args, const char **args, + int vaarg, const char *text) +{ + PyObject *file = lookup_source_file(filename); + PyObject *type = PyString_FromString("macro"); + PyObject *name = PyTuple_New(1); + PyTuple_SET_ITEM(name, 0, PyString_FromString(macro_name)); + PyObject *params = 0; + if (args) + { + params = PyList_New(vaarg ? num_args + 1 : num_args); + for (int i = 0; i < num_args; i++) + PyList_SET_ITEM(params, i, PyString_FromString(args[i])); + if (vaarg) + PyList_SET_ITEM(params, num_args, PyString_FromString("...")); + } + else + { + params = Py_None; + Py_INCREF(Py_None); + } + PyObject *pytext = PyString_FromString(text); + PyObject *ast_module = PyImport_ImportModule("Synopsis.AST"); + PyObject *macro = PyObject_CallMethod(ast_module, "Macro", "OiOOOOO", + file, line, language, type, + name, params, pytext); + Py_DECREF(ast_module); + Py_DECREF(pytext); + Py_DECREF(params); + Py_DECREF(name); + Py_DECREF(type); + Py_DECREF(file); + PyObject *declarations = PyObject_CallMethod(ast, "declarations", 0); + PyObject_CallMethod(declarations, "append", "O", macro); + Py_DECREF(macro); + Py_DECREF(declarations); +} bool extract(PyObject *list, std::vector &out) { @@ -98,16 +186,26 @@ bool extract(PyObject *list, std::vector return true; } +extern "C" +{ + // ucpp_main is the renamed main() func of ucpp, since it is included in this + // module + int ucpp_main(int argc, char** argv); +} + PyObject *ucpp_parse(PyObject *self, PyObject *args) { - PyObject *ast; - char *input, *output; + char *output; + char *mmap_file; PyObject *py_cppflags; std::vector cppflags; - if (!PyArg_ParseTuple(args, "OszO!ii", + if (!PyArg_ParseTuple(args, "OszszOO!ii", &ast, &input, + &prefix, &output, + &mmap_file, + &language, &PyList_Type, &py_cppflags, &verbose, &debug) @@ -115,7 +213,7 @@ PyObject *ucpp_parse(PyObject *self, PyO return 0; Py_INCREF(ast); - + source_file = create_source_file(input, true); cppflags.insert(cppflags.begin(), "ucpp"); cppflags.push_back("-C"); // keep comments @@ -138,9 +236,48 @@ PyObject *ucpp_parse(PyObject *self, PyO int status = ucpp_main(cppflags.size(), (char **)&*cppflags.begin()); if (status != 0) std::cerr << "ucpp returned error flag. ignoring error." << std::endl; + + if (mmap_file) mmap.write(mmap_file); + return ast; } +extern "C" +{ + //. This function is a callback from the ucpp code to store macro + //. expansions + void synopsis_macro_hook(const char *name, int line, int start, int end, int diff) + { + if (debug) + std::cout << "macro : " << name << ' ' << line << ' ' << start << ' ' << end << ' ' << diff << std::endl; + + mmap.add(name, line, start, end, diff); + } + + //. This function is a callback from the ucpp code to store includes + void synopsis_include_hook(const char *source, const char *target, int is_macro, int is_next) + { + if (debug) + std::cout << "include : " << source << ' ' << target << ' ' << is_macro << ' ' << is_next << std::endl; + + if (strcmp(input, source) != 0) return; + PyObject *target_file = lookup_source_file(target); + create_include(source_file, target_file, is_macro, is_next); + Py_DECREF(target_file); + } + + //. This function is a callback from the ucpp code to store macro + //. definitions + void synopsis_define_hook(const char *filename, int line, const char *name, int num_args, const char **args, int vaarg, const char *text) + { + if (debug) + std::cout << "define : " << filename << ' ' << line << ' ' << name << ' ' << num_args << ' ' << text << std::endl; + + if (strcmp(input, filename) != 0) return; + create_macro(filename, line, name, num_args, args, vaarg, text); + } +}; + PyMethodDef ucpp_methods[] = {{(char*)"parse", ucpp_parse, METH_VARARGS}, {0, 0}}; }; From stefan at synopsis.fresco.org Fri Jan 9 19:57:43 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:22 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/include - New directory Message-ID: Update of /cvs/synopsis/Synopsis/include In directory frida:/tmp/cvs-serv9936/include Log Message: Directory /cvs/synopsis/Synopsis/include added to the repository From stefan at synopsis.fresco.org Fri Jan 9 19:58:09 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:22 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/include/Synopsis - New directory Message-ID: Update of /cvs/synopsis/Synopsis/include/Synopsis In directory frida:/tmp/cvs-serv9960/include/Synopsis Log Message: Directory /cvs/synopsis/Synopsis/include/Synopsis added to the repository From stefan at synopsis.fresco.org Fri Jan 9 19:59:24 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:22 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/tests/CXX-API - New directory Message-ID: Update of /cvs/synopsis/Synopsis/tests/CXX-API In directory frida:/tmp/cvs-serv9973/tests/CXX-API Log Message: Directory /cvs/synopsis/Synopsis/tests/CXX-API added to the repository From stefan at synopsis.fresco.org Fri Jan 9 19:59:54 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:22 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/tests/CXX-API/Python - New directory Message-ID: Update of /cvs/synopsis/Synopsis/tests/CXX-API/Python In directory frida:/tmp/cvs-serv9986/tests/CXX-API/Python Log Message: Directory /cvs/synopsis/Synopsis/tests/CXX-API/Python added to the repository From stefan at synopsis.fresco.org Fri Jan 9 20:03:28 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:22 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/tests/CXX-API/Python Command.py,NONE,1.1 Dict.cc,NONE,1.1 Guard.hh,NONE,1.1 Interpreter.cc,NONE,1.1 List.cc,NONE,1.1 Makefile,NONE,1.1 Object.cc,NONE,1.1 Tuple.cc,NONE,1.1 script.py,NONE,1.1 Message-ID: Update of /cvs/synopsis/Synopsis/tests/CXX-API/Python In directory frida:/tmp/cvs-serv10107/tests/CXX-API/Python Added Files: Command.py Dict.cc Guard.hh Interpreter.cc List.cc Makefile Object.cc Tuple.cc script.py Log Message: new C++ interface --- NEW FILE: Command.py --- class Command: def __init__(self, *args, **kwds): print 'Command.__init__:' print args print kwds --- NEW FILE: Dict.cc --- #include #include "Guard.hh" #include #include using namespace Synopsis; void test1() { Dict dict; dict.set('a', 'A'); dict.set(1, 2); dict.set("hello", "world"); std::cout << Object::narrow(dict.str()) << std::endl; std::cout << Object::narrow(dict.keys().str()) << std::endl; std::cout << Object::narrow(dict.values().str()) << std::endl; std::cout << Object::narrow(dict.items().str()) << std::endl; } void test2() { Dict dict; dict.set('a', 'A'); std::cout << Object::narrow(dict.get('a').str()) << std::endl; std::cout << Object::narrow(dict.get('b').str()) << std::endl; dict.set(1, 2); dict.set("hello", "world"); for (Dict::iterator i = dict.begin(); i != dict.end(); ++i) std::cout << Object::narrow((*i).str()) << std::endl; } int main(int, char **) { try { test1(); test2(); } catch (const std::exception &e) { std::cout << "Error : " << e.what() << std::endl; } } --- NEW FILE: Guard.hh --- #ifndef _Guard_hh #define _Guard_hh #include struct Guard { Guard() { Py_Initialize();} ~Guard() { Py_Finalize();} }; Guard guard; #endif --- NEW FILE: Interpreter.cc --- #include #include #include #include #include "Guard.hh" #include #include #include using namespace Synopsis; void print(Dict &d) { List keys = d.keys(); for (int i = 0; i != keys.size(); ++i) { Object key = keys.get(i); std::cout << Object::narrow(key) << ' ' << Object::narrow(d.get(key).str()) << std::endl; } } void test1() { std::cout << "=== test1 ===" << std::endl; Interpreter interp; Module module("__main__"); Dict global = module.dict(); Dict local; Object retn = interp.run_string("print 'hello world'", Interpreter::FILE, global, local); } void test2() { std::cout << "=== test2 ===" << std::endl; Interpreter interp; Module module("__main__"); Dict global = module.dict(); Dict local; Object retn = interp.run_file("script.py", Interpreter::FILE, global, local); print(global); print(local); } void test3() { std::cout << "=== test3 ===" << std::endl; Interpreter interp; Module module("__main__"); Dict global = module.dict(); Dict local; Object retn = interp.run_file("Command.py", Interpreter::FILE, global, local); if (!retn) PyErr_Print(); Object o = local.get("Command"); if (!o) { throw std::runtime_error("missing object 'Command' in 'Command.py'");} Callable type = local.get("Command"); Tuple args("first", "second", "third"); Dict kwds; kwds.set("input", "foo.h"); kwds.set("output", "foo.i"); type.call(); type.call(args); type.call(args, kwds); } int main(int, char **) { try { test1(); test2(); test3(); } catch (const std::exception &e) { std::cout << "Error : " << e.what() << std::endl; } } --- NEW FILE: List.cc --- #include #include "Guard.hh" #include #include using namespace Synopsis; void test1() { List list; list.append('a'); list.append(1); list.append("hello"); list.append("world"); std::cout << Object::narrow(list.str()) << std::endl; list.sort(); std::cout << Object::narrow(list.str()) << std::endl; list.reverse(); std::cout << Object::narrow(list.str()) << std::endl; Object o = list.get(0); std::cout << Object::narrow(o.str()) << std::endl; } int main(int, char **) { try { test1(); } catch (const std::exception &e) { std::cout << "Error : " << e.what() << std::endl; } } --- NEW FILE: Makefile --- # $Id: Makefile,v 1.1 2004/01/09 20:03:26 stefan Exp $ # # Copyright (C) 2003 Stefan Seefeld # All rights reserved. # Licensed to the public under the terms of the GNU LGPL (>= 2), # see the file COPYING for details. # SHELL := /bin/sh python := python PYPREFIX:=$(shell $(python) -c "import sys; print sys.prefix") PYVERSION:=$(shell $(python) -c "from distutils import sysconfig; print sysconfig.get_config_var('VERSION')") PYINC :=$(shell $(python) -c "from distutils import sysconfig; print sysconfig.get_python_inc()") PYLIBS :=-L $(PYPREFIX)/lib/python$(PYVERSION)/config -lpython$(PYVERSION) -ldl -lutil -lpthread CPPFLAGS:= -I .. -I $(PYINC) LIBS := $(PYLIBS) TESTS := Object List Tuple Dict Interpreter all: $(TESTS) %.o: %.cc $(CXX) $(CPPFLAGS) -ggdb $(CXXFLAGS) -c -o $@ $< $(TESTS): %: %.o $(CXX) -ggdb $(LDFLAGS) -o $@ $^ $(LIBS) clean: rm -rf *.o $(TESTS) --- NEW FILE: Object.cc --- #include #include "Guard.hh" #include #include using namespace Synopsis; void test1() { Object object; Object character('q'); std::cout << Object::narrow(character) << std::endl; std::cout << Object::narrow(character.str()) << std::endl; Object string("hello world"); std::cout << Object::narrow(string) << std::endl; std::cout << Object::narrow(string.str()) << std::endl; Object integer(42); std::cout << Object::narrow(integer) << std::endl; std::cout << Object::narrow(integer.str()) << std::endl; try { std::cout << Object::narrow(string) << std::endl;} catch (Object::TypeError &e) { std::cout << e.what() << std::endl;} } int main(int, char **) { try { test1(); } catch (const std::exception &e) { std::cout << "Error : " << e.what() << std::endl; } } --- NEW FILE: Tuple.cc --- #include #include "Guard.hh" #include #include using namespace Synopsis; void test1() { List list; list.append('a'); list.append(1); list.append("hello"); list.append("world"); Tuple tuple(list); std::cout << Object::narrow(tuple.str()) << std::endl; Object object(tuple); tuple = Object::narrow(object); std::cout << Object::narrow(tuple.str()) << std::endl; } void test2() { Tuple t1('1', '2', '3'); std::cout << Object::narrow(t1.str()) << std::endl; Tuple t2("hello", "world", 42); std::cout << Object::narrow(t2.str()) << std::endl; } int main(int, char **) { try { test1(); test2(); } catch (const std::exception &e) { std::cout << "Error : " << e.what() << std::endl; } } --- NEW FILE: script.py --- foo = 'bar' print 'hello world' From stefan at synopsis.fresco.org Fri Jan 9 20:03:28 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:22 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/include/Synopsis Callable.hh,NONE,1.1 Dict.hh,NONE,1.1 Interpreter.hh,NONE,1.1 List.hh,NONE,1.1 Module.hh,NONE,1.1 Object.hh,NONE,1.1 Tuple.hh,NONE,1.1 Message-ID: Update of /cvs/synopsis/Synopsis/include/Synopsis In directory frida:/tmp/cvs-serv10107/include/Synopsis Added Files: Callable.hh Dict.hh Interpreter.hh List.hh Module.hh Object.hh Tuple.hh Log Message: new C++ interface --- NEW FILE: Callable.hh --- // $Id: Callable.hh,v 1.1 2004/01/09 20:03:25 stefan Exp $ // // Copyright (C) 2004 Stefan Seefeld // All rights reserved. // Licensed to the public under the terms of the GNU LGPL (>= 2), // see the file COPYING for details. // #ifndef _Synopsis_Callable_hh #define _Synopsis_Callable_hh #include #include #include namespace Synopsis { class Callable : public Object { public: Callable(Object); Object call(); Object call(Tuple); Object call(Tuple, Dict); }; template <> Callable Object::narrow(Object o) throw(Object::TypeError) { return Callable(o); } inline Callable::Callable(Object o) : Object(o) { if (!PyCallable_Check(o.my_impl)) throw TypeError("object not a callable"); } inline Object Callable::call() { return PyObject_CallObject(my_impl, 0); } inline Object Callable::call(Tuple args) { return PyObject_Call(my_impl, args.my_impl, 0); } inline Object Callable::call(Tuple args, Dict kwds) { return PyObject_Call(my_impl, args.my_impl, kwds.my_impl); } } #endif --- NEW FILE: Dict.hh --- // $Id: Dict.hh,v 1.1 2004/01/09 20:03:25 stefan Exp $ // // Copyright (C) 2004 Stefan Seefeld // All rights reserved. // Licensed to the public under the terms of the GNU LGPL (>= 2), // see the file COPYING for details. // #ifndef _Synopsis_Dict_hh #define _Synopsis_Dict_hh #include #include #include namespace Synopsis { class Dict : public Object { public: class iterator; friend class iterator; Dict() : Object(PyDict_New()) {} void set(Object k, Object v); Object get(Object k) const; bool del(Object k); iterator begin(); iterator end(); void clear() { PyDict_Clear(my_impl);} Dict copy() const { return PyDict_Copy(my_impl);} List keys() const { return List(Object(PyDict_Keys(my_impl)));} List values() const { return List(Object(PyDict_Values(my_impl)));} List items() const { return List(Object(PyDict_Items(my_impl)));} Dict(PyObject *o) throw(TypeError) : Object(o) { if (!PyDict_Check(o)) throw TypeError("object not a dict");} private: PyObject *impl() { return my_impl;} // extend friendship }; class Dict::iterator { friend class Dict; public: iterator(const iterator &i) : my_dict(i.my_dict), my_pos(i.my_pos) {} iterator &operator = (const iterator &); bool operator == (iterator i); bool operator != (iterator i) { return !operator==(i);} const Tuple &operator *() { return my_current;} const Tuple *operator ->() { return &(operator *());} iterator operator ++(int) { incr(); return *this;} iterator operator ++() { iterator tmp = *this; incr(); return tmp;} private: iterator(Dict, int); void incr(); Dict my_dict; int my_pos; Tuple my_current; }; template <> inline Dict Object::narrow(Object o) throw(Object::TypeError) { if (!PyDict_Check(o.my_impl)) throw TypeError("object not a dict"); return Dict(o.my_impl); } inline Dict::iterator::iterator(Dict dict, int pos) : my_dict(dict), my_pos(pos) { if (pos != -1) incr(); } inline Dict::iterator &Dict::iterator::operator = (const Dict::iterator &i) { my_dict = i.my_dict; my_pos = i.my_pos; my_current = i.my_current; } inline void Dict::iterator::incr() { PyObject *key = 0, *value = 0; bool valid = PyDict_Next(my_dict.impl(), &my_pos, &key, &value); if (!valid) my_pos = -1; else { Py_INCREF(key); Py_INCREF(value); my_current = Tuple(key, value); } } inline bool Dict::iterator::operator == (Dict::iterator i) { return i.my_dict.impl() == my_dict.impl() && i.my_pos == my_pos; } inline void Dict::set(Object k, Object v) { // Py_INCREF(k.my_impl); // ? // Py_INCREF(v.my_impl); // ? PyDict_SetItem(my_impl, k.my_impl, v.my_impl); } inline Object Dict::get(Object k) const { PyObject *retn = PyDict_GetItem(my_impl, k.my_impl); if (retn) Py_INCREF(retn); return retn; } inline bool Dict::del(Object k) { return PyDict_DelItem(my_impl, k.my_impl) == 0; } inline Dict::iterator Dict::begin() { return iterator(*this, 0); } inline Dict::iterator Dict::end() { return iterator(*this, -1); } } #endif --- NEW FILE: Interpreter.hh --- // $Id: Interpreter.hh,v 1.1 2004/01/09 20:03:25 stefan Exp $ // // Copyright (C) 2004 Stefan Seefeld // All rights reserved. // Licensed to the public under the terms of the GNU LGPL (>= 2), // see the file COPYING for details. // #ifndef _Synopsis_Interpreter_hh #define _Synopsis_Interpreter_hh #include #include namespace Synopsis { class Interpreter { public: enum Mode { EVAL = Py_eval_input, FILE = Py_file_input, SINGLE = Py_single_input}; Interpreter() {} ~Interpreter() {} Object run_string(const std::string &, Mode, Object, Object); Object run_file(const std::string &, Mode, Object, Object); private: }; inline Object Interpreter::run_string(const std::string &code, Mode m, Object globals, Object locals) { Object retn = PyRun_String(const_cast(code.c_str()), m, globals.my_impl, locals.my_impl); if (!retn) PyErr_Print(); return retn; } inline Object Interpreter::run_file(const std::string &script, Mode m, Object globals, Object locals) { ::FILE *file = fopen(script.c_str(), "r"); Object retn = PyRun_File(file, const_cast(script.c_str()), m, globals.my_impl, locals.my_impl); fclose(file); if (!retn) PyErr_Print(); return retn; } } #endif --- NEW FILE: List.hh --- // $Id: List.hh,v 1.1 2004/01/09 20:03:25 stefan Exp $ // // Copyright (C) 2004 Stefan Seefeld // All rights reserved. // Licensed to the public under the terms of the GNU LGPL (>= 2), // see the file COPYING for details. // #ifndef _Synopsis_List_hh #define _Synopsis_List_hh #include namespace Synopsis { class List : public Object { public: List(size_t i = 0) : Object(PyList_New(i)) {} List(const Object &) throw(TypeError); size_t size() const { return PyList_GET_SIZE(my_impl);} void set(int i, Object o); Object get(int i) const; void append(Object o) { PyList_Append(my_impl, o.my_impl);} void insert(int i, Object o) { PyList_Insert(my_impl, i, o.my_impl);} List get_slice(int low, int high) const { return List(PyList_GetSlice(my_impl, low, high));} bool sort() { return PyList_Sort(my_impl) == 0;} bool reverse() { return PyList_Reverse(my_impl) == 0;} }; template <> List Object::narrow(Object o) throw(Object::TypeError) { return List(o); } List::List(const Object &o) throw(TypeError) : Object(o) { if (!PyList_Check(o.my_impl)) throw TypeError("object not a list"); } inline void List::set(int i, Object o) { Py_INCREF(o.my_impl); PyList_SetItem(my_impl, i, o.my_impl); } inline Object List::get(int i) const { PyObject *retn = PyList_GetItem(my_impl, i); Py_INCREF(retn); return Object(retn); } } #endif --- NEW FILE: Module.hh --- // $Id: Module.hh,v 1.1 2004/01/09 20:03:25 stefan Exp $ // // Copyright (C) 2004 Stefan Seefeld // All rights reserved. // Licensed to the public under the terms of the GNU LGPL (>= 2), // see the file COPYING for details. // #ifndef _Synopsis_Module_hh #define _Synopsis_Module_hh #include #include namespace Synopsis { class Module : public Object { public: Module(const std::string &); std::string name() const { return PyModule_GetName(my_impl);} std::string filename() const { return PyModule_GetFilename(my_impl);} Dict dict() const; }; inline Module::Module(const std::string &name) : Object(PyImport_AddModule(const_cast(name.c_str()))) { Py_INCREF(my_impl); } inline Dict Module::dict() const { PyObject *d = PyModule_GetDict(my_impl); Py_INCREF(d); return d; } } #endif --- NEW FILE: Object.hh --- // $Id: Object.hh,v 1.1 2004/01/09 20:03:26 stefan Exp $ // // Copyright (C) 2004 Stefan Seefeld // All rights reserved. // Licensed to the public under the terms of the GNU LGPL (>= 2), // see the file COPYING for details. // #ifndef _Synopsis_Object_hh #define _Synopsis_Object_hh #include #include #include namespace Synopsis { //. Object provides basic //. functionality to access the underlaying //. python object, to be used in subclasses and //. generic accessors such as (python) lists and tuples class Object { friend class List; friend class Tuple; friend class Dict; friend class Callable; friend class Module; friend class Interpreter; public: struct TypeError : std::invalid_argument { TypeError(const char *msg = "") : std::invalid_argument(msg) {} }; struct AttributeError : std::invalid_argument { AttributeError(const char *msg = "") : std::invalid_argument(msg) {} }; struct ImportError : std::invalid_argument { ImportError(const char *msg = "") : std::invalid_argument(msg) {} }; Object() : my_impl(Py_None) { Py_INCREF(Py_None);} Object(PyObject *); Object(const Object &o) : my_impl(o.my_impl) { Py_INCREF(my_impl);} Object(const std::string &value) : my_impl(PyString_FromString(value.c_str())) {} Object(const char *value) : my_impl(PyString_FromString(value)) {} Object(char value) : my_impl(PyString_FromStringAndSize(&value, 1)) {} Object(double value) : my_impl(PyFloat_FromDouble(value)) {} Object(int value) : my_impl(PyInt_FromLong(value)) {} Object(long value) : my_impl(PyInt_FromLong(value)) {} Object(bool value) : my_impl(PyInt_FromLong(value)) {} virtual ~Object() { Py_DECREF(my_impl);} Object &operator = (Object o); int hash() const { return PyObject_Hash(my_impl);} operator bool () const { return PyObject_IsTrue(my_impl);} Object repr() const { return PyObject_Repr(my_impl);} Object str() const { return PyObject_Str(my_impl);} bool is_instance(Object) const; template static T narrow(Object) throw(TypeError); static Object import(const char *name); Object attr(const char *name) const; Object call(const char *name); Object call(const char *name, Object); Object call(const char *name, Object, Object); Object call(const char *name, Object, Object, Object); Object call(const char *name, Object, Object, Object, Object); Object call(const char *name, Object, Object, Object, Object, Object); Object call(const char *name, Object, Object, Object, Object, Object, Object); Object call(const char *name, Object, Object, Object, Object, Object, Object, Object); Object call(const char *name, Object, Object, Object, Object, Object, Object, Object, Object); Object call(const char *name, Object, Object, Object, Object, Object, Object, Object, Object, Object); private: PyObject *my_impl; }; inline Object::Object(PyObject *o) : my_impl(o) { if (!my_impl) { my_impl = Py_None; Py_INCREF(Py_None); } } inline Object &Object::operator = (Object o) { Py_DECREF(my_impl); my_impl = o.my_impl; Py_INCREF(my_impl); } inline bool Object::is_instance(Object o) const { return PyObject_IsInstance(my_impl, o.my_impl) == 1; } inline Object Object::import(const char *name) { PyObject *retn = PyImport_ImportModule(const_cast(name)); if (!retn) throw ImportError(name); else return Object(retn); } inline Object Object::attr(const char *name) const { PyObject *retn = PyObject_GetAttrString(my_impl, const_cast(name)); if (!retn) throw AttributeError(name); else return Object(retn); } inline Object Object::call(const char *name) { return PyObject_CallMethod(my_impl, const_cast(name), 0); } inline Object Object::call(const char *name, Object o1) { return PyObject_CallMethod(my_impl, const_cast(name), "O", o1.my_impl); } inline Object Object::call(const char *name, Object o1, Object o2) { return PyObject_CallMethod(my_impl, const_cast(name), "OO", o1.my_impl, o2.my_impl); } inline Object Object::call(const char *name, Object o1, Object o2, Object o3) { return PyObject_CallMethod(my_impl, const_cast(name), "OOO", o1.my_impl, o2.my_impl, o3.my_impl); } inline Object Object::call(const char *name, Object o1, Object o2, Object o3, Object o4) { return PyObject_CallMethod(my_impl, const_cast(name), "OOOO", o1.my_impl, o2.my_impl, o3.my_impl, o4.my_impl); } inline Object Object::call(const char *name, Object o1, Object o2, Object o3, Object o4, Object o5) { return PyObject_CallMethod(my_impl, const_cast(name), "OOOOO", o1.my_impl, o2.my_impl, o3.my_impl, o4.my_impl, o5.my_impl); } inline Object Object::call(const char *name, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { return PyObject_CallMethod(my_impl, const_cast(name), "OOOOOO", o1.my_impl, o2.my_impl, o3.my_impl, o4.my_impl, o5.my_impl, o6.my_impl); } inline Object Object::call(const char *name, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) { return PyObject_CallMethod(my_impl, const_cast(name), "OOOOOOO", o1.my_impl, o2.my_impl, o3.my_impl, o4.my_impl, o5.my_impl, o6.my_impl, o7.my_impl); } inline Object Object::call(const char *name, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) { return PyObject_CallMethod(my_impl, const_cast(name), "OOOOOOOO", o1.my_impl, o2.my_impl, o3.my_impl, o4.my_impl, o5.my_impl, o6.my_impl, o7.my_impl, o8.my_impl); } inline Object Object::call(const char *name, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) { return PyObject_CallMethod(my_impl, const_cast(name), "OOOOOOOOO", o1.my_impl, o2.my_impl, o3.my_impl, o4.my_impl, o5.my_impl, o6.my_impl, o7.my_impl, o8.my_impl, o9.my_impl); } template <> inline char Object::narrow(Object o) throw(Object::TypeError) { if (!PyString_Check(o.my_impl) || PyString_GET_SIZE(o.my_impl) != 1) throw TypeError("object not a character"); char *value; int length; PyString_AsStringAndSize(o.my_impl, &value, &length); return value[0]; } template <> inline const char *Object::narrow(Object o) throw(Object::TypeError) { if (!PyString_Check(o.my_impl)) throw TypeError("object not a string"); return PyString_AS_STRING(o.my_impl); } template <> inline std::string Object::narrow(Object o) throw(Object::TypeError) { if (!PyString_Check(o.my_impl)) throw TypeError("object not a string"); return PyString_AS_STRING(o.my_impl); } template <> inline double Object::narrow(Object o) throw(Object::TypeError) { if (!PyFloat_Check(o.my_impl)) throw TypeError("object not a float"); return PyFloat_AsDouble(o.my_impl); } template <> inline long Object::narrow(Object o) throw(Object::TypeError) { if (!PyInt_Check(o.my_impl)) throw TypeError("object not an integer"); return PyInt_AsLong(o.my_impl); } template <> inline bool Object::narrow(Object o) throw(Object::TypeError) { if (!PyInt_Check(o.my_impl)) throw TypeError("object not an integer"); return PyInt_AsLong(o.my_impl); } } #endif --- NEW FILE: Tuple.hh --- // $Id: Tuple.hh,v 1.1 2004/01/09 20:03:26 stefan Exp $ // // Copyright (C) 2004 Stefan Seefeld // All rights reserved. // Licensed to the public under the terms of the GNU LGPL (>= 2), // see the file COPYING for details. // #ifndef _Synopsis_Tuple_hh #define _Synopsis_Tuple_hh #include #include namespace Synopsis { class Tuple : public Object { public: Tuple(size_t i = 0) : Object(PyTuple_New(i)) {} Tuple(PyObject *); Tuple(const List &l) : Object(PyList_AsTuple(l.my_impl)) {} Tuple(Object); Tuple(Object, Object); Tuple(Object, Object, Object); Tuple(Object, Object, Object, Object); Tuple(Object, Object, Object, Object, Object); Tuple(Object, Object, Object, Object, Object, Object); Object get(size_t i) const { return PyTuple_GetItem(my_impl, i); } }; template <> Tuple Object::narrow(Object o) throw(Object::TypeError) { if (!PyTuple_Check(o.my_impl)) throw TypeError("object not a tuple"); return Tuple(o.my_impl); } Tuple::Tuple(PyObject *o) : Object(o) { if (!PyTuple_Check(o)) throw TypeError("object not a tuple"); } Tuple::Tuple(Object o) : Object(PyTuple_New(1)) { PyTuple_SET_ITEM(my_impl, 0, o.my_impl); Py_INCREF(o.my_impl); } Tuple::Tuple(Object o1, Object o2) : Object(PyTuple_New(2)) { PyTuple_SET_ITEM(my_impl, 0, o1.my_impl); Py_INCREF(o1.my_impl); PyTuple_SET_ITEM(my_impl, 1, o2.my_impl); Py_INCREF(o2.my_impl); } Tuple::Tuple(Object o1, Object o2, Object o3) : Object(PyTuple_New(3)) { PyTuple_SET_ITEM(my_impl, 0, o1.my_impl); Py_INCREF(o1.my_impl); PyTuple_SET_ITEM(my_impl, 1, o2.my_impl); Py_INCREF(o2.my_impl); PyTuple_SET_ITEM(my_impl, 2, o3.my_impl); Py_INCREF(o3.my_impl); } Tuple::Tuple(Object o1, Object o2, Object o3, Object o4) : Object(PyTuple_New(4)) { PyTuple_SET_ITEM(my_impl, 0, o1.my_impl); Py_INCREF(o1.my_impl); PyTuple_SET_ITEM(my_impl, 1, o2.my_impl); Py_INCREF(o2.my_impl); PyTuple_SET_ITEM(my_impl, 1, o3.my_impl); Py_INCREF(o3.my_impl); PyTuple_SET_ITEM(my_impl, 1, o4.my_impl); Py_INCREF(o4.my_impl); } Tuple::Tuple(Object o1, Object o2, Object o3, Object o4, Object o5) : Object(PyTuple_New(5)) { PyTuple_SET_ITEM(my_impl, 0, o1.my_impl); Py_INCREF(o1.my_impl); PyTuple_SET_ITEM(my_impl, 1, o2.my_impl); Py_INCREF(o2.my_impl); PyTuple_SET_ITEM(my_impl, 1, o3.my_impl); Py_INCREF(o3.my_impl); PyTuple_SET_ITEM(my_impl, 1, o4.my_impl); Py_INCREF(o4.my_impl); PyTuple_SET_ITEM(my_impl, 1, o5.my_impl); Py_INCREF(o5.my_impl); } Tuple::Tuple(Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) : Object(PyTuple_New(6)) { PyTuple_SET_ITEM(my_impl, 0, o1.my_impl); Py_INCREF(o1.my_impl); PyTuple_SET_ITEM(my_impl, 1, o2.my_impl); Py_INCREF(o2.my_impl); PyTuple_SET_ITEM(my_impl, 1, o3.my_impl); Py_INCREF(o3.my_impl); PyTuple_SET_ITEM(my_impl, 1, o4.my_impl); Py_INCREF(o4.my_impl); PyTuple_SET_ITEM(my_impl, 1, o5.my_impl); Py_INCREF(o5.my_impl); PyTuple_SET_ITEM(my_impl, 1, o6.my_impl); Py_INCREF(o6.my_impl); } } #endif From stefan at synopsis.fresco.org Sat Jan 10 22:48:42 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:22 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/include/Synopsis/AST - New directory Message-ID: Update of /cvs/synopsis/Synopsis/include/Synopsis/AST In directory frida:/tmp/cvs-serv8887/include/Synopsis/AST Log Message: Directory /cvs/synopsis/Synopsis/include/Synopsis/AST added to the repository From stefan at synopsis.fresco.org Sat Jan 10 22:50:36 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:22 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/include/Synopsis/AST AST.hh,NONE,1.1 ASTModule.hh,NONE,1.1 Declaration.hh,NONE,1.1 SourceFile.hh,NONE,1.1 Message-ID: Update of /cvs/synopsis/Synopsis/include/Synopsis/AST In directory frida:/tmp/cvs-serv9027/include/Synopsis/AST Added Files: AST.hh ASTModule.hh Declaration.hh SourceFile.hh Log Message: more work on C++ API --- NEW FILE: AST.hh --- // $Id: AST.hh,v 1.1 2004/01/10 22:50:34 stefan Exp $ // // Copyright (C) 2004 Stefan Seefeld // All rights reserved. // Licensed to the public under the terms of the GNU LGPL (>= 2), // see the file COPYING for details. // #ifndef _Synopsis_AST_AST_hh #define _Synopsis_AST_AST_hh #include #include #include #include namespace Synopsis { class AST : public Object { public: AST() {} AST(const Object &o) throw(TypeError) : Object(o) { assert_type();} Dict files() { return Dict(call("files"));} List declarations() { return List(call("declarations"));} void assert_type() throw(TypeError) { Object::assert_type("Synopsis.AST", "AST");} }; } #endif --- NEW FILE: ASTModule.hh --- // $Id: ASTModule.hh,v 1.1 2004/01/10 22:50:34 stefan Exp $ // // Copyright (C) 2004 Stefan Seefeld // All rights reserved. // Licensed to the public under the terms of the GNU LGPL (>= 2), // see the file COPYING for details. // #ifndef _Synopsis_AST_ASTModule_hh #define _Synopsis_AST_ASTModule_hh #include #include #include #include #include namespace Synopsis { // basically a factory for all AST types class ASTModule : public Module { public: ASTModule() : Module("Synopsis.AST") {} AST create_ast() { return create("AST");} Declaration create_declaration(const SourceFile &sf, long line, const char *lang, const char *type, const char *name) { return create("Declaration", Tuple(sf, line, lang, type, name));} Include create_include(const SourceFile &sf, bool is_macro, bool is_next) { return create("Include", Tuple(sf, is_macro, is_next));} Macro create_macro(SourceFile &sf, long line, const char *lang, const char *type, Tuple &name, const std::vector ¶meters, const char *text) { List params(parameters.size()); for (size_t i = 0; i != parameters.size(); ++i) params.set(i, Object(parameters[i])); return create("Macro", Tuple(sf, line, lang, type, name, params, text)); } SourceFile create_source_file(const std::string &name, const std::string &longname, const std::string &language) { return create("SourceFile", Tuple(name, longname, language));} private: template T create(const char *name, const Tuple &t = Tuple(), const Dict &d = Dict()) { Callable type = dict().get(name); return type.call(t, d); } }; } #endif --- NEW FILE: Declaration.hh --- // $Id: Declaration.hh,v 1.1 2004/01/10 22:50:34 stefan Exp $ // // Copyright (C) 2004 Stefan Seefeld // All rights reserved. // Licensed to the public under the terms of the GNU LGPL (>= 2), // see the file COPYING for details. // #ifndef _Synopsis_AST_Declaration_hh #define _Synopsis_AST_Declaration_hh #include #include namespace Synopsis { class Declaration : public Object { public: Declaration(const Object &o) : Object(o) { assert_type();} SourceFile file() { return narrow(call("file"));} int line() { return narrow(call("line"));} bool language() { return narrow(call("language"));} const char *type() { return narrow(call("type"));} const char *name() { return narrow(call("name"));} List comments() { return List(call("comments"));} void assert_type() throw(TypeError) { Object::assert_type("Synopsis.AST", "Declaration");} }; class Macro : public Declaration { public: Macro(const Object &o) : Declaration(o) {} List parameters() { return List(call("parameters"));} const char *text() { return narrow(call("text"));} }; } #endif --- NEW FILE: SourceFile.hh --- // $Id: SourceFile.hh,v 1.1 2004/01/10 22:50:34 stefan Exp $ // // Copyright (C) 2004 Stefan Seefeld // All rights reserved. // Licensed to the public under the terms of the GNU LGPL (>= 2), // see the file COPYING for details. // #ifndef _Synopsis_AST_SourceFile_hh #define _Synopsis_AST_SourceFile_hh #include namespace Synopsis { class SourceFile : public Object { public: SourceFile() {} SourceFile(const Object &o) : Object(o) {} std::string name() { return narrow(call("filename"));} std::string long_name() { return narrow(call("full_filename"));} bool is_main() { return narrow(call("is_main"));} void is_main(bool flag) { call("set_is_main", flag);} List includes() { return List(call("includes"));} }; class Include : public Object { public: Include(const Object &o) throw(TypeError) : Object(o) { assert_type();} SourceFile target() const { return narrow(attr("target"));} bool is_macro() const { return narrow(attr("is_macro"));} bool is_next() const { return narrow(attr("is_next"));} void assert_type() throw(TypeError) { Object::assert_type("Synopsis.AST", "Include");} }; } #endif From stefan at synopsis.fresco.org Sat Jan 10 22:50:36 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:22 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/include/Synopsis Dict.hh,1.1,1.2 List.hh,1.1,1.2 Module.hh,1.1,1.2 Object.hh,1.1,1.2 Tuple.hh,1.1,1.2 Message-ID: Update of /cvs/synopsis/Synopsis/include/Synopsis In directory frida:/tmp/cvs-serv9027/include/Synopsis Modified Files: Dict.hh List.hh Module.hh Object.hh Tuple.hh Log Message: more work on C++ API Index: Dict.hh =================================================================== RCS file: /cvs/synopsis/Synopsis/include/Synopsis/Dict.hh,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- Dict.hh 9 Jan 2004 20:03:25 -0000 1.1 +++ Dict.hh 10 Jan 2004 22:50:34 -0000 1.2 @@ -23,6 +23,8 @@ public: friend class iterator; Dict() : Object(PyDict_New()) {} + Dict(Object o) throw(TypeError) : Object(o) + { if (!PyDict_Check(o.my_impl)) throw TypeError("object not a dict");} void set(Object k, Object v); Object get(Object k) const; bool del(Object k); @@ -31,14 +33,12 @@ public: iterator end(); void clear() { PyDict_Clear(my_impl);} - Dict copy() const { return PyDict_Copy(my_impl);} + Dict copy() const { return Object(PyDict_Copy(my_impl));} List keys() const { return List(Object(PyDict_Keys(my_impl)));} List values() const { return List(Object(PyDict_Values(my_impl)));} List items() const { return List(Object(PyDict_Items(my_impl)));} - Dict(PyObject *o) throw(TypeError) - : Object(o) { if (!PyDict_Check(o)) throw TypeError("object not a dict");} private: PyObject *impl() { return my_impl;} // extend friendship }; @@ -68,13 +68,6 @@ private: Tuple my_current; }; -template <> -inline Dict Object::narrow(Object o) throw(Object::TypeError) -{ - if (!PyDict_Check(o.my_impl)) throw TypeError("object not a dict"); - return Dict(o.my_impl); -} - inline Dict::iterator::iterator(Dict dict, int pos) : my_dict(dict), my_pos(pos) { Index: List.hh =================================================================== RCS file: /cvs/synopsis/Synopsis/include/Synopsis/List.hh,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- List.hh 9 Jan 2004 20:03:25 -0000 1.1 +++ List.hh 10 Jan 2004 22:50:34 -0000 1.2 @@ -18,7 +18,7 @@ class List : public Object { public: List(size_t i = 0) : Object(PyList_New(i)) {} - List(const Object &) throw(TypeError); + List(Object) throw(TypeError); size_t size() const { return PyList_GET_SIZE(my_impl);} void set(int i, Object o); Object get(int i) const; @@ -29,13 +29,7 @@ public: bool reverse() { return PyList_Reverse(my_impl) == 0;} }; -template <> -List Object::narrow(Object o) throw(Object::TypeError) -{ - return List(o); -} - -List::List(const Object &o) throw(TypeError) +List::List(Object o) throw(TypeError) : Object(o) { if (!PyList_Check(o.my_impl)) throw TypeError("object not a list"); Index: Module.hh =================================================================== RCS file: /cvs/synopsis/Synopsis/include/Synopsis/Module.hh,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- Module.hh 9 Jan 2004 20:03:25 -0000 1.1 +++ Module.hh 10 Jan 2004 22:50:34 -0000 1.2 @@ -11,6 +11,7 @@ #include #include +#include namespace Synopsis { @@ -34,10 +35,9 @@ inline Dict Module::dict() const { PyObject *d = PyModule_GetDict(my_impl); Py_INCREF(d); - return d; + return Object(d); } - } #endif Index: Object.hh =================================================================== RCS file: /cvs/synopsis/Synopsis/include/Synopsis/Object.hh,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- Object.hh 9 Jan 2004 20:03:26 -0000 1.1 +++ Object.hh 10 Jan 2004 22:50:34 -0000 1.2 @@ -31,17 +31,17 @@ class Object public: struct TypeError : std::invalid_argument { - TypeError(const char *msg = "") : std::invalid_argument(msg) {} + TypeError(const std::string &msg = "") : std::invalid_argument(msg) {} }; struct AttributeError : std::invalid_argument { - AttributeError(const char *msg = "") : std::invalid_argument(msg) {} + AttributeError(const std::string &msg = "") : std::invalid_argument(msg) {} }; struct ImportError : std::invalid_argument { - ImportError(const char *msg = "") : std::invalid_argument(msg) {} + ImportError(const std::string &msg = "") : std::invalid_argument(msg) {} }; Object() : my_impl(Py_None) { Py_INCREF(Py_None);} @@ -62,6 +62,9 @@ public: Object repr() const { return PyObject_Repr(my_impl);} Object str() const { return PyObject_Str(my_impl);} bool is_instance(Object) const; + void assert_type(const char *module, + const char *type) const + throw(TypeError); template static T narrow(Object) throw(TypeError); @@ -124,6 +127,8 @@ public: Object, Object, Object); + + PyObject *ref() { Py_INCREF(my_impl); return my_impl;} private: PyObject *my_impl; }; @@ -150,6 +155,21 @@ inline bool Object::is_instance(Object o return PyObject_IsInstance(my_impl, o.my_impl) == 1; } +inline void Object::assert_type(const char *module_name, + const char *type_name) const + throw(TypeError) +{ + Object module = Object::import(module_name); + if (!this->is_instance(module.attr(type_name))) + { + std::string msg = "object not a "; + msg += module_name; + msg += "."; + msg += type_name; + throw TypeError(msg); + } +} + inline Object Object::import(const char *name) { PyObject *retn = PyImport_ImportModule(const_cast(name)); @@ -313,6 +333,12 @@ inline Object Object::call(const char *n o9.my_impl); } +template +inline T Object::narrow(Object o) throw(Object::TypeError) +{ + return T(o.my_impl); +} + template <> inline char Object::narrow(Object o) throw(Object::TypeError) { Index: Tuple.hh =================================================================== RCS file: /cvs/synopsis/Synopsis/include/Synopsis/Tuple.hh,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- Tuple.hh 9 Jan 2004 20:03:26 -0000 1.1 +++ Tuple.hh 10 Jan 2004 22:50:34 -0000 1.2 @@ -20,23 +20,17 @@ class Tuple : public Object public: Tuple(size_t i = 0) : Object(PyTuple_New(i)) {} Tuple(PyObject *); - Tuple(const List &l) : Object(PyList_AsTuple(l.my_impl)) {} + Tuple(List l) : Object(PyList_AsTuple(l.my_impl)) {} Tuple(Object); Tuple(Object, Object); Tuple(Object, Object, Object); Tuple(Object, Object, Object, Object); Tuple(Object, Object, Object, Object, Object); Tuple(Object, Object, Object, Object, Object, Object); + Tuple(Object, Object, Object, Object, Object, Object, Object); Object get(size_t i) const { return PyTuple_GetItem(my_impl, i); } }; -template <> -Tuple Object::narrow(Object o) throw(Object::TypeError) -{ - if (!PyTuple_Check(o.my_impl)) throw TypeError("object not a tuple"); - return Tuple(o.my_impl); -} - Tuple::Tuple(PyObject *o) : Object(o) { @@ -118,6 +112,27 @@ Tuple::Tuple(Object o1, Object o2, Objec Py_INCREF(o6.my_impl); } +Tuple::Tuple(Object o1, Object o2, Object o3, + Object o4, Object o5, Object o6, + Object o7) + : Object(PyTuple_New(7)) +{ + PyTuple_SET_ITEM(my_impl, 0, o1.my_impl); + Py_INCREF(o1.my_impl); + PyTuple_SET_ITEM(my_impl, 1, o2.my_impl); + Py_INCREF(o2.my_impl); + PyTuple_SET_ITEM(my_impl, 1, o3.my_impl); + Py_INCREF(o3.my_impl); + PyTuple_SET_ITEM(my_impl, 1, o4.my_impl); + Py_INCREF(o4.my_impl); + PyTuple_SET_ITEM(my_impl, 1, o5.my_impl); + Py_INCREF(o5.my_impl); + PyTuple_SET_ITEM(my_impl, 1, o6.my_impl); + Py_INCREF(o6.my_impl); + PyTuple_SET_ITEM(my_impl, 1, o7.my_impl); + Py_INCREF(o7.my_impl); +} + } #endif From stefan at synopsis.fresco.org Sun Jan 11 19:43:59 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/tests/Cxx-API/Synopsis - New directory Message-ID: Update of /cvs/synopsis/Synopsis/tests/Cxx-API/Synopsis In directory frida:/tmp/cvs-serv6387/Synopsis Log Message: Directory /cvs/synopsis/Synopsis/tests/Cxx-API/Synopsis added to the repository From stefan at synopsis.fresco.org Sun Jan 11 19:44:14 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/tests/Cxx-API/Synopsis/AST - New directory Message-ID: Update of /cvs/synopsis/Synopsis/tests/Cxx-API/Synopsis/AST In directory frida:/tmp/cvs-serv6407/Synopsis/AST Log Message: Directory /cvs/synopsis/Synopsis/tests/Cxx-API/Synopsis/AST added to the repository From stefan at synopsis.fresco.org Sun Jan 11 19:45:23 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/tests/Cxx-API/Synopsis/AST Guard.hh,NONE,1.1 Makefile,NONE,1.1 SourceFile.cc,NONE,1.1 SourceFile.py,NONE,1.1 Message-ID: Update of /cvs/synopsis/Synopsis/tests/Cxx-API/Synopsis/AST In directory frida:/tmp/cvs-serv6537/Synopsis/AST Added Files: Guard.hh Makefile SourceFile.cc SourceFile.py Log Message: more unit tests and better coverage of the Cxx API --- NEW FILE: Guard.hh --- #ifndef _Guard_hh #define _Guard_hh #include struct Guard { Guard() { Py_Initialize();} ~Guard() { Py_Finalize();} }; Guard guard; #endif --- NEW FILE: Makefile --- # $Id: Makefile,v 1.1 2004/01/11 19:45:21 stefan Exp $ # # Copyright (C) 2003 Stefan Seefeld # All rights reserved. # Licensed to the public under the terms of the GNU LGPL (>= 2), # see the file COPYING for details. # SHELL := /bin/sh python := python PYPREFIX:=$(shell $(python) -c "import sys; print sys.prefix") PYVERSION:=$(shell $(python) -c "from distutils import sysconfig; print sysconfig.get_config_var('VERSION')") PYINC :=$(shell $(python) -c "from distutils import sysconfig; print sysconfig.get_python_inc()") PYLIBS :=-L $(PYPREFIX)/lib/python$(PYVERSION)/config -lpython$(PYVERSION) -ldl -lutil -lpthread CPPFLAGS:= -I ../../../../include -I $(PYINC) LDFLAGS := -rdynamic LIBS := $(PYLIBS) TESTS := SourceFile all: $(TESTS) %.o: %.cc $(CXX) $(CPPFLAGS) -ggdb $(CXXFLAGS) -c -o $@ $< $(TESTS): %: %.o $(CXX) -ggdb $(LDFLAGS) -o $@ $^ $(LIBS) clean: rm -rf *.o $(TESTS) --- NEW FILE: SourceFile.cc --- #include #include #include #include "Guard.hh" #include #include using namespace Synopsis; void test2() { Interpreter interp; Module module("__main__"); Dict global = module.dict(); Dict local; Object retn = interp.run_file("SourceFile.py", Interpreter::FILE, global, local); Callable type = local.get("SourceFile"); } void test1() { ASTModule module = Synopsis::ASTModule(); SourceFile sf = module.create_source_file("filename", "/long/filename", "C++"); std::cout << "created source file " << sf.name() << ' ' << sf.long_name() << ' ' << sf.is_main() << std::endl; } int main(int, char **) { try { test2(); test1(); } catch (const Interpreter::Exception &) { PyErr_Print(); } catch (const std::exception &e) { std::cout << "Error : " << e.what() << std::endl; } } --- NEW FILE: SourceFile.py --- from Synopsis.AST import SourceFile From stefan at synopsis.fresco.org Sun Jan 11 19:45:23 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/tests/Cxx-API/Python Command.py,1.1,1.2 Interpreter.cc,1.1,1.2 Makefile,1.1,1.2 Message-ID: Update of /cvs/synopsis/Synopsis/tests/Cxx-API/Python In directory frida:/tmp/cvs-serv6537/Python Modified Files: Command.py Interpreter.cc Makefile Log Message: more unit tests and better coverage of the Cxx API Index: Command.py =================================================================== RCS file: /cvs/synopsis/Synopsis/tests/Cxx-API/Python/Command.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- Command.py 9 Jan 2004 20:03:26 -0000 1.1 +++ Command.py 11 Jan 2004 19:45:21 -0000 1.2 @@ -3,3 +3,6 @@ class Command: print 'Command.__init__:' print args print kwds + + def execute(self): + print 'hello world' Index: Interpreter.cc =================================================================== RCS file: /cvs/synopsis/Synopsis/tests/Cxx-API/Python/Interpreter.cc,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- Interpreter.cc 9 Jan 2004 20:03:26 -0000 1.1 +++ Interpreter.cc 11 Jan 2004 19:45:21 -0000 1.2 @@ -2,7 +2,6 @@ #include #include #include -#include "Guard.hh" #include #include #include @@ -53,17 +52,17 @@ void test3() Dict local; Object retn = interp.run_file("Command.py", Interpreter::FILE, global, local); - if (!retn) PyErr_Print(); - Object o = local.get("Command"); - if (!o) { throw std::runtime_error("missing object 'Command' in 'Command.py'");} Callable type = local.get("Command"); Tuple args("first", "second", "third"); Dict kwds; kwds.set("input", "foo.h"); kwds.set("output", "foo.i"); - type.call(); - type.call(args); - type.call(args, kwds); + Object o = type.call(); + o = type.call(args); + o = type.call(args, kwds); + o.call("execute"); + Callable c(o.attr("execute")); + c.call(); } int main(int, char **) @@ -74,6 +73,10 @@ int main(int, char **) test2(); test3(); } + catch (const Interpreter::Exception &) + { + PyErr_Print(); + } catch (const std::exception &e) { std::cout << "Error : " << e.what() << std::endl; Index: Makefile =================================================================== RCS file: /cvs/synopsis/Synopsis/tests/Cxx-API/Python/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- Makefile 9 Jan 2004 20:03:26 -0000 1.1 +++ Makefile 11 Jan 2004 19:45:21 -0000 1.2 @@ -14,7 +14,8 @@ PYVERSION:=$(shell $(python) -c "from di PYINC :=$(shell $(python) -c "from distutils import sysconfig; print sysconfig.get_python_inc()") PYLIBS :=-L $(PYPREFIX)/lib/python$(PYVERSION)/config -lpython$(PYVERSION) -ldl -lutil -lpthread -CPPFLAGS:= -I .. -I $(PYINC) +CPPFLAGS:= -I ../../../include -I $(PYINC) +LDFLAGS := -rdynamic LIBS := $(PYLIBS) TESTS := Object List Tuple Dict Interpreter @@ -28,4 +29,4 @@ $(TESTS): %: %.o $(CXX) -ggdb $(LDFLAGS) -o $@ $^ $(LIBS) clean: - rm -rf *.o $(TESTS) \ No newline at end of file + rm -rf *.o $(TESTS) From stefan at synopsis.fresco.org Sun Jan 11 19:46:31 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/include/Synopsis/AST AST.hh,1.1,1.2 Declaration.hh,1.1,1.2 SourceFile.hh,1.1,1.2 Message-ID: Update of /cvs/synopsis/Synopsis/include/Synopsis/AST In directory frida:/tmp/cvs-serv6573/include/Synopsis/AST Modified Files: AST.hh Declaration.hh SourceFile.hh Log Message: refinements Index: AST.hh =================================================================== RCS file: /cvs/synopsis/Synopsis/include/Synopsis/AST/AST.hh,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- AST.hh 10 Jan 2004 22:50:34 -0000 1.1 +++ AST.hh 11 Jan 2004 19:46:29 -0000 1.2 @@ -10,6 +10,7 @@ #define _Synopsis_AST_AST_hh #include +#include #include #include #include @@ -23,8 +24,8 @@ public: AST() {} AST(const Object &o) throw(TypeError) : Object(o) { assert_type();} - Dict files() { return Dict(call("files"));} - List declarations() { return List(call("declarations"));} + Dict files() { return Dict(Callable(attr("files")).call());} + List declarations() { return List(Callable(attr("declarations")).call());} void assert_type() throw(TypeError) { Object::assert_type("Synopsis.AST", "AST");} }; Index: Declaration.hh =================================================================== RCS file: /cvs/synopsis/Synopsis/include/Synopsis/AST/Declaration.hh,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- Declaration.hh 10 Jan 2004 22:50:34 -0000 1.1 +++ Declaration.hh 11 Jan 2004 19:46:29 -0000 1.2 @@ -19,12 +19,12 @@ class Declaration : public Object { public: Declaration(const Object &o) : Object(o) { assert_type();} - SourceFile file() { return narrow(call("file"));} - int line() { return narrow(call("line"));} - bool language() { return narrow(call("language"));} - const char *type() { return narrow(call("type"));} - const char *name() { return narrow(call("name"));} - List comments() { return List(call("comments"));} + SourceFile file() { return narrow(Callable(attr("file")).call());} + int line() { return narrow(Callable(attr("line")).call());} + bool language() { return narrow(Callable(attr("language")).call());} + const char *type() { return narrow(Callable(attr("type")).call());} + const char *name() { return narrow(Callable(attr("name")).call());} + List comments() { return List(Callable(attr("comments")).call());} void assert_type() throw(TypeError) { Object::assert_type("Synopsis.AST", "Declaration");} }; @@ -33,8 +33,8 @@ class Macro : public Declaration { public: Macro(const Object &o) : Declaration(o) {} - List parameters() { return List(call("parameters"));} - const char *text() { return narrow(call("text"));} + List parameters() { return List(Callable(attr("parameters")).call());} + const char *text() { return narrow(Callable(attr("text")).call());} }; } Index: SourceFile.hh =================================================================== RCS file: /cvs/synopsis/Synopsis/include/Synopsis/AST/SourceFile.hh,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- SourceFile.hh 10 Jan 2004 22:50:34 -0000 1.1 +++ SourceFile.hh 11 Jan 2004 19:46:29 -0000 1.2 @@ -10,6 +10,8 @@ #define _Synopsis_AST_SourceFile_hh #include +#include +#include namespace Synopsis { @@ -19,20 +21,20 @@ class SourceFile : public Object public: SourceFile() {} SourceFile(const Object &o) : Object(o) {} - std::string name() { return narrow(call("filename"));} - std::string long_name() { return narrow(call("full_filename"));} - bool is_main() { return narrow(call("is_main"));} - void is_main(bool flag) { call("set_is_main", flag);} - List includes() { return List(call("includes"));} + std::string name() { return narrow(Callable(attr("filename")).call());} + std::string long_name() { return narrow(Callable(attr("full_filename")).call());} + bool is_main() { return narrow(Callable(attr("is_main")).call());} + void is_main(bool flag) { Callable c(attr("set_is_main")); c.call(Tuple(flag));} + List includes() { return List(Callable(attr("includes")).call());} }; class Include : public Object { public: Include(const Object &o) throw(TypeError) : Object(o) { assert_type();} - SourceFile target() const { return narrow(attr("target"));} - bool is_macro() const { return narrow(attr("is_macro"));} - bool is_next() const { return narrow(attr("is_next"));} + SourceFile target() const { return narrow(Callable(attr("target")).call());} + bool is_macro() const { return narrow(Callable(attr("is_macro")).call());} + bool is_next() const { return narrow(Callable(attr("is_next")).call());} void assert_type() throw(TypeError) { Object::assert_type("Synopsis.AST", "Include");} }; From stefan at synopsis.fresco.org Sun Jan 11 19:46:31 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/include/Synopsis Interpreter.hh,1.1,1.2 Object.hh,1.2,1.3 Message-ID: Update of /cvs/synopsis/Synopsis/include/Synopsis In directory frida:/tmp/cvs-serv6573/include/Synopsis Modified Files: Interpreter.hh Object.hh Log Message: refinements Index: Interpreter.hh =================================================================== RCS file: /cvs/synopsis/Synopsis/include/Synopsis/Interpreter.hh,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- Interpreter.hh 9 Jan 2004 20:03:25 -0000 1.1 +++ Interpreter.hh 11 Jan 2004 19:46:29 -0000 1.2 @@ -18,37 +18,41 @@ namespace Synopsis class Interpreter { public: + struct Exception + { + Exception() {} + }; - enum Mode { EVAL = Py_eval_input, - FILE = Py_file_input, - SINGLE = Py_single_input}; + enum Mode { EVAL = Py_eval_input, + FILE = Py_file_input, + SINGLE = Py_single_input}; - Interpreter() {} - ~Interpreter() {} + Interpreter() {} + ~Interpreter() {} - Object run_string(const std::string &, Mode, Object, Object); - Object run_file(const std::string &, Mode, Object, Object); + Object run_string(const std::string &, Mode, Object, Object); + Object run_file(const std::string &, Mode, Object, Object); private: }; inline Object Interpreter::run_string(const std::string &code, Mode m, Object globals, Object locals) { - Object retn = PyRun_String(const_cast(code.c_str()), m, - globals.my_impl, locals.my_impl); - if (!retn) PyErr_Print(); - return retn; + PyObject *retn = PyRun_String(const_cast(code.c_str()), m, + globals.my_impl, locals.my_impl); + if (!retn) throw Exception(); + return retn; } inline Object Interpreter::run_file(const std::string &script, Mode m, Object globals, Object locals) { - ::FILE *file = fopen(script.c_str(), "r"); - Object retn = PyRun_File(file, const_cast(script.c_str()), - m, globals.my_impl, locals.my_impl); - fclose(file); - if (!retn) PyErr_Print(); - return retn; + ::FILE *file = fopen(script.c_str(), "r"); + PyObject *retn = PyRun_File(file, const_cast(script.c_str()), + m, globals.my_impl, locals.my_impl); + fclose(file); + if (!retn) throw Exception(); + return retn; } } Index: Object.hh =================================================================== RCS file: /cvs/synopsis/Synopsis/include/Synopsis/Object.hh,v retrieving revision 1.2 retrieving revision 1.3 diff -u -p -d -r1.2 -r1.3 --- Object.hh 10 Jan 2004 22:50:34 -0000 1.2 +++ Object.hh 11 Jan 2004 19:46:29 -0000 1.3 @@ -58,9 +58,10 @@ public: Object &operator = (Object o); int hash() const { return PyObject_Hash(my_impl);} - operator bool () const { return PyObject_IsTrue(my_impl);} + operator bool () const { return my_impl != Py_None;} Object repr() const { return PyObject_Repr(my_impl);} Object str() const { return PyObject_Str(my_impl);} + Object boolean() const { return PyObject_IsTrue(my_impl);} bool is_instance(Object) const; void assert_type(const char *module, const char *type) const @@ -72,62 +73,6 @@ public: Object attr(const char *name) const; - Object call(const char *name); - Object call(const char *name, - Object); - Object call(const char *name, - Object, - Object); - Object call(const char *name, - Object, - Object, - Object); - Object call(const char *name, - Object, - Object, - Object, - Object); - Object call(const char *name, - Object, - Object, - Object, - Object, - Object); - Object call(const char *name, - Object, - Object, - Object, - Object, - Object, - Object); - Object call(const char *name, - Object, - Object, - Object, - Object, - Object, - Object, - Object); - Object call(const char *name, - Object, - Object, - Object, - Object, - Object, - Object, - Object, - Object); - Object call(const char *name, - Object, - Object, - Object, - Object, - Object, - Object, - Object, - Object, - Object); - PyObject *ref() { Py_INCREF(my_impl); return my_impl;} private: PyObject *my_impl; @@ -184,155 +129,6 @@ inline Object Object::attr(const char *n else return Object(retn); } -inline Object Object::call(const char *name) -{ - return PyObject_CallMethod(my_impl, const_cast(name), 0); -} - -inline Object Object::call(const char *name, - Object o1) -{ - return PyObject_CallMethod(my_impl, const_cast(name), - "O", - o1.my_impl); -} - -inline Object Object::call(const char *name, - Object o1, - Object o2) -{ - return PyObject_CallMethod(my_impl, const_cast(name), - "OO", - o1.my_impl, - o2.my_impl); -} - -inline Object Object::call(const char *name, - Object o1, - Object o2, - Object o3) -{ - return PyObject_CallMethod(my_impl, const_cast(name), - "OOO", - o1.my_impl, - o2.my_impl, - o3.my_impl); -} - -inline Object Object::call(const char *name, - Object o1, - Object o2, - Object o3, - Object o4) -{ - return PyObject_CallMethod(my_impl, const_cast(name), - "OOOO", - o1.my_impl, - o2.my_impl, - o3.my_impl, - o4.my_impl); -} - -inline Object Object::call(const char *name, - Object o1, - Object o2, - Object o3, - Object o4, - Object o5) -{ - return PyObject_CallMethod(my_impl, const_cast(name), - "OOOOO", - o1.my_impl, - o2.my_impl, - o3.my_impl, - o4.my_impl, - o5.my_impl); -} - -inline Object Object::call(const char *name, - Object o1, - Object o2, - Object o3, - Object o4, - Object o5, - Object o6) -{ - return PyObject_CallMethod(my_impl, const_cast(name), - "OOOOOO", - o1.my_impl, - o2.my_impl, - o3.my_impl, - o4.my_impl, - o5.my_impl, - o6.my_impl); -} - -inline Object Object::call(const char *name, - Object o1, - Object o2, - Object o3, - Object o4, - Object o5, - Object o6, - Object o7) -{ - return PyObject_CallMethod(my_impl, const_cast(name), - "OOOOOOO", - o1.my_impl, - o2.my_impl, - o3.my_impl, - o4.my_impl, - o5.my_impl, - o6.my_impl, - o7.my_impl); -} - -inline Object Object::call(const char *name, - Object o1, - Object o2, - Object o3, - Object o4, - Object o5, - Object o6, - Object o7, - Object o8) -{ - return PyObject_CallMethod(my_impl, const_cast(name), - "OOOOOOOO", - o1.my_impl, - o2.my_impl, - o3.my_impl, - o4.my_impl, - o5.my_impl, - o6.my_impl, - o7.my_impl, - o8.my_impl); -} - -inline Object Object::call(const char *name, - Object o1, - Object o2, - Object o3, - Object o4, - Object o5, - Object o6, - Object o7, - Object o8, - Object o9) -{ - return PyObject_CallMethod(my_impl, const_cast(name), - "OOOOOOOOO", - o1.my_impl, - o2.my_impl, - o3.my_impl, - o4.my_impl, - o5.my_impl, - o6.my_impl, - o7.my_impl, - o8.my_impl, - o9.my_impl); -} - template inline T Object::narrow(Object o) throw(Object::TypeError) { From stefan at synopsis.fresco.org Mon Jan 12 01:00:59 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/Synopsis/Parsers/Cpp Makefile.in,1.12,1.13 Message-ID: Update of /cvs/synopsis/Synopsis/Synopsis/Parsers/Cpp In directory frida:/tmp/cvs-serv14075/Synopsis/Parsers/Cpp Modified Files: Makefile.in Log Message: prepare for use of C++ API Index: Makefile.in =================================================================== RCS file: /cvs/synopsis/Synopsis/Synopsis/Parsers/Cpp/Makefile.in,v retrieving revision 1.12 retrieving revision 1.13 diff -u -p -d -r1.12 -r1.13 --- Makefile.in 2 Jan 2004 03:58:05 -0000 1.12 +++ Makefile.in 12 Jan 2004 01:00:57 -0000 1.13 @@ -1,22 +1,10 @@ # $Id$ # -# This source file is a part of the Synopsis Project # Copyright (C) 2003 Stefan Seefeld +# All rights reserved. +# Licensed to the public under the terms of the GNU LGPL (>= 2), +# see the file COPYING for details. # -# 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., 675 Mass Ave, Cambridge, -# MA 02139, USA. SHELL := /bin/sh @@ -27,7 +15,7 @@ PYTHON := @PYTHON@ CC := @CC@ CXX := @CXX@ MAKEDEP := $(CXX) -M -CPPFLAGS:= @CPPFLAGS@ -I $(srcdir) -I @PYTHON_INCLUDE@ +CPPFLAGS:= @CPPFLAGS@ -I $(srcdir) -I $(srcdir)/../../../include -I @PYTHON_INCLUDE@ CFLAGS := @CFLAGS@ CXXFLAGS:= @CXXFLAGS@ LDFLAGS := @LDFLAGS@ From stefan at synopsis.fresco.org Mon Jan 12 20:23:22 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/tests/Cxx-API/Python/expected - New directory Message-ID: Update of /cvs/synopsis/Synopsis/tests/Cxx-API/Python/expected In directory frida:/tmp/cvs-serv9616/Cxx-API/Python/expected Log Message: Directory /cvs/synopsis/Synopsis/tests/Cxx-API/Python/expected added to the repository From stefan at synopsis.fresco.org Mon Jan 12 20:24:48 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/tests/QMTest configuration.in,NONE,1.1 Message-ID: Update of /cvs/synopsis/Synopsis/tests/QMTest In directory frida:/tmp/cvs-serv9641/QMTest Added Files: configuration.in Log Message: support unit tests for C++ API --- NEW FILE: configuration.in --- @CXX@ -I ../include @CPPFLAGS@ @CXXFLAGS@ @LDFLAGS@ @LIBS@ From stefan at synopsis.fresco.org Mon Jan 12 20:24:48 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/tests configure.ac,NONE,1.1 Message-ID: Update of /cvs/synopsis/Synopsis/tests In directory frida:/tmp/cvs-serv9641 Added Files: configure.ac Log Message: support unit tests for C++ API --- NEW FILE: configure.ac --- dnl $Id: configure.ac,v 1.1 2004/01/12 20:24:46 stefan Exp $ dnl dnl Copyright (C) 2003 Stefan Seefeld dnl All rights reserved. dnl Licensed to the public under the terms of the GNU LGPL (>= 2), dnl see the file COPYING for details. dnl AC_PREREQ(2.56) AC_REVISION($Revision: 1.1 $) AC_INIT(tests, 1.0, synopsis-devel@fresco.org) AC_ARG_WITH(python, [ --with-python=PATH specify the Python interpreter], PYTHON="$with_python", PYTHON="" ) AC_PROG_CXX if test -n "$PYTHON" -a "$PYTHON" != yes; then AC_CHECK_FILE($PYTHON,,AC_MSG_ERROR([Cannot find Python interpreter])) else AC_PATH_PROG(PYTHON, python2 python, python) fi PYTHON_PREFIX=`$PYTHON -c "import sys; print sys.prefix"` PYTHON_INCLUDE=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_inc()"` PYTHON_VERSION=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_config_var('VERSION')"` PYTHON_LIBS="-L $PYTHON_PREFIX/lib/python$PYTHON_VERSION/config -lpython$PYTHON_VERSION" PYTHON_DEP_LIBS=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_config_var('LIBS') or ''"` case `uname -s` in CYGWIN*) if test `$PYTHON -c "import os; print os.name"` = posix; then dnl Cygwin doesn't have an -lutil, but some versions of distutils tell us to use it anyway. dnl It would be better to check for each library it tells us to use with AC_CHECK_LIB, but dnl to do that, we need the name of a function in each one, so we'll just hack -lutil out dnl of the list. PYTHON_DEP_LIBS=`$PYTHON -c "from distutils import sysconfig; import re; print re.sub(r'\\s*-lutil', '', sysconfig.get_config_var('LIBS') or '')"` else dnl this is 'nt' if test "$CXX" = "g++"; then CXXFLAGS="-mno-cygwin $CXXFLAGS" LDFLAGS="-mno-cygwin $LDFLAGS" fi PYTHON_INCLUDE=`cygpath -a $PYTHON_INCLUDE` PYTHON_DEP_LIBS=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_config_var('LIBS') or ''"` fi ;; *) ;; esac CPPFLAGS="-I $PYTHON_INCLUDE $CPPFLAGS" LDFLAGS="-rdynamic $LDFLAGS" LIBS="$LIBS $PYTHON_LIBS $PYTHON_DEP_LIBS" AC_CONFIG_FILES([QMTest/configuration]) AC_OUTPUT From stefan at synopsis.fresco.org Mon Jan 12 20:24:48 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/tests/Cxx-API/Python/expected Dict.out,NONE,1.1 List.out,NONE,1.1 Object.out,NONE,1.1 Tuple.out,NONE,1.1 Message-ID: Update of /cvs/synopsis/Synopsis/tests/Cxx-API/Python/expected In directory frida:/tmp/cvs-serv9641/Cxx-API/Python/expected Added Files: Dict.out List.out Object.out Tuple.out Log Message: support unit tests for C++ API --- NEW FILE: Dict.out --- {'a': 'A', 1: 2, 'hello': 'world'} ['a', 1, 'hello'] ['A', 2, 'world'] [('a', 'A'), (1, 2), ('hello', 'world')] A None ('a', 'A') (1, 2) ('hello', 'world') --- NEW FILE: List.out --- ['a', 1, 'hello', 'world'] [1, 'a', 'hello', 'world'] ['world', 'hello', 'a', 1] world --- NEW FILE: Object.out --- q q hello world hello world 42 42 object not an integer --- NEW FILE: Tuple.out --- ('a', 1, 'hello', 'world') ('a', 1, 'hello', 'world') ('1', '2', '3') ('hello', 'world', 42) From stefan at synopsis.fresco.org Mon Jan 12 20:25:11 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis autogen.sh,1.5,1.6 Message-ID: Update of /cvs/synopsis/Synopsis In directory frida:/tmp/cvs-serv9783 Modified Files: autogen.sh Log Message: support unit tests for C++ API Index: autogen.sh =================================================================== RCS file: /cvs/synopsis/Synopsis/autogen.sh,v retrieving revision 1.5 retrieving revision 1.6 diff -u -p -d -r1.5 -r1.6 --- autogen.sh 30 Dec 2003 19:32:21 -0000 1.5 +++ autogen.sh 12 Jan 2004 20:25:08 -0000 1.6 @@ -13,3 +13,4 @@ conf Synopsis/Parsers/Cpp conf Synopsis/Parsers/C conf Synopsis/Parsers/Cxx conf Synopsis/Parsers/Cxx/gc +conf tests \ No newline at end of file From stefan at synopsis.fresco.org Mon Jan 12 20:31:05 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/tests/qmtest/classes synopsis_database.py,1.3,1.4 synopsis_test.py,1.2,1.3 Message-ID: Update of /cvs/synopsis/Synopsis/tests/qmtest/classes In directory frida:/tmp/cvs-serv9911/qmtest/classes Modified Files: synopsis_database.py synopsis_test.py Log Message: adapt test classes to support C++ API tests Index: synopsis_database.py =================================================================== RCS file: /cvs/synopsis/Synopsis/tests/qmtest/classes/synopsis_database.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -p -d -r1.3 -r1.4 --- synopsis_database.py 2 Dec 2003 16:34:30 -0000 1.3 +++ synopsis_database.py 12 Jan 2004 20:31:03 -0000 1.4 @@ -7,16 +7,23 @@ # see the file COPYING for details. # -from qm.test import database -from qm.test.database import TestDescriptor -from qm.test.database import NoSuchTestError, NoSuchSuiteError -from qm.test.suite import Suite +from qm.fields import TextField +from qm.test import database +from qm.test.database import TestDescriptor +from qm.test.database import NoSuchTestError, NoSuchSuiteError +from qm.test.suite import Suite import os, string, dircache class Database(database.Database): """The Database stores the synopsis tests.""" + arguments = [TextField(name="CXX"), + TextField(name="CPPFLAGS"), + TextField(name="CXXFLAGS"), + TextField(name="LDFLAGS"), + TextField(name="LIBS")] + def GetSuite(self, id): """Construct a suite for the given id""" @@ -41,6 +48,17 @@ class Database(database.Database): dircache.listdir(path)) suite_ids = [] + elif id.startswith('Cxx-API'): + test_ids = [] + suite_ids = filter(lambda x: os.path.isdir(os.path.join(path, x)), + dircache.listdir(path)) + if 'src' in suite_ids: + test_ids = map(lambda x: os.path.splitext(x)[0], + filter(lambda x: x.endswith('.cc'), + dircache.listdir(os.path.join(path, 'src')))) + suite_ids.remove('src') + if 'expected' in suite_ids: suite_ids.remove('expected') + else: test_ids = [] suite_ids = filter(lambda x: os.path.isdir(os.path.join(path, x)), @@ -48,10 +66,12 @@ class Database(database.Database): if 'input' in suite_ids: test_ids = map(lambda x: os.path.splitext(x)[0], dircache.listdir(os.path.join(path, 'input'))) - if 'CVS' in test_ids: test_ids.remove('CVS') suite_ids.remove('input') if 'expected' in suite_ids: suite_ids.remove('expected') - if 'CVS' in suite_ids: suite_ids.remove('CVS') + + if 'CVS' in test_ids: test_ids.remove('CVS') + if 'CVS' in suite_ids: suite_ids.remove('CVS') + if 'autom4te.cache' in suite_ids: suite_ids.remove('autom4te.cache') if id: test_ids = map(lambda x: string.join([id, x], '.'), test_ids) @@ -66,6 +86,10 @@ class Database(database.Database): if id.startswith('Processors.Linker'): return self.make_linker_test(id) + + elif id.startswith('Cxx-API'): + return self.make_api_test(id) + else: return self.make_test(id) @@ -116,3 +140,21 @@ class Database(database.Database): parameters['synopsis'] = os.path.join(*components + ['synopsis.py']) return TestDescriptor(self, id, 'synopsis_test.ProcessorTest', parameters) + + def make_api_test(self, id): + + components = id.split('.') + dirname = os.path.join(*components[:-1]) + + parameters = {} + parameters['CXX'] = self.CXX + parameters['CPPFLAGS'] = self.CPPFLAGS + parameters['CXXFLAGS'] = self.CXXFLAGS + parameters['LDFLAGS'] = self.LDFLAGS + parameters['LIBS'] = self.LIBS + parameters['src'] = os.path.join(dirname, 'src', components[-1]) + '.cc' + parameters['exe'] = os.path.join(dirname, 'bin', components[-1]) + parameters['expected'] = os.path.join(dirname, 'expected', + components[-1] + '.out') + + return TestDescriptor(self, id, 'synopsis_test.APITest', parameters) Index: synopsis_test.py =================================================================== RCS file: /cvs/synopsis/Synopsis/tests/qmtest/classes/synopsis_test.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -p -d -r1.2 -r1.3 --- synopsis_test.py 3 Dec 2003 05:43:55 -0000 1.2 +++ synopsis_test.py 12 Jan 2004 20:31:03 -0000 1.3 @@ -16,6 +16,56 @@ import os import string import sys +class APITest(Test): + """Compile and run a test to validate the C++ API.""" + + arguments = [TextField(name="src", description="The source file."), + TextField(name="exe", description="The executable file."), + TextField(name="expected", description="The expected output file."), + TextField(name="CXX", description="The compiler command."), + TextField(name="CPPFLAGS", description="The preprocessor flags."), + TextField(name="CXXFLAGS", description="The compiler flags."), + TextField(name="LDFLAGS", description="The linker flags."), + TextField(name="LIBS", description="The libraries to link with.")] + + def compile(self, context, result): + if not os.path.isdir(os.path.dirname(self.exe)): + os.makedirs(os.path.dirname(self.exe)) + + command = '%s %s %s %s -o %s %s %s'%(self.CXX, + self.CPPFLAGS, self.CXXFLAGS, + self.LDFLAGS, + self.exe, self.src, self.LIBS) + compiler = RedirectedExecutable() + status = compiler.Run(string.split(command)) + if os.WIFEXITED(status) and os.WEXITSTATUS(status) == 0: + return self.exe + else: + result.Fail('compilation failed', + {'synopsis_test.error': compiler.stderr, + 'synopsis_test.command': command}) + return None + + def Run(self, context, result): + exe = self.compile(context, result) + if not exe: return + test = RedirectedExecutable() + status = test.Run([exe]) + if not os.WIFEXITED(status) and os.WEXITSTATUS(status) == 0: + result.Fail('program exit value : %i'%os.WEXITSTATUS(status)) + if test.stderr: result['orthotest.error'] = test.stderr + + expected = string.join(open(self.expected, 'r').readlines(), '') + if expected and not test.stdout: + result.Fail('program did not generate output') + elif expected and not expected == test.stdout: + expected = '\'%s\''%(expected) + output = '\'%s\''%(test.stdout) + result.Fail('incorrect output', + {'synopsis_test.expected': expected, + 'synopsis_test.output': output}) + + class ProcessorTest(Test): """Process an input file with a synopsis script and compare the output.""" From stefan at synopsis.fresco.org Tue Jan 13 07:37:06 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/Synopsis AST.py,1.30,1.31 Message-ID: Update of /cvs/synopsis/Synopsis/Synopsis In directory frida:/tmp/cvs-serv25705/Synopsis Modified Files: AST.py Log Message: add 'MacroCall' type Index: AST.py =================================================================== RCS file: /cvs/synopsis/Synopsis/Synopsis/AST.py,v retrieving revision 1.30 retrieving revision 1.31 diff -u -p -d -r1.30 -r1.31 --- AST.py 2 Dec 2003 05:44:07 -0000 1.30 +++ AST.py 13 Jan 2004 07:37:03 -0000 1.31 @@ -185,6 +185,17 @@ class Include: def is_next(self): return self.__is_next +class MacroCall: + """A class to support mapping from positions in a preprocessed file + back to positions in the original file.""" + + def __init__(self, name, start, end, diff): + + self.name = name + self.start = start, + self.end = end + self.diff = diff + class SourceFile: """The information about a file that the AST was generated from. Contains filename, all declarations from this file (even nested ones) and @@ -201,6 +212,7 @@ class SourceFile: self.__includes = [] self.__declarations = [] self.__is_main = 0 + self.__macro_calls = {} def is_main(self): """Returns whether this was a main file. A source file is a main file @@ -246,6 +258,9 @@ class SourceFile: tracking since *all* files read while parsing this file are included in the list (even system files).""" return self.__includes + + def macro_calls(self): + return self.__macro_calls class Declaration: """Declaration base class. Every declaration has a name, comments, From stefan at synopsis.fresco.org Tue Jan 13 07:42:12 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/include/Synopsis/AST ASTModule.hh,1.1,1.2 SourceFile.hh,1.2,1.3 Message-ID: Update of /cvs/synopsis/Synopsis/include/Synopsis/AST In directory frida:/tmp/cvs-serv25883/include/Synopsis/AST Modified Files: ASTModule.hh SourceFile.hh Log Message: bug fixes, and support for 'MacroCall' type Index: ASTModule.hh =================================================================== RCS file: /cvs/synopsis/Synopsis/include/Synopsis/AST/ASTModule.hh,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- ASTModule.hh 10 Jan 2004 22:50:34 -0000 1.1 +++ ASTModule.hh 13 Jan 2004 07:42:09 -0000 1.2 @@ -39,6 +39,10 @@ public: params.set(i, Object(parameters[i])); return create("Macro", Tuple(sf, line, lang, type, name, params, text)); } + MacroCall create_macro_call(const std::string &name, int start, int end, int diff) + { + return create("MacroCall", Tuple(name, start, end, diff)); + } SourceFile create_source_file(const std::string &name, const std::string &longname, const std::string &language) Index: SourceFile.hh =================================================================== RCS file: /cvs/synopsis/Synopsis/include/Synopsis/AST/SourceFile.hh,v retrieving revision 1.2 retrieving revision 1.3 diff -u -p -d -r1.2 -r1.3 --- SourceFile.hh 11 Jan 2004 19:46:29 -0000 1.2 +++ SourceFile.hh 13 Jan 2004 07:42:09 -0000 1.3 @@ -26,6 +26,7 @@ public: bool is_main() { return narrow(Callable(attr("is_main")).call());} void is_main(bool flag) { Callable c(attr("set_is_main")); c.call(Tuple(flag));} List includes() { return List(Callable(attr("includes")).call());} + Dict macro_calls() { return Dict(Callable(attr("macro_calls")).call());} }; class Include : public Object @@ -38,6 +39,17 @@ public: void assert_type() throw(TypeError) { Object::assert_type("Synopsis.AST", "Include");} }; +class MacroCall : public Object +{ +public: + MacroCall(const Object &o) throw(TypeError) : Object(o) { assert_type();} + void assert_type() throw(TypeError) { Object::assert_type("Synopsis.AST", "MacroCall");} + std::string name() { return narrow(attr("name"));} + int start() { return narrow(attr("start"));} + int end() { return narrow(attr("end"));} + int diff() { return narrow(attr("diff"));} +}; + } #endif From stefan at synopsis.fresco.org Tue Jan 13 07:42:11 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/include/Synopsis Dict.hh,1.2,1.3 List.hh,1.2,1.3 Tuple.hh,1.2,1.3 Message-ID: Update of /cvs/synopsis/Synopsis/include/Synopsis In directory frida:/tmp/cvs-serv25883/include/Synopsis Modified Files: Dict.hh List.hh Tuple.hh Log Message: bug fixes, and support for 'MacroCall' type Index: Dict.hh =================================================================== RCS file: /cvs/synopsis/Synopsis/include/Synopsis/Dict.hh,v retrieving revision 1.2 retrieving revision 1.3 diff -u -p -d -r1.2 -r1.3 --- Dict.hh 10 Jan 2004 22:50:34 -0000 1.2 +++ Dict.hh 13 Jan 2004 07:42:09 -0000 1.3 @@ -26,7 +26,8 @@ public: Dict(Object o) throw(TypeError) : Object(o) { if (!PyDict_Check(o.my_impl)) throw TypeError("object not a dict");} void set(Object k, Object v); - Object get(Object k) const; + Object get(Object k, Object d = Object()) const; + bool has_key(Object k) const; bool del(Object k); iterator begin(); @@ -34,6 +35,7 @@ public: void clear() { PyDict_Clear(my_impl);} Dict copy() const { return Object(PyDict_Copy(my_impl));} + bool update(Dict d) { return PyDict_Update(my_impl, d.my_impl) == 0;} List keys() const { return List(Object(PyDict_Keys(my_impl)));} List values() const { return List(Object(PyDict_Values(my_impl)));} @@ -106,11 +108,16 @@ inline void Dict::set(Object k, Object v PyDict_SetItem(my_impl, k.my_impl, v.my_impl); } -inline Object Dict::get(Object k) const +inline Object Dict::get(Object k, Object d) const { PyObject *retn = PyDict_GetItem(my_impl, k.my_impl); if (retn) Py_INCREF(retn); - return retn; + return retn ? Object(retn) : d; +} + +inline bool Dict::has_key(Object k) const +{ + return PyDict_GetItem(my_impl, k.my_impl) != 0; } inline bool Dict::del(Object k) Index: List.hh =================================================================== RCS file: /cvs/synopsis/Synopsis/include/Synopsis/List.hh,v retrieving revision 1.2 retrieving revision 1.3 diff -u -p -d -r1.2 -r1.3 --- List.hh 10 Jan 2004 22:50:34 -0000 1.2 +++ List.hh 13 Jan 2004 07:42:09 -0000 1.3 @@ -10,6 +10,7 @@ #define _Synopsis_List_hh #include +#include namespace Synopsis { @@ -19,6 +20,7 @@ class List : public Object public: List(size_t i = 0) : Object(PyList_New(i)) {} List(Object) throw(TypeError); + Tuple tuple() const { return Tuple(PyList_AsTuple(my_impl));} size_t size() const { return PyList_GET_SIZE(my_impl);} void set(int i, Object o); Object get(int i) const; Index: Tuple.hh =================================================================== RCS file: /cvs/synopsis/Synopsis/include/Synopsis/Tuple.hh,v retrieving revision 1.2 retrieving revision 1.3 diff -u -p -d -r1.2 -r1.3 --- Tuple.hh 10 Jan 2004 22:50:34 -0000 1.2 +++ Tuple.hh 13 Jan 2004 07:42:09 -0000 1.3 @@ -10,7 +10,6 @@ #define _Synopsis_Tuple_hh #include -#include namespace Synopsis { @@ -18,9 +17,8 @@ namespace Synopsis class Tuple : public Object { public: - Tuple(size_t i = 0) : Object(PyTuple_New(i)) {} - Tuple(PyObject *); - Tuple(List l) : Object(PyList_AsTuple(l.my_impl)) {} + Tuple() : Object(PyTuple_New(0)) {} + explicit Tuple(PyObject *); Tuple(Object); Tuple(Object, Object); Tuple(Object, Object, Object); @@ -72,9 +70,9 @@ Tuple::Tuple(Object o1, Object o2, Objec Py_INCREF(o1.my_impl); PyTuple_SET_ITEM(my_impl, 1, o2.my_impl); Py_INCREF(o2.my_impl); - PyTuple_SET_ITEM(my_impl, 1, o3.my_impl); + PyTuple_SET_ITEM(my_impl, 2, o3.my_impl); Py_INCREF(o3.my_impl); - PyTuple_SET_ITEM(my_impl, 1, o4.my_impl); + PyTuple_SET_ITEM(my_impl, 3, o4.my_impl); Py_INCREF(o4.my_impl); } @@ -86,11 +84,11 @@ Tuple::Tuple(Object o1, Object o2, Objec Py_INCREF(o1.my_impl); PyTuple_SET_ITEM(my_impl, 1, o2.my_impl); Py_INCREF(o2.my_impl); - PyTuple_SET_ITEM(my_impl, 1, o3.my_impl); + PyTuple_SET_ITEM(my_impl, 2, o3.my_impl); Py_INCREF(o3.my_impl); - PyTuple_SET_ITEM(my_impl, 1, o4.my_impl); + PyTuple_SET_ITEM(my_impl, 3, o4.my_impl); Py_INCREF(o4.my_impl); - PyTuple_SET_ITEM(my_impl, 1, o5.my_impl); + PyTuple_SET_ITEM(my_impl, 4, o5.my_impl); Py_INCREF(o5.my_impl); } @@ -102,13 +100,13 @@ Tuple::Tuple(Object o1, Object o2, Objec Py_INCREF(o1.my_impl); PyTuple_SET_ITEM(my_impl, 1, o2.my_impl); Py_INCREF(o2.my_impl); - PyTuple_SET_ITEM(my_impl, 1, o3.my_impl); + PyTuple_SET_ITEM(my_impl, 2, o3.my_impl); Py_INCREF(o3.my_impl); - PyTuple_SET_ITEM(my_impl, 1, o4.my_impl); + PyTuple_SET_ITEM(my_impl, 3, o4.my_impl); Py_INCREF(o4.my_impl); - PyTuple_SET_ITEM(my_impl, 1, o5.my_impl); + PyTuple_SET_ITEM(my_impl, 4, o5.my_impl); Py_INCREF(o5.my_impl); - PyTuple_SET_ITEM(my_impl, 1, o6.my_impl); + PyTuple_SET_ITEM(my_impl, 5, o6.my_impl); Py_INCREF(o6.my_impl); } @@ -121,15 +119,15 @@ Tuple::Tuple(Object o1, Object o2, Objec Py_INCREF(o1.my_impl); PyTuple_SET_ITEM(my_impl, 1, o2.my_impl); Py_INCREF(o2.my_impl); - PyTuple_SET_ITEM(my_impl, 1, o3.my_impl); + PyTuple_SET_ITEM(my_impl, 2, o3.my_impl); Py_INCREF(o3.my_impl); - PyTuple_SET_ITEM(my_impl, 1, o4.my_impl); + PyTuple_SET_ITEM(my_impl, 3, o4.my_impl); Py_INCREF(o4.my_impl); - PyTuple_SET_ITEM(my_impl, 1, o5.my_impl); + PyTuple_SET_ITEM(my_impl, 4, o5.my_impl); Py_INCREF(o5.my_impl); - PyTuple_SET_ITEM(my_impl, 1, o6.my_impl); + PyTuple_SET_ITEM(my_impl, 5, o6.my_impl); Py_INCREF(o6.my_impl); - PyTuple_SET_ITEM(my_impl, 1, o7.my_impl); + PyTuple_SET_ITEM(my_impl, 6, o7.my_impl); Py_INCREF(o7.my_impl); } From stefan at synopsis.fresco.org Tue Jan 13 07:43:11 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/tests/Cxx-API/Synopsis/AST/src Makefile,1.1,1.2 SourceFile.cc,1.1,1.2 Message-ID: Update of /cvs/synopsis/Synopsis/tests/Cxx-API/Synopsis/AST/src In directory frida:/tmp/cvs-serv25917/tests/Cxx-API/Synopsis/AST/src Modified Files: Makefile SourceFile.cc Log Message: bug fixes Index: Makefile =================================================================== RCS file: /cvs/synopsis/Synopsis/tests/Cxx-API/Synopsis/AST/src/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- Makefile 11 Jan 2004 19:45:21 -0000 1.1 +++ Makefile 13 Jan 2004 07:43:08 -0000 1.2 @@ -14,7 +14,7 @@ PYVERSION:=$(shell $(python) -c "from di PYINC :=$(shell $(python) -c "from distutils import sysconfig; print sysconfig.get_python_inc()") PYLIBS :=-L $(PYPREFIX)/lib/python$(PYVERSION)/config -lpython$(PYVERSION) -ldl -lutil -lpthread -CPPFLAGS:= -I ../../../../include -I $(PYINC) +CPPFLAGS:= -I ../../../../../include -I $(PYINC) LDFLAGS := -rdynamic LIBS := $(PYLIBS) Index: SourceFile.cc =================================================================== RCS file: /cvs/synopsis/Synopsis/tests/Cxx-API/Synopsis/AST/src/SourceFile.cc,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- SourceFile.cc 11 Jan 2004 19:45:21 -0000 1.1 +++ SourceFile.cc 13 Jan 2004 07:43:08 -0000 1.2 @@ -23,10 +23,17 @@ void test1() { ASTModule module = Synopsis::ASTModule(); SourceFile sf = module.create_source_file("filename", "/long/filename", "C++"); + sf.is_main(true); std::cout << "created source file " << sf.name() << ' ' << sf.long_name() << ' ' << sf.is_main() << std::endl; + + MacroCall mc = module.create_macro_call("FOO", 1, 2, 3); + Dict mmap = sf.macro_calls(); + List line = mmap.get(0, List()); + line.append(mc); + mmap.set(0, line); } int main(int, char **) From stefan at synopsis.fresco.org Tue Jan 13 07:43:10 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/tests/Cxx-API/Python/src Interpreter.cc,1.2,1.3 Makefile,1.2,1.3 Tuple.cc,1.1,1.2 Message-ID: Update of /cvs/synopsis/Synopsis/tests/Cxx-API/Python/src In directory frida:/tmp/cvs-serv25917/tests/Cxx-API/Python/src Modified Files: Interpreter.cc Makefile Tuple.cc Log Message: bug fixes Index: Interpreter.cc =================================================================== RCS file: /cvs/synopsis/Synopsis/tests/Cxx-API/Python/src/Interpreter.cc,v retrieving revision 1.2 retrieving revision 1.3 diff -u -p -d -r1.2 -r1.3 --- Interpreter.cc 11 Jan 2004 19:45:21 -0000 1.2 +++ Interpreter.cc 13 Jan 2004 07:43:08 -0000 1.3 @@ -60,9 +60,8 @@ void test3() Object o = type.call(); o = type.call(args); o = type.call(args, kwds); - o.call("execute"); - Callable c(o.attr("execute")); - c.call(); + Callable method = o.attr("execute"); + method.call(); } int main(int, char **) Index: Makefile =================================================================== RCS file: /cvs/synopsis/Synopsis/tests/Cxx-API/Python/src/Makefile,v retrieving revision 1.2 retrieving revision 1.3 diff -u -p -d -r1.2 -r1.3 --- Makefile 11 Jan 2004 19:45:21 -0000 1.2 +++ Makefile 13 Jan 2004 07:43:08 -0000 1.3 @@ -14,7 +14,7 @@ PYVERSION:=$(shell $(python) -c "from di PYINC :=$(shell $(python) -c "from distutils import sysconfig; print sysconfig.get_python_inc()") PYLIBS :=-L $(PYPREFIX)/lib/python$(PYVERSION)/config -lpython$(PYVERSION) -ldl -lutil -lpthread -CPPFLAGS:= -I ../../../include -I $(PYINC) +CPPFLAGS:= -I ../../../../include -I $(PYINC) LDFLAGS := -rdynamic LIBS := $(PYLIBS) Index: Tuple.cc =================================================================== RCS file: /cvs/synopsis/Synopsis/tests/Cxx-API/Python/src/Tuple.cc,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -d -r1.1 -r1.2 --- Tuple.cc 9 Jan 2004 20:03:26 -0000 1.1 +++ Tuple.cc 13 Jan 2004 07:43:08 -0000 1.2 @@ -1,4 +1,5 @@ #include +#include #include "Guard.hh" #include #include @@ -12,7 +13,7 @@ void test1() list.append(1); list.append("hello"); list.append("world"); - Tuple tuple(list); + Tuple tuple = list.tuple(); std::cout << Object::narrow(tuple.str()) << std::endl; Object object(tuple); tuple = Object::narrow(object); From stefan at synopsis.fresco.org Tue Jan 13 07:44:28 2004 From: stefan at synopsis.fresco.org (Stefan Seefeld) Date: Wed Mar 2 21:07:23 2005 Subject: [Synopsis-changes] Synopsis/Synopsis/Synopsis/Parsers/Cpp Parser.py,1.2,1.3 cpp.cc,1.3,1.4 Message-ID: Update of /cvs/synopsis/Synopsis/Synopsis/Parsers/Cpp In directory frida:/tmp/cvs-serv25948/Synopsis/Parsers/Cpp Modified Files: Parser.py cpp.cc Log Message: usr new C++ API Index: Parser.py =================================================================== RCS file: /cvs/synopsis/Synopsis/Synopsis/Parsers/Cpp/Parser.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -p -d -r1.2 -r1.3 --- Parser.py 4 Jan 2004 02:08:26 -0000 1.2 +++ Parser.py 13 Jan 2004 07:44:25 -0000 1.3 @@ -18,7 +18,6 @@ class Parser(Processor): emulate_compiler = Parameter('c++', 'a compiler to emulate') flags = Parameter([], 'list of preprocessor flags such as -I or -D') cpp_output = Parameter(None, 'filename for preprocessed file') - cpp_mmap = Parameter(None, 'output macro calls for the given file') prefix = Parameter(None, 'prefix to strip off from the filename') language = Parameter('C', 'source code programming language of the given input file') @@ -35,7 +34,7 @@ class Parser(Processor): flags += map(lambda x:'-D%s=%s'%(x[0], x[1]), info.macros) for file in self.input: self.ast = ucpp.parse(self.ast, file, self.prefix, - self.cpp_output, self.cpp_mmap, + self.cpp_output, self.language, flags, self.verbose, self.debug) else: print 'not implemented yet: spawn external preprocessor' Index: cpp.cc =================================================================== RCS file: /cvs/synopsis/Synopsis/Synopsis/Parsers/Cpp/cpp.cc,v retrieving revision 1.3 retrieving revision 1.4 diff -u -p -d -r1.3 -r1.4 --- cpp.cc 4 Jan 2004 02:08:26 -0000 1.3 +++ cpp.cc 13 Jan 2004 07:44:25 -0000 1.4 @@ -6,7 +6,7 @@ // see the file COPYING for details. // -#include +#include #include #include #include @@ -21,65 +21,13 @@ namespace int verbose = 0; int debug = 0; -PyObject *ast; +const char *language; const char *prefix = 0; -PyObject *language = 0; -PyObject *source_file = 0; +Synopsis::ASTModule ast_module; +Synopsis::AST ast; +Synopsis::SourceFile source_file; const char *input = 0; -//. MacroMap is a map from preprocessed file positions to input file positions. -//. This may eventually be part of the AST (if more than just declarations are -//. supported), but for now it is persisted into a file in parallel so it can be -//. read in by C/C++ parsers for correct symbol cross referencing. -struct MacroMap -{ - struct Node - { - std::string name; - int start; - int end; - enum Type { START, END } type; - int diff; - bool operator <(const Node &other) const - { - return start < other.start; - } - }; - typedef std::set Line; - typedef std::map LineMap; - - //. Adds a map at the given line. out_{start,end} define the start and - //. past-the-end markers for the macro in the output file. diff defines - //. the signed difference to add to the pos. - void add(const char *name, int linenum, int start, int end, int diff) - { - Line &line = lines[linenum]; - Node node; - node.name = name; // name isn't really needed. For now keep it for debugging... - node.start = start; - node.end = end; - node.type = Node::START; - node.diff = diff; - line.insert(node); - } - void write(const char *filename) - { - std::ofstream ofs(filename); - for (LineMap::iterator i = lines.begin(); - i != lines.end(); ++i) - for (MacroMap::Line::iterator j = (*i).second.begin(); - j != (*i).second.end(); ++j) - ofs << (*i).first << ' ' - << (*j).name << ' ' - << (*j).start << ' ' - << (*j).end << ' ' - << (*j).type << ' ' - << (*j).diff << '\n'; - } - - LineMap l