Functions | |
def | output |
def | rec_name_n_param |
def | start_recording |
def | is_recording_finished |
def | gather_comment |
Gather comment block. | |
def | print_comment |
Output comment block and empty buffer. | |
def | set_state |
def | get_state |
def | push_state |
def | pop_state |
def | tok_eater |
def | dump |
def | filter |
def | filterFile |
def | preparePath |
def | isNewer |
def | convert |
Variables | |
int | OUTSIDE = 0 |
int | BUILD_COMMENT = 1 |
int | BUILD_CLASS_DECL = 2 |
int | BUILD_CLASS_BODY = 3 |
int | BUILD_DEF_DECL = 4 |
int | BUILD_DEF_BODY = 5 |
int | IMPORT = 6 |
int | IMPORT_OP = 7 |
int | IMPORT_APPEND = 8 |
outfile = sys.stdout | |
list | outbuffer = [] |
int | out_row = 0 |
int | out_col = 0 |
string | name = "" |
string | param = "" |
string | doc_string = "" |
int | record_state = 0 |
int | bracket_counter = 0 |
tuple | class_spos = (0,0) |
tuple | def_spos = (0,0) |
tuple | import_spos = (0,0) |
string | import_token = "" |
list | comment_block = [] |
int | comment_finished = 0 |
list | modules = [] |
list | stateStack = [OUTSIDE] |
module_has_docstring = False | |
string | protection_level = "public" |
private_member = False | |
string | namespace = "" |
filter_file = False | |
tuple | filename = string.join(args) |
tuple | c = convert(args[0],args[1]) |
def pythfilter::convert | ( | srcpath, | ||
destpath | ||||
) |
Convert a Python source tree into a C+ stub tree. All *.py files in srcpath (including sub-directories) are filtered and written to destpath. If destpath exists, only the files that have been modified are filtered again. Files that were deleted from srcpath are also deleted in destpath if they are still present. The function returns the number of processed *.py files.
Definition at line 504 of file pythfilter.py.
00504 : 00505 """Convert a Python source tree into a C+ stub tree. 00506 00507 All *.py files in srcpath (including sub-directories) are filtered 00508 and written to destpath. If destpath exists, only the files 00509 that have been modified are filtered again. Files that were deleted 00510 from srcpath are also deleted in destpath if they are still present. 00511 The function returns the number of processed *.py files. 00512 """ 00513 count=0 00514 sp = os.path.join(srcpath,"*") 00515 sfiles = glob.glob(sp) 00516 dp = os.path.join(destpath,"*") 00517 dfiles = glob.glob(dp) 00518 leftovers={} 00519 for df in dfiles: 00520 leftovers[os.path.basename(df)]=1 00521 00522 for srcfile in sfiles: 00523 basename = os.path.basename(srcfile) 00524 if basename in leftovers: 00525 del leftovers[basename] 00526 00527 # Is it a subdirectory? 00528 if os.path.isdir(srcfile): 00529 sdir = os.path.join(srcpath,basename) 00530 ddir = os.path.join(destpath,basename) 00531 count+=convert(sdir, ddir) 00532 continue 00533 # Check the extension (only *.py will be converted) 00534 root, ext = os.path.splitext(srcfile) 00535 if ext.lower()!=".py": 00536 continue 00537 00538 destfile = os.path.join(destpath,basename) 00539 if destfile==srcfile: 00540 print "WARNING: Input and output names are identical!" 00541 sys.exit(1) 00542 00543 count+=1 00544 # sys.stdout.write("%s\015"%(srcfile)) 00545 00546 if isNewer(srcfile, destfile): 00547 preparePath(os.path.dirname(destfile)) 00548 # out=open(destfile,"w") 00549 # filterFile(srcfile, out) 00550 # out.close() 00551 os.system("python %s -f %s>%s"%(sys.argv[0],srcfile,destfile)) 00552 00553 # Delete obsolete files in destpath 00554 for df in leftovers: 00555 dname=os.path.join(destpath,df) 00556 if os.path.isdir(dname): 00557 try: 00558 shutil.rmtree(dname) 00559 except: 00560 print "Can't remove obsolete directory '%s'"%dname 00561 else: 00562 try: 00563 os.remove(dname) 00564 except: 00565 print "Can't remove obsolete file '%s'"%dname 00566 00567 return count 00568 00569 ######################################################################
def pythfilter::dump | ( | filename | ) |
Definition at line 426 of file pythfilter.py.
00426 : 00427 f = open(filename) 00428 r = f.readlines() 00429 for s in r: 00430 sys.stdout.write(s) 00431 def filter(filename):
def pythfilter::filter | ( | filename | ) |
Definition at line 432 of file pythfilter.py.
00432 : 00433 global name, module_has_docstring 00434 00435 path,name = os.path.split(filename) 00436 root,ext = os.path.splitext(name) 00437 00438 output("namespace "+root+" {\n",(0,0)) 00439 00440 # set module name for tok_eater to use if there's a module doc string 00441 name = root 00442 00443 sys.stderr.write('Filtering "'+filename+'"...') 00444 f = open(filename) 00445 tokenize.tokenize(f.readline, tok_eater) 00446 f.close() 00447 print_comment((0,0)) 00448 00449 output("\n",(0,0)) 00450 output("} // end of namespace\n",(0,0)) 00451 00452 if not module_has_docstring: 00453 # Put in default namespace documentation 00454 output('/** \\namespace '+root+' \n',(0,0)) 00455 output(' \\brief Module "%s" */\n'%(root),(0,0)) 00456 00457 for s in outbuffer: 00458 outfile.write(s) 00459 00460 def filterFile(filename, out=sys.stdout):
def pythfilter::filterFile | ( | filename, | ||
out = sys.stdout | ||||
) |
Definition at line 461 of file pythfilter.py.
00461 : 00462 global outfile 00463 00464 outfile = out 00465 00466 try: 00467 root,ext = os.path.splitext(filename) 00468 00469 if ext==".py": 00470 filter(filename) 00471 else: 00472 dump(filename) 00473 00474 sys.stderr.write("OK\n") 00475 except IOError,e: 00476 sys.stderr.write(e[1]+"\n") 00477 00478 ######################################################################
def pythfilter::gather_comment | ( | type, | ||
tok, | ||||
spos | ||||
) |
Definition at line 249 of file pythfilter.py.
00249 : 00250 global comment_block,comment_finished 00251 if (type!=tokenize.COMMENT): 00252 comment_finished = 1 00253 else: 00254 # Output old comment block if a new one is started. 00255 if (comment_finished): 00256 print_comment(spos) 00257 comment_finished=0 00258 if (tok[0:2]=="##" and tok[0:3]!="###"): 00259 comment_block.append(tok[2:]) 00260 ######################################################################
def pythfilter::get_state | ( | ) |
Definition at line 280 of file pythfilter.py.
00280 : 00281 global stateStack 00282 return stateStack[len(stateStack)-1] 00283 ######################################################################
def pythfilter::is_recording_finished | ( | ) |
Definition at line 242 of file pythfilter.py.
00242 : 00243 global record_state 00244 return record_state==0 00245 ######################################################################
def pythfilter::isNewer | ( | file1, | ||
file2 | ||||
) |
Check if file1 is newer than file2. file1 must be an existing file.
Definition at line 494 of file pythfilter.py.
00494 : 00495 """Check if file1 is newer than file2. 00496 00497 file1 must be an existing file. 00498 """ 00499 if not os.path.exists(file2): 00500 return True 00501 return os.stat(file1)[ST_MTIME]>os.stat(file2)[ST_MTIME] 00502 00503 # convert def convert(srcpath, destpath):
def pythfilter::output | ( | s, | ||
spos, | ||||
immediate = 0 | ||||
) |
Definition at line 155 of file pythfilter.py.
00155 : 00156 global outbuffer, out_row, out_col, outfile 00157 00158 os = string.rjust(s,spos[1]-out_col+len(s)) 00159 if immediate: 00160 outfile.write(os) 00161 else: 00162 outbuffer.append(os) 00163 if (s[-1:]=="\n"): 00164 out_row = out_row+1 00165 out_col = 0 00166 else: 00167 out_col = spos[1]+len(s) 00168 00169 ######################################################################
def pythfilter::pop_state | ( | ) |
Definition at line 290 of file pythfilter.py.
00290 : 00291 global stateStack 00292 stateStack.pop() 00293 00294 ######################################################################
def pythfilter::preparePath | ( | path | ) |
Prepare a path. Checks if the path exists and creates it if it does not exist.
Definition at line 482 of file pythfilter.py.
00482 : 00483 """Prepare a path. 00484 00485 Checks if the path exists and creates it if it does not exist. 00486 """ 00487 if not os.path.exists(path): 00488 parent = os.path.dirname(path) 00489 if parent!="": 00490 preparePath(parent) 00491 os.mkdir(path) 00492 00493 # isNewer def isNewer(file1,file2):
def pythfilter::print_comment | ( | spos | ) |
Definition at line 264 of file pythfilter.py.
00264 : 00265 global comment_block,comment_finished 00266 if (comment_block!=[]): 00267 output("/**\n",spos) 00268 for c in comment_block: 00269 output(c,spos) 00270 output("*/\n",spos) 00271 comment_block = [] 00272 comment_finished = 0 00273 ######################################################################
def pythfilter::push_state | ( | s | ) |
Definition at line 285 of file pythfilter.py.
00285 : 00286 global stateStack 00287 stateStack.append(s) 00288 ######################################################################
def pythfilter::rec_name_n_param | ( | type, | ||
tok | ||||
) |
Definition at line 182 of file pythfilter.py.
00182 : 00183 global record_state,name,param,doc_string,bracket_counter 00184 s = record_state 00185 # State 0: Do nothing. 00186 if (s==0): 00187 return 00188 # State 1: Remember name. 00189 elif (s==1): 00190 name = tok 00191 record_state = 2 00192 # State 2: Wait for opening bracket or colon 00193 elif (s==2): 00194 if (tok=='('): 00195 bracket_counter = 1 00196 record_state=3 00197 if (tok==':'): record_state=4 00198 # State 3: Store parameter (or base class) and wait for an ending bracket 00199 elif (s==3): 00200 if (tok=='*' or tok=='**'): 00201 tok='' 00202 if (tok=='('): 00203 bracket_counter = bracket_counter+1 00204 if (tok==')'): 00205 bracket_counter = bracket_counter-1 00206 if bracket_counter==0: 00207 record_state=4 00208 else: 00209 param=param+tok 00210 # State 4: Look for doc string 00211 elif (s==4): 00212 if (type==token.NEWLINE or type==token.INDENT or type==token.SLASHEQUAL): 00213 return 00214 elif (tok==":"): 00215 return 00216 elif (type==token.STRING): 00217 while tok[:1]=='r' or tok[:1]=='u': 00218 tok=tok[1:] 00219 while tok[:1]=='"': 00220 tok=tok[1:] 00221 while tok[-1:]=='"': 00222 tok=tok[:-1] 00223 doc_string=tok 00224 record_state=0 00225 ######################################################################
def pythfilter::set_state | ( | s | ) |
Definition at line 275 of file pythfilter.py.
00275 : 00276 global stateStack 00277 stateStack[len(stateStack)-1]=s 00278 ######################################################################
def pythfilter::start_recording | ( | ) |
Definition at line 232 of file pythfilter.py.
00232 : 00233 global record_state,param,name, doc_string 00234 record_state=1 00235 name="" 00236 param="" 00237 doc_string="" 00238 ######################################################################
def pythfilter::tok_eater | ( | type, | ||
tok, | ||||
spos, | ||||
epos, | ||||
line | ||||
) |
Definition at line 296 of file pythfilter.py.
00296 : 00297 global stateStack,name,param,class_spos,def_spos,import_spos 00298 global doc_string, modules, import_token, module_has_docstring 00299 global protection_level, private_member 00300 00301 rec_name_n_param(type,tok) 00302 if (string.replace(string.strip(tok)," ","")=="##private:"): 00303 protection_level = "private" 00304 output("private:\n",spos) 00305 elif (string.replace(string.strip(tok)," ","")=="##protected:"): 00306 protection_level = "protected" 00307 output("protected:\n",spos) 00308 elif (string.replace(string.strip(tok)," ","")=="##public:"): 00309 protection_level = "public" 00310 output("public:\n",spos) 00311 else: 00312 gather_comment(type,tok,spos) 00313 00314 state = get_state() 00315 00316 # sys.stderr.write("%d: %s\n"%(state, tok)) 00317 00318 # OUTSIDE 00319 if (state==OUTSIDE): 00320 if (tok=="class"): 00321 start_recording() 00322 class_spos = spos 00323 push_state(BUILD_CLASS_DECL) 00324 elif (tok=="def"): 00325 start_recording() 00326 def_spos = spos 00327 push_state(BUILD_DEF_DECL) 00328 elif (tok=="import") or (tok=="from"): 00329 import_token = tok 00330 import_spos = spos 00331 modules = [] 00332 push_state(IMPORT) 00333 elif (spos[1] == 0 and tok[:3] == '"""'): 00334 # Capture module docstring as namespace documentation 00335 module_has_docstring = True 00336 comment_block.append("\\namespace %s\n" % namespace) 00337 comment_block.append(tok[3:-3]) 00338 print_comment(spos) 00339 00340 # IMPORT 00341 elif (state==IMPORT): 00342 if (type==token.NAME): 00343 modules.append(tok) 00344 set_state(IMPORT_OP) 00345 # IMPORT_OP 00346 elif (state==IMPORT_OP): 00347 if (tok=="."): 00348 set_state(IMPORT_APPEND) 00349 elif (tok==","): 00350 set_state(IMPORT) 00351 else: 00352 for m in modules: 00353 output('#include "'+m.replace('.',os.path.sep)+'.py"\n', import_spos, immediate=1) 00354 if import_token=="from": 00355 output('using namespace '+m.replace('.', '::')+';\n', import_spos) 00356 pop_state() 00357 # IMPORT_APPEND 00358 elif (state==IMPORT_APPEND): 00359 if (type==token.NAME): 00360 modules[len(modules)-1]+="."+tok 00361 set_state(IMPORT_OP) 00362 # BUILD_CLASS_DECL 00363 elif (state==BUILD_CLASS_DECL): 00364 if (is_recording_finished()): 00365 s = "class "+name 00366 if (param!=""): s = s+" : public "+param.replace('.','::') 00367 if (doc_string!=""): comment_block.append(doc_string) 00368 print_comment(class_spos) 00369 output(s+"\n",class_spos) 00370 output("{\n",(class_spos[0]+1,class_spos[1])) 00371 protection_level = "public" 00372 output(" public:\n",(class_spos[0]+2,class_spos[1])) 00373 set_state(BUILD_CLASS_BODY) 00374 # BUILD_CLASS_BODY 00375 elif (state==BUILD_CLASS_BODY): 00376 if (type!=token.INDENT and type!=token.NEWLINE and type!=40 and 00377 type!=tokenize.NL and type!=tokenize.COMMENT and 00378 (spos[1]<=class_spos[1])): 00379 output("}; // end of class\n",(out_row+1,class_spos[1])) 00380 pop_state() 00381 elif (tok=="def"): 00382 start_recording() 00383 def_spos = spos 00384 push_state(BUILD_DEF_DECL) 00385 # BUILD_DEF_DECL 00386 elif (state==BUILD_DEF_DECL): 00387 if (is_recording_finished()): 00388 s = '' 00389 # Do we document a class method? then remove the 'self' parameter 00390 if BUILD_CLASS_BODY in stateStack: 00391 params = param.split(",") 00392 if params[0] == 'self': 00393 param = string.join(params[1:], ",") 00394 else: 00395 s = 'static ' 00396 if params[0] == 'cls': 00397 param = string.join(params[1:], ",") 00398 s = s+name+"("+param+");\n" 00399 if len(name) > 1 \ 00400 and name[0:2] == '__' \ 00401 and name[len(name)-2:len(name)] != '__' \ 00402 and protection_level != 'private': 00403 private_member = True 00404 output(" private:\n",(def_spos[0]+2,def_spos[1])) 00405 else: 00406 s = name+"("+param+");\n" 00407 if (doc_string!=""): comment_block.append(doc_string) 00408 print_comment(def_spos) 00409 output(s,def_spos) 00410 # output("{\n",(def_spos[0]+1,def_spos[1])) 00411 set_state(BUILD_DEF_BODY) 00412 # BUILD_DEF_BODY 00413 elif (state==BUILD_DEF_BODY): 00414 if (type!=token.INDENT and type!=token.NEWLINE \ 00415 and type!=40 and type!=tokenize.NL \ 00416 and (spos[1]<=def_spos[1])): 00417 # output("} // end of method/function\n",(out_row+1,def_spos[1])) 00418 if private_member and protection_level != 'private': 00419 private_member = False 00420 output(" " + protection_level + ":\n",(def_spos[0]+2,def_spos[1])) 00421 pop_state() 00422 # else: 00423 # output(tok,spos) 00424 00425 def dump(filename):
int pythfilter::bracket_counter = 0 |
Definition at line 118 of file pythfilter.py.
int pythfilter::BUILD_CLASS_BODY = 3 |
Definition at line 97 of file pythfilter.py.
int pythfilter::BUILD_CLASS_DECL = 2 |
Definition at line 96 of file pythfilter.py.
int pythfilter::BUILD_COMMENT = 1 |
Definition at line 95 of file pythfilter.py.
int pythfilter::BUILD_DEF_BODY = 5 |
Definition at line 99 of file pythfilter.py.
int pythfilter::BUILD_DEF_DECL = 4 |
Definition at line 98 of file pythfilter.py.
tuple pythfilter::c = convert(args[0],args[1]) |
Definition at line 598 of file pythfilter.py.
tuple pythfilter::class_spos = (0,0) |
Definition at line 121 of file pythfilter.py.
list pythfilter::comment_block = [] |
Definition at line 129 of file pythfilter.py.
int pythfilter::comment_finished = 0 |
Definition at line 130 of file pythfilter.py.
tuple pythfilter::def_spos = (0,0) |
Definition at line 122 of file pythfilter.py.
string pythfilter::doc_string = "" |
Definition at line 116 of file pythfilter.py.
tuple pythfilter::filename = string.join(args) |
Definition at line 588 of file pythfilter.py.
pythfilter::filter_file = False |
Definition at line 574 of file pythfilter.py.
int pythfilter::IMPORT = 6 |
Definition at line 100 of file pythfilter.py.
int pythfilter::IMPORT_APPEND = 8 |
Definition at line 102 of file pythfilter.py.
int pythfilter::IMPORT_OP = 7 |
Definition at line 101 of file pythfilter.py.
tuple pythfilter::import_spos = (0,0) |
Definition at line 123 of file pythfilter.py.
string pythfilter::import_token = "" |
Definition at line 126 of file pythfilter.py.
pythfilter::module_has_docstring = False |
Definition at line 139 of file pythfilter.py.
list pythfilter::modules = [] |
Definition at line 133 of file pythfilter.py.
string pythfilter::name = "" |
Definition at line 114 of file pythfilter.py.
string pythfilter::namespace = "" |
Definition at line 146 of file pythfilter.py.
int pythfilter::out_col = 0 |
Definition at line 111 of file pythfilter.py.
int pythfilter::out_row = 0 |
Definition at line 110 of file pythfilter.py.
list pythfilter::outbuffer = [] |
Definition at line 108 of file pythfilter.py.
pythfilter::outfile = sys.stdout |
Definition at line 105 of file pythfilter.py.
int pythfilter::OUTSIDE = 0 |
Definition at line 94 of file pythfilter.py.
string pythfilter::param = "" |
Definition at line 115 of file pythfilter.py.
pythfilter::private_member = False |
Definition at line 143 of file pythfilter.py.
string pythfilter::protection_level = "public" |
Definition at line 142 of file pythfilter.py.
int pythfilter::record_state = 0 |
Definition at line 117 of file pythfilter.py.
list pythfilter::stateStack = [OUTSIDE] |
Definition at line 136 of file pythfilter.py.