📄 cpp_codegen.py
字号:
random.randrange(10**6, 10**7)) classes = {} header_lines = ['// -*- C++ -*- generated by wxGlade %s on %s%s\n\n' % \ (common.version, time.asctime(), common.generated_from()), '#include <wx/wx.h>\n', '#include <wx/image.h>\n'] if not config.preferences.write_timestamp: header_lines[0] = '// -*- C++ -*- generated by wxGlade %s%s\n\n' % \ (common.version, common.generated_from()) # extra lines to generate (see the 'extracode' property of top-level # widgets) _current_extra_code_h = [] _current_extra_code_cpp = [] multiple_files = multi_files if not multiple_files: global output_header, output_source, output_name name, ext = os.path.splitext(out_path) output_name = name if not _overwrite and os.path.isfile(name + '.h'): # the file exists, we must keep all the lines not inside a wxGlade # block. NOTE: this may cause troubles if out_path is not a valid # C++ file, so be careful! previous_source = SourceFileContent(name) else: previous_source = None output_header = cStringIO.StringIO() output_source = cStringIO.StringIO() for line in header_lines: output_header.write(line) #output_source.write(line) # isolation directives oh = os.path.basename(name + '.h').upper().replace('.', '_') # extra headers #for val in _obj_headers.itervalues():## for handler in obj_builders.itervalues():## for header in getattr(handler, 'extra_headers', []):## output_header.write('#include %s\n' % header) # now, write the tag to store dependencies output_header.write('<%swxGlade replace dependencies>\n' % nonce) output_header.write('\n#ifndef %s\n#define %s\n' % (oh, oh)) output_header.write('\n') # write the tag to store extra code output_header.write('\n<%swxGlade replace extracode>\n' % nonce) output_source.write(header_lines[0]) output_source.write('#include "%s%s"\n\n' % \ (os.path.basename(name), '.h')) output_source.write('<%swxGlade replace extracode>\n\n' % nonce) else: previous_source = None global out_dir if not os.path.isdir(out_path): raise IOError("'path' must be a directory when generating"\ " multiple output files") out_dir = out_pathdef finalize(): """\ Writer ``finalization'' function: flushes buffers, closes open files, ... """ if previous_source is not None: # insert all the new custom classes inside the old file tag = '<%swxGlade insert new_classes>' % nonce if previous_source.new_classes: code = "".join([ c[0] for c in previous_source.new_classes]) else: code = "" header_content = previous_source.header_content.replace(tag, code) extra_source = "".join([ c[1] for c in previous_source.new_classes]) source_content = previous_source.source_content # extra code (see the 'extracode' property of top-level widgets) tag = '<%swxGlade replace extracode>' % nonce code = "\n".join(['// begin wxGlade: ::extracode'] + _current_extra_code_h + ['// end wxGlade\n']) header_content = header_content.replace(tag, code) code = "\n".join(['// begin wxGlade: ::extracode'] + _current_extra_code_cpp + ['// end wxGlade\n']) source_content = source_content.replace(tag, code) # -------------------------------------------------------------- # now remove all the remaining <123415wxGlade ...> tags from the # source: this may happen if we're not generating multiple files, # and one of the container class names is changed tags = re.findall('(<%swxGlade replace ([a-zA-Z_]*\w*) (\w+)>)' % nonce, header_content) for tag in tags: if tag[2] == 'dependencies': #print 'writing dependencies' deps = [] for code in classes.itervalues(): deps.extend(code.dependencies) tmp = ["// begin wxGlade: ::dependencies\n"] for dep in _unique(deps): if dep and ('"' != dep[0] != '<'): tmp.append('#include "%s.h"\n' % dep) else: tmp.append('#include %s\n' % dep) tmp.append("// end wxGlade\n") lines = "".join(tmp) elif tag[2] == 'methods': lines = '%svoid set_properties();\n%svoid do_layout();\n' \ % (tabs(1), tabs(1)) else: lines = '// content of this block (%s) not found: ' \ 'did you rename this class?\n' % tag[2] header_content = header_content.replace(tag[0], lines) tags = re.findall('(<%swxGlade replace ([a-zA-Z_]\w*) +(\w+)>)' % nonce, source_content) for tag in tags: comment = '// content of this block not found: ' \ 'did you rename this class?\n' source_content = source_content.replace(tag[0], comment) # ALB 2004-12-08 tags = re.findall('<%swxGlade event_handlers \w+>' % nonce, header_content) for tag in tags: header_content = header_content.replace(tag, "") tags = re.findall('<%swxGlade add \w+ event_handlers>' % nonce, source_content) for tag in tags: source_content = source_content.replace(tag, "") # write the new file contents to disk common.save_file(previous_source.name + '.h', header_content, 'codegen') common.save_file(previous_source.name + '.cpp', source_content + '\n\n' + extra_source, 'codegen') elif not multiple_files: oh = os.path.basename(output_name).upper() + '_H' output_header.write('\n#endif // %s\n' % oh) # write the list of include files header_content = output_header.getvalue() source_content = output_source.getvalue() tags = re.findall('<%swxGlade replace dependencies>' % nonce, header_content) deps = [] for code in classes.itervalues(): deps.extend(code.dependencies) tmp = ["// begin wxGlade: ::dependencies\n"] for dep in _unique(deps): if dep and ('"' != dep[0] != '<'): tmp.append('#include "%s.h"\n' % dep) else: tmp.append('#include %s\n' % dep) tmp.append("// end wxGlade\n") header_content = header_content.replace( '<%swxGlade replace dependencies>' % nonce, "".join(tmp)) # extra code (see the 'extracode' property of top-level widgets) tag = '<%swxGlade replace extracode>' % nonce code = "\n".join(['// begin wxGlade: ::extracode'] + _current_extra_code_h + ['// end wxGlade\n']) header_content = header_content.replace(tag, code) code = "\n".join(['// begin wxGlade: ::extracode'] + _current_extra_code_cpp + ['// end wxGlade\n']) source_content = source_content.replace(tag, code) # -------------------------------------------------------------- common.save_file(output_name + '.h', header_content, 'codegen') common.save_file(output_name + '.cpp', source_content, 'codegen')def test_attribute(obj): """\ Returns True if 'obj' should be added as an attribute of its parent's class, False if it should be created as a local variable of __do_layout. To do so, tests for the presence of the special property 'attribute' """ try: return int(obj.properties['attribute']) except (KeyError, ValueError): return True # this is the defaultdef add_object(top_obj, sub_obj): """\ adds the code to build 'sub_obj' to the class body of 'top_obj'. """ try: klass = classes[top_obj.klass] except KeyError: klass = classes[top_obj.klass] = ClassLines() try: builder = obj_builders[sub_obj.base] except KeyError: # no code generator found: write a comment about it klass.init.extend(['\n', '// code for %s (type %s) not generated: ' 'no suitable writer found' % (sub_obj.name, sub_obj.klass),'\n']) else: try: init, ids, props, layout = builder.get_code(sub_obj) #builder(sub_obj) except: print sub_obj raise if sub_obj.in_windows: # the object is a wxWindow instance # --- patch 2002-08-26 ------------------------------------------ if sub_obj.is_container and not sub_obj.is_toplevel: init.reverse() klass.parents_init.extend(init) else: klass.init.extend(init) # --------------------------------------------------------------- # -- ALB 2004-12-08 --------------------------------------------- if hasattr(builder, 'get_events'): klass.event_handlers.extend(builder.get_events(sub_obj)) elif 'events' in sub_obj.properties: id_name, id = generate_code_id(sub_obj) #if id == '-1': id = 'self.%s.GetId()' % sub_obj.name for event, handler in sub_obj.properties['events'].iteritems(): klass.event_handlers.append((id, event, handler)) # --------------------------------------------------------------- # try to see if there's some extra code to add to this class extra_code = getattr(builder, 'extracode', sub_obj.properties.get('extracode', "")) if extra_code: extra_code = re.sub(r'\\n', '\n', extra_code) extra_code = re.split(re.compile(r'^###\s*$', re.M), extra_code, 1) klass.extra_code_h.append(extra_code[0]) if len(extra_code) > 1: klass.extra_code_cpp.append(extra_code[1]) # if we are not overwriting existing source, warn the user # about the presence of extra code if multiple_files: warn = False else: warn = previous_source is not None if warn: common.message( 'WARNING', '%s has extra code, but you are ' 'not overwriting existing sources: please check ' 'that the resulting code is correct!' % \ sub_obj.name) # ----------------------------------------------------------- klass.ids.extend(ids) if sub_obj.klass != 'spacer': # attribute is a special property which control whether # sub_obj must be accessible as an attribute of top_obj, # or as a local variable in the do_layout method if test_attribute(sub_obj): klass.sub_objs.append( (sub_obj.klass, sub_obj.name) ) else: # the object is a sizer # ALB 2004-09-17: workaround (hack) for static box sizers... if sub_obj.base == 'wxStaticBoxSizer': klass.sub_objs.insert(0, ('wxStaticBox', '%s_staticbox' % sub_obj.name)) klass.parents_init.insert(1, init.pop(0)) klass.sizers_init.extend(init) klass.props.extend(props) klass.layout.extend(layout) if multiple_files and \ (sub_obj.is_toplevel and sub_obj.base != sub_obj.klass): #print top_obj.name, sub_obj.name klass.dependencies.append(sub_obj.klass) else:## headers = _obj_headers.get(sub_obj.base, []) if sub_obj.base in obj_builders: headers = getattr(obj_builders[sub_obj.base], 'extra_headers', []) klass.dependencies.extend(headers)def add_sizeritem(toplevel, sizer, obj, option, flag, border): """\ writes the code to add the object 'obj' to the sizer 'sizer' in the 'toplevel' object. """ try: klass = classes[toplevel.klass] except KeyError: klass = classes[toplevel.klass] = ClassLines() name = obj.name if obj.base == 'wxNotebook' and for_version < (2, 5): name = 'new wxNotebookSizer(%s)' % obj.name buffer = '%s->Add(%s, %s, %s, %s);\n' % \ (sizer.name, name, option, flag, border) klass.layout.append(buffer)def add_class(code_obj): """\ Generates the code for a custom class. """ if classes.has_key(code_obj.klass) and classes[code_obj.klass].done: return # the code has already been generated if not multiple_files: # in this case, previous_source is the SourceFileContent instance # that keeps info about the single file to generate prev_src = previous_source else: # let's see if the file to generate exists, and in this case # create a SourceFileContent instance filename = os.path.join(out_dir, code_obj.klass.replace('::', '_') + '.h') if _overwrite or not os.path.exists(filename): prev_src = None else: prev_src = SourceFileContent(os.path.join(out_dir, code_obj.klass)) if prev_src is not None and prev_src.classes.has_key(code_obj.klass): # this class wasn't in the previous version of the source (if any) is_new = False
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -