Commit code, circa 2010
This commit is contained in:
80
cblnum.c
Executable file
80
cblnum.c
Executable file
@@ -0,0 +1,80 @@
|
|||||||
|
/* cblnum - automated COBOL line numberer
|
||||||
|
* (C) 2005 Andrew Kesterson andrew@aklabs.net
|
||||||
|
* Possible room for improvement here: use getopt() or
|
||||||
|
* similar to allow the user to specify the step in the
|
||||||
|
* line numbering. */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define LINESIZE 4096
|
||||||
|
|
||||||
|
int getline(FILE *fp, char *buff)
|
||||||
|
{
|
||||||
|
if ( fp != NULL && buff != NULL ) {
|
||||||
|
int i = 0;
|
||||||
|
int ws = 0;
|
||||||
|
char c = 0x00;
|
||||||
|
c = fgetc(fp);
|
||||||
|
while ( !feof(fp) ) {
|
||||||
|
if ( (c == ' ' || c == '\t') && i == 0 && ws <= 8) {
|
||||||
|
/* skip leading whitespace for editors
|
||||||
|
* that autoindent like slickedit for
|
||||||
|
* cobol -- but don't strip >8 */
|
||||||
|
ws++;
|
||||||
|
c = fgetc(fp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if ( c != '\n' && i < LINESIZE ) {
|
||||||
|
buff[i] = c;
|
||||||
|
}
|
||||||
|
else if ( i >= LINESIZE ) {
|
||||||
|
fprintf(stderr, "buff was too small for line from file.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
i++;
|
||||||
|
c = fgetc(fp);
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
else return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if ( argc < 2 ) {
|
||||||
|
printf("(C)Andrew Kesterson andrew@aklabs.net 2005\n");
|
||||||
|
printf("\tcblnum (input file) \n\toutputs to stdout\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *buffer = (char *)malloc(LINESIZE); // should be big enough for most..
|
||||||
|
if ( !buffer ) {
|
||||||
|
fprintf(stderr, "cblnum: Out of memory.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fp = fopen(argv[1], "r");
|
||||||
|
if ( !fp ) {
|
||||||
|
fprintf(stderr, "cblnum: Couldn't open file for reading.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int line = 100;
|
||||||
|
|
||||||
|
while (!feof(fp)) {
|
||||||
|
if ( getline(fp, buffer) > 1 ) {
|
||||||
|
// the >1 is an ugly hack to account for junk coming
|
||||||
|
// up at EOF, but I don't think any cobol statements
|
||||||
|
// could be just 1 char long.....
|
||||||
|
printf("%06d %s\n", line, buffer);
|
||||||
|
line += 100;
|
||||||
|
memset(buffer, 0x00, LINESIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
739
pcfconv.py
Executable file
739
pcfconv.py
Executable file
@@ -0,0 +1,739 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
# pcfconf.py : A utility to convert mathetmatical formulas
|
||||||
|
# from one language to another. it currently only supports
|
||||||
|
# Microsoft PowerToy Calculator save files for reading,
|
||||||
|
# and Python for writing. But it can be easily extended
|
||||||
|
# to handle other file formats; see SOURCE DOC below
|
||||||
|
# for details.
|
||||||
|
|
||||||
|
# TODO: Set default data type (short, int, long, double, float)
|
||||||
|
# it currently defaults to int or float, depending on
|
||||||
|
# what's in the file
|
||||||
|
# Implement some sanity checking on function arguments, to
|
||||||
|
# make sure only arguments present in the arg list or the
|
||||||
|
# parent object's body, are referenced. Currently, there
|
||||||
|
# are no such checks.
|
||||||
|
|
||||||
|
################# SOURCE DOC ##############################################
|
||||||
|
############## (read here if you want to extend this program) #############
|
||||||
|
|
||||||
|
# The actual conversion is done by XXXXConverter classes that
|
||||||
|
# do the actual conversion. They are passed a generic list of the following
|
||||||
|
# form:
|
||||||
|
#
|
||||||
|
# [ [TYPE, NAME, VALUE] ]
|
||||||
|
#
|
||||||
|
# where TYPE is either "VAR" or "FUNC". If TYPE is "VAR", then the rest of
|
||||||
|
# the values are obvious (the name and value of the variable). If TYPE is
|
||||||
|
# "FUNC", then VALUE is actually another list of the form:
|
||||||
|
#
|
||||||
|
# [ARGS, CODE]
|
||||||
|
#
|
||||||
|
# where ARGS is yet another list containing the names of the function's arguments,
|
||||||
|
# and CODE is the original PowerToyCalc code for the function.
|
||||||
|
#
|
||||||
|
# To extend this program with a new filetype, scan down to the "PROCESSOR CLASSES"
|
||||||
|
# comment. At this point there is no programmatic reason to inherit your classes
|
||||||
|
# from GenericProcessor, but GenericProcessor is to be considered the base class
|
||||||
|
# for all new file processors; if GenericProcessor has a method, your class
|
||||||
|
# must have it as well. Use the PythonProcessor class as a guide to how the existing
|
||||||
|
# code works, if you need to. But as long as the converter winds up printing usable
|
||||||
|
# code to the output file, and errors to sys.__stderr__ (via the *err functions), then
|
||||||
|
# you're doing it right. Once you've done that, add it to the "PROCESSORS" dictionary
|
||||||
|
# in the global variables section. The format of the dictionary is obvious.
|
||||||
|
#
|
||||||
|
# To extend this program with a new target language, scan down to the "GENERATOR
|
||||||
|
# CLASSES" comment. The general process for processor classes applies here; if it's
|
||||||
|
# in the base class, it needs to be in your new subclass. Use the PythonConverter
|
||||||
|
# class as a guide to how to write your own converter, if necessary. The converter just
|
||||||
|
# needs to return usable output to the processor class, which prints it to whatever
|
||||||
|
# output file has been specified. Once you've done that, add it to the "CONVERTERS"
|
||||||
|
# dictionary in the global variables section. The format of the dictionary is obvious.
|
||||||
|
#
|
||||||
|
# Got it? easy.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import getopt
|
||||||
|
import math
|
||||||
|
|
||||||
|
# Functions that will be used throughout the module.
|
||||||
|
|
||||||
|
def syntaxerr (linenum, line, err):
|
||||||
|
sys.__stderr__.write("%d : %s : %s\n" % (linenum, err, line))
|
||||||
|
|
||||||
|
def generalerr (err):
|
||||||
|
sys.__stderr__.write("%s\n" % err)
|
||||||
|
|
||||||
|
def debugmsg (err):
|
||||||
|
global DEBUG
|
||||||
|
if ( DEBUG ) :
|
||||||
|
sys.__stderr__.write("DEBUG: %s\n" % err)
|
||||||
|
|
||||||
|
def cloneList (list1):
|
||||||
|
list2 = []
|
||||||
|
for item in list1:
|
||||||
|
list2.append(item)
|
||||||
|
return list2
|
||||||
|
|
||||||
|
################## CONVERTER CLASSES #######################
|
||||||
|
|
||||||
|
class GenericConverter:
|
||||||
|
def __init__ (self, langopts, contextName=""):
|
||||||
|
"""contextname is the name of the class, context, or namespace that should be
|
||||||
|
generated for the incoming data. langopts is a dictionary containing
|
||||||
|
the language specific options that the processor should follow."""
|
||||||
|
return
|
||||||
|
|
||||||
|
def convertFile (self, data):
|
||||||
|
"""data is the data to interpret to your native language"""
|
||||||
|
generalerr("convertFile is not implemented in GenericConverter")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def convertCalls (self, code):
|
||||||
|
"""For the given block of code, translate any calls to things like atan() and
|
||||||
|
acos() to functions that exist in your language's internal math library."""
|
||||||
|
global MATHSYMS
|
||||||
|
ourlist = cloneList(MATHSYMS)
|
||||||
|
ourlist.append(",")
|
||||||
|
ourlist.append(" ")
|
||||||
|
ourlist.append("\t")
|
||||||
|
# we do our best here to ensure we don't change someone's defined function that
|
||||||
|
# happens to have the name of one of ours inside of it. For example, if someone
|
||||||
|
# makes a function MYacos(), then a replace on "acos" with "math.acos" would result
|
||||||
|
# in the code being MYmath.acos(), which is guaranteed to do nothing but explode.
|
||||||
|
# So we try to make sure that we're only replacing exact matches, by checking that
|
||||||
|
# it follows any of the items in MATHSYMS, a comma(,), " ", or \t. The downside
|
||||||
|
# to this is that it winds up being pretty slow.
|
||||||
|
for call in self.__subs__.keys():
|
||||||
|
for symbol in ourlist :
|
||||||
|
toreplace = "%s%s" % (symbol, call)
|
||||||
|
replacer = "%s%s" % (symbol, self.__subs__[call])
|
||||||
|
if ( toreplace in code ):
|
||||||
|
debugmsg("Replacing %s with %s in code line %s" % (toreplace, replacer, code))
|
||||||
|
code = code.replace(toreplace, replacer)
|
||||||
|
return code
|
||||||
|
|
||||||
|
def supportedTranslations (self):
|
||||||
|
"""return a string that lists all of the translations your language's
|
||||||
|
converter supports"""
|
||||||
|
generalerr("supportedTranslations is not implemetned in GenericConverter")
|
||||||
|
|
||||||
|
class CPPConverter:
|
||||||
|
class CPPVariable:
|
||||||
|
def __init__ (self, name, initValue, baseType, namespace):
|
||||||
|
self.__name__ = name
|
||||||
|
self.__value__ = initValue
|
||||||
|
self.__vartype__ = baseType
|
||||||
|
self.__namespace__ = namespace
|
||||||
|
def __str__ (self, defonly = False):
|
||||||
|
retStr = ""
|
||||||
|
if ( isinstance(self.__value__, list) or isinstance(self.__value__, tuple) ):
|
||||||
|
if ( defonly ):
|
||||||
|
return "%s %s[%d];" % (self.__vartype__, self.__name__, len(self.__value__))
|
||||||
|
# if we're not doing definitions, then assignments only occur in the constructor
|
||||||
|
for i in range(0, len(self.__value__)-1):
|
||||||
|
retStr += "\tthis->%s[%d] = %s;\n" % (self.__name__, i, self.__value__[i])
|
||||||
|
else:
|
||||||
|
if ( defonly ):
|
||||||
|
return "%s %s;" % (self.__vartype__, self.__name__)
|
||||||
|
retStr = "\tthis->%s = %s;" % (self.__name__, self.__value__)
|
||||||
|
return retStr
|
||||||
|
class CPPFunction:
|
||||||
|
def __init__ (self, namespace, argtype, rettype, name, arguments, code):
|
||||||
|
self.__rettype__ = rettype
|
||||||
|
self.__argtype__ = argtype
|
||||||
|
self.__name__ = name
|
||||||
|
self.__namespace__ = namespace
|
||||||
|
self.__args__ = arguments
|
||||||
|
self.__code__ = code
|
||||||
|
def replaceVars (self, varlist):
|
||||||
|
"""Find any instance of a variable in our code that is not in our argument list,
|
||||||
|
and is a member variable of our parent class"""
|
||||||
|
codeCopy = self.__code__
|
||||||
|
ourlist = cloneList(MATHSYMS)
|
||||||
|
ourlist.append(",")
|
||||||
|
ourlist.append(" ")
|
||||||
|
for var in varlist :
|
||||||
|
if ( var.__name__ in self.__args__ ):
|
||||||
|
continue
|
||||||
|
for symbol in ourlist:
|
||||||
|
toreplace = "%s%s" % (symbol, var.__name__)
|
||||||
|
replacer = "this->%s" % (var.__name__)
|
||||||
|
debugmsg("Searching for \" %s\" in code block %s" % (toreplace, codeCopy))
|
||||||
|
if ( toreplace in codeCopy ):
|
||||||
|
debugmsg("Replacing \"%s\" with \"%s\" in %s" % (toreplace, replacer, codeCopy))
|
||||||
|
codeCopy = codeCopy.replace(toreplace, replacer)
|
||||||
|
self.__code__ = codeCopy
|
||||||
|
def __str__ (self, defonly=False):
|
||||||
|
if ( defonly ):
|
||||||
|
str = "%s %s (" % (self.__rettype__, self.__name__)
|
||||||
|
else:
|
||||||
|
str = "%s %s::%s (" % (self.__rettype__, self.__namespace__, self.__name__)
|
||||||
|
argcnt = 0
|
||||||
|
for item in self.__args__:
|
||||||
|
if ( argcnt > 0 ):
|
||||||
|
str += ", "
|
||||||
|
str += "%s %s" % (self.__argtype__, item)
|
||||||
|
argcnt += 1
|
||||||
|
str += ")"
|
||||||
|
if ( defonly ):
|
||||||
|
return str+";"
|
||||||
|
str += "\n{\n\treturn (%s);\n}\n" % (self.__code__)
|
||||||
|
return str
|
||||||
|
class CPPClass:
|
||||||
|
def __init__ (self, namespace, variables, functions, langopts):
|
||||||
|
self.__namespace__ = namespace
|
||||||
|
self.__vars__ = variables
|
||||||
|
self.__funcs__ = functions
|
||||||
|
self.__langopts__ = langopts
|
||||||
|
def toASCII (self):
|
||||||
|
hdrstr = ""
|
||||||
|
impstr = ""
|
||||||
|
# generate definition
|
||||||
|
hdrstr = "#ifndef __%s__\n" % self.__namespace__
|
||||||
|
hdrstr += "#define __%s__\n" % self.__namespace__
|
||||||
|
hdrstr += "#include <math.h>\n\n"
|
||||||
|
hdrstr += "class %s {\n" % self.__namespace__
|
||||||
|
hdrstr += "public:\n"
|
||||||
|
hdrstr += "\t%s::%s(void);\n" % (self.__namespace__, self.__namespace__)
|
||||||
|
for func in self.__funcs__:
|
||||||
|
hdrstr += "\t%s\n" % func.__str__(True)
|
||||||
|
hdrstr += "protected:\n"
|
||||||
|
for var in self.__vars__ :
|
||||||
|
hdrstr += "\t%s\n" % (var.__str__(True))
|
||||||
|
hdrstr += "}\n"
|
||||||
|
hdrstr += "#endif /* __%s__ */\n" % self.__namespace__
|
||||||
|
# generate implementation
|
||||||
|
if ( self.__langopts__["writefiles"].lower() == "true" ):
|
||||||
|
impstr = "#include \"%s.h\"\n\n" % self.__namespace__
|
||||||
|
impstr += "\n"
|
||||||
|
# generate the constructor
|
||||||
|
impstr += "void %s::%s(void)\n{\n" % (self.__namespace__, self.__namespace__)
|
||||||
|
# assignments happen in the constructor, not the class def
|
||||||
|
for var in self.__vars__ :
|
||||||
|
impstr += "%s\n" % str(var)
|
||||||
|
impstr += "}\n"
|
||||||
|
for func in self.__funcs__:
|
||||||
|
impstr += "%s\n" % str(func)
|
||||||
|
if ( self.__langopts__["writefiles"].lower() == "true" ):
|
||||||
|
# write the definition to the header file
|
||||||
|
ofile = open(("%s.h" % self.__namespace__), "w")
|
||||||
|
ofile.write(hdrstr)
|
||||||
|
ofile.close()
|
||||||
|
# write the implementation to the C file
|
||||||
|
ofile = open(("%s.c" % self.__namespace__), "w")
|
||||||
|
ofile.write(impstr)
|
||||||
|
ofile.close()
|
||||||
|
return ""
|
||||||
|
return hdrstr+"\n"+impstr
|
||||||
|
def __init__ (self, langopts, namespace="PTC"):
|
||||||
|
self.__namespace__ = namespace
|
||||||
|
self.__langopts__ = { "deftype" : "double",
|
||||||
|
"defrettype" : "double",
|
||||||
|
"writefiles" : "false" }
|
||||||
|
self.__funclist__ = []
|
||||||
|
self.__varlist__ = []
|
||||||
|
self.__subs__ = {}
|
||||||
|
for key in langopts.keys():
|
||||||
|
self.__langopts__[key] = langopts[key]
|
||||||
|
return
|
||||||
|
def convertFile (self, data):
|
||||||
|
for item in data:
|
||||||
|
debugmsg("Processing item %s" % (item))
|
||||||
|
if ( item[0] == "VAR" ):
|
||||||
|
self.__varlist__.append( CPPConverter.CPPVariable(item[1],
|
||||||
|
item[2], self.__langopts__["deftype"], self.__namespace__ ))
|
||||||
|
else:
|
||||||
|
self.__funclist__.append( CPPConverter.CPPFunction(self.__namespace__,
|
||||||
|
self.__langopts__["deftype"], self.__langopts__["defrettype"],
|
||||||
|
item[1], item[2][0], item[2][1]))
|
||||||
|
for func in self.__funclist__ :
|
||||||
|
func.replaceVars(self.__varlist__)
|
||||||
|
defclass = CPPConverter.CPPClass(self.__namespace__, self.__varlist__, self.__funclist__, self.__langopts__)
|
||||||
|
return defclass.toASCII()
|
||||||
|
def supportedTranslations (self):
|
||||||
|
return "The entire C++ math.h library is supported. You are almost guaranteed 100% conversion."
|
||||||
|
|
||||||
|
class CConverter:
|
||||||
|
class CVariable:
|
||||||
|
def __init__ (self, name, initValue, baseType, namespace):
|
||||||
|
self.__name__ = name
|
||||||
|
self.__value__ = initValue
|
||||||
|
self.__vartype__ = baseType
|
||||||
|
self.__namespace__ = namespace
|
||||||
|
def __str__ (self, defonly = False):
|
||||||
|
retStr = ""
|
||||||
|
if ( isinstance(self.__value__, list) or isinstance(self.__value__, tuple) ):
|
||||||
|
if ( defonly ):
|
||||||
|
return "%s %s_%s[%d];" % (self.__vartype__, self.__namespace__, self.__name__, len(self.__value__))
|
||||||
|
retStr = "%s %s_%s[%d] = {" % (self.__vartype__, self.__namespace__, self.__name__, len(self.__value__))
|
||||||
|
for i in self.__value__:
|
||||||
|
retStr += "%s, " % i
|
||||||
|
retStr += "};"
|
||||||
|
else:
|
||||||
|
if ( defonly ):
|
||||||
|
return "%s %s_%s;" % (self.__vartype__, self.__namespace__, self.__name__)
|
||||||
|
retStr = "%s %s_%s = %s;" % (self.__vartype__, self.__namespace__, self.__name__, self.__value__)
|
||||||
|
return retStr
|
||||||
|
class CFunction:
|
||||||
|
def __init__ (self, namespace, argtype, rettype, name, arguments, code):
|
||||||
|
self.__rettype__ = rettype
|
||||||
|
self.__argtype__ = argtype
|
||||||
|
self.__name__ = name
|
||||||
|
self.__namespace__ = namespace
|
||||||
|
self.__args__ = arguments
|
||||||
|
self.__code__ = code
|
||||||
|
def replaceVars (self, varlist):
|
||||||
|
"""Find any instance of a variable in our code that is not in our argument list,
|
||||||
|
and is a member variable of our parent class"""
|
||||||
|
codeCopy = self.__code__
|
||||||
|
ourlist = cloneList(MATHSYMS)
|
||||||
|
ourlist.append(",")
|
||||||
|
ourlist.append(" ")
|
||||||
|
for var in varlist :
|
||||||
|
if ( var.__name__ in self.__args__ ):
|
||||||
|
continue
|
||||||
|
for symbol in ourlist:
|
||||||
|
toreplace = "%s%s" % (symbol, var.__name__)
|
||||||
|
replacer = "%s_%s" % (self.__namespace__, var.__name__)
|
||||||
|
debugmsg("Searching for \" %s\" in code block %s" % (toreplace, codeCopy))
|
||||||
|
if ( toreplace in codeCopy ):
|
||||||
|
debugmsg("Replacing \"%s\" with \"%s\" in %s" % (toreplace, replacer, codeCopy))
|
||||||
|
codeCopy = codeCopy.replace(toreplace, replacer)
|
||||||
|
self.__code__ = codeCopy
|
||||||
|
def __str__ (self, defonly=False):
|
||||||
|
str = "%s %s_%s (" % (self.__rettype__, self.__namespace__, self.__name__)
|
||||||
|
argcnt = 0
|
||||||
|
for item in self.__args__:
|
||||||
|
if ( argcnt > 0 ):
|
||||||
|
str += ", "
|
||||||
|
str += "%s %s" % (self.__argtype__, item)
|
||||||
|
argcnt += 1
|
||||||
|
str += ")"
|
||||||
|
if ( defonly ):
|
||||||
|
return str+";"
|
||||||
|
str += "\n{\n\treturn (%s);\n}\n" % (self.__code__)
|
||||||
|
return str
|
||||||
|
class CInclude:
|
||||||
|
def __init__ (self, namespace, variables, functions):
|
||||||
|
self.__namespace__ = namespace
|
||||||
|
self.__vars__ = variables
|
||||||
|
self.__funcs__ = functions
|
||||||
|
def toASCII (self, writefiles):
|
||||||
|
hdrstr = ""
|
||||||
|
impstr = ""
|
||||||
|
# generate definition
|
||||||
|
hdrstr = "#ifndef __%s__\n" % self.__namespace__
|
||||||
|
hdrstr += "#define __%s__\n" % self.__namespace__
|
||||||
|
hdrstr += "#include <math.h>\n\n"
|
||||||
|
for var in self.__vars__ :
|
||||||
|
hdrstr += "extern %s\n" % (var.__str__(True))
|
||||||
|
hdrstr += "\n"
|
||||||
|
for func in self.__funcs__:
|
||||||
|
hdrstr += "extern %s\n" % func.__str__(True)
|
||||||
|
hdrstr += "#endif /* __%s__ */" % self.__namespace__
|
||||||
|
# generate implementation
|
||||||
|
if ( writefiles.lower() == "true" ):
|
||||||
|
impstr = "#include \"%s.h\"\n\n" % self.__namespace__
|
||||||
|
for var in self.__vars__ :
|
||||||
|
impstr += "%s\n" % (str(var))
|
||||||
|
impstr += "\n"
|
||||||
|
for func in self.__funcs__:
|
||||||
|
impstr += "%s\n" % str(func)
|
||||||
|
if ( writefiles.lower() == "true" ):
|
||||||
|
# write the definition to the header file
|
||||||
|
ofile = open(("%s.h" % self.__namespace__), "w")
|
||||||
|
ofile.write(hdrstr)
|
||||||
|
ofile.close()
|
||||||
|
# write the implementation to the C file
|
||||||
|
ofile = open(("%s.c" % self.__namespace__), "w")
|
||||||
|
ofile.write(impstr)
|
||||||
|
ofile.close()
|
||||||
|
return ""
|
||||||
|
return hdrstr+"\n"+impstr
|
||||||
|
def __init__ (self, langopts, namespace="PTC"):
|
||||||
|
self.__namespace__ = namespace
|
||||||
|
self.__langopts__ = { "deftype" : "double",
|
||||||
|
"defrettype" : "double",
|
||||||
|
"writefiles" : "false" }
|
||||||
|
self.__funclist__ = []
|
||||||
|
self.__varlist__ = []
|
||||||
|
# thankfully C doesn't require any substitutions; we just include math.h and
|
||||||
|
# everything is groovy.
|
||||||
|
self.__subs__ = {}
|
||||||
|
for key in langopts.keys():
|
||||||
|
self.__langopts__[key] = langopts[key]
|
||||||
|
return
|
||||||
|
def convertFile (self, data):
|
||||||
|
# forcibly process all the variables first, then do the functions.
|
||||||
|
# We do it in this specific order so we can do some variable replacement.
|
||||||
|
for item in data:
|
||||||
|
debugmsg("Processing item %s" % (item))
|
||||||
|
if ( item[0] == "VAR" ):
|
||||||
|
self.__varlist__.append( CConverter.CVariable(item[1],
|
||||||
|
item[2], self.__langopts__["deftype"], self.__namespace__ ))
|
||||||
|
else:
|
||||||
|
self.__funclist__.append( CConverter.CFunction(self.__namespace__,
|
||||||
|
self.__langopts__["deftype"], self.__langopts__["defrettype"],
|
||||||
|
item[1], item[2][0], item[2][1]))
|
||||||
|
for func in self.__funclist__ :
|
||||||
|
func.replaceVars(self.__varlist__)
|
||||||
|
defclass = CConverter.CInclude(self.__namespace__, self.__varlist__, self.__funclist__)
|
||||||
|
return defclass.toASCII(self.__langopts__["writefiles"])
|
||||||
|
def supportedTranslations (self):
|
||||||
|
return "The entire C math.h library is supported. You are almost guaranteed 100% conversion."
|
||||||
|
|
||||||
|
class PythonConverter:
|
||||||
|
# what the class needs to know:
|
||||||
|
# - the name of the class being generated. All data found in the .pcf file is
|
||||||
|
# placed into a generated class of the given name. Variables are listed as
|
||||||
|
# instance variables, and functions are of course generated as member functions.
|
||||||
|
# - list of functions
|
||||||
|
# - list of variables
|
||||||
|
class PythonVariable:
|
||||||
|
def __init__ (self, name, initValue, baseType):
|
||||||
|
# note that initValue can be a list when the baseType constructor
|
||||||
|
# requires more than one argument
|
||||||
|
self.__name__ = name
|
||||||
|
self.__value__ = initValue
|
||||||
|
self.__vartype__ = baseType
|
||||||
|
def __str__ (self):
|
||||||
|
retStr = ""
|
||||||
|
if ( isinstance(self.__value__, list) or isinstance(self.__value__, tuple) ):
|
||||||
|
retStr = "%s = %s(" % (self.__name__, self.__vartype__)
|
||||||
|
for i in self.__value__:
|
||||||
|
retStr += "%s, " % i
|
||||||
|
retStr += ")"
|
||||||
|
else:
|
||||||
|
retStr = "__%s__ = %s(%s)" % (self.__name__, self.__vartype__, self.__value__)
|
||||||
|
return retStr
|
||||||
|
class PythonFunction:
|
||||||
|
def __init__ (self, name, arguments, code):
|
||||||
|
self.__name__ = name
|
||||||
|
self.__args__ = arguments
|
||||||
|
self.__code__ = code
|
||||||
|
def replaceVars (self, varlist):
|
||||||
|
"""Find any instance of a variable in our code that is not in our argument list,
|
||||||
|
and is a member variable of our parent class"""
|
||||||
|
codeCopy = self.__code__
|
||||||
|
ourlist = cloneList(MATHSYMS)
|
||||||
|
ourlist.append(",")
|
||||||
|
ourlist.append(" ")
|
||||||
|
for var in varlist :
|
||||||
|
if ( var.__name__ in self.__args__ ):
|
||||||
|
continue
|
||||||
|
for symbol in ourlist:
|
||||||
|
toreplace = "%s%s" % (symbol, var.__name__)
|
||||||
|
replacer = "self.__%s__" % (var.__name__)
|
||||||
|
debugmsg("Searching for \" %s\" in code block %s" % (toreplace, codeCopy))
|
||||||
|
if ( toreplace in codeCopy ):
|
||||||
|
debugmsg("Replacing \"%s\" with \"%s\" in %s" % (toreplace, replacer, codeCopy))
|
||||||
|
codeCopy = codeCopy.replace(toreplace, replacer)
|
||||||
|
self.__code__ = codeCopy
|
||||||
|
def __str__ (self):
|
||||||
|
str = "def %s (self, " % (self.__name__)
|
||||||
|
argcnt = 0
|
||||||
|
for item in self.__args__:
|
||||||
|
if ( argcnt > 0 ):
|
||||||
|
str += ", "
|
||||||
|
str += "%s" % (item)
|
||||||
|
argcnt += 1
|
||||||
|
str += "): return (%s)" % (self.__code__)
|
||||||
|
return str
|
||||||
|
class PythonClass:
|
||||||
|
def __init__ (self, name, variables, functions):
|
||||||
|
self.__name__ = name
|
||||||
|
self.__vars__ = variables
|
||||||
|
self.__funcs__ = functions
|
||||||
|
def toASCII (self, tabstop):
|
||||||
|
# return all elements in a string suitable for printing to stdout
|
||||||
|
# "tabstop" specifies the tabstop to use. Pass "\t" or "" with a number of
|
||||||
|
# spaces per tabstop. There will be one additional space per tabstop
|
||||||
|
# because it makes it easier for me to write that way.
|
||||||
|
retstr = "import math\n"
|
||||||
|
retstr += "class %s:\n" % self.__name__
|
||||||
|
retstr += "%s def __init__(self):\n" % (tabstop)
|
||||||
|
for var in self.__vars__ :
|
||||||
|
retstr += "%s self.%s\n" % ((tabstop*2), str(var))
|
||||||
|
retstr += "%s return\n" % ((tabstop *2))
|
||||||
|
for func in self.__funcs__:
|
||||||
|
retstr += "%s %s\n" % (tabstop, str(func))
|
||||||
|
return retstr
|
||||||
|
def __init__ (self, langopts, className="PowerToyCapsule"):
|
||||||
|
self.__className__ = className
|
||||||
|
self.__langopts__ = langopts
|
||||||
|
self.__funclist__ = []
|
||||||
|
self.__varlist__ = []
|
||||||
|
self.__subs__ = {}
|
||||||
|
for item in dir(math):
|
||||||
|
if ( "__" in item ):
|
||||||
|
continue
|
||||||
|
self.__subs__[item] = "math.%s" % item
|
||||||
|
return
|
||||||
|
def convertFile (self, data):
|
||||||
|
# forcibly process all the variables first, then do the functions.
|
||||||
|
# We do it in this specific order so we can do some variable replacement.
|
||||||
|
for item in data:
|
||||||
|
debugmsg("Processing item %s" % (item))
|
||||||
|
if ( item[0] == "VAR" ):
|
||||||
|
if ( "." in item[2] ):
|
||||||
|
self.__varlist__.append( PythonConverter.PythonVariable(item[1], item[2], "float") )
|
||||||
|
else:
|
||||||
|
self.__varlist__.append( PythonConverter.PythonVariable(item[1], item[2], "int") )
|
||||||
|
else:
|
||||||
|
self.__funclist__.append( PythonConverter.PythonFunction(item[1], item[2][0], item[2][1]) )
|
||||||
|
for func in self.__funclist__ :
|
||||||
|
func.replaceVars(self.__varlist__)
|
||||||
|
defclass = PythonConverter.PythonClass(self.__className__, self.__varlist__, self.__funclist__)
|
||||||
|
return defclass.toASCII(" ")
|
||||||
|
def supportedTranslations (self):
|
||||||
|
retstr = ""
|
||||||
|
for call in self.__subs__.keys():
|
||||||
|
retstr += "%s " % call
|
||||||
|
return retstr
|
||||||
|
|
||||||
|
############################# PROCESSOR CLASSES ###################
|
||||||
|
|
||||||
|
class GenericProcessor:
|
||||||
|
def __init__ (self, converters):
|
||||||
|
# "converters" is a dictionary of language types and the corresponding classes that
|
||||||
|
# convert for that type
|
||||||
|
self.__converters__ = converters
|
||||||
|
|
||||||
|
def convertFile (self, filename, outfile, language, ignoreErrors, recovery, translate, langopts):
|
||||||
|
debugmsg("convertFile is not implemented in the GenericConverter base class.")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
class MSPowerToyProcessor(GenericProcessor):
|
||||||
|
def convertFile (self, filename, outfile, language, ignoreErrors, recovery, translate, langopts):
|
||||||
|
global MATHSYMS
|
||||||
|
# get the right converter for our language type
|
||||||
|
convclass = self.__converters__[language]
|
||||||
|
converter = convclass(langopts)
|
||||||
|
data = []
|
||||||
|
if ( filename == "-" ):
|
||||||
|
ifile = sys.__stdin__
|
||||||
|
else:
|
||||||
|
ifile = open(filename, "rb")
|
||||||
|
if ( not ifile ):
|
||||||
|
generalerr("Unable to open input file %s, aborting." % filename)
|
||||||
|
linenum = 1
|
||||||
|
line = ifile.readline()
|
||||||
|
while ( line and (len(line) != 0) and line != "\x00"):
|
||||||
|
debugmsg("Operating on line %d with length %d : %s" % (linenum, len(line), line))
|
||||||
|
dataTYPE = ""
|
||||||
|
dataNAME = ""
|
||||||
|
dataVALUELITERAL = 0
|
||||||
|
dataVALUELIST = [[], ""]
|
||||||
|
# if there are parenthesis present on the LEFT side of the =, then the line is a function
|
||||||
|
# replace the BS nulls that PowerToyCalc puts into these files for some reason
|
||||||
|
line = line.replace("\x00", "").replace("\r", "").replace("\n", "")
|
||||||
|
# strip out the parts
|
||||||
|
parts = line.split("=")
|
||||||
|
debugmsg("Operating on parts %s" % parts)
|
||||||
|
# strip out all arithmetic operators and spaces, and drop the bare contents into a
|
||||||
|
# temporary string
|
||||||
|
if ( len(parts) > 1 ):
|
||||||
|
temp = parts[1]
|
||||||
|
for oper in MATHSYMS:
|
||||||
|
temp = temp.replace(oper, "")
|
||||||
|
# this final string will be used to test if any of the data in it is non-constant
|
||||||
|
# e.g., are there just numbers, or are there alphanumerics in there too?
|
||||||
|
temp = temp.replace(" ", "")
|
||||||
|
else:
|
||||||
|
sys.__stderr__.write("%s : %d : syntax error : no value in variable assignment : %s\n" \
|
||||||
|
% (filename, linenum, line))
|
||||||
|
if ( ignoreErrors ):
|
||||||
|
sys.__stderr__.write("%s : %d : defaulting value to 0 to continue\n" % (filename, linenum))
|
||||||
|
temp = "0"
|
||||||
|
else:
|
||||||
|
if ( ifile != sys.__stdin__ ):
|
||||||
|
ifile.close()
|
||||||
|
return 1
|
||||||
|
# if they are present on the right side of the equals, it's a variable
|
||||||
|
# If the variable has non-constant values to the right of =, then define that as a
|
||||||
|
# function with no arguments that returns the contents of the right side of the
|
||||||
|
# equals
|
||||||
|
if ( temp.isdigit() ):
|
||||||
|
# it's a variable, regardless of the presence of (), because it's just digits
|
||||||
|
dataTYPE = "VAR"
|
||||||
|
dataNAME = parts[0].replace(" ", "")
|
||||||
|
dataVALUELITERAL = parts[1].replace(" ", "")
|
||||||
|
elif ( "(" in parts[0] and ")" in parts[0] ):
|
||||||
|
# it's a function (though it may have been defined as a variable with non-constant
|
||||||
|
# values, such as the results of other functions, in PowerToyCalc. We define such
|
||||||
|
# variables as funtions in the converter because they may have data in them
|
||||||
|
# that needs to be re-calculated every time they are used, and a function is the
|
||||||
|
# only way to do that. We're actually beyond PowerToyCalc in that, because
|
||||||
|
# the user has to manually change a variable in PowerToyCalc to update it, we
|
||||||
|
# don't.)
|
||||||
|
dataTYPE = "FUNC"
|
||||||
|
dataNAME = parts[0].split("(")[0].split(")")[0].replace(" ", "")
|
||||||
|
dataVALUELIST[0] = parts[0].replace(" ", "").split("(")[1].replace(")", "").split(",")
|
||||||
|
if ( translate ):
|
||||||
|
dataVALUELIST[1] = converter.convertCalls(parts[1])
|
||||||
|
else:
|
||||||
|
dataVALUELIST[1] = parts[1]
|
||||||
|
else:
|
||||||
|
# if it didn't fit into the two top categories, I dunno WTF it is
|
||||||
|
sys.__stderr__.write("%s : %d : syntax error, no value in variable assignment : %s\n" % (filename, linenum, line))
|
||||||
|
# unless we're ignoring all errors, stop processing!
|
||||||
|
if ( ignoreErrors ):
|
||||||
|
if ( recovery ):
|
||||||
|
sys.__stderr__.write("%s : %d : defaulting value to 0 to continue\n" % (filename, linenum))
|
||||||
|
dataTYPE = "VAR"
|
||||||
|
dataNAME = parts[0].replace(" ", "")
|
||||||
|
dataVALUELITERAL = "0"
|
||||||
|
else:
|
||||||
|
line = ifile.readline()
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
if ( ifile != sys.__stdin__ ):
|
||||||
|
ifile.close()
|
||||||
|
return 1
|
||||||
|
if ( dataTYPE == "FUNC" ):
|
||||||
|
newlist=[dataTYPE, dataNAME, dataVALUELIST]
|
||||||
|
else:
|
||||||
|
newlist=[dataTYPE, dataNAME, dataVALUELITERAL]
|
||||||
|
debugmsg("Adding new list : %s" % newlist)
|
||||||
|
data.append(newlist)
|
||||||
|
line = ifile.readline()
|
||||||
|
linenum += 1
|
||||||
|
# out of the main conversion loop
|
||||||
|
if ( ifile != sys.__stdin__ ):
|
||||||
|
ifile.close()
|
||||||
|
if ( outfile == "-" ):
|
||||||
|
sys.__stdout__.write(converter.convertFile(data))
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
ofile = file(outfile, "w")
|
||||||
|
ofile.write(converter.convertFile(data))
|
||||||
|
ofile.close()
|
||||||
|
except IOError, e:
|
||||||
|
sys.__stderr__.write("Failed to open output file %s : %s" % (outfile, e))
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
|
################ GLOBALS ########################
|
||||||
|
DEBUG=False
|
||||||
|
MATHSYMS=["*", "+", "-", "=", "/", ">>", "<<", "%", "(", ")"]
|
||||||
|
CONVERTERS = { "python" : PythonConverter,
|
||||||
|
"C" : CConverter,
|
||||||
|
"C++" : CPPConverter }
|
||||||
|
PROCESSORS = { "mspcf" : [MSPowerToyProcessor, "MS Powertoy Calculator variable / function save data"]}
|
||||||
|
SHORTOPTS = "hf:l:t:o:erTSdO:"
|
||||||
|
LONGOPTS = ["help", "filename=", "language=", "filetype=",
|
||||||
|
"outfile=", "ignore-err", "recovery", "translate",
|
||||||
|
"supp-trans", "debug", "langopts="]
|
||||||
|
USAGE = \
|
||||||
|
"""Interpret mathematical formulae from various formats (such as
|
||||||
|
MS PowerToy Calculator saves) to usable source code for one of
|
||||||
|
a number of languages.
|
||||||
|
|
||||||
|
usage: pcfconv.py (opts)
|
||||||
|
options:
|
||||||
|
-h | --help : print this help
|
||||||
|
-f | --filename : filename to read from. If unspecified,
|
||||||
|
stdin is read by default.
|
||||||
|
-o | --outfile : filename to write to. If unspecified,
|
||||||
|
the text is written to stdout.
|
||||||
|
-t | --filetype : type of file being processed. If unspecified,
|
||||||
|
MS Powertoy Calculator is the default.
|
||||||
|
The interpreter cannot currently accurately
|
||||||
|
determine filetypes on its own.
|
||||||
|
-l | --language : language to write out. If unspecified,
|
||||||
|
python is the default output language.
|
||||||
|
-e | --ignore-err : ignore syntax errors in the source file
|
||||||
|
when one is encountered and continue
|
||||||
|
processing (note that the error will
|
||||||
|
still be reported to stderr)
|
||||||
|
-r | --recovery : Attempt to recover from any ignored
|
||||||
|
errors, in the best way the interpreter
|
||||||
|
can see fit. This could be dangerous.
|
||||||
|
Don't blame the interpreter if this
|
||||||
|
results in a divide by zero, you've
|
||||||
|
been warned!
|
||||||
|
-T | --translate : Setting this option will force the interpreter
|
||||||
|
to attempt to translate calls to math functions,
|
||||||
|
such as cos, acos, tan and log10, etc, to the
|
||||||
|
internal math functions of whatever host language
|
||||||
|
you're converting to. If this is unset - which
|
||||||
|
is the default - such calls will be left as-is,
|
||||||
|
and if necessary, you will have to change them
|
||||||
|
yourself. Note that some functions may not
|
||||||
|
be interpreted properly by your host language.
|
||||||
|
-S | --supp-trans : Print out what function translations (handled
|
||||||
|
by the -T option) are supported by the converter
|
||||||
|
for your host language
|
||||||
|
-d | --debug : Print debug output (normally supressed.)
|
||||||
|
-O | --langopts : A comma separated list of options for the
|
||||||
|
language processor for your given language,
|
||||||
|
with each option conforming to option=value. For
|
||||||
|
a list of options for each language processor,
|
||||||
|
refer to the complete documentation.
|
||||||
|
|
||||||
|
Languages currently supported: \n"""
|
||||||
|
USAGE += "\t" + (" ".join(CONVERTERS.keys())) + "\n"
|
||||||
|
USAGE += """Filetypes currently supported:\n"""
|
||||||
|
for proc in PROCESSORS.keys() :
|
||||||
|
USAGE += "\t%s : %s\n" % (proc, PROCESSORS[proc][1])
|
||||||
|
USAGE += """\npcfconv.py by Andrew Kesterson, 2008, released under the AKLabs
|
||||||
|
License. Go to http://www.aklabs.net/source/license.txt for the
|
||||||
|
full text of this license. Email the author andrew@aklabs.net for
|
||||||
|
all questions and bug reports.
|
||||||
|
"""
|
||||||
|
|
||||||
|
######################## MAIN LOGIC #############################
|
||||||
|
|
||||||
|
def main (argc, argv):
|
||||||
|
global DEBUG
|
||||||
|
infile = "-"
|
||||||
|
outfile = "-"
|
||||||
|
language = "python"
|
||||||
|
filetype = "mspcf"
|
||||||
|
ignoreErrors = False
|
||||||
|
recovery = False
|
||||||
|
translate = False
|
||||||
|
supp_trans = False
|
||||||
|
langopts = {}
|
||||||
|
opts = getopt.getopt(argv, SHORTOPTS, LONGOPTS)
|
||||||
|
for pair in opts[0]:
|
||||||
|
if ( pair[0] == "-h" or pair[0] == "--help" ):
|
||||||
|
sys.__stderr__.write(USAGE)
|
||||||
|
return 1
|
||||||
|
elif ( pair[0] == "-d" or pair[0] == "--debug" ):
|
||||||
|
DEBUG=True
|
||||||
|
elif ( pair[0] == "-l" or pair[0] == "--language" ):
|
||||||
|
language = pair[1]
|
||||||
|
elif ( pair[0] == "-f" or pair[0] == "--filename" ):
|
||||||
|
infile = pair[1]
|
||||||
|
elif ( pair[0] == "-o" or pair[0] == "--outfile" ):
|
||||||
|
outfile = pair[1]
|
||||||
|
elif ( pair[0] == "-e" or pair[0] == "--ignore-err" ):
|
||||||
|
ignoreErrors = True
|
||||||
|
elif ( pair[0] == "-r" or pair[0] == "--recovery" ):
|
||||||
|
recovery = True
|
||||||
|
elif ( pair[0] == "-t" or pair[0] == "--filetype" ):
|
||||||
|
filetype = pair[1]
|
||||||
|
elif ( pair[0] == "-T" or pair[0] == "--translate" ):
|
||||||
|
translate = True
|
||||||
|
elif ( pair[0] == "-S" or pair[0] == "--supp-trans" ):
|
||||||
|
supp_trans = True
|
||||||
|
elif ( pair[0] == "-O" or pair[0] == "--langopts" ):
|
||||||
|
splitopts = pair[1].split("=")
|
||||||
|
for i in range(0, len(splitopts)-1, 2):
|
||||||
|
#print "Assigning language option %s = %s" % (splitopts[i], splitopts[i+1])
|
||||||
|
langopts[splitopts[i]] = splitopts[i+1]
|
||||||
|
procclass = PROCESSORS[filetype][0]
|
||||||
|
proc = procclass(CONVERTERS)
|
||||||
|
if ( supp_trans ):
|
||||||
|
convclass = CONVERTERS[language]
|
||||||
|
conv = convclass(langopts)
|
||||||
|
print conv.supportedTranslations()
|
||||||
|
return 0
|
||||||
|
return proc.convertFile(infile, outfile, language, ignoreErrors, recovery, translate, langopts)
|
||||||
|
|
||||||
|
if ( __name__ == "__main__" ):
|
||||||
|
sys.exit(main(len(sys.argv[1:])-1, sys.argv[1:]))
|
||||||
|
|
||||||
290
pycc
Executable file
290
pycc
Executable file
@@ -0,0 +1,290 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# python script that compiles files and directories to python bytecode,
|
||||||
|
# possibly with optimizations
|
||||||
|
|
||||||
|
# TODO:
|
||||||
|
# Distinguish between files and directories
|
||||||
|
# Accept the optimization flag
|
||||||
|
# Enforce command option rules
|
||||||
|
|
||||||
|
import py_compile
|
||||||
|
import compileall
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import getopt
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
usage = r"""
|
||||||
|
pycc : Python byteCode Compiler (pronounced "pie-sees")
|
||||||
|
(C) Andrew Kesterson 2006, <andrew@aklabs.net>
|
||||||
|
usage: pycc <options> src_files ...
|
||||||
|
options:
|
||||||
|
-L dir : Add the following directory to the sys.path; similar to
|
||||||
|
the -L directive in gcc
|
||||||
|
-l lib : Specifically import the given module before compiling
|
||||||
|
any modules (successive -l directives are processed in
|
||||||
|
the order received); similar to -l directive in gcc. The
|
||||||
|
argument should be in standard python 'import' notation.
|
||||||
|
"from xxx import y' should be enclosed in quotes. Otherwise
|
||||||
|
provide 'xxx' alone for the module name to import
|
||||||
|
-O : Enable the python compiler's optimizations; default output
|
||||||
|
will have a .pyo extension instead of a .pyc. NOTE: FOR
|
||||||
|
SOME REASON, this option doesn't work on single files.
|
||||||
|
Only directories. This is a limitation of the python
|
||||||
|
compiler libraries, not this program.
|
||||||
|
-o : When compiling a single file, specify the output filename.
|
||||||
|
When compiling a directory or multiple files, this directive
|
||||||
|
has no effect.
|
||||||
|
-r : Recurse beyond the first level of directories given on the
|
||||||
|
command line, so that for example passing src/dir on the
|
||||||
|
command line would compile src/dir/src1.py and also
|
||||||
|
src/dir/subdir/src2.py.
|
||||||
|
src_files This is a list of single files and directories. Directories
|
||||||
|
are not recursed into (beyond the first level) unless the
|
||||||
|
-r option is specified.
|
||||||
|
-E : Stop compilation of all source files when one source file
|
||||||
|
has an error (otherwise, an error message is printed to
|
||||||
|
stderr and compilation continues to the next file). Error
|
||||||
|
messages are printed regardless of this flag.
|
||||||
|
-d n : Tells the compiler to descend up to (at maximum) n levels of
|
||||||
|
directories when running recursively
|
||||||
|
-F : Force the generation of code, even when the .pyc/.pyo
|
||||||
|
timestamps are up to date
|
||||||
|
-v : Be verbose (errors are always printed regardless)
|
||||||
|
-h : display this help
|
||||||
|
"""
|
||||||
|
|
||||||
|
shortopts = "L:l:Oo:rd:EvhF"
|
||||||
|
|
||||||
|
class ArgChecker:
|
||||||
|
def printErr(self, msg):
|
||||||
|
if ( not msg.endswith("\n") ):
|
||||||
|
msg += "\n"
|
||||||
|
sys.__stdout__.write(msg)
|
||||||
|
|
||||||
|
def importPaths (self, importStr):
|
||||||
|
fromRE = re.compile(r"""^from\s+([\w.]+)\s+import\s+(\w+).*$""")
|
||||||
|
importRE = re.compile(r"""^import\s+([.\w]+).*$""")
|
||||||
|
fromparts = fromRE.findall(importStr)
|
||||||
|
importparts = importRE.findall(importStr)
|
||||||
|
try:
|
||||||
|
if ( (len(fromparts) != 1 or len(fromparts[0]) != 2 ) and len(importparts) == 0):
|
||||||
|
self.printErr("Bad option: -l %s : invalid syntax : not enough arguments!" % (importStr))
|
||||||
|
self.printErr("%s : %s" % (fromparts, importparts))
|
||||||
|
return False
|
||||||
|
elif ( len(fromparts) == 1 and len(fromparts[0]) == 2 ):
|
||||||
|
__import__(fromparts[0][1], globals(), None, fromparts[0][0].split("."))
|
||||||
|
return True
|
||||||
|
elif ( len(importparts) == 1):
|
||||||
|
__import__(importparts[0][0], globals(), None, None)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
except Exception, e:
|
||||||
|
self.printErr("Import error:%s: %s" % (importStr, str(e)))
|
||||||
|
return False
|
||||||
|
|
||||||
|
def checkArgs (self, argc, argv):
|
||||||
|
global shortopts
|
||||||
|
global usage
|
||||||
|
compiler = PYCompiler()
|
||||||
|
opts, args = getopt.getopt(argv, shortopts)
|
||||||
|
# self.printErr("%s : %s" % (opts, args))
|
||||||
|
errors = False
|
||||||
|
if ( len(args) == 0 ):
|
||||||
|
self.printErr(usage)
|
||||||
|
return None
|
||||||
|
for file in args:
|
||||||
|
if ( os.path.exists(file) ):
|
||||||
|
if ( os.path.isfile(file) ):
|
||||||
|
compiler.queueFile(file)
|
||||||
|
elif ( os.path.isdir(file) ):
|
||||||
|
compiler.queueDir(file)
|
||||||
|
else:
|
||||||
|
self.printErr("Bad Option: Unable to determine type of file %s" % file)
|
||||||
|
errors = True
|
||||||
|
else:
|
||||||
|
self.printErr("Bad Option: File or directory does not exist %s" % file)
|
||||||
|
errors = True
|
||||||
|
for opt in opts:
|
||||||
|
if ( opt[0] == "-L" ):
|
||||||
|
# add library path
|
||||||
|
if ( os.path.exists(opt[1]) and os.path.isdir(opt[1]) ):
|
||||||
|
sys.path.append(opt[1])
|
||||||
|
else:
|
||||||
|
self.printErr("Bad option: -L %s : Path is not a directory or is nonexistant" % opt[1])
|
||||||
|
errors = True
|
||||||
|
elif ( opt[0] == "-l" ):
|
||||||
|
# specifically import the given module before continuing
|
||||||
|
if ( not self.importPaths(opt[1]) ):
|
||||||
|
errors = True
|
||||||
|
elif ( opt[0] == "-O" ) :
|
||||||
|
compiler.optimize(True)
|
||||||
|
elif ( opt[0] == "-o" ) :
|
||||||
|
if ( len(compiler.files) == 1 and len(compiler.dirs) == 0 ):
|
||||||
|
compiler.ofile = opt[1]
|
||||||
|
else:
|
||||||
|
if ( compiler.verbose ):
|
||||||
|
self.printErr("Ignoring option -o with multiple files or directories...")
|
||||||
|
elif ( opt[0] == "-r" ):
|
||||||
|
compiler.recursive(True)
|
||||||
|
elif ( opt[0] == "-E" ):
|
||||||
|
compiler.stopOnError(True)
|
||||||
|
elif ( opt[0] == "-v" ):
|
||||||
|
compiler.setVerbose(True)
|
||||||
|
elif ( opt[0] == "-F" ):
|
||||||
|
compiler.forceGen(True)
|
||||||
|
elif ( opt[0] == "-h" ):
|
||||||
|
self.printErr("HELP FOUND")
|
||||||
|
return False
|
||||||
|
elif ( opt[0] == "-d" ):
|
||||||
|
try:
|
||||||
|
compiler.setMaxDepth(int(opt[1]))
|
||||||
|
except Exception, e:
|
||||||
|
self.printErr("Bad Option: %s : must pass an integer" % opt[0])
|
||||||
|
else:
|
||||||
|
self.printErr(usage)
|
||||||
|
errors = True
|
||||||
|
if ( not errors ):
|
||||||
|
return compiler
|
||||||
|
else:
|
||||||
|
#self.printErr("%s : %s" % (opts, args))
|
||||||
|
return None
|
||||||
|
|
||||||
|
class PYCompiler :
|
||||||
|
def __init__ (self):
|
||||||
|
self.files = []
|
||||||
|
self.dirs = []
|
||||||
|
self.opt = False
|
||||||
|
self.recurse = False
|
||||||
|
self.stopErr = False
|
||||||
|
self.verbose = 0
|
||||||
|
self.depth = 10
|
||||||
|
self.force = 0
|
||||||
|
self.ofile = ""
|
||||||
|
|
||||||
|
def setVerbose (self, opt):
|
||||||
|
if ( opt ):
|
||||||
|
self.verbose = 1
|
||||||
|
else:
|
||||||
|
self.verbose = 0
|
||||||
|
|
||||||
|
def forceGen (self, opt):
|
||||||
|
if ( opt ):
|
||||||
|
self.force = 1
|
||||||
|
else:
|
||||||
|
self.force = 0
|
||||||
|
|
||||||
|
def setMaxDepth (self, depth):
|
||||||
|
self.depth = depth
|
||||||
|
|
||||||
|
def printErr(self, msg):
|
||||||
|
sys.__stdout__.write(msg)
|
||||||
|
if ( (not msg.endswith("\n")) ):
|
||||||
|
sys.__stdout__.write("\n")
|
||||||
|
|
||||||
|
def queueFile (self, fname):
|
||||||
|
self.files.append(fname)
|
||||||
|
|
||||||
|
def queueDir (self, dirname):
|
||||||
|
self.dirs.append(dirname)
|
||||||
|
|
||||||
|
def printCompileErr (self, e):
|
||||||
|
#self.printErr("printErr called with exception %s" % str(e))
|
||||||
|
efile = e.file
|
||||||
|
etype = e.exc_type_name
|
||||||
|
if ( len(e.exc_value) > 1 ) :
|
||||||
|
eline = e.exc_value[1][1]
|
||||||
|
ecode = e.exc_value[1][3]
|
||||||
|
else:
|
||||||
|
eline = -1
|
||||||
|
ecode = "(no code given)"
|
||||||
|
edesc = e.exc_value[0]
|
||||||
|
msg = "%s:%d: %s : %s : %s" % (efile, eline, etype, edesc, str(ecode))
|
||||||
|
self.printErr(msg)
|
||||||
|
|
||||||
|
def compile (self):
|
||||||
|
for fname in self.files:
|
||||||
|
ofile = ""
|
||||||
|
if ( len(self.files) == 1 and len(self.dirs) == 0 and self.ofile) :
|
||||||
|
ofile = self.ofile
|
||||||
|
else:
|
||||||
|
ofile = fname + "c"
|
||||||
|
if ( not self.__compile_file(fname, ofile) ):
|
||||||
|
if ( self.stopErr or ( len(self.files) + len(self.dirs)) == 1):
|
||||||
|
return False
|
||||||
|
for dirname in self.dirs :
|
||||||
|
if ( not os.path.walk(dirname, self.__compile_dir, None) ):
|
||||||
|
if ( self.stopErr ):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def __compile_file (self, fname, ofile = None):
|
||||||
|
try:
|
||||||
|
if ( self.force == 1 and len(self.files) == 1 and len(self.dirs) == 0):
|
||||||
|
if ( os.path.exists(ofile) and os.path.isfile(ofile) ):
|
||||||
|
try:
|
||||||
|
os.remove(ofile)
|
||||||
|
except OSError, e:
|
||||||
|
if ( self.verbose ):
|
||||||
|
self.printErr("%s : Failed to remove original - ignoring ... " % fname)
|
||||||
|
else:
|
||||||
|
if ( self.verbose ):
|
||||||
|
self.printErr("%s : Original output does not exist - ignoring ... " % fname)
|
||||||
|
#self.printErr("%s -> %s ..." % (fname, ofile))
|
||||||
|
py_compile.compile(fname, ofile, None, True)
|
||||||
|
if ( (fname in self.files) and self.verbose ):
|
||||||
|
# don't print this if we're being called from __compile_dir
|
||||||
|
self.printErr("%s -> %s ... OK" % (fname, ofile))
|
||||||
|
return True
|
||||||
|
except py_compile.PyCompileError, e:
|
||||||
|
self.printCompileErr(e)
|
||||||
|
if ( fname in self.files ):
|
||||||
|
self.printErr("%s -> %s ... FAILED" % (fname, ofile))
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __compile_dir (self, arg, dirname, fnames):
|
||||||
|
try:
|
||||||
|
for fname in fnames:
|
||||||
|
if ( not (fname.endswith("py") or fname.endswith("PY")) ):
|
||||||
|
continue
|
||||||
|
tocompile = os.path.join(dirname, fname)
|
||||||
|
if ( os.path.isdir(tocompile) ):
|
||||||
|
os.path.walk(dirname, self.__compile_dir, None)
|
||||||
|
outfile = tocompile+"c"
|
||||||
|
if ( not self.__compile_file(tocompile, outfile) ):
|
||||||
|
self.printErr("%s -> %s ... FAILED" % (tocompile, outfile))
|
||||||
|
if ( self.stopErr ):
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
if ( self.verbose ):
|
||||||
|
self.printErr("%s -> %s ... OK" % (tocompile, outfile))
|
||||||
|
return True
|
||||||
|
except py_compile.PyCompileError, e:
|
||||||
|
self.printCompileErr(e)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def optimize (self, opt):
|
||||||
|
self.opt = opt
|
||||||
|
|
||||||
|
def recursive (self, opt):
|
||||||
|
self.recurse = opt
|
||||||
|
|
||||||
|
def stopOnError (self, opt):
|
||||||
|
self.stopErr = opt
|
||||||
|
|
||||||
|
def main (argc, argv):
|
||||||
|
checker = ArgChecker()
|
||||||
|
compiler = checker.checkArgs(argc, argv)
|
||||||
|
if ( not compiler ):
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
if ( not compiler.compile() ):
|
||||||
|
sys.exit(2)
|
||||||
|
else:
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
if ( __name__ == "__main__" ):
|
||||||
|
main(len(sys.argv)-1, sys.argv[1:])
|
||||||
13
tocaps.c
Executable file
13
tocaps.c
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
char c = 0x00;
|
||||||
|
c = fgetc(stdin);
|
||||||
|
while (!feof(stdin)) {
|
||||||
|
c = toupper(c);
|
||||||
|
printf("%c", c);
|
||||||
|
c = fgetc(stdin);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
41
wrap.c
Executable file
41
wrap.c
Executable file
@@ -0,0 +1,41 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
const char *usage = "\
|
||||||
|
wrap - wrap a text file.\n\
|
||||||
|
Usage: wrap <infile> <outfile>\n";
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if ( argc < 3 ) {
|
||||||
|
printf("%s", usage);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *in = fopen(argv[1], "r");
|
||||||
|
FILE *out = fopen(argv[2], "w");
|
||||||
|
int cn = 0;
|
||||||
|
char c = 0x00;
|
||||||
|
|
||||||
|
if ( !in || !out ) {
|
||||||
|
printf("Failed to open input/output file.\n");
|
||||||
|
in ? fclose(in) : 0 ;
|
||||||
|
out ? fclose(out) : 0 ;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( !feof(in) ) {
|
||||||
|
c = fgetc(in);
|
||||||
|
if ( cn > 60 &&
|
||||||
|
( c == ' ' || c == '\n' || c == '\t' )) {
|
||||||
|
fputc('\n', out);
|
||||||
|
cn = 0;
|
||||||
|
if ( c != '\t' ) continue;
|
||||||
|
}
|
||||||
|
fputc(c, out);
|
||||||
|
cn++;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(in);
|
||||||
|
fclose(out);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user