summaryrefslogtreecommitdiff
path: root/cppe/config/makeprops.py
diff options
context:
space:
mode:
Diffstat (limited to 'cppe/config/makeprops.py')
-rw-r--r--cppe/config/makeprops.py379
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)