diff --git a/scripts/eolian_generate.py b/scripts/eolian_generate.py index b8e4996..933000d 100755 --- a/scripts/eolian_generate.py +++ b/scripts/eolian_generate.py @@ -6,11 +6,11 @@ import keyword from argparse import ArgumentParser parser = ArgumentParser(description="Python generator for eolian") -parser.add_argument( - '--header-file', required=True, - help="Filename of the library header") +# parser.add_argument( +# '--header-file', required=True, +# help="Filename of the library header") parser.add_argument('-o', '--output', default="/tmp") -parser.add_argument('path') +parser.add_argument('paths', nargs="+") args = parser.parse_args() import logging @@ -444,6 +444,7 @@ class Class(object): self.methods = [] self.props = [] self.default_ctor = None + self.header_path = None @classmethod def parse(klass, cls): @@ -451,17 +452,13 @@ class Class(object): self.__init__() self.cls = cls - for i in cls.inherits_list: - i_cls = eolian.class_find_by_name(i) - if i_cls and ( - i_cls.type == eolian.ClassType.INTERFACE or - i_cls.type == eolian.ClassType.MIXIN): - continue - self.inherits.append("_" + i) + header_path = cls.filename + if not header_path: + return + header_path = os.path.basename(header_path + ".h") + self.header_path = header_path - if not self.inherits: - self.inherits = ("object", ) - self.inherits = ", ".join(self.inherits) + self.inherits = cls.inherits_list desc = self.cls.description if desc: @@ -522,14 +519,32 @@ class Class(object): def pyx_generate(self, gen): if self.ctors or self.methods or self.props: - gen.write('cdef extern from "%s":' % (args.header_file)) + gen.write('cdef extern from "%s":' % (self.header_path)) gen.indent() for o in self.ctors + self.methods + self.props: o.cdef_generate(gen) gen.dedent() gen.write() - gen.write("cdef class _%s(%s):" % (self.cls.name, self.inherits)) + inherits = [] + for i in self.inherits: + i_cls = eolian.class_find_by_name(i) + if i_cls: + if i_cls.type == eolian.ClassType.INTERFACE or \ + i_cls.type == eolian.ClassType.MIXIN: + continue + else: + log.warn("Class %s is unknown" % (i)) + inherits.append("_" + i) + assert len(inherits) < 2, ( + "Multiple inheritance is not supported in extension classes.\n" + "Class: %r, inherits: %r" % (cls, inherits)) + + if not inherits: + inherits = ("object", ) + inherits = ", ".join(inherits) + + gen.write("cdef class _%s(%s):" % (self.cls.name, inherits)) gen.indent() gen.docstring_write(self.docs) @@ -550,23 +565,63 @@ class Class(object): gen.dedent() gen.write() + def py_generate(self, gen): + if len(self.inherits) < 2: + return -for dirpath, dirnames, filenames in os.walk(args.path): - for filename in filenames: - if filename.endswith(".eo"): - f = os.path.join(dirpath, filename) - eolian.eo_file_parse(f) - cls = eolian.class_find_by_file(f) + inherits = ["_" + self.cls.name] + for i in self.inherits: + i_cls = eolian.class_find_by_name(i) + if i_cls: + if i_cls.type == eolian.ClassType.REGULAR or \ + i_cls.type == eolian.ClassType.ABSTRACT: + continue + else: + log.warn("Class %s is unknown" % (i)) + inherits.append("_" + i) - pyxgen = PyxGenerator() - gencls = Class.parse(cls) - gencls.pyx_generate(pyxgen) + gen.write("class %s(%s):" % (self.cls.name, ", ".join(inherits))) + gen.indent() + gen.write("pass") + gen.dedent() + gen.write() - f_base = os.path.splitext(filename)[0] - pxi_path = os.path.join(args.output, f_base + ".pxi") - with open(pxi_path, "w") as f: - f.write(pyxgen.printout().encode("utf-8")) - f.write("\n") - log.info(pxi_path + " written") + +py_path = os.path.join(args.output, "__init__" + ".py") +if os.path.exists(py_path): + os.remove(py_path) + +for path in args.paths: + for dirpath, dirnames, filenames in os.walk(path): + eolian.directory_scan(dirpath) + eolian.all_eo_files_parse() + for filename in filenames: + if filename.endswith(".eo"): + f = os.path.join(dirpath, filename) + if not eolian.eo_file_parse(f): + log.error("Could not parse %s" % (f)) + cls = eolian.class_find_by_file(f) + gencls = Class.parse(cls) + + pyxgen = PyxGenerator() + gencls.pyx_generate(pyxgen) + + f_base = os.path.splitext(filename)[0] + pxi_path = os.path.join(args.output, f_base + ".pxi") + o = pyxgen.printout() + if o: + with open(pxi_path, "w") as f: + f.write(o.encode("utf-8")) + log.info(pxi_path + " written") + + pygen = Generator() + gencls.py_generate(pygen) + + o = pygen.printout() + if o: + with open(py_path, "a") as f: + f.write(o.encode("utf-8")) + f.write("\n") + log.info(py_path + " written") eolian.shutdown()