#!/usr/bin/env python import os, sys, string, regsub, posixpath # Doesn't overwrite input files, various cleanup -- Peter Onyisi # Original authors unknown. #------------------------------------------------------------------------------- # parse single EXPAND directive #------------------------------------------------------------------------------- def parse_directive(directive): # print " ----------------- parse directive " # print directive n_errors = 0 s = string.lower(directive) list = string.split(s) if (list[0] == '$$if') : # $$IF directive list[0] = '#ifdef' if list[1] == 'ibm' and len(list) > 2 : if list[2] == 'or' and list[3] == 'rs6000': list = ('#if','defined(IBM) || defined(RS6000) || defined(LINUX)') else: if (list[1] == 'rs6000'): list = ('#if','defined(RS6000) || defined(LINUX)') list[1] = string.upper(list[1]); elif (list[0] == '$$debug'): # $$ELSEIF directive list = ('#ifdef DEBUG','') elif (list[0] == '$$enddebug'): # $$ELSEIF directive list = ('#endif','') elif (list[0] == '$$elseif'): # $$ELSEIF directive if (list[1] == 'rs6000'): list[0] = '#elif' list[1] = 'defined(RS6000) || defined(LINUX)' else: list[0] = '#elif' list[1] = string.upper(list[1]); elif (list[0] == '$$endif'): # $$ENDIF directive list[0] = '#endif' elif (list[0] == '$$else'): # $$ELSE directive list[0] = '#else' elif (list[0] == '$$alias'): # $$ALIAS directive: I dont want # to change the substitution itself list[0] = '#define' l = string.split(directive); list[1] = l[1] list[2] = l[2] elif (list[0] == '$$implicit'): # $$IF directive list = (' implicit','none') elif (list[0] == '$$include') : # $$INCLUDE directive list = string.split(s,"'") list[0] = '#include ' # print ' list = ', list l1 = string.split(list[1],":") # print ' -- after spliting log:name l1 = ', l1 # # at least in UIPACK package there # are includes (in VAX version), which # have names, consisting just of 1 # environmental variable: do nothing # if (len(l1) > 1) : # l1[0] - logical name # l1[1] - include name # change logical name log = l1[0] name = string.split(log,'$'); # check whether there is a '$' in # the name if (len(name) == 1): # there is just one env variable in # the name name = [name[0],'/'] else: # name contains '$' sign in it (this is a regular case) # process the name of the include file # # print ' -> l1 :' , l1 fname = string.split(l1[1],'.') # print fname # # cut out trailing blanks in name # fname[0] = string.split(fname[0],' ')[0] # # process extention # # print fname if (fname[1][0:2] == 'cin') or (fname[1][0:2] == 'inc') : fname[1] = '.inc' # join name and extention back # l1[1] = string.join(fname,'.') # print ' -- after joining fname l1 = ', l1 # ------------------------------ # process the logical name # ------------------------------ if name[0] == 'c' : # change name of the area, however # preserve extention name[0] = 'inc' name[0] = name[0]+'/' name[1] = name[1]+'/' # print directive, name # print ' ---- before error: l1 = ', l1 # # cut out trailing comments and options # on include card # l1[1] = string.split(l1[1],'/')[0] l1[1] = string.split(l1[1],'!')[0] l1[0] = '"'+name[0]; l1[1] = l1[1]+'"' list[1] = string.joinfields(l1,'') list = (list[0],list[1]) else: # unknown directive n_errors = n_errors+1 print ' ***** Unknown directive: ',s # merge fields of the string back q = (n_errors, string.join(list)) # print q return q #----------------------------------------------------------------- # Changes all the directives in a given file. #----------------------------------------------------------------- def change_expand_directives(filename): # print ' ------- file : ', filename,':' f1=open(filename) f2=open('.tmp','w') # form file header # f2.write(' \n') # f2.write('#include \n\n') n_expand_directives = 0 n_errors = 0 while 1: s = f1.readline() # print s n_err = 0 if (not s) : break # # cut leading blanks q = string.split(s) if (q != []) and (len(q[0]) > 2): if (q[0][0:2] == '$$'): # EXPAND directive found, cut line feed n_expand_directives = n_expand_directives+1 # print string.split(s,'\n')[0] # convert it to lower case and # split into components, but # save string before save = s q = parse_directive(s) n_errors = n_errors+q[0] s = q[1]+'\n' f2.write(s) # all the cards have been processed f1.close() f2.close() # return if (n_errors == 0): os.system('mv .tmp '+filename) else: print 'Errors occured while processing '+filename+'.' os.system('rm .tmp') #------------------------------------------------------------------------------- # parse FORTRAN comment line and make sure that text strings conform ANSI # standard (this is a new version: just change ' or " to ` ) #------------------------------------------------------------------------------- def parse_fortran_comment(comment): # print " ----------------- parse directive " # print directive s = regsub.gsub('"','`',comment) s = regsub.gsub("'",'`',s) return (1, s) #----------------------------------------------------------------------- # change FORTRAN comments in one file to make them conforming ANSI standard #----------------------------------------------------------------------- def change_fortran_comments(filename): # print ' ------- file : ', filename,':' f1=open(filename) f2=open('.tmp','w') n_changed_comments = 0 n_errors = 0 while 1: line = f1.readline() # print line n_err = 0 if (not line) : break if (line[0] == 'c') or (line[0]=='C') or (line[0] == '*') : # print line; # # FORTRAN comment line found, on return we have # (n_changes, comment) # res = parse_fortran_comment(line) if res[0] > 0: n_changed_comments = n_changed_comments+res[0] line = res[1] # Bad code. If you happen to have an exclamation point in a string, # this will muck up your output file. Disabled. # else: # card doesn't start with 'c', look for the '!' # i = string.find(line,'!') # if (i > 0 ): # '!' found, make sure there is no trailing ' and " # i = i+1 # while i < len(line): # if (line[i] == '"' or line[i] == "'") and (line[i+1] != ')'): # line = line[:i]+'`'+line[i+1:] # i = i+1 f2.write(line) # all the cards have been processed f1.close() f2.close() # return if (n_changed_comments > 0): if (n_errors == 0): os.system('mv .tmp '+filename) else: os.system('rm .tmp') #----------------------------------------------------------------------- # Finds .CDF and .CIN files in directores, copies to new files, and # calls change_expand_directives on each copy. #----------------------------------------------------------------------- def change(directory): # Now renames CDF and CIN files properly catalog= os.popen('ls '+directory) while 1: line = catalog.readline() if (not line): # end of directory catalog break line = string.split(line,'\n')[0] list = string.split(line,'.') # If .CDF or .CIN file, copy to .F or .inc, call change_expand_directives if (string.lower(list[len(list)-1]) == 'cdf'): name = directory + '/' + \ string.join(list[0:len(list)-1],'.') + '.F' os.system('cp ' + directory + '/' + line + ' ' + name) print ' expand : ' + directory + '/' + line + ' -----> ' + \ name change_expand_directives(name) elif (string.lower(list[len(list)-1]) == 'cin'): name = directory + '/' + \ string.join(list[0:len(list)-1],'.') + '.inc' os.system('cp ' + directory + '/' + line + ' ' + name) print ' expand : ' + directory + '/' + line + ' -----> ' + \ name change_expand_directives(name) #--------------------------------------------------------------------- # Takes all .F and .inc files in a given directory, cleans up the # comments. Called after change() above, so the .F and .inc files # exist. #--------------------------------------------------------------------- def make_ansi(directory): catalog= os.popen('ls '+directory) while 1: line = catalog.readline() if (not line): # end of directory catalog break # Chop off the trailing newline line = string.split(line,'\n')[0] # Find extension list = string.split(line,'.') if ((string.lower(list[len(list)-1]) == 'f') or (string.lower(list[len(list)-1]) == 'inc')): name = directory+'/'+line change_fortran_comments(name) #--------------------------------------------------------------------- # Main! #--------------------------------------------------------------------- if __name__ == '__main__': if (len(sys.argv)<2): print ' usage: ' + sys.argv[0] + ' [filename | directory]\n' else: for fn in sys.argv[1:]: # fn = sys.argv[1] if (posixpath.isdir(fn)): # this is a directory print ' Processing expand directives' change(fn); print ' Cleaning up comments' make_ansi(fn); else: # a single file ? if (not posixpath.exists(fn)): print ' Error: `' + fn + '\' does not exist.' sys.exit(1) base = string.split(fn,'.') if (len(base) < 2): fn2 = fn + '.F' else: # I'm assuming here that one might have a.b.CDF. Without recognized # extension, we add .F. -- PO if (string.lower(base[len(base)-1]) == 'cin'): fn2 = string.join(base[0:len(base)-1],'.') + '.inc' elif (string.lower(base[len(base)-1]) == 'cdf'): fn2 = string.join(base[0:len(base)-1],'.') + '.F' else: fn2 = fn + '.F' os.system('cp ' + fn + ' ' + fn2) print ' Processing expand directives' print ' expand : ' + fn + ' -----> ' + fn2 change_expand_directives(fn2) print ' Cleaning up comments' change_fortran_comments(fn2)