⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpp_codegen.py

📁 用python写的ide开发环境,巨强大,不过需要wxpython的支持
💻 PY
📖 第 1 页 / 共 5 页
字号:
# cpp_codegen.py: C++ code generator# $Id: cpp_codegen.py,v 1.49 2007/03/30 06:37:53 agriggio Exp $## Copyright (c) 2002-2007 Alberto Griggio <agriggio@users.sourceforge.net># License: MIT (see license.txt)# THIS PROGRAM COMES WITH NO WARRANTYimport sys, os, os.pathimport common, configimport cStringIO, refrom xml_parse import XmlParsingError# these two globals must be defined for every code generator modulelanguage = 'C++'writer = sys.modules[__name__] # the writer is the module itself# default extensions for generated files: a list of file extensionsdefault_extensions = ['h', 'cpp']"""\dictionary that maps the lines of code of a class to the name of such class:the lines are divided in 3 categories: lines in the constructor,'set_properties' and 'do_layout'"""classes = None"""\dictionary of ``writers'' for the various objects. These are objects that mustimplement the WidgetHandler interface (see below)"""obj_builders = {}# random number used to be sure that the replaced tags in the sources are# the right ones (see SourceFileContent and add_class)nonce = None# lines common to all the generated files (include of <wx/wx.h>, ...)header_lines = []# if True, generate a file for each custom classmultiple_files = False# if not None, they are the header and source file to write intooutput_header, output_source = None, None# if not None, name (without extension) of the file to write intooutput_name = None# if not None, it is the directory inside which the output files are savedout_dir = None# ALB 2004-12-05: wx version we are generating code forfor_version = (2, 4)class ClassLines:    """\    Stores the lines of python code for a custom class    """    def __init__(self):        self.init = [] # lines of code to insert in the constructor        self.parents_init = [] # lines of code to insert in the constructor for                               # container widgets (panels, splitters, ...)        self.ids = [] # ids declared in the source (to use for Event handling):                      # these are grouped together into a public enum in                      # the custom class        self.sizers_init = [] # lines related to sizer objects declarations        self.props = [] # lines to insert in the __set_properties method        self.layout = [] # lines to insert in the __do_layout method        self.sub_objs = [] # list of 2-tuples (type, name) of the                           # sub-objects which are attributes of the                           # toplevel object                self.dependencies = [] # names of the modules this class depends on        self.done = False # if True, the code for this class has already                          # been generated        # ALB 2004-12-08        self.event_handlers = [] # lines to bind events        self.extra_code_h = [] # extra code to output        self.extra_code_cpp = []# end of class ClassLinesclass SourceFileContent:    """\    Keeps info about an existing file that has to be updated, to replace only    the lines inside a wxGlade block, an to keep the rest of the file as it was    """    def __init__(self, name):        self.name = name # name of the file without extension                         # (both header and .cpp)        self.header_content = None # content of the header file        self.source_content = None        self.classes = {} # classes declared in the file        self.new_classes = [] # new classes to add to the file (they are                              # inserted BEFORE the old ones)        # ALB 2004-12-08        self.event_handlers = {} # list of event handlers for each class        self.event_table_decl = {}        self.event_table_def = {}        self.end_class_re = re.compile('^\s*};\s*//\s+wxGlade:\s+end class\s*$')        if classes is None: self.classes = {}        self.build_untouched_content()    def build_untouched_content(self):        """\        Builds a string with the contents of the file that must be left as is,        and replaces the wxGlade blocks with tags that in turn will be replaced        by the new wxGlade blocks        """        self._build_untouched(self.name + '.h', True)        self._build_untouched(self.name + '.cpp', False)    def _build_untouched(self, filename, is_header):        class_name = None        new_classes_inserted = False        # regexp to match class declarations (this isn't very accurate -        # doesn't match template classes, nor virtual inheritance, but        # should be enough for most cases)        class_decl = re.compile(r'^\s*class\s+([a-zA-Z_]\w*)\s*')##                                 '(:\s*(public|protected|private)?\s+[\w:]+'##                                 '(,\s*(public|protected|private)?\s+[\w:]+)*'##                                 ')?')        # regexps to match wxGlade blocks        block_start = re.compile(r'^\s*//\s*begin\s+wxGlade:\s*'                                 '(\w*)::(\w+)\s*$')        block_end = re.compile(r'^\s*//\s*end\s+wxGlade\s*$')        # regexp to match event handlers        # ALB 2004-12-08        event_handler = re.compile(r'^\s*(?:virtual\s+)?'                                   'void\s+([A-Za-z_]+\w*)\s*'                                   '\([A-Za-z_:0-9]+\s*&\s*\w*\)\s*;\s*'                                   '//\s*wxGlade:\s*<event_handler>\s*$')        decl_event_table = re.compile(r'^\s*DECLARE_EVENT_TABLE\s*\(\s*\)'                                      '\s*;?\s*$')        def_event_table = re.compile(r'^\s*BEGIN_EVENT_TABLE\s*\(\s*(\w+)\s*,'                                     '\s*(\w+)\s*\)\s*$')        event_handlers_marker = re.compile(r'^\s*//\s*wxGlade:\s*add\s+'                                           '((?:\w|:)+)\s+event handlers\s*$')        prev_was_handler = False        events_tag_added = False        inside_block = False        inside_comment = False        tmp_in = open(filename)        out_lines = []        for line in tmp_in:            comment_index = line.find('/*')            if not inside_comment and comment_index != -1 \                   and comment_index > line.find('//'):                inside_comment = True            if inside_comment:                end_index = line.find('*/')                if end_index > comment_index: inside_comment = False            if not is_header: result = None            else: result = class_decl.match(line)            if not inside_comment and not inside_block and result is not None:                if class_name is None:                    # this is the first class declared in the file: insert the                    # new ones before this                    out_lines.append('<%swxGlade insert new_classes>' %                                     nonce)                    new_classes_inserted = True                class_name = result.group(1)##                 print 'OK:', class_name                self.classes[class_name] = 1 # add the found class to the list                                             # of classes of this module                out_lines.append(line)            elif not inside_block:                result = block_start.match(line)                if not inside_comment and result is not None:                    # replace the lines inside a wxGlade block with a tag that                    # will be used later by add_class                    inside_block = True                    out_lines.append('<%swxGlade replace %s %s>' % \                                     (nonce, result.group(1), result.group(2)))                else:                    dont_append = False                                        # ALB 2004-12-08 event handling support...                    if is_header and not inside_comment:                        result = event_handler.match(line)                        if result is not None:                            prev_was_handler = True                            which_handler = result.group(1)                            which_class = class_name #result.group(2)                            self.event_handlers.setdefault(                                which_class, {})[which_handler] = 1                        else:                            if prev_was_handler:                                # add extra event handlers here...                                out_lines.append('<%swxGlade event_handlers %s>'                                                 % (nonce, class_name))                                prev_was_handler = False                                events_tag_added = True                            elif not events_tag_added and \                                     self.is_end_of_class(line):                                out_lines.append('<%swxGlade event_handlers %s>'                                                 % (nonce, class_name))                            # now try to see if we already have a                            # DECLARE_EVENT_TABLE                            result = decl_event_table.match(line)                            if result is not None:                                self.event_table_decl[class_name] = True                    elif not inside_comment:                        result = event_handlers_marker.match(line)                        if result is not None:                            out_lines.append('<%swxGlade add %s event '                                             'handlers>' % \                                             (nonce, result.group(1)))                            dont_append = True                        result = def_event_table.match(line)                        if result is not None:                            which_class = result.group(1)                            self.event_table_def[which_class] = True                    # ----------------------------------------                                        if not dont_append:                        out_lines.append(line)            else:                # ignore all the lines inside a wxGlade block                if block_end.match(line) is not None:                    inside_block = False        if is_header and not new_classes_inserted:            # if we are here, the previous ``version'' of the file did not            # contain any class, so we must add the new_classes tag at the            # end of the file            out_lines.append('<%swxGlade insert new_classes>' % nonce)        tmp_in.close()        # set the ``persistent'' content of the file        if is_header: self.header_content = "".join(out_lines)        else: self.source_content = "".join(out_lines)            def is_end_of_class(self, line):        # not really, but for wxglade-generated code it should work...        return self.end_class_re.match(line) is not None #[:2] == '};'# end of class SourceFileContent# if not None, it is an instance of SourceFileContent that keeps info about# the previous version of the source to generateprevious_source = None def tabs(number):    return '    ' * number# if True, overwrite any previous version of the source file instead of# updating only the wxGlade blocks_overwrite = False# if True, enable gettext support_use_gettext = False_quote_str_pattern = re.compile(r'\\[natbv"]?')def _do_replace(match):    if match.group(0) == '\\': return '\\\\'    else: return match.group(0)def quote_str(s, translate=True, escape_chars=True):    """\    returns a quoted version of 's', suitable to insert in a C++ source file    as a string object. Takes care also of gettext support    """    if not s: return 'wxEmptyString'    s = s.replace('"', r'\"')    if escape_chars: s = _quote_str_pattern.sub(_do_replace, s)    else: s = s.replace('\\', r'\\')    if _use_gettext and translate: return '_("' + s + '")'    else: return 'wxT("' + s + '")'def initialize(app_attrs):    """\    Writer initialization function.    See py_codegen.initialize for a description of the parameter.    """    out_path = app_attrs['path']    multi_files = app_attrs['option']        global classes, header_lines, multiple_files, previous_source, nonce, \           _use_gettext, _overwrite, _last_generated_id, \           _current_extra_code_h, _current_extra_code_cpp    import time, random    _last_generated_id = 1000    try: _use_gettext = int(app_attrs['use_gettext'])    except (KeyError, ValueError): _use_gettext = False    # overwrite added 2003-07-15    try: _overwrite = int(app_attrs['overwrite'])    except (KeyError, ValueError): _overwrite = False    # ALB 2004-12-05    global for_version    try:        for_version = tuple([int(t) for t in                             app_attrs['for_version'].split('.')[:2]])    except (KeyError, ValueError):        if common.app_tree is not None:            for_version = common.app_tree.app.for_version        else:            for_version = (2, 4) # default...    # this is to be more sure to replace the right tags    nonce = '%s%s' % (str(time.time()).replace('.', ''),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -