diff options
Diffstat (limited to 'cppe/config/makeprops.py')
-rw-r--r-- | cppe/config/makeprops.py | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/cppe/config/makeprops.py b/cppe/config/makeprops.py new file mode 100644 index 00000000000..46fe82247ea --- /dev/null +++ b/cppe/config/makeprops.py @@ -0,0 +1,379 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, shutil, re, signal, time, string + +progname = os.path.basename(sys.argv[0]) +infile = "" +classname = "" +lineNum = 0 +errors = 0 +outputFiles = [] + +def usage(): + global progname + print >> sys.stderr, "Usage: " + progname + " [--{cpp|java|cs} file]" + +def fileError(msg): + global progname, infile, lineNum, errors + print >> sys.stderr, progname + ": " + infile + ':' + str(lineNum) + ": " + msg + errors += 1 + +def progError(msg): + global progname + print >> sys.stderr, progname + ": " + msg + +def removeOutputFiles(): + global outputFiles + for entry in outputFiles: + try: + if os.path.exists(entry[0]): + os.remove(entry[0]) + except EnvironmentError, ex: + progError("warning: could not unlink `" + entry[0] + "': " + ex.strerror + \ + " -- generated file contains errors"); + +def handler(signum, frame): + removeOutputFiles() + sys.exit(128 + signum) + +def openOutputFile(filename): + global outputFiles + try: + outfile = file(filename, 'w') + outputFiles.append([filename, outfile]) + except IOError, ex: + progError("cannot open `" + filename + "' for writing: " + ex.strerror) + removeOutputFiles() + sys.exit(1) + +def writePreamble(lang): + global progname + global infile + global outputFiles + global classname + + for entry in outputFiles: + file = entry[1] + file.write("// **********************************************************************\n") + file.write("//\n") + file.write("// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.\n") + file.write("//\n") + file.write("// This copy of Ice is licensed to you under the terms described in the\n") + file.write("// ICE_LICENSE file included in this distribution.\n") + file.write("//\n") + file.write("// **********************************************************************\n") + file.write("\n") + file.write("// Generated by " + progname + " from file `" + infile + "', " + time.ctime() + "\n") + file.write("\n") + file.write("// IMPORTANT: Do not edit this file -- any edits made here will be lost!\n"); + if lang == "cpp": + continue + if lang == "java": + file.write("\n"); + file.write("package IceInternal;\n") + file.write("\n") + file.write("public final class " + classname + '\n'); + file.write("{\n") + continue + if lang == "cs": + file.write("\n"); + file.write("namespace IceInternal\n") + file.write("{\n") + file.write(" public sealed class " + classname + '\n') + file.write(" {\n"); + continue + progError("Internal error: impossible language: `" + lang + "'") + sys.exit(1) + + if lang == "cpp": + header = outputFiles[1][1] + header.write("\n"); + header.write("#ifndef ICE_INTERNAL_" + classname + "_H\n"); + header.write("#define ICE_INTERNAL_" + classname + "_H\n"); + header.write("\n") + header.write("#include <Ice/Config.h>") + header.write("\n") + header.write("namespace IceInternal\n") + header.write("{\n") + header.write("\n") + header.write("class " + classname + '\n') + header.write("{\n") + header.write("public:\n") + header.write("\n") + file = outputFiles[0][1] + file.write("\n"); + file.write("#include <Ice/" + classname + ".h>\n") + +def writePostamble(lang, labels): + file = outputFiles[0][1] + if lang == "cpp": + header = outputFiles[1][1] + header.write("\n") + header.write(" ICE_API static const char* const* validProps[];\n") + header.write("};\n") + header.write("\n") + header.write("}\n") + header.write("\n") + header.write("#endif\n"); + file.write("\n"); + file.write("ICE_API const char* const* IceInternal::" + classname + "::validProps[] =\n") + file.write("{\n") + for label, line in labels.iteritems(): + file.write(" " + label + "Props,\n") + file.write(" 0\n"); + file.write("};\n") + return + if lang == "java": + file.write(" public static final String[] validProps[] =\n") + file.write(" {\n") + for label, line in labels.iteritems(): + file.write(" " + label + "Props,\n") + file.write(" null\n") + file.write(" };\n"); + file.write("}\n"); + return + if lang == "cs": + file.write(" public static string[][] validProps =\n") + file.write(" {\n") + for label, line in labels.iteritems(): + file.write(" " + label + "Props,\n") + file.write(" null\n") + file.write(" };\n"); + file.write(" }\n"); + file.write("}\n"); + return + +def startSection(lang, label): + if lang == "cpp": + header = outputFiles[1][1] + header.write(" static const char* " + label + "Props[];\n") + + file = outputFiles[0][1] + if lang == "cpp": + file.write("\n"); + file.write("const char* IceInternal::" + classname + "::" + label + "Props[] =\n") + file.write("{\n"); + return + if lang == "java": + file.write(" public static final String " + label + "Props[] =\n"); + file.write(" {\n") + return + if lang == "cs": + file.write(" public static string[] " + label + "Props =\n"); + file.write(" {\n") + return + +def endSection(lang): + file = outputFiles[0][1] + if lang == "cpp": + file.write(" 0\n"); + file.write("};\n"); + return + if lang == "java": + file.write(" null\n"); + file.write(" };\n"); + file.write("\n") + return + if lang == "cs": + file.write(" null\n"); + file.write(" };\n"); + file.write("\n") + return + +wildcard = re.compile(".*<any>.*") + +def writeEntry(lang, label, entry): + file = outputFiles[0][1] + if lang == "cpp": + file.write(" \"" + label + '.' + string.replace(entry, "<any>", "*") + "\",\n") + elif lang == "java": + pattern = string.replace(entry, ".", "\\\\.") + pattern = string.replace(pattern, "<any>", "[^\\\\s.]+") + file.write(" " + "\"^" + label + "\\\\." + pattern + "$\",\n") + elif lang == "cs": + pattern = string.replace(entry, ".", "\\.") + pattern = string.replace(pattern, "<any>", "[^\\s.]+") + file.write(" " + "@\"^" + label + "\\." + pattern + "$\",\n") + +def processFile(lang): + + # + # Open input file. + # + global infile + try: + f = file(infile, 'r') + except IOError, ex: + progError("cannot open `" + infile + "': " + ex.strerror) + sys.exit(1) + + # + # Set up regular expressions for empty and comment lines, section headings, and entry lines. + # + ignore = re.compile("^\s*(?:#.*)?$") # Empty line or comment line + section = re.compile("^\s*([a-zA-z_]\w*)\s*:\s*$") # Section heading + entry = re.compile("^\s*([^ \t\n\r\f\v#]+)(?:\s*#.*)?$") # Any non-whitespace character sequence, except for # + + # + # Install signal handler so we can remove the output files if we are interrupted. + # + signal.signal(signal.SIGINT, handler) + signal.signal(signal.SIGHUP, handler) + signal.signal(signal.SIGTERM, handler) + + # + # Open output files. + # + global classname + classname, ext = os.path.splitext(os.path.basename(infile)) + openOutputFile(classname + '.' + lang) + if(lang == "cpp"): + openOutputFile(classname + ".h") + + labels = {} # Records the line number on which each label is defined + atSectionStart = 0 # True for the line on which a label is defined + seenSection = 0 # Set to true (and the remains as true) once the first label is defined + numEntries = 0 # Number of entries within a section + errors = 0 # Number of syntax errors in the input file + + # + # Write preamble. + # + writePreamble(lang) + + # + # Loop over lines in input file. + # + global lineNum + lines = f.readlines() + for l in lines: + lineNum += 1 + + # + # Ignore empty lines and comments. + # + if ignore.match(l) != None: + continue + + # + # Start of section. + # + labelMatch = section.match(l) + if labelMatch != None: + if atSectionStart: + fileError("section `" + label + "' must have at least one entry") + label = labelMatch.group(1) + try: + badLine = labels[label] + fileError("duplicate section heading: `" + label + "': previously defined on line " + badLine) + except KeyError: + pass + if label == "validProps": + fileError("`validProps' is reserved and cannot be used as a section heading") + labels[label] = lineNum + if seenSection: + endSection(lang) + numEntries = 0 + startSection(lang, label) + seenSection = 1 + atSectionStart = 1 + continue + + entryMatch = entry.match(l) + if entryMatch != None: + writeEntry(lang, label, entryMatch.group(1)) + atSectionStart = 0 + numEntries += 1 + continue + + fileError("syntax error") + + if len(labels) == 0: + fileError("input must define at least one section"); + + # + # End the final section. + # + if numEntries == 0: + fileError("section `" + label + "' must have at least one entry") + endSection(lang) + + # + # End the source files. + # + writePostamble(lang, labels) + + global outputFiles + for entry in outputFiles: + entry[1].close() + + # + # Remove the output files if anything went wrong, so we don't leave partically written files behind. + # + if errors != 0: + removeOutputFiles() + sys.exit(1) + outputFiles = [] + +# +# Check arguments. +# +if len(sys.argv) != 1 and len(sys.argv) != 3: + usage() + sys.exit(1) + +lang = "" +if len(sys.argv) == 1: + # + # Find where the root of the tree is. + # + for toplevel in [".", "..", "../..", "../../..", "../../../.."]: + toplevel = os.path.normpath(toplevel) + if os.path.exists(os.path.join(toplevel, "config", "makeprops.py")): + break + else: + progError("cannot find top-level directory") + sys.exit(1) + + infile = os.path.join(toplevel, "config", "PropertyNames.def") + lang = "all" + +else: + option = sys.argv[1] + if option == "--cpp": + lang = "cpp" + elif option == "--java": + lang = "java" + elif option == "--cs": + lang = "cs" + elif option == "-h" or option == "--help" or option == "-?": + usage() + sys.exit(0) + else: + usage() + sys.exit(1) + infile = sys.argv[2] + +if lang == "all": + processFile("cpp") + shutil.move("PropertyNames.cpp", os.path.join(toplevel, "src", "Ice")) + shutil.move("PropertyNames.h", os.path.join(toplevel, "src", "Ice")) + processFile("java") + if os.path.exists(os.path.join(toplevel, "..", "icej")): + shutil.move("PropertyNames.java", os.path.join(toplevel, "..", "icej", "src", "IceInternal")); + processFile("cs") + if os.path.exists(os.path.join(toplevel, "..", "icecs")): + shutil.move("PropertyNames.cs", os.path.join(toplevel, "..", "icecs", "src", "Ice")); +else: + processFile(lang) + + +sys.exit(0) |