"""
compilerlike -- framework code for building compiler-like programs.

There is a common `compiler-like' pattern in Unix scripts which is useful
for translation utilities of all sorts.  A program following this pattern
behaves as a filter when no argument files are specified on the command
line, but otherwise transforms each file individually into a corresponding
output file.

This module provides framework and glue code to make such programs
easy to write.  You supply a function to massage the file data.  It
always takes initial name and filename arguments; depending on which
entry point you use, it can also take input and output file pointers,
or it can take a string consisting of the entire file's data and
return a replacement, or it can take in succession strings consisting
of each of the file's lines and return a translated line for each.

The fourth, optional argument of each entry point is a name
transformation function or name suffix string.  If it is of string
type, the shortest suffix of each filename beginning with the first
character of the argument string is stripped off.  If the first
character of the argument does not occur in the filename, no suffix is
removed.  Then the name suffix argument is concatenated to the end of
the stripped filename.  (Thus, a name suffix argument of ".x" will
cause the filenames foo.c and bar.d to be transformed to foo.x and
bar.x respectively.)

Argument files are transformed in left to right order in the argument list.
A filename consisting of a dash is interpreted as a directive to read from
standard input (this can be useful in pipelines).

Replacement of each file is atomic and doesn't occur until the
translation of that file has completed.  Any tempfiles are removed
automatically on any exception thrown by the translation function,
and the exception is then passed upwards.
"""

# Requires Python 2.
import sys, os, filecmp, traceback

def filefilter(name, arguments, trans_data, trans_filename=None):
    "Filter stdin to stdout, or file arguments to renamed files."
    if not arguments:
        trans_data(name, "stdin", sys.stdin, sys.stdout)
    else:
        for file in arguments:
            if file == '-':             # - is conventional for stdin
                file = "stdin"
                infp = sys.stdin
            else:
                infp = open(file)
            tempfile = file + ".~%s-%d~" % (name, os.getpid())
            outfp = open(tempfile, "w")
            try:
                trans_data(name, file, infp, outfp)
            except:
                os.remove(tempfile)
                # Pass the exception upwards
                (exc_type, exc_value, exc_traceback) = sys.exc_info()
                raise exc_type, exc_value, exc_traceback
            if filecmp.cmp(file, tempfile):
                os.remove(tempfile)
            else:
                if not trans_filename:
                    os.rename(tempfile, file)
                elif type(trans_filename) == type(""):
                    i = file.rfind(trans_filename[0])
                    if i > -1:
                        file = file[:i]
                    os.rename(tempfile, stem + trans_filename)
                else:
                    os.rename(tempfile, trans_filename(file))

def line_by_line(name, file, infp, outfp, translate_line):
    "Hook to do line-by-line translation for filters."
    while 1:
        line = infp.readline()
        if line == "":
            break
        elif line:      # None returns are skipped
            outfp.write(translate_line(name, file, line))

def linefilter(name, arguments, trans_data, trans_filename=None):
    "Filter framework for line-by-line transformation."
    return filefilter(name,
                  arguments,
                  lambda name, file, infp, outfp: line_by_line(name, file, infp, outfp, trans_data),
                  trans_filename)

def sponge(name, arguments, trans_data, trans_filename=None):
    "Read input sources entire and transform them in memory."
    if not arguments:
        sys.stdout.write(trans_data(name, "stdin", sys.stdin.read()))
    else:
        for file in arguments:
            infp = open(file)
            indoc = infp.read()
            infp.close()
            tempfile = file + ".~%s-%d~" % (name, os.getpid())
            try:
                outfp = open(tempfile, "w")
            except OSError:
                sys.stderr.write("%s: can't open tempfile" % name)
                return 1
            try:
                outdoc = trans_data(name, file, indoc)
            except:
                os.remove(tempfile)
                # Pass the exception upwards
                (exc_type, exc_value, exc_traceback) = sys.exc_info()
                raise exc_type, exc_value, exc_traceback
            if outdoc == indoc:
                os.remove(tempfile)
            else:
                outfp.write(outdoc)
                if not trans_filename:
                    os.rename(tempfile, file)
                elif type(trans_filename) == type(""):
                    i = file.rfind(trans_filename[0])
                    if i > -1:
                        file = file[:i]
                    os.rename(tempfile, file + trans_filename)
                else:
                    os.rename(tempfile, trans_filename(file))

if __name__ == '__main__':
    import getopt

    def nametrans(name):
        return name + ".out"

    def filefilter_test(name, file, infp, outfp):
        "Test hook for filefilter entry point -- put dashes before blank lines."
        while 1:
            line = infp.readline()
            if not line:
                break
            if line == "\n":
                outfp.write("------------------------------------------\n")
            outfp.write(line)

    def linefilter_test(name, file, data):
        "Test hook for linefilter entry point -- wrap lines in brackets."
        return "<" + data[:-1] + ">\n"

    def sponge_test(name, file, data):
        "Test hook for the sponge entry point -- reverse file lines."
        lines = data.split("\n")
        lines.reverse()
        return "\n".join(lines)

    (options, arguments) = getopt.getopt(sys.argv[1:], "fls")
    for (switch, val) in options:
        if switch == '-f':
            filefilter("filefilter_test", arguments, filefilter_test,nametrans)
        elif switch == '-l':
            linefilter("linefilter_test", arguments, linefilter_test,nametrans)
        elif switch == '-s':
            sponge("sponge_test", arguments, sponge_test, ".foo")
        else:
            print "Unknown option."

# End
