Пример #1
0
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
Пример #2
0
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
Пример #3
0
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
Пример #4
0
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
Пример #5
0
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
Пример #6
0
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
Пример #7
0
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