def build(classfile): global dclass global vclass global fclass global allclasses global allheaders global withoutpath #print "adding", classfile + "'s members to dictionary" # Reading the header file f = open(classfile, 'r') lines = f.readlines() f.close() vlist = [] # List of members and methods classname = "" COMMENT = FALSE INMACRO = FALSE INRECORD = FALSE INCLASS = FALSE for line in lines: line = wstring.chop(line) # Remove line separators if wstring.strip(line) == "": continue if not INCLASS: INCLASS = lexer.openclass(line) if not INCLASS: continue INCLASS = lexer.closeclass(line) if not INCLASS: continue # Skip typedef and struct blocks if not INRECORD: INRECORD = lexer.openrecord(line) if INRECORD: INRECORD = lexer.closerecord(line) continue # If we are inside a macro or pragma block, skip it if not INMACRO: INMACRO = lexer.opendef(line) if INMACRO: INMACRO = lexer.closedef(line) continue words = string.split(line) if len(words) > 1: w = words[0] if w == "class": # First of new class found if len(vlist) > 0: if classname == "": print "Error, members without class", vlist sys.exit(0) classname = words[1] if classname not in allclasses: allclasses[classname] = classfile if classfile not in allheaders: allheaders[classfile] = classname dummy, fname = os.path.split(classfile) withoutpath[fname] = classname print "class", classname, "in", classfile INCLASS = TRUE continue # Processing comment block if not COMMENT: if not lexer.embeddedcomment(line): COMMENT = lexer.opencomment(line) else: test = lexer.removecomment(line) if wstring.strip(test) == "": continue # Inside a multi-line comment if COMMENT: # Comment opened COMMENT = lexer.closecomment(line) # Always inside comment? # End of multi-line comment if not COMMENT: # Terminator reached i = string.find(line, "*/") if i == -1: print "Error in parsing header" sys.exit(0) line = line[i + 2:] # Keeping the code is exists # Start of multi-line comment if COMMENT: i = string.find(line, "/*") if i != -1: line = line[:i] else: continue line = wstring.strip(line) if line == "": continue # Define statement are ignored if line[0:7] == "#define": continue if lexer.isdeclaration(line): # Processing simple var declarations if lexer.isvardecl(line): nlist = lexer.splitvardecl(line) for n in nlist: vlist.append(n) n = lexer.getident(n) vclass[n] = classname dclass[n] = classname #print "append var", n continue # Processing function declaration if lexer.isprototype(line): f = lexer.prototype vlist.append(f) fkey = lexer.getident(f) fclass[fkey] = classname dclass[fkey] = classname #print "append function", f continue
def processfile(cfile): global extension node, ext = os.path.splitext(cfile) headername = node + ".h" print "mkheader - processing", cfile, "and" , headername infile = open(cfile, "rb") if infile is None: print "Enable to open", cfile sys.exit(0) varlist = [] # list of declarations funclist = [] # list of prototypes defdict = {} # define statements may be needed defflag = {} # flags for things to be inside header defline = {} # the original line linecount = 0 defcount = 0 # Pass 1 - Processing the C file # ------------------------------ # make a list of # - each function definition # - each global variable declaration (simple or array) # - make also a dictionary of define statements COMMENT = FALSE # This flag is true inside a comment INSBLK = FALSE # This one inside a function's body while(1): line = infile.readline() if not line: break linecount = linecount + 1 line = wstring.chop(line) # Removing line separators line = wstring.strip(line) # Removing spaces (with better strip) if len(line) == 0: continue # Empty line ignored # If we enter a comment block, remove it if not COMMENT: COMMENT = lexer.opencomment(line) if COMMENT: i = string.find(line, "/*") left = line[:i] while COMMENT: COMMENT = lexer.closecomment(line) if COMMENT: line = infile.readline() if not line: COMMENT = FALSE linecount = linecount + 1 if not COMMENT: i = string.find(line, "*/") right = line[i + 2:] line = left + right # If we are inside a compound block, skip the content # print linecount, ') [' + str(lexer.blocklevel) + ']', line if not INSBLK: INSBLK = lexer.openblock(line) if INSBLK: i = string.find(line, '{') left = line[:i] # Getting the code at left of { while(INSBLK): INSBLK = lexer.closeblock(line) if INSBLK: line = infile.readline() # Skipping the content linecount = linecount + 1 # print "skiping", lexer.blocklevel, wstring.chop(line) if not line: INSBLK = FALSE if not INSBLK: i = string.find(line, '}') right = line[i + 1:] # Getting the code at right of } line = left + right # "shortened" may change inside the call of the test functions if line is None: continue if line == "": continue # A define statement if line[0] == '#': # Define or pragma statement if line[0:7] == "#define": key, value = lexer.splitdefine(line) if key != None: defdict[key] = value # Add to dictionary defflag[key] = FALSE # By default not to be included in header defline[key] = line #print "define added", line, "value=", value continue if not lexer.isdefinition(line): continue #print "is typed", line # Simple keywords of type on the line if lexer.typeonly(line): while(1): next = infile.readline() if not next: break next = wstring.clean(next) if next == "": continue linecount = linecount + 1 line = line + ' ' + next break # A function prototype: ignore it if lexer.isprototype(line): continue # A function definition if lexer.isfunction(line) == TRUE: line = lexer.shortened #print "is function ", line # The heading may use several lines while string.find(line, ')') == -1: next = infile.readline() linecount = linecount + 1 if next == None: print "Error, function uncomplete" exit() next = wstring.chop(next) next = wstring.strip(next) line = line + next # Handling the old format with declarations on next lines if lexer.oldformat(line): #print "old format", line tlist = [] while(1): l = infile.readline() if not l: break linecount = linecount + 1 l = wstring.chop(l) l = wstring.strip(l) l = lexer.getdecl(l) if lexer.isvardef(l): tlist.append(l) else: break if '{' in l: break # Rebuilding the heading according to the new format line = lexer.argreplace(line, tlist) #print "args replace", line, "with list", tlist i = string.find(line, '{') if i != -1: line = line[:i] line = lexer.removecomment(line) line = lexer.addsemicolon(line) #print "append to funclist", line # There is no prototype for the main function funcname = lexer.getident(line) if funcname is None: print "Error in (" + linecount + ')', line sys.exit(0) funcname = string.lower(funcname) if funcname == "main": continue funclist.append(line) defcount = defcount + 1 #print line continue # An array declaration # is static, ignored # Removing from = to end of line # Adding each size parameter to defdict (done in processarray) # if initializer, become static for C++ line = lexer.getdecl(line) # removing extra codes if lexer.isarray(line): #print "is array", line # Udate defflag vlist = [] if lexer.multivar(line): vlist = lexer.splitvardef(line) #print "multivar", vlist else: vlist.append(line) for vardef in vlist: j = string.find(vardef, '=') k = string.find(vardef, ';') if k == -1: k = len(vardef) if j < k: vardef = vardef[:j] + ';' lexer.processarray(vardef, defdict, defflag) var = lexer.shortened #print "in main shortened", var var = lexer.addextern(var) varlist.append(var) #print "added array", var defcount = defcount + 1 #print line continue # A variable declaration if lexer.isvardef(line): #print "255 var", line vlist = [] if lexer.multivar(line): vlist = lexer.splitvardef(line) #print "multivar", vlist else: vlist.append(line) for vardef in vlist: j = string.find(vardef, '=') k = string.find(vardef, ';') if k == -1: k = len(vardef) if j < k: vardef = vardef[:j] + ';' var = lexer.addextern(vardef) varlist.append(var) #print "added var", var defcount = defcount + 1 #print line # end while infile.close() print linecount, "lines in", cfile # Pass 2 - Processing the header file # ----------------------------------- # I compare it with declarations extracted from the C source, # I replace changes from source into the header file. # I append missing declarations. # I join multi-lines declarations. # And I rewrite the header file. # Reading the file and removing end of file code if exists header = [] if os.path.exists(headername): hfile = open(headername, "rb") header = hfile.readlines() hfile.close # Removing EOF 0x1a ctrl-z is presents if len(header) != 0: l = header[-1] l = wstring.strip(l) if l < ' ': header = header[:-1] tmpheader = [] # For rebuilding the file defheader = {} # Define declarations inside header file rcount = 0 # Replacements kcount = 0 # Fully identical declaration matches = 0 # Declarations with same names COMMENT = FALSE # This flag is true inside a multiline comment INSDEF = FALSE # This one inside a define declaration INSBLK = FALSE # This one inside a compound block oldline = "" # Save line for multi-lines declarations for o in header: # Scanning the header file line = wstring.chop(o) # Remove annoying line separators if wstring.strip(line) == "": # Empty line, keep it tmpheader.append(line) continue # If we enter a comment block, append it and process other code if not COMMENT: if not lexer.embeddedcomment(line): COMMENT = lexer.opencomment(line) else: test = lexer.removecomment(line) if wstring.strip(test) == "": # Simple one-line comment tmpheader.append(line) continue # Inside comment, this is a multi-line comment if COMMENT: # Comment opened COMMENT = lexer.closecomment(line) # Always inside comment? # End of multi-line comment if not COMMENT: # Terminator reached i = string.find(line, "*/") if i == -1: print "Error in parsing header" sys.exit(0) tmpheader.append(line[:i+2]) line = line[i + 2:] # Keeping the code is exists # Start of multi-line comment if COMMENT: i = string.find(line, "/*") if i != -1: tmpheader.append(line[i:]) line = line[:i] else: tmpheader.append(line) # A line of the comment block continue line = wstring.strip(line) if line == "": continue # If we are inside a macro or pragma block, skip it if not INSDEF: INSDEF = lexer.opendef(line) if INSDEF: INSDEF = lexer.closedef(line) tmpheader.append(line) continue # If we are inside some block (struct, typedef), skip it if not INSBLK: INSBLK = lexer.openblock(line) if INSBLK: INSBLK = lexer.closeblock(line) tmpheader.append(line) continue # join declarations in splitted lines if (line[ -1 ] == ","): oldline = oldline + line continue else: if (oldline != ""): line = oldline + line oldline = "" # Define statements are memorized if line[0:7] == "#define": key, value = lexer.splitdefine(line) #print "in header", line, key, value if key != None: defheader[key] = value # Add to dictionary # Searching for var declarations in header file elif lexer.isvardecl(line): #print "var in header", line for n in varlist[:]: #print "in varlist", n #test = wstring.replace(line, "global", "static", FALSE) if lexer.samevar(line, n): # Same name #print "samevars", line, n matches = matches + 1 if lexer.vchanged(line, n): #print "vchanged" lexer.replace(line, n) # Replace, keep comments #print "replaced=", line line = lexer.shortened # old decl. in line replaced if DEBUG: print "replacing", n rcount = rcount + 1 else: kcount = kcount + 1 varlist.remove(n) break # exit for loop line = lexer.addextern(line) # adding "extern" if missing #print "new dec", line # Searching for function declaration elif lexer.isprototype(line): for n in funclist[:]: #print line, n if lexer.samefunction(line, n): # Same name matches = matches + 1 if lexer.fchanged(line, n): # Different returns or arguments lexer.replace(line, n) line = lexer.shortened if DEBUG: print "replacing", line rcount = rcount + 1 else: kcount = kcount + 1 funclist.remove(n) break # In all case, adding the line, either changed or not tmpheader.append(line) # Rewriting and completing the header file added = 0 k = defflag.keys() for d in k: #print "next key", d, defflag[d] if defflag[d] == TRUE: #print "defheader", defheader if not defheader.has_key(d): tmpheader.append(defline[d]) if DEBUG: print "adding", defline[d] for line in varlist: if lexer.isstatic(line): continue tmpheader.append(line) if DEBUG: print "adding", line added = added + 1 for line in funclist: tmpheader.append(line) if DEBUG: print "adding", line added = added + 1 # All done pos = headername.find(".") if (pos != -1): headername = headername[ : pos] headername += ".hpp" hfile = open(headername, "wb") for o in tmpheader: hfile.write(o + "\n") hfile.close() dummy, hname = os.path.split(headername) print "***", defcount, "declaration" + wstring.plural(defcount)+',' , matches, "in", hname + "," , kcount, "identical", rcount , "replaced", added, "added" print "" return
def transform(cfile): global cpp global hpp global locals global linenumber global lastinclude global included global omitted global allclasses global allheaders global withoutpath # I guess the header file name node, ext = os.path.splitext(cfile) hppname = node + ".hpp" # I guess the class name to create an instance dummy, instance = os.path.split(node) instance = allheaders[hppname] print "mkcpp - converting", cfile, "with" , hppname infile = open(cfile, "rb") if infile is None: print "Enable to open", cfile sys.exit(0) cpp = [] hpp = [] varlist = [] funclist = [] staticlist = [] included = [] omitted = [] linenumber = 0 # Internal function: add a line to cpp file def addit(line): global linenumber line = wstring.chop(line) cpp.append(line) linenumber += 1 return # Processing the C file COMMENT = FALSE # This flag is true inside a comment INSBLK = FALSE # This one inside a function's body INSMAC = FALSE NOCASE = (os.name == "nt") | (os.name == "dos") while(1): line = infile.readline() if not line: break line = wstring.chop(line) # Removing line separators if len(wstring.strip(line)) == 0: addit("") continue # Empty line ignored # Updating include statements if len(line) > 11: # min is #include "a" if line[:9] == "#include ": # get last include linenumber lastinclude = linenumber i = string.find(line, '\"') # locate first " if i == -1: #print "no valid" addit(line) continue j = string.find(line, '\"', i + 1) # locate second " if j == -1: print "Error, quotes not closed" print line sys.exit(0) hpath = line[i + 1:j] if len(hpath) > 2: node, ext = os.path.splitext(hpath) hppath = node + ".hpp" if NOCASE: hppath = string.lower(hppath) # add this path to the list of included header files if hppath not in included: included.append(hppath) line = string.replace(line, hpath, hppath) #print "replaced", line addit(line) continue # If we enter a comment block, append it and # process other code on the same line if not COMMENT: if not lexer.embeddedcomment(line): COMMENT = lexer.opencomment(line) else: test = lexer.removecomment(line) if wstring.strip(test) == "": # Simple one-line comment addit(line) continue # Inside a comment block if multi-lines if COMMENT: # Comment opened #print "inside c comment", line COMMENT = lexer.closecomment(line) # Always inside comment? # End of multi-line comment if not COMMENT: # Terminator reached i = string.find(line, "*/") if i == -1: print "Error in parsing header" sys.exit(0) addit(line[:i+2]) line = line[i + 2:] # Keeping the code is exists # Start of multi-line comment if COMMENT: i = string.find(line, "/*") if i != -1: addit(line[i:]) line = line[:i] else: addit(line) # A line of the comment block continue if line is None: continue if wstring.strip(line) == "": addit(line) continue # If we are inside a macro or pragma block, skip it if not INSMAC: INSMAC = lexer.opendef(line) if INSMAC: INSMAC = lexer.closedef(line) addit(line) continue # Comment unterminated are removed if lexer.unterminated(line): line = lexer.removecomment(line) # Simple keywords of type on the line if lexer.typeonly(line): #print "type only", line while(1): next = infile.readline() if not next: break next = wstring.clean(next) if next == "": continue line = line + ' ' + next break #print "type only now", line # A function's prototype: remove it if lexer.isprototype(line): continue # A local one line typedef if lexer.linetypedef(line): addit(line) continue if lexer.linestruct(line): addit(line) continue # A function's definition if lexer.isfunction(line) == TRUE: #print "is function ", line # The heading may use several lines while string.find(line, ')') == -1: next = infile.readline() if next == None: print "Error, function uncomplete" exit() next = wstring.chop(next) next = wstring.strip(next) line = line + next # Handling the old format with declarations on next lines nextline = line if lexer.oldformat(line): #print "old format", line tlist = [] counter = lexer.argscount(line) while(counter): l = infile.readline() if not l: break l = wstring.clean(l) l = lexer.getdecl(l) if lexer.isvardecl(l): tlist.append(l) counter = counter - 1 else: break if '{' in l: i = string.find(l, '{') nextline = l[i:] break # Rebuilding the heading according to the new format line = lexer.argreplace(line, tlist) #print "args replace", line, "with list", tlist # With the class prefix, a function becomes a method # but for the main function funcname = lexer.getident(line) if funcname is None: print "Error, no ident in", line sys.exit(0) funcname = string.lower(funcname) # add the class prefix, but for the main function # for wich classname (used further) must be defined if funcname != "main": line, classname = setmethod(line) else: classname = getclass("main") line = lexer.removestatic(line) addit(line) #print "Added method", line # Now making a list from the block, # for scanning variables inside local scope blocklist = [] # Adding the arguments in the list of local variables plist, pi, pj = lexer.getargs(line) arglist = [] if not plist is None: for p in plist: arglist.append(lexer.addsemicolon(p)) locals = [] processlocals(arglist) # Handling already skiped lines by giving the last line # read from the file, for following tests line = nextline if not INSBLK: INSBLK = '{' in line # reading next lines, skipping empty or comment lines while not INSBLK: line = infile.readline() if not line: print "Error, end of file in block" print line sys.exit(0) blocklist.append(line) INSBLK = lexer.openblock(line) while(INSBLK): INSBLK = lexer.closeblock(line) if INSBLK: #print "inside c block", line line = infile.readline() # Skipping the content if not line: INSBLK = FALSE else: blocklist.append(line) # Making a list of local variables into the "locals" list processlocals(blocklist) # Now performing replacements newblock = processblock(blocklist, classname) for line in newblock: addit(line) continue # Continue in main loop # An external declaration should be ignored # since all vars now have declaration in headers # this works if the declaration is a single line elif lexer.isextern(line): continue # An array declaration # - static: remain global, static removed # - with initializer: become static attribute definition # - without initializer: declared in class, removed here elif lexer.isarray(line): # print "is array", line # One line declaration, save it and continue i = string.find(line, ';') if i != -1: # one line global array with initializer or not if lexer.isstatic(line): line = lexer.removestatic(line) addit(line) continue # attribute with initalizer, transformed j = string.find(line, '='); if j != -1: ahead = line[:j] + ";" line = setmember(line) addit(line) staticlist.append(ahead[:i+1]) # other attribute, removed from source file # but added to list of attributes else: ahead = line varlist.append(ahead[:i + 1]) #print "one line", line[:i + 1] continue # Multiline array with assignment fulldecl = line + "\n" initflag = FALSE globalflag = lexer.isstatic(line) j = string.find(line, "=") if j != -1: ahead = line[:j] + ";" initflag = TRUE else: ahead = line ARRAY = lexer.openarray(line) #print "open?", ARRAY while ARRAY == FALSE: line = infile.readline() #line = lexer.removecomment(line) if wstring.clean(line) != "": fulldecl = fulldecl + line ARRAY = lexer.openarray(line) ARRAY = lexer.closearray(line) while(ARRAY): line = infile.readline() #line = lexer.removecomment(line) fulldecl = fulldecl + line ARRAY = lexer.closearray(line) varlist.append(ahead) if globalflag == TRUE: # a global array fulldecl = lexer.removestatic(fulldecl) addit(fulldecl) continue if initflag == TRUE: fulldecl = setmember(fulldecl) addit(fulldecl) staticlist.append(ahead) continue # A variable definition else: if lexer.isvardef(line): #print "var in source", line globalflag = lexer.isstatic(line) if globalflag: line = lexer.removestatic(line) nlist = [] if lexer.multivar(line): nlist = lexer.splitvardef(line) else: nlist.append(line) for n in nlist: j = string.find(n, '=') if j != -1: ahead = n[:j] + ";" if not globalflag: n = setmember(n) addit(n) staticlist.append(ahead) else: if globalflag: addit(n) ahead = n varlist.append(ahead) #print "append var", n #print line continue # Save a compound block not previously handled if not INSBLK: INSBLK = lexer.openblock(line) if INSBLK: INSBLK = lexer.closeblock(line) #print "open block >", line addit(line) while INSBLK: line = infile.readline() # Skipping the content if not line: break #print "block >", line addit(line) INSBLK = lexer.closeblock(line) continue # other statement #print "other", line addit(line) # end main while addit("") # add the instance of the class addit(instance + " " + instance + "Obj;\n") infile.close() # Processing the header file # It is rebuilt # Reading the file and removing end of file code if exists header = [] if os.path.exists(hppname): hfile = open(hppname, "rb") header = hfile.readlines() hfile.close # Removing EOF 0x1a ctrl-z is presents if len(header) != 0: l = header[-1] l = wstring.strip(l) if l < ' ': header = header[:-1] hpp = [] # To rebuild the file defheader = {} # Define declarations inside header file rcount = 0 # Replacements COMMENT = FALSE # This flag is true while inside a comment block INSMAC = FALSE # This one inside a macro INSTYP = FALSE # This one inside a typedef or struct # Now the header file is rebuilt for o in header: # Scanning the header file line = wstring.chop(o) # Remove annoying line separators if wstring.strip(line) == "": # Empty line, keep it hpp.append(line) continue # If we enter a comment block, append it and process other code if not COMMENT: if not lexer.embeddedcomment(line): COMMENT = lexer.opencomment(line) else: test = lexer.removecomment(line) if wstring.strip(test) == "": # Simple one-line comment hpp.append(line) continue # Inside comment, this is a multi-line comment if COMMENT: # Comment opened #print "inside comment", line COMMENT = lexer.closecomment(line) # Always inside comment? # End of multi-line comment if not COMMENT: # Terminator reached i = string.find(line, "*/") if i == -1: print "Error in parsing header" sys.exit(0) hpp.append(line[:i+2]) line = line[i + 2:] # Keeping the code is exists # Start of multi-line comment if COMMENT: i = string.find(line, "/*") if i != -1: hpp.append(line[i:]) line = line[:i] else: hpp.append(line) # A line of the comment block continue line = wstring.strip(line) if line == "": continue # If we are inside a macro or pragma block, skip it if not INSMAC: INSMAC = lexer.opendef(line) if INSMAC: #print "inside macro", line INSMAC = lexer.closedef(line) hpp.append(line) continue # If we are inside struct or typedef, skip it if not INSTYP: INSTYP = lexer.openrecord(line) if INSTYP: INSTYP = lexer.closerecord(line) hpp.append(line) continue # Define statement are memorized if line[0:7] == "#define": key, value = lexer.splitdefine(line) #print "in header", line, key, value if key != None: defheader[key] = value # Add to dictionary # get the class name from the header if string.find(line, "class") != -1: classname = lexer.getclassname(line) if lexer.isprototype(line): if lexer.isglobal(line): line = lexer.removeglobal(line) hpp.append(line) continue if lexer.isvardecl(line): # print "var in header", line if not lexer.isextern(line): for n in staticlist[:]: #print "var in source", n if lexer.samevar(line, n): # Same name line = lexer.addstatic(line) staticlist.remove(n) break # exit for loop # In all case, adding the line, either changed or not hpp.append(line) # Adding one instance of this class # it must to be defined in the cpp source also # as: classname classnameObj; obj = classname + "Obj" hpp.append("extern " + classname + " " + obj + ';') # Rewriting the updated header file hfile = open(hppname, "wb") for o in hpp: hfile.write(o + "\n") hfile.close() # For each include directive # I get header path, and with it the class name # and I test if the class is in the list of classes used by this source # if not, I add the missing header in which this class is declared for hname in included: # get the path from an include directive if allheaders.has_key(hname): # if this path in allheaders? clname = allheaders[hname] # get the class name the header contains else: dummy, fname = os.path.split(hname) # get the filename if withoutpath.has_key(fname): # perhaps path missing in directive? clname = withoutpath[fname] # get the class from the second list else: print "*", fname, "not in list of headers" continue if clname in omitted: # is class in the list of used classes? omitted.remove(clname) # class already included, remove it #print "already included", clname continue # now adding all omitted include statements for cname in omitted: # get a class name if allclasses.has_key(cname): # is it in the dict hname = allclasses[cname] # get the header filename s = "#include \"" + hname + "\"" # build an include statement cpp.insert(lastinclude + 1, s) # insert it in last position print "added ", s # Creating the C++ code file node, ext = os.path.splitext(cfile) cppname = node + ".cpp" cppfile = open(cppname, "wb") for o in cpp: cppfile.write(o + "\n") cppfile.close() dummy, cppname = os.path.split(cppname) #dummy, hppname = os.path.split(hppname) print cppname, "created,", "and", hppname, "updated" print "" return
def processblock(blocklist, classname): newblock = [] COMMENT = FALSE # This flag is true inside a comment INSBLK = FALSE # This one inside a function's body INSMAC = FALSE linenum = 0 for line in blocklist: linenum = linenum + 1 line = wstring.chop(line) # Removing line separators subline = wstring.strip(line) if len(subline) == 0: continue # Empty line ignored # Processing first line if linenum == 0: i = string.find(subline, '{') if i == -1: print "Error in compound processing" sys.exit(0) subline = subline[i:] # Processing last line if linenum == len(blocklist): i = string.find(subline, '}') if i == -1: print "Error in compound processing" sys.exit(0) subline = subline[0: i+1] # Skip comment block, append it and if not COMMENT: if not lexer.embeddedcomment(subline): COMMENT = lexer.opencomment(subline) else: test = lexer.removecomment(subline) if wstring.strip(test) == "": # Simple one-line comment newblock.append(line) continue # Inside a comment block if multi-lines if COMMENT: # Comment opened COMMENT = lexer.closecomment(subline) # Always inside comment? # End of multi-line comment if not COMMENT: # Terminator reached i = string.find(subline, "*/") if i == -1: print "Error in parsing header" sys.exit(0) subline = subline[i + 2:] # Keeping the code is exists # Start of multi-line comment if COMMENT: i = string.find(subline, "/*") if i != -1: subline = subline[:i] else: newblock.append(line) continue if subline is None: continue subline = wstring.strip(subline) if subline == "": newblock.append(line) continue # If we are inside a macro or pragma block, skip it if not INSMAC: INSMAC = lexer.opendef(subline) if INSMAC: INSMAC = lexer.closedef(line) newblock.append(line) continue # Process ident replacement in other cases line = cppreference(line, subline, classname) newblock.append(line) continue # end of the main for loop return newblock
def processlocals(blocklist): global locals COMMENT = FALSE # This flag is true inside a comment INSBLK = FALSE # This one inside a function's body INSMAC = FALSE #print "processlocals" for line in blocklist: line = wstring.chop(line) # Removing line separators line = wstring.strip(line) # Removing spaces (with better strip) if len(line) == 0: continue # Empty line ignored # If we enter a comment block, append it and # process other code on the same line if not COMMENT: if not lexer.embeddedcomment(line): COMMENT = lexer.opencomment(line) else: test = lexer.removecomment(line) if wstring.strip(test) == "": # Simple one-line comment continue # Inside a comment block if multi-lines if COMMENT: # Comment opened COMMENT = lexer.closecomment(line) # Always inside comment? # End of multi-line comment if not COMMENT: # Terminator reached i = string.find(line, "*/") if i == -1: print "Error in parsing header" sys.exit(0) line = line[i + 2:] # Keeping the code is exists # Start of multi-line comment if COMMENT: i = string.find(line, "/*") if i != -1: line = line[:i] else: continue if line is None: continue line = wstring.strip(line) if line == "": continue # If we are inside a macro or pragma block, skip it if not INSMAC: INSMAC = lexer.opendef(line) if INSMAC: INSMAC = lexer.closedef(line) continue # A declaration if lexer.islocalvar(line): nlist = [] if lexer.multivar(line): nlist = lexer.splitvardef(line) else: nlist.append(line) for n in nlist: id = lexer.getident(n) locals.append(id) #print "is local", id continue if lexer.isarray(line): id = lexer.getident(line) locals.append(id) #print "is array local", id continue if lexer.isprototype(line): continue
def processheader(headername): # Old header, .h or .hpp global classname node, dummy = os.path.splitext(headername) hpath = node + ".hpp" # Path of the new header .hpp dummy, classname = os.path.split(node) hname = classname + ".hpp" # Name of the new header print "mkclass - processing" , headername # Reading the file and removing end of file code if exists header = [] if os.path.exists(headername): hfile = open(headername, "rb") header = hfile.readlines() hfile.close # Removing EOF 0x1a ctrl-z is presents if len(header) != 0: l = header[-1] l = wstring.strip(l) if l < ' ': header = header[:-1] tmpheader = [] # For rebuilding the file sttname = "" COMMENT = FALSE # This flag is true inside a multiline comment INSDEF = FALSE # This one inside a define declaration INSBLK = FALSE # This one inside a compound block INSSTT = FALSE # this one inside a struct decl. INSTYP = FALSE # this one inside a typedef decl. TYPSTT = FALSE # inside a typedef of struct or enum # The first loop copies all defines, multiline macros, blocks # plus static vars and function for o in header: line = o if line == os.linesep: continue line = wstring.chop(line) # If we are inside a comment block, skip it if not COMMENT: COMMENT = lexer.opencomment(line) if COMMENT: COMMENT = lexer.closecomment(line) continue # macro statements are memorized if not INSDEF: INSDEF = lexer.opendef(line) if INSDEF: #print "opend def", line tmpheader.append(line) INSDEF = lexer.closedef(line) continue # instances of enum, struct are outside class if lexer.recordinstance(line): #print "record", line tmpheader.append(line) continue # Processing simple typedef if lexer.newtype(line): name = lexer.lastword(line) if name is None: print "Error no name in", line else: lexer.types.append(name) #print "typedef:", name #print "line", line tmpheader.append(line) continue # processing typdef of struct if not TYPSTT: if lexer.typedefstruct(line): TYPSTT = lexer.opentypedef(line) if TYPSTT: #print "inside typedef of struct", line name = None if lexer.typelevel == 0: # first line name = lexer.getident(line) if name != None: lexer.types.append(name) lexer.typstruct.append(name) #print "new type 1:", name, lexer.typstruct, line if TYPSTT: tmpheader.append(line) TYPSTT = lexer.closetypedef(line) if not TYPSTT: name = lexer.typename(line) if name != None: lexer.types.append(name) lexer.typstruct.append(name) #print "new type 2:" ,name, lexer.typstruct, line continue # processing compound typedef if not INSTYP: INSTYP = lexer.opentypedef(line) if INSTYP: #print "inside typedef", line name = None if lexer.typelevel == 0: # first line name = lexer.getident(line) if name != None: lexer.types.append(name) #print "new type 3:", name, line if INSTYP: tmpheader.append(line) INSTYP = lexer.closetypedef(line) if not INSTYP: name = lexer.typename(line) if name != None: lexer.types.append(name) #lexer.typstruct.append(name) #print "new type 4:" ,name, line continue # structs declarations and instances are kept outside class # as I consider they are ancestors of classes and objects if not INSSTT: INSSTT = lexer.openstruct(line) # test for start of struct if INSSTT: # found #print "inside struct", line name = None if lexer.structlevel == 0: name = lexer.structname(line) # get name if name != None: lexer.types.append(name) # add to types for good parsing lexer.typstruct.append(name) #print "new type 5:", name #print "line", line if INSSTT: # always inside struct INSSTT = lexer.closestruct(line) # test for end tmpheader.append(line) continue # Define are memorized if lexer.isdefine(line): tmpheader.append(line) continue # instances of typedef of struct are outside the class also # static vars remain global and are added to this list # the static modifier should be removed for C++ if lexer.isvardecl(line): #print "pass I - isvardecl", line if lexer.isglobal(line): line = lexer.removeglobal(line) tmpheader.append(lexer.addextern(line)) #print "global added", lexer.addextern(line) continue if lexer.istypstruct(line): tmpheader.append(line) continue # static function added to list if lexer.isglobal(line): if lexer.isprototype(line): tmpheader.append(line) # end of for # Second pass tmpheader.append("") tmpheader.append("class " + classname) tmpheader.append("{") tmpheader.append("public:") COMMENT = FALSE INSDEF = FALSE INSBLK = FALSE INSSTT = FALSE INSTYP = FALSE INUNION = FALSE # The second loop build a class and # copies all variables, functions, comments for o in header: line = wstring.chop(o) if line == None: break # Empty lines are kept if wstring.strip(line) == "": tmpheader.append("") continue # If we enter a comment block, append it and process other code if not COMMENT: if not lexer.embeddedcomment(line): COMMENT = lexer.opencomment(line) else: test = lexer.removecomment(line) if wstring.strip(test) == "": # Simple one-line comment tmpheader.append(line) continue # Inside comment, this is a multi-line comment if COMMENT: # Comment opened COMMENT = lexer.closecomment(line) # Always inside comment? # End of multi-line comment if not COMMENT: # Terminator reached i = string.find(line, "*/") if i == -1: print "Error in parsing header" sys.exit(0) tmpheader.append(line[:i+2]) line = line[i + 2:] # Keeping the code is exists # Start of multi-line comment if COMMENT: i = string.find(line, "/*") if i != -1: tmpheader.append(line[i:]) line = line[:i] else: tmpheader.append(line) # A line of the comment block continue line = wstring.strip(line) if line == "": continue # If we are inside a macro or pragma block, skip it if not INSDEF: INSDEF = lexer.opendef(line) if INSDEF: INSDEF = lexer.closedef(line) continue if lexer.isdefine(line): continue # struct declaration are now ignored if not INSSTT: INSSTT = lexer.openstruct(line) if INSSTT: # inside block sttname = "" #print "(inside struct)", line #if lexer.structlevel == 0: # start or decl. # name = lexer.structname(line) # get name of structure # if name != None: sttname = name #print "structname", sttname INSSTT = lexer.closestruct(line) # end of block? # if INSSTT: continue continue # while in struct continue # typedef are now ignored if not INSTYP: INSTYP = lexer.opentypedef(line) if INSTYP: #print "(in typedef)", line INSTYP = lexer.closetypedef(line) continue # union are stored without change if not INUNION: INUNION = lexer.openunion(line) if INUNION: #print "in union", line INUNION = lexer.closeunion(line) tmpheader.append(line) continue #print "(mkclass, test for func or var)", line # prototype is kept, remove extern if present if lexer.isprototype(line): if lexer.isglobal(line): continue line = lexer.removextern(line) pass elif lexer.isvardecl(line): # static vars remain global in C++ (convention) #print "pass II - var", line if lexer.isglobal(line): #print "global, pass" continue # ignore an instance of struct if lexer.istypstruct(line): #print "mkclass (detect inst. of typedef struct)", line continue # "struct" found # ignore an user's type of struct name = lexer.getident(line) #print "getident", name if name is None: continue if name in lexer.typstruct: #print "in struct", name continue # normal variable becomes attribute # inside class, remove "extern" line = lexer.removextern(line) #print "mkclass (new line):", line else: pass tmpheader.append(line) #print line # End of loop tmpheader.append("};") # Creating the new C++ header file with .hpp extension nh = open(hpath, "wb") for str in tmpheader: nh.write(str + "\n") nh.write("\n") nh.close() print "class", classname, "created into", hname
def build(classfile): global dclass print "adding", classfile + "'s content to dictionary" # Reading the header file f = open(classfile, 'r') lines = f.readlines() f.close() vlist = [] # List of members and methods key = "" COMMENT = FALSE INSMAC = FALSE INSBLK = FALSE INCLASS = FALSE for line in lines: line = wstring.chop(line) # Remove line separators if wstring.strip(line) == "": continue # Skip typedef and struct blocks if not INSBLK: INSBLK = lexer.openstruct(line) if INSBLK: INSBLK = lexer.closeblock(line) continue # If we are inside a macro or pragma block, skip it if not INSMAC: INSMAC = lexer.opendef(line) if INSMAC: INSMAC = lexer.closedef(line) continue words = string.split(line) w = words[0] if (w == "class"): # First of new class found if len(vlist) > 0: if key == "": print "Error, members without class", vlist sys.exit(0) dclass[key] = vlist key = words[1] #print "class", key vlist = [] # New list of members INCLASS = TRUE continue # Processing comment block if not COMMENT: if not lexer.embeddedcomment(line): COMMENT = lexer.opencomment(line) else: test = lexer.removecomment(line) if wstring.strip(test) == "": continue # Inside a multi-line comment if COMMENT: # Comment opened COMMENT = lexer.closecomment(line) # Always inside comment? # End of multi-line comment if not COMMENT: # Terminator reached i = string.find(line, "*/") if i == -1: print "Error in parsing header" sys.exit(0) line = line[i + 2:] # Keeping the code is exists # Start of multi-line comment if COMMENT: i = string.find(line, "/*") if i != -1: line = line[:i] else: continue line = wstring.strip(line) if line == "": continue # Define statement are ignored if line[0:7] == "#define": continue if lexer.isdeclaration(line): # Processing var declarations if lexer.isvardecl(line): nlist = lexer.splitvardecl(line) for n in nlist: vlist.append(n) #print "append var", n continue # Processing function declaration if lexer.isprototype(line): f = lexer.prototype vlist.append(f) #print "append function", f continue # End for # Adding the list of members of the class if key != "": dclass[key] = vlist