# HG changeset patch # User Paul Boddie # Date 1486571071 -3600 # Node ID c34d7d187b2c7aff1cd6f6974d88e0b4c995b481 # Parent aa11ebd14c79eac3a5bcda5c18d8593f0aaa665d Introduced a warnings mechanism to support invocation-related messages. Added a help message and handled missing command line arguments better. diff -r aa11ebd14c79 -r c34d7d187b2c importer.py --- a/importer.py Wed Feb 08 16:20:27 2017 +0100 +++ b/importer.py Wed Feb 08 17:24:31 2017 +0100 @@ -35,7 +35,7 @@ special_attributes = ("__args__", "__file__", "__fn__", "__name__", "__parent__") - def __init__(self, path, cache=None, verbose=False): + def __init__(self, path, cache=None, verbose=False, warnings=None): """ Initialise the importer with the given search 'path' - a list of @@ -46,11 +46,15 @@ The optional 'verbose' parameter causes output concerning the activities of the object to be produced if set to a true value (not the default). + + The optional 'warnings' parameter may indicate classes of warnings to be + produced. """ self.path = path self.cache = cache self.verbose = verbose + self.warnings = warnings # Module importing queue, required modules, removed modules and active # modules in the final program. @@ -116,6 +120,12 @@ self.make_cache() + def give_warning(self, name): + + "Return whether the indicated warning 'name' should be given." + + return self.warnings and (name in self.warnings or "all" in self.warnings) + def make_cache(self): "Make a cache directory if it does not already exist." diff -r aa11ebd14c79 -r c34d7d187b2c lplc --- a/lplc Wed Feb 08 16:20:27 2017 +0100 +++ b/lplc Wed Feb 08 17:24:31 2017 +0100 @@ -43,12 +43,59 @@ stdout, stderr = cmd.communicate() return cmd.wait() +def start_arg_list(l, arg, prefix, needed): + + """ + Add to 'l' any value given as part of 'arg' having the given option + 'prefix'. The 'needed' number of values is provided in case no value is + found. + + Return 'l' and 'needed' decremented by 1 together in a tuple. + """ + + s = arg[len(prefix):].strip() + if s: + l.append(s) + return l, needed - 1 + else: + return l, needed + # Main program. if __name__ == "__main__": + basename = split(sys.argv[0])[-1] args = sys.argv[1:] path = libdirs + if "--help" in args or not args: + print >>sys.stderr, """\ +Usage: %s [ ] + +Compile the program whose principal file is given in place of . +The following options may be specified: + +-c Only partially compile the program; do not attempt to build or link it +-g Generate debugging information for the built executable +-q Silence messages produced when building an executable +-r Reset (discard) cached program information; inspect the whole program again +-tb Provide a traceback for any internal errors (development only) +-v Report compiler activities in a verbose fashion (development only) + +Some options may be followed by values, either immediately after the option +(without any space between) or in the arguments that follow them: + +-o Indicate the output executable name +-W Show warnings on the topics indicated + +Currently, the following warnings are supported: + +all Show all possible warnings + +args Show invocations where a callable may be involved that cannot accept the + arguments provided +""" % basename + sys.exit(1) + # Determine the options and arguments. debug = False @@ -57,6 +104,7 @@ reset = False traceback = False verbose = False + warnings = [] filenames = [] outputs = [] @@ -64,6 +112,7 @@ # Obtain program filenames by default. l = filenames + needed = None for arg in args: if arg == "-c": make = False @@ -71,20 +120,21 @@ elif arg == "-q": make_verbose = False elif arg == "-r": reset = True elif arg == "-tb": traceback = True - elif arg == "-o": l = outputs + elif arg.startswith("-o"): l, needed = start_arg_list(outputs, arg, "-o", 1) elif arg == "-v": verbose = True + elif arg.startswith("-W"): l, needed = start_arg_list(warnings, arg, "-W", 1) else: l.append(arg) + if needed: + needed -= 1 - # Revert to collecting program filenames after obtaining the output - # executable filename. - - if l is outputs: l = filenames + if needed == 0: + l = filenames # Obtain the program filename. - if len(filenames) > 1: - print >>sys.stderr, "Only one main program file can be specified." + if len(filenames) != 1: + print >>sys.stderr, "One main program file must be specified." sys.exit(1) filename = abspath(filenames[0]) @@ -92,6 +142,9 @@ # Obtain the output filename. + if outputs and not make: + print >>sys.stderr, "Output specified but building disabled." + output = outputs and outputs[0] or "_main" # Define the output data directories. @@ -107,7 +160,7 @@ try: start = now = time() - i = importer.Importer(path, cache_dir, verbose) + i = importer.Importer(path, cache_dir, verbose, warnings) m = i.initialise(filename, reset) success = i.finalise() diff -r aa11ebd14c79 -r c34d7d187b2c translator.py --- a/translator.py Wed Feb 08 16:20:27 2017 +0100 +++ b/translator.py Wed Feb 08 17:24:31 2017 +0100 @@ -1215,9 +1215,11 @@ target_structure = "&%s" % encode_path(objpath) - # Other targets are retrieved at run-time. - - else: + # Other targets are retrieved at run-time. Some information about them + # may be available and be used to provide warnings about argument + # compatibility. + + elif self.importer.give_warning("args"): unsuitable = self.get_referenced_attribute_invocations(location) if unsuitable: