diff options
| author | Steven Knight <knight@baldmt.com> | 2001-09-17 04:57:00 (GMT) |
|---|---|---|
| committer | Steven Knight <knight@baldmt.com> | 2001-09-17 04:57:00 (GMT) |
| commit | 3c81bb2bd0e009c0ee81570e17b0f87ad8d034ab (patch) | |
| tree | 1a08c189644909cdadc489cce0eaa487e2c6f578 /src/scons | |
| parent | e2faf9c21bc7712fcdc547b7df0f12a6b2177601 (diff) | |
| download | SCons-3c81bb2bd0e009c0ee81570e17b0f87ad8d034ab.zip SCons-3c81bb2bd0e009c0ee81570e17b0f87ad8d034ab.tar.gz SCons-3c81bb2bd0e009c0ee81570e17b0f87ad8d034ab.tar.bz2 | |
Run setup.py on the unpacked .tar.gz for testing.
Diffstat (limited to 'src/scons')
29 files changed, 0 insertions, 2062 deletions
diff --git a/src/scons/.aeignore b/src/scons/.aeignore deleted file mode 100644 index 43fe851..0000000 --- a/src/scons/.aeignore +++ /dev/null @@ -1,4 +0,0 @@ -*,D -*.pyc -.*.swp -.consign diff --git a/src/scons/Builder.py b/src/scons/Builder.py deleted file mode 100644 index 8b19bd5..0000000 --- a/src/scons/Builder.py +++ /dev/null @@ -1,100 +0,0 @@ -"""scons.Builder - -XXX - -""" - -__revision__ = "Builder.py __REVISION__ __DATE__ __DEVELOPER__" - - - -import os -import types -from scons.Node.FS import Dir, File, lookup - - - -class Builder: - """Base class for Builders, objects that create output - nodes (files) from input nodes (files). - """ - - def __init__(self, name = None, - action = None, - input_suffix = None, - output_suffix = None, - node_class = File): - self.name = name - self.action = Action(action) - self.insuffix = input_suffix - self.outsuffix = output_suffix - self.node_class = node_class - if not self.insuffix is None and self.insuffix[0] != '.': - self.insuffix = '.' + self.insuffix - if not self.outsuffix is None and self.outsuffix[0] != '.': - self.outsuffix = '.' + self.outsuffix - - def __cmp__(self, other): - return cmp(self.__dict__, other.__dict__) - - def __call__(self, env, target = None, source = None): - node = lookup(self.node_class, target) - node.builder_set(self) - node.env_set(self) - node.sources = source # XXX REACHING INTO ANOTHER OBJECT - return node - - def execute(self, **kw): - """Execute a builder's action to create an output object. - """ - apply(self.action.execute, (), kw) - - - -print_actions = 1; -execute_actions = 1; - - - -def Action(act): - """A factory for action objects.""" - if type(act) == types.FunctionType: - return FunctionAction(act) - elif type(act) == types.StringType: - return CommandAction(act) - else: - return None - -class ActionBase: - """Base class for actions that create output objects. - - We currently expect Actions will only be accessible through - Builder objects, so they don't yet merit their own module.""" - def __cmp__(self, other): - return cmp(self.__dict__, other.__dict__) - - def show(self, string): - print string - -class CommandAction(ActionBase): - """Class for command-execution actions.""" - def __init__(self, string): - self.command = string - - def execute(self, **kw): - cmd = self.command % kw - if print_actions: - self.show(cmd) - if execute_actions: - os.system(cmd) - -class FunctionAction(ActionBase): - """Class for Python function actions.""" - def __init__(self, function): - self.function = function - - def execute(self, **kw): - # if print_actions: - # XXX: WHAT SHOULD WE PRINT HERE? - if execute_actions: - self.function(kw) diff --git a/src/scons/BuilderTests.py b/src/scons/BuilderTests.py deleted file mode 100644 index 822b64c..0000000 --- a/src/scons/BuilderTests.py +++ /dev/null @@ -1,113 +0,0 @@ -__revision__ = "BuilderTests.py __REVISION__ __DATE__ __DEVELOPER__" - -import sys -import unittest - -import TestCmd -from scons.Builder import Builder, CommandAction, FunctionAction - - -# Initial setup of the common environment for all tests, -# a temporary working directory containing a -# script for writing arguments to an output file. -# -# We don't do this as a setUp() method because it's -# unnecessary to create a separate directory and script -# for each test, they can just use the one. -test = TestCmd.TestCmd(workdir = '') - -test.write('act.py', """import os, string, sys -f = open(sys.argv[1], 'w') -f.write("act.py: " + string.join(sys.argv[2:]) + "\\n") -f.close() -sys.exit(0) -""") - -act_py = test.workpath('act.py') -outfile = test.workpath('outfile') - - -class BuilderTestCase(unittest.TestCase): - - def test_action(self): - """Test Builder creation - - Verify that we can retrieve the supplied action attribute. - """ - builder = Builder(action = "foo") - assert builder.action.command == "foo" - - def test_cmp(self): - """Test simple comparisons of Builder objects - """ - b1 = Builder(input_suffix = '.o') - b2 = Builder(input_suffix = '.o') - assert b1 == b2 - b3 = Builder(input_suffix = '.x') - assert b1 != b3 - assert b2 != b3 - - def test_execute(self): - """Test execution of simple Builder objects - - One Builder is a string that executes an external command, - and one is an internal Python function. - """ - cmd = "python %s %s xyzzy" % (act_py, outfile) - builder = Builder(action = cmd) - builder.execute() - assert test.read(outfile, 'r') == "act.py: xyzzy\n" - - def function(kw): - import os, string, sys - f = open(kw['out'], 'w') - f.write("function\n") - f.close() - return not None - - builder = Builder(action = function) - builder.execute(out = outfile) - assert test.read(outfile, 'r') == "function\n" - - def test_insuffix(self): - """Test Builder creation with a specified input suffix - - Make sure that the '.' separator is appended to the - beginning if it isn't already present. - """ - builder = Builder(input_suffix = '.c') - assert builder.insuffix == '.c' - builder = Builder(input_suffix = 'c') - assert builder.insuffix == '.c' - - def test_name(self): - """Test Builder creation with a specified name - """ - builder = Builder(name = 'foo') - assert builder.name == 'foo' - - def test_node_class(self): - """Test a Builder that creates nodes of a specified class - """ - class Foo: - pass - builder = Builder(node_class = Foo) - assert builder.node_class is Foo - - def test_outsuffix(self): - """Test Builder creation with a specified output suffix - - Make sure that the '.' separator is appended to the - beginning if it isn't already present. - """ - builder = Builder(input_suffix = '.o') - assert builder.insuffix == '.o' - builder = Builder(input_suffix = 'o') - assert builder.insuffix == '.o' - - - -if __name__ == "__main__": - suite = unittest.makeSuite(BuilderTestCase, 'test_') - if not unittest.TextTestRunner().run(suite).wasSuccessful(): - sys.exit(1) diff --git a/src/scons/Defaults.py b/src/scons/Defaults.py deleted file mode 100644 index 0aa2b82..0000000 --- a/src/scons/Defaults.py +++ /dev/null @@ -1,20 +0,0 @@ -"""scons.Defaults - -Builders and other things for the local site. Here's where we'll -duplicate the functionality of autoconf until we move it into the -installation procedure or use something like qmconf. - -""" - -__revision__ = "local.py __REVISION__ __DATE__ __DEVELOPER__" - - - -from scons.Builder import Builder - - - -Object = Builder(name = 'Object', action = 'cc -c -o %(target)s %(source)s') -Program = Builder(name = 'Program', action = 'cc -o %(target)s %(source)s') - -Builders = [Object, Program] diff --git a/src/scons/Environment.py b/src/scons/Environment.py deleted file mode 100644 index 9b050d1..0000000 --- a/src/scons/Environment.py +++ /dev/null @@ -1,133 +0,0 @@ -"""scons.Environment - -XXX - -""" - -__revision__ = "Environment.py __REVISION__ __DATE__ __DEVELOPER__" - - - -import copy -import re -import types - - - -def Command(): - pass # XXX - -def Install(): - pass # XXX - -def InstallAs(): - pass # XXX - - - -_cv = re.compile(r'%([_a-zA-Z]\w*|{[_a-zA-Z]\w*})') -_self = None - - - -def _deepcopy_atomic(x, memo): - return x -copy._deepcopy_dispatch[types.ModuleType] = _deepcopy_atomic -copy._deepcopy_dispatch[types.ClassType] = _deepcopy_atomic -copy._deepcopy_dispatch[types.FunctionType] = _deepcopy_atomic -copy._deepcopy_dispatch[types.MethodType] = _deepcopy_atomic -copy._deepcopy_dispatch[types.TracebackType] = _deepcopy_atomic -copy._deepcopy_dispatch[types.FrameType] = _deepcopy_atomic -copy._deepcopy_dispatch[types.FileType] = _deepcopy_atomic - - - -class Environment: - """Base class for construction Environments. These are - the primary objects used to communicate dependency and - construction information to the build engine. - - Keyword arguments supplied when the construction Environment - is created are construction variables used to initialize the - Environment. - """ - - def __init__(self, **kw): - self.Dictionary = {} - if kw.has_key('BUILDERS'): - builders = kw['BUILDERS'] - if not type(builders) is types.ListType: - kw['BUILDERS'] = [builders] - else: - import scons.Defaults - kw['BUILDERS'] = scons.Defaults.Builders[:] - self.Dictionary.update(copy.deepcopy(kw)) - - class BuilderWrapper: - """Wrapper class that allows an environment to - be associated with a Builder at instantiation. - """ - def __init__(self, env, builder): - self.env = env - self.builder = builder - - def __call__(self, target = None, source = None): - return self.builder(self.env, target, source) - - def execute(self, **kw): - apply(self.builder.execute, (), kw) - - for b in kw['BUILDERS']: - setattr(self, b.name, BuilderWrapper(self, b)) - - - - def __cmp__(self, other): - return cmp(self.Dictionary, other.Dictionary) - - def Builders(self): - pass # XXX - - def Copy(self, **kw): - """Return a copy of a construction Environment. The - copy is like a Python "deep copy"--that is, independent - copies are made recursively of each objects--except that - a reference is copied when an object is not deep-copyable - (like a function). There are no references to any mutable - objects in the original Environment. - """ - clone = copy.deepcopy(self) - apply(clone.Update, (), kw) - return clone - - def Scanners(self): - pass # XXX - - def Update(self, **kw): - """Update an existing construction Environment with new - construction variables and/or values. - """ - self.Dictionary.update(copy.deepcopy(kw)) - - def subst(self, string): - """Recursively interpolates construction variables from the - Environment into the specified string, returning the expanded - result. Construction variables are specified by a % prefix - in the string and begin with an initial underscore or - alphabetic character followed by any number of underscores - or alphanumeric characters. The construction variable names - may be surrounded by curly braces to separate the name from - trailing characters. - """ - global _self - _self = self # XXX NOT THREAD SAFE, BUT HOW ELSE DO WE DO THIS? - def repl(m): - key = m.group(1) - if key[:1] == '{' and key[-1:] == '}': - key = key[1:-1] - if _self.Dictionary.has_key(key): return _self.Dictionary[key] - else: return '' - n = 1 - while n != 0: - string, n = _cv.subn(repl, string) - return string diff --git a/src/scons/EnvironmentTests.py b/src/scons/EnvironmentTests.py deleted file mode 100644 index 2f13c81..0000000 --- a/src/scons/EnvironmentTests.py +++ /dev/null @@ -1,144 +0,0 @@ -__revision__ = "EnivronmentTests.py __REVISION__ __DATE__ __DEVELOPER__" - -import sys -import unittest - -from scons.Environment import * - - - -built_it = {} - -class Builder: - """A dummy Builder class for testing purposes. "Building" - a target is simply setting a value in the dictionary. - """ - def __init__(self, name = None): - self.name = name - - def execute(self, target = None, source = None): - built_it[target] = 1 - - - -class EnvironmentTestCase(unittest.TestCase): - - def test_Builders(self): - """Test Builder execution through different environments - - One environment is initialized with a single - Builder object, one with a list of a single Builder - object, and one with a list of two Builder objects. - """ - global built_it - - b1 = Builder(name = 'builder1') - b2 = Builder(name = 'builder2') - - built_it = {} - env1 = Environment(BUILDERS = b1) - env1.builder1.execute(target = 'out1') - assert built_it['out1'] - - built_it = {} - env2 = Environment(BUILDERS = [b1]) - env1.builder1.execute(target = 'out1') - assert built_it['out1'] - - built_it = {} - env3 = Environment(BUILDERS = [b1, b2]) - env3.builder1.execute(target = 'out1') - env3.builder2.execute(target = 'out2') - env3.builder1.execute(target = 'out3') - assert built_it['out1'] - assert built_it['out2'] - assert built_it['out3'] - - def test_Command(self): - pass # XXX - - def test_Copy(self): - """Test construction Environment copying - - Update the copy independently afterwards and check that - the original remains intact (that is, no dangling - references point to objects in the copied environment). - Copy the original with some construction variable - updates and check that the original remains intact - and the copy has the updated values. - """ - env1 = Environment(XXX = 'x', YYY = 'y') - env2 = env1.Copy() - env1copy = env1.Copy() - env2.Update(YYY = 'yyy') - assert env1 != env2 - assert env1 == env1copy - - env3 = env1.Copy(XXX = 'x3', ZZZ = 'z3') - assert env3.Dictionary['XXX'] == 'x3' - assert env3.Dictionary['YYY'] == 'y' - assert env3.Dictionary['ZZZ'] == 'z3' - assert env1 == env1copy - - def test_Dictionary(self): - """Test retrieval of known construction variables - - Fetch them from the Dictionary and check for well-known - defaults that get inserted. - """ - env = Environment(XXX = 'x', YYY = 'y') - assert env.Dictionary['XXX'] == 'x' - assert env.Dictionary['YYY'] == 'y' - assert env.Dictionary.has_key('BUILDERS') - - def test_Environment(self): - """Test construction Environments creation - - Create two with identical arguments and check that - they compare the same. - """ - env1 = Environment(XXX = 'x', YYY = 'y') - env2 = Environment(XXX = 'x', YYY = 'y') - assert env1 == env2 - - def test_Install(self): - pass # XXX - - def test_InstallAs(self): - pass # XXX - - def test_Scanners(self): - pass # XXX - - def test_Update(self): - """Test updating an Environment with new construction variables - - After creation of the Environment, of course. - """ - env1 = Environment(AAA = 'a', BBB = 'b') - env1.Update(BBB = 'bbb', CCC = 'ccc') - env2 = Environment(AAA = 'a', BBB = 'bbb', CCC = 'c') - assert env1 != env2 - - def test_subst(self): - """Test substituting construction variables within strings - - Check various combinations, including recursive expansion - of variables into other variables. - """ - env = Environment(AAA = 'a', BBB = 'b') - str = env.subst("%AAA %{AAA}A %BBBB %BBB") - assert str == "a aA b", str - env = Environment(AAA = '%BBB', BBB = 'b', BBBA = 'foo') - str = env.subst("%AAA %{AAA}A %{AAA}B %BBB") - assert str == "b foo b", str - env = Environment(AAA = '%BBB', BBB = '%CCC', CCC = 'c') - str = env.subst("%AAA %{AAA}A %{AAA}B %BBB") - assert str == "c c", str - - - -if __name__ == "__main__": - suite = unittest.makeSuite(EnvironmentTestCase, 'test_') - if not unittest.TextTestRunner().run(suite).wasSuccessful(): - sys.exit(1) diff --git a/src/scons/Errors.py b/src/scons/Errors.py deleted file mode 100644 index 2709c19..0000000 --- a/src/scons/Errors.py +++ /dev/null @@ -1,18 +0,0 @@ -"""scons.Errors - -This file contains the exception classes used to handle internal -and user errors in scons. - -""" - -__revision__ = "Errors.py __REVISION__ __DATE__ __DEVELOPER__" - - - -class InternalError(Exception): - def __init__(self, args=None): - self.args = args - -class UserError(Exception): - def __init__(self, args=None): - self.args = args diff --git a/src/scons/ErrorsTests.py b/src/scons/ErrorsTests.py deleted file mode 100644 index 8d27332..0000000 --- a/src/scons/ErrorsTests.py +++ /dev/null @@ -1,28 +0,0 @@ -__revision__ = "ErrorsTests.py __REVISION__ __DATE__ __DEVELOPER__" - -import sys -import unittest -from scons.Errors import InternalError, UserError - - -class ErrorsTestCase(unittest.TestCase): - def test_InternalError(self): - """Test the InternalError exception.""" - try: - raise InternalError, "test internal error" - except InternalError, e: - assert e.args == "test internal error" - - def test_UserError(self): - """Test the UserError exception.""" - try: - raise UserError, "test user error" - except UserError, e: - assert e.args == "test user error" - - - -if __name__ == "__main__": - suite = unittest.makeSuite(ErrorsTestCase, 'test_') - if not unittest.TextTestRunner().run(suite).wasSuccessful(): - sys.exit(1) diff --git a/src/scons/Job.py b/src/scons/Job.py deleted file mode 100644 index 09bfcb8..0000000 --- a/src/scons/Job.py +++ /dev/null @@ -1,239 +0,0 @@ -"""scons.Job - -This module defines the Serial and Parallel classes that execute tasks to -complete a build. The Jobs class provides a higher level interface to start, -stop, and wait on jobs. - -""" - -__revision__ = "Job.py __REVISION__ __DATE__ __DEVELOPER__" - -class Jobs: - """An instance of this class initializes N jobs, and provides - methods for starting, stopping, and waiting on all N jobs. - """ - - def __init__(self, num, taskmaster): - """ - create 'num' jobs using the given taskmaster. - - If 'num' is equal to 0, then a serial job will be used, - otherwise 'num' parallel jobs will be used. - """ - - if num > 1: - self.jobs = [] - for i in range(num): - self.jobs.append(Parallel(taskmaster, self)) - else: - self.jobs = [Serial(taskmaster)] - - def start(self): - """start the jobs""" - - for job in self.jobs: - job.start() - - def wait(self): - """ wait for the jobs started with start() to finish""" - - for job in self.jobs: - job.wait() - - def stop(self): - """ - stop the jobs started with start() - - This function does not wait for the jobs to finish. - """ - - for job in self.jobs: - job.stop() - -class Serial: - """This class is used to execute tasks in series, and is more efficient - than Parallel, but is only appropriate for non-parallel builds. Only - one instance of this class should be in existence at a time. - - This class is not thread safe. - """ - - def __init__(self, taskmaster): - """Create a new serial job given a taskmaster. - - The taskmaster's next_task() method should return the next task - that needs to be executed, or None if there are no more tasks. The - taskmaster's executed() method will be called for each task when it - is successfully executed or failed() will be called if it failed to - execute (e.g. execute() raised an exception). The taskmaster's - is_blocked() method will not be called. """ - - self.taskmaster = taskmaster - - def start(self): - - """Start the job. This will begin pulling tasks from the taskmaster - and executing them, and return when there are no more tasks. If a task - fails to execute (i.e. execute() raises an exception), then the job will - stop.""" - - while 1: - task = self.taskmaster.next_task() - - if task is None: - break - - try: - task.execute() - except: - self.taskmaster.failed(task) - return - else: - self.taskmaster.executed(task) - - def stop(self): - """Serial jobs are always finished when start() returns, so there - is nothing to do here""" - - pass - - def wait(self): - """Serial jobs are always finished when start() returns, so there - is nothing to do here""" - pass - - -# The will hold a condition variable once the first parallel task -# is created. -cv = None - -class Parallel: - """This class is used to execute tasks in parallel, and is less - efficient than Serial, but is appropriate for parallel builds. Create - an instance of this class for each job or thread you want. - - This class is thread safe. - """ - - - def __init__(self, taskmaster, jobs): - """Create a new parallel job given a taskmaster, and a Jobs instance. - Multiple jobs will be using the taskmaster in parallel, but all - method calls to taskmaster methods are serialized by the jobs - themselves. - - The taskmaster's next_task() method should return the next task - that needs to be executed, or None if there are no more tasks. The - taskmaster's executed() method will be called for each task when it - is successfully executed or failed() will be called if the task - failed to execute (i.e. execute() raised an exception). The - taskmaster's is_blocked() method should return true iff there are - more tasks, but they can't be executed until one or more other - tasks have been executed. next_task() will be called iff - is_blocked() returned false. - - Note: calls to taskmaster are serialized, but calls to execute() on - distinct tasks are not serialized, because that is the whole point - of parallel jobs: they can execute multiple tasks - simultaneously. """ - - global cv - - # import threading here so that everything in the Job module - # but the Parallel class will work if the interpreter doesn't - # support threads - import threading - - self.taskmaster = taskmaster - self.jobs = jobs - self.thread = threading.Thread(None, self.__run) - self.stop_running = 0 - - if cv is None: - cv = threading.Condition() - - def start(self): - """Start the job. This will spawn a thread that will begin pulling - tasks from the task master and executing them. This method returns - immediately and doesn't wait for the jobs to be executed. - - If a task fails to execute (i.e. execute() raises an exception), - all jobs will be stopped. - - To stop the job, call stop(). - To wait for the job to finish, call wait(). - """ - self.thread.start() - - def stop(self): - """Stop the job. This will cause the job to finish after the - currently executing task is done. A job that has been stopped can - not be restarted. - - To wait for the job to finish, call wait(). - """ - - cv.acquire() - self.stop_running = 1 - # wake up the sleeping jobs so this job will end as soon as possible: - cv.notifyAll() - cv.release() - - def wait(self): - """Wait for the job to finish. A job is finished when either there - are no more tasks or the job has been stopped and it is no longer - executing a task. - - This method should only be called after start() has been called. - - To stop the job, call stop(). - """ - self.thread.join() - - def __run(self): - """private method that actually executes the tasks""" - - cv.acquire() - - try: - - while 1: - while self.taskmaster.is_blocked() and not self.stop_running: - cv.wait(None) - - # check this before calling next_task(), because - # this job may have been stopped because of a build - # failure: - if self.stop_running: - break - - task = self.taskmaster.next_task() - - if task == None: - break - - cv.release() - try: - try: - task.execute() - finally: - cv.acquire() - except: - self.taskmaster.failed(task) - # stop all jobs since there was a failure: - # (this will wake up any waiting jobs, so - # it isn't necessary to explicitly wake them - # here) - self.jobs.stop() - else: - self.taskmaster.executed(task) - - if not self.taskmaster.is_blocked(): - cv.notifyAll() - - finally: - cv.release() - - - - diff --git a/src/scons/JobTests.py b/src/scons/JobTests.py deleted file mode 100644 index 2d9eff0..0000000 --- a/src/scons/JobTests.py +++ /dev/null @@ -1,228 +0,0 @@ -__revision__ = "JobTests.py __REVISION__ __DATE__ __DEVELOPER__" - -import unittest -import random -import math -import scons.Job -import sys - -# a large number -num_sines = 10000 - -# how many parallel jobs to perform for the test -num_jobs = 11 - -# how many tasks to perform for the test -num_tasks = num_jobs*5 - -class DummyLock: - "fake lock class to use if threads are not supported" - def acquire(self): - pass - - def release(self): - pass - -class NoThreadsException: - "raised by the ParallelTestCase if threads are not supported" - - def __str__(self): - return "the interpreter doesn't support threads" - -class Task: - """A dummy task class for testing purposes.""" - - def __init__(self, i, taskmaster): - self.i = i - self.taskmaster = taskmaster - self.was_executed = 0 - - def execute(self): - self.taskmaster.guard.acquire() - self.taskmaster.begin_list.append(self.i) - self.taskmaster.guard.release() - - # do something that will take some random amount of time: - for i in range(random.randrange(0, num_sines, 1)): - x = math.sin(i) - - self.was_executed = 1 - - self.taskmaster.guard.acquire() - self.taskmaster.end_list.append(self.i) - self.taskmaster.guard.release() - -class ExceptionTask: - """A dummy task class for testing purposes.""" - - def __init__(self, i, taskmaster): - pass - - def execute(self): - raise "exception" - -class Taskmaster: - """A dummy taskmaster class for testing the job classes.""" - - def __init__(self, n, test_case, Task): - """n is the number of dummy tasks to perform.""" - - self.test_case = test_case - self.num_tasks = n - self.num_iterated = 0 - self.num_executed = 0 - self.num_failed = 0 - self.Task = Task - # 'guard' guards 'task_begin_list' and 'task_end_list' - try: - import threading - self.guard = threading.Lock() - except: - self.guard = DummyLock() - - # keep track of the order tasks are begun in - self.begin_list = [] - - # keep track of the order tasks are completed in - self.end_list = [] - - - def next_task(self): - if self.all_tasks_are_iterated(): - return None - else: - self.num_iterated = self.num_iterated + 1 - return self.Task(self.num_iterated, self) - - def all_tasks_are_executed(self): - return self.num_executed == self.num_tasks - - def all_tasks_are_iterated(self): - return self.num_iterated == self.num_tasks - - def executed(self, task): - self.num_executed = self.num_executed + 1 - - self.test_case.failUnless(task.was_executed, - "the task wasn't really executed") - self.test_case.failUnless(task.__class__ is Task, - "the task wasn't really a Task instance") - - def failed(self, task): - self.num_failed = self.num_failed + 1 - - def is_blocked(self): - # simulate blocking tasks - return self.num_iterated - self.num_executed >= max(num_jobs/2, 2) - - def tasks_were_serial(self): - "analyze the task order to see if they were serial" - serial = 1 # assume the tasks were serial - for i in range(num_tasks): - serial = serial and (self.begin_list[i] - == self.end_list[i] - == (i + 1)) - return serial - -class ParallelTestCase(unittest.TestCase): - def runTest(self): - "test parallel jobs" - - try: - import threading - except: - raise NoThreadsException() - - taskmaster = Taskmaster(num_tasks, self, Task) - jobs = scons.Job.Jobs(num_jobs, taskmaster) - jobs.start() - jobs.wait() - - self.failUnless(not taskmaster.tasks_were_serial(), - "the tasks were not executed in parallel") - self.failUnless(taskmaster.all_tasks_are_executed(), - "all the tests were not executed") - self.failUnless(taskmaster.all_tasks_are_iterated(), - "all the tests were not iterated over") - self.failIf(taskmaster.num_failed, - "some task(s) failed to execute") - -class SerialTestCase(unittest.TestCase): - def runTest(self): - "test a serial job" - - taskmaster = Taskmaster(num_tasks, self, Task) - jobs = scons.Job.Jobs(1, taskmaster) - jobs.start() - jobs.wait() - - self.failUnless(taskmaster.tasks_were_serial(), - "the tasks were not executed in series") - self.failUnless(taskmaster.all_tasks_are_executed(), - "all the tests were not executed") - self.failUnless(taskmaster.all_tasks_are_iterated(), - "all the tests were not iterated over") - self.failIf(taskmaster.num_failed, - "some task(s) failed to execute") - -class SerialExceptionTestCase(unittest.TestCase): - def runTest(self): - "test a serial job with tasks that raise exceptions" - - taskmaster = Taskmaster(num_tasks, self, ExceptionTask) - jobs = scons.Job.Jobs(1, taskmaster) - jobs.start() - jobs.wait() - - self.failIf(taskmaster.num_executed, - "a task was executed") - self.failUnless(taskmaster.num_iterated == 1, - "exactly one task should have been iterated") - self.failUnless(taskmaster.num_failed == 1, - "exactly one task should have failed") - -class ParallelExceptionTestCase(unittest.TestCase): - def runTest(self): - "test parallel jobs with tasks that raise exceptions" - - taskmaster = Taskmaster(num_tasks, self, ExceptionTask) - jobs = scons.Job.Jobs(num_jobs, taskmaster) - jobs.start() - jobs.wait() - - self.failIf(taskmaster.num_executed, - "a task was executed") - self.failUnless(taskmaster.num_iterated >= 1, - "one or more task should have been iterated") - self.failUnless(taskmaster.num_failed >= 1, - "one or more tasks should have failed") - - -def suite(): - suite = unittest.TestSuite() - suite.addTest(ParallelTestCase()) - suite.addTest(SerialTestCase()) - suite.addTest(SerialExceptionTestCase()) - suite.addTest(ParallelExceptionTestCase()) - return suite - -if __name__ == "__main__": - runner = unittest.TextTestRunner() - result = runner.run(suite()) - if (len(result.failures) == 0 - and len(result.errors) == 1 - and type(result.errors[0][0]) == SerialTestCase - and type(result.errors[0][1][0]) == NoThreadsException): - sys.exit(2) - elif not result.wasSuccessful(): - sys.exit(1) - - - - - - - - - - diff --git a/src/scons/Node/.aeignore b/src/scons/Node/.aeignore deleted file mode 100644 index 43fe851..0000000 --- a/src/scons/Node/.aeignore +++ /dev/null @@ -1,4 +0,0 @@ -*,D -*.pyc -.*.swp -.consign diff --git a/src/scons/Node/FS.py b/src/scons/Node/FS.py deleted file mode 100644 index 7640a7a..0000000 --- a/src/scons/Node/FS.py +++ /dev/null @@ -1,139 +0,0 @@ -"""scons.Node.FS - -File system nodes. - -""" - -__revision__ = "Node/FS.py __REVISION__ __DATE__ __DEVELOPER__" - - - -import os -import os.path -from scons.Node import Node - - - -Top = None -Root = {} - - - -def init(path = None): - """Initialize the Node.FS subsystem. - - The supplied path is the top of the source tree, where we - expect to find the top-level build file. If no path is - supplied, the current directory is the default. - """ - global Top - if path == None: - path = os.getcwd() - Top = lookup(Dir, path, directory = None) - Top.path = '.' - -def lookup(fsclass, name, directory = Top): - """Look up a file system node for a path name. If the path - name is relative, it will be looked up relative to the - specified directory node, or to the top-level directory - if no node was specified. An initial '#' specifies that - the name will be looked up relative to the top-level directory, - regardless of the specified directory argument. Returns the - existing or newly-created node for the specified path name. - The node returned will be of the specified fsclass (Dir or - File). - """ - global Top - head, tail = os.path.split(name) - if not tail: - drive, path = os.path.splitdrive(head) - if not Root.has_key(drive): - Root[drive] = Dir(head, None) - Root[drive].abspath = head - Root[drive].path = head - return Root[drive] - if tail[0] == '#': - directory = Top - tail = tail[1:] - elif directory is None: - directory = Top - if head: - directory = lookup(Dir, head, directory) - try: - self = directory.entries[tail] - except AttributeError: - # There was no "entries" attribute on the directory, - # which essentially implies that it was a file. - # Return it as a more descriptive exception. - raise TypeError, directory - except KeyError: - # There was to entry for "tail," so create the new - # node and link it in to the existing structure. - self = fsclass(tail, directory) - self.name = tail - if self.path[0:2] == "./": - self.path = self.path[2:] - directory.entries[tail] = self - except: - raise - if self.__class__.__name__ != fsclass.__name__: - # Here, we found an existing node for this path, - # but it was the wrong type (a File when we were - # looking for a Dir, or vice versa). - raise TypeError, self - return self - - - -# XXX TODO? -# Annotate with the creator -# is_under -# rel_path -# srcpath / srcdir -# link / is_linked -# linked_targets -# is_accessible - -class Dir(Node): - """A class for directories in a file system. - """ - - def __init__(self, name, directory): - self.entries = {} - self.entries['.'] = self - self.entries['..'] = directory - if not directory is None: - self.abspath = os.path.join(directory.abspath, name, '') - self.path = os.path.join(directory.path, name, '') - - def up(self): - return self.entries['..'] - - -# XXX TODO? -# rfile -# precious -# no_rfile -# rpath -# rsrcpath -# source_exists -# derived_exists -# is_on_rpath -# local -# base_suf -# suffix -# addsuffix -# accessible -# ignore -# build -# bind -# is_under -# relpath - -class File(Node): - """A class for files in a file system. - """ - - def __init__(self, name, directory): - self.abspath = os.path.join(directory.abspath, name) - self.path = os.path.join(directory.path, name) diff --git a/src/scons/Node/FS/.aeignore b/src/scons/Node/FS/.aeignore deleted file mode 100644 index 43fe851..0000000 --- a/src/scons/Node/FS/.aeignore +++ /dev/null @@ -1,4 +0,0 @@ -*,D -*.pyc -.*.swp -.consign diff --git a/src/scons/Node/FSTests.py b/src/scons/Node/FSTests.py deleted file mode 100644 index 14b62c2..0000000 --- a/src/scons/Node/FSTests.py +++ /dev/null @@ -1,109 +0,0 @@ -__revision__ = "Node/FSTests.py __REVISION__ __DATE__ __DEVELOPER__" - -import os -import sys -import unittest - -from scons.Node.FS import init, lookup, Dir, File - - - -built_it = None - -class Builder: - def execute(self, target = None, source = None): - global built_it - built_it = 1 - - - -class FSTestCase(unittest.TestCase): - def runTest(self): - """Test FS (file system) Node operations - - This test case handles all of the file system node - tests in one environment, so we don't have to set up a - complicated directory structure for each test individually. - """ - from TestCmd import TestCmd - - test = TestCmd(workdir = '') - test.subdir('sub', ['sub', 'dir']) - - wp = test.workpath('') - sub = test.workpath('sub', '') - sub_dir = test.workpath('sub', 'dir', '') - sub_dir_foo = test.workpath('sub', 'dir', 'foo', '') - sub_dir_foo_bar = test.workpath('sub', 'dir', 'foo', 'bar', '') - sub_foo = test.workpath('sub', 'foo', '') - - os.chdir(sub_dir) - - init() - - def Dir_test(lpath, path, abspath, up_path): - dir = lookup(Dir, lpath) - assert(dir.path == path) - assert(dir.abspath == abspath) - assert(dir.up().path == up_path) - - Dir_test('foo', 'foo/', sub_dir_foo, '.') - Dir_test('foo/bar', 'foo/bar/', sub_dir_foo_bar, 'foo/') - Dir_test('/foo', '/foo/', '/foo/', '/') - Dir_test('/foo/bar', '/foo/bar/', '/foo/bar/', '/foo/') - Dir_test('..', sub, sub, wp) - Dir_test('foo/..', '.', sub_dir, sub) - Dir_test('../foo', sub_foo, sub_foo, sub) - Dir_test('.', '.', sub_dir, sub) - Dir_test('./.', '.', sub_dir, sub) - Dir_test('foo/./bar', 'foo/bar/', sub_dir_foo_bar, 'foo/') - - d1 = lookup(Dir, 'd1') - - f1 = lookup(File, 'f1', directory = d1) - - assert(f1.path == 'd1/f1') - - try: - f2 = lookup(File, 'f1/f2', directory = d1) - except TypeError, x: - node = x.args[0] - assert(node.path == 'd1/f1') - assert(node.__class__.__name__ == 'File') - except: - raise - - try: - dir = lookup(Dir, 'd1/f1') - except TypeError, x: - node = x.args[0] - assert(node.path == 'd1/f1') - assert(node.__class__.__name__ == 'File') - except: - raise - - # Test for sub-classing of node building. - global built_it - - built_it = None - assert not built_it - d1.path = "d" # XXX FAKE SUBCLASS ATTRIBUTE - d1.sources = "d" # XXX FAKE SUBCLASS ATTRIBUTE - d1.builder_set(Builder()) - d1.build() - assert built_it - - built_it = None - assert not built_it - f1.path = "f" # XXX FAKE SUBCLASS ATTRIBUTE - f1.sources = "f" # XXX FAKE SUBCLASS ATTRIBUTE - f1.builder_set(Builder()) - f1.build() - assert built_it - - -if __name__ == "__main__": - suite = unittest.TestSuite() - suite.addTest(FSTestCase()) - if not unittest.TextTestRunner().run(suite).wasSuccessful(): - sys.exit(1) diff --git a/src/scons/Node/NodeTests.py b/src/scons/Node/NodeTests.py deleted file mode 100644 index 46292bc..0000000 --- a/src/scons/Node/NodeTests.py +++ /dev/null @@ -1,45 +0,0 @@ -__revision__ = "Node/NodeTests.py __REVISION__ __DATE__ __DEVELOPER__" - -import os -import sys -import unittest - -from scons.Node import Node - - - -built_it = None - -class Builder: - def execute(self, target = None, source = None): - global built_it - built_it = 1 - - - -class NodeTestCase(unittest.TestCase): - - def test_build(self): - """Test building a node - """ - node = Node() - node.builder_set(Builder()) - node.path = "xxx" # XXX FAKE SUBCLASS ATTRIBUTE - node.sources = "yyy" # XXX FAKE SUBCLASS ATTRIBUTE - node.build() - assert built_it - - def test_builder_set(self): - """Test setting a Node's Builder - """ - node = Node() - b = Builder() - node.builder_set(b) - assert node.builder == b - - - -if __name__ == "__main__": - suite = unittest.makeSuite(NodeTestCase, 'test_') - if not unittest.TextTestRunner().run(suite).wasSuccessful(): - sys.exit(1) diff --git a/src/scons/Node/__init__.py b/src/scons/Node/__init__.py deleted file mode 100644 index e4eb45a..0000000 --- a/src/scons/Node/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -"""scons.Node - -The Node package for the scons software construction utility. - -""" - -__revision__ = "Node/__init__.py __REVISION__ __DATE__ __DEVELOPER__" - - - -class Node: - """The base Node class, for entities that we know how to - build, or use to build other Nodes. - """ - def build(self): - self.builder.execute(target = self.path, source = self.sources) - - def builder_set(self, builder): - self.builder = builder - - def env_set(self, env): - self.env = env diff --git a/src/scons/Scanner/.aeignore b/src/scons/Scanner/.aeignore deleted file mode 100644 index 43fe851..0000000 --- a/src/scons/Scanner/.aeignore +++ /dev/null @@ -1,4 +0,0 @@ -*,D -*.pyc -.*.swp -.consign diff --git a/src/scons/Scanner/C.py b/src/scons/Scanner/C.py deleted file mode 100644 index fcb3a46..0000000 --- a/src/scons/Scanner/C.py +++ /dev/null @@ -1,87 +0,0 @@ -"""scons.Scanner.C - -This module implements the depenency scanner for C/C++ code. - -""" - -__revision__ = "Scanner/C.py __REVISION__ __DATE__ __DEVELOPER__" - - -import scons.Scanner -import re -import os.path - -angle_re = re.compile('^[ \t]*#[ \t]*include[ \t]+<([\\w./\\\\]+)>', re.M) -quote_re = re.compile('^[ \t]*#[ \t]*include[ \t]+"([\\w./\\\\]+)"', re.M) - -def CScan(): - "Return a Scanner instance for scanning C/C++ source files" - return scons.Scanner.Scanner(scan) - -def find_files(filenames, paths): - """ - find_files([str], [str]) -> [str] - - filenames - a list of filenames to find - paths - a list of paths to search in - - returns - the fullnames of the files - - Only the first fullname found is returned for each filename, and any - file that aren't found are ignored. - """ - fullnames = [] - for filename in filenames: - for path in paths: - fullname = os.path.join(path, filename) - if os.path.exists(fullname): - fullnames.append(fullname) - break - - return fullnames - -def scan(filename, env): - """ - scan(str, Environment) -> [str] - - the C/C++ dependency scanner function - - This function is intentionally simple. There are two rules it - follows: - - 1) #include <foo.h> - search for foo.h in CPPPATH followed by the - directory 'filename' is in - 2) #include \"foo.h\" - search for foo.h in the directory 'filename' is - in followed by CPPPATH - - These rules approximate the behaviour of most C/C++ compilers. - - This scanner also ignores #ifdef and other preprocessor conditionals, so - it may find more depencies than there really are, but it never misses - dependencies. - """ - - if hasattr(env, "CPPPATH"): - paths = env.CPPPATH - else: - paths = [] - - file = open(filename) - contents = file.read() - file.close() - - angle_includes = angle_re.findall(contents) - quote_includes = quote_re.findall(contents) - - source_dir = os.path.dirname(filename) - - deps = (find_files(angle_includes, paths + [source_dir]) - + find_files(quote_includes, [source_dir] + paths)) - - return deps - - - - - - diff --git a/src/scons/Scanner/CTests.py b/src/scons/Scanner/CTests.py deleted file mode 100644 index 326e9b8..0000000 --- a/src/scons/Scanner/CTests.py +++ /dev/null @@ -1,131 +0,0 @@ -__revision__ = "Scanner/CTests.py __REVISION__ __DATE__ __DEVELOPER__" - -from TestCmd import TestCmd -import scons.Scanner.C -import unittest -import sys - -test = TestCmd(workdir = '') - -# create some source files and headers: - -test.write('f1.cpp',""" -#include \"f1.h\" -#include <f2.h> - -int main() -{ - return 0; -} -""") - -test.write('f2.cpp',""" -#include \"d1/f1.h\" -#include <d2/f1.h> -#include \"f1.h\" -#include <f4.h> - -int main() -{ - return 0; -} -""") - -test.write('f3.cpp',""" -#include \t "f1.h" - \t #include "f2.h" -# \t include "f3.h" - -#include \t <d1/f1.h> - \t #include <d1/f2.h> -# \t include <d1/f3.h> - -// #include "never.h" - -const char* x = "#include <never.h>" - -int main() -{ - return 0; -} -""") - - -# for Emacs -> " - -test.subdir('d1', ['d1', 'd2']) - -headers = ['f1.h','f2.h', 'f3.h', 'never.h', - 'd1/f1.h', 'd1/f2.h', 'd1/f3.h', - 'd1/d2/f1.h', 'd1/d2/f2.h', 'd1/d2/f3.h', 'd1/d2/f4.h'] - -for h in headers: - test.write(h, " ") - -# define some helpers: - -class DummyEnvironment: - pass - -def deps_match(deps, headers): - return deps.sort() == map(test.workpath, headers).sort() - -# define some tests: - -class CScannerTestCase1(unittest.TestCase): - def runTest(self): - env = DummyEnvironment - s = scons.Scanner.C.CScan() - deps = s.scan(test.workpath('f1.cpp'), env) - self.failUnless(deps_match(deps, ['f1.h', 'f2.h'])) - -class CScannerTestCase2(unittest.TestCase): - def runTest(self): - env = DummyEnvironment - env.CPPPATH = [test.workpath("d1")] - s = scons.Scanner.C.CScan() - deps = s.scan(test.workpath('f1.cpp'), env) - headers = ['f1.h', 'd1/f2.h'] - self.failUnless(deps_match(deps, headers)) - -class CScannerTestCase3(unittest.TestCase): - def runTest(self): - env = DummyEnvironment - env.CPPPATH = [test.workpath("d1")] - s = scons.Scanner.C.CScan() - deps = s.scan(test.workpath('f2.cpp'), env) - headers = ['f1.h', 'd1/f2.h', 'd1/d2/f1.h'] - self.failUnless(deps_match(deps, headers)) - - -class CScannerTestCase4(unittest.TestCase): - def runTest(self): - env = DummyEnvironment - env.CPPPATH = [test.workpath("d1"), test.workpath("d1/d2")] - s = scons.Scanner.C.CScan() - deps = s.scan(test.workpath('f2.cpp'), env) - headers = ['f1.h', 'd1/f2.h', 'd1/d2/f1.h', 'd1/d2/f4.h'] - self.failUnless(deps_match(deps, headers)) - -class CScannerTestCase5(unittest.TestCase): - def runTest(self): - env = DummyEnvironment - s = scons.Scanner.C.CScan() - deps = s.scan(test.workpath('f3.cpp'), env) - headers = ['f1.h', 'f2.h', 'f3.h', 'd1/f1.h', 'd1/f2.h', 'd1/f3.h'] - self.failUnless(deps_match(deps, headers)) - -def suite(): - suite = unittest.TestSuite() - suite.addTest(CScannerTestCase1()) - suite.addTest(CScannerTestCase2()) - suite.addTest(CScannerTestCase3()) - suite.addTest(CScannerTestCase4()) - suite.addTest(CScannerTestCase5()) - return suite - -if __name__ == "__main__": - runner = unittest.TextTestRunner() - result = runner.run(suite()) - if not result.wasSuccessful(): - sys.exit(1) diff --git a/src/scons/Scanner/ScannerTests.py b/src/scons/Scanner/ScannerTests.py deleted file mode 100644 index 9761cd0..0000000 --- a/src/scons/Scanner/ScannerTests.py +++ /dev/null @@ -1,84 +0,0 @@ -__revision__ = "Scanner/ScannerTests.py __REVISION__ __DATE__ __DEVELOPER__" - -import unittest -import scons.Scanner -import sys - -class ScannerTestBase: - - def func(self, filename, env, *args): - self.filename = filename - self.env = env - - if len(args) > 0: - self.arg = args[0] - - return self.deps - - - def test(self, scanner, env, filename, deps, *args): - self.deps = deps - deps = scanner.scan(filename, env) - - self.failUnless(self.filename == filename, "the filename was passed incorrectly") - self.failUnless(self.env == env, "the environment was passed incorrectly") - self.failUnless(self.deps == deps, "the dependencies were returned incorrectly") - - if len(args) > 0: - self.failUnless(self.arg == args[0], "the argument was passed incorrectly") - else: - self.failIf(hasattr(self, "arg"), "an argument was given when it shouldn't have been") - -class DummyEnvironment: - pass - - -class ScannerPositionalTestCase(ScannerTestBase, unittest.TestCase): - "Test the Scanner class using the position argument" - def runTest(self): - s = scons.Scanner.Scanner(self.func) - env = DummyEnvironment() - env.VARIABLE = "var1" - self.test(s, env, 'f1.cpp', ['f1.h', 'f1.hpp']) - -class ScannerKeywordTestCase(ScannerTestBase, unittest.TestCase): - "Test the Scanner class using the keyword argument" - def runTest(self): - s = scons.Scanner.Scanner(function = self.func) - env = DummyEnvironment() - env.VARIABLE = "var2" - self.test(s, env, 'f2.cpp', ['f2.h', 'f2.hpp']) - -class ScannerPositionalArgumentTestCase(ScannerTestBase, unittest.TestCase): - "Test the Scanner class using the position argument and optional argument" - def runTest(self): - arg = "this is the argument" - s = scons.Scanner.Scanner(self.func, arg) - env = DummyEnvironment() - env.VARIABLE = "var3" - self.test(s, env, 'f3.cpp', ['f3.h', 'f3.hpp'], arg) - -class ScannerKeywordArgumentTestCase(ScannerTestBase, unittest.TestCase): - "Test the Scanner class using the keyword argument and optional argument" - def runTest(self): - arg = "this is another argument" - s = scons.Scanner.Scanner(function = self.func, argument = arg) - env = DummyEnvironment() - env.VARIABLE = "var4" - self.test(s, env, 'f4.cpp', ['f4.h', 'f4.hpp'], arg) - -def suite(): - suite = unittest.TestSuite() - suite.addTest(ScannerPositionalTestCase()) - suite.addTest(ScannerKeywordTestCase()) - suite.addTest(ScannerPositionalArgumentTestCase()) - suite.addTest(ScannerKeywordArgumentTestCase()) - return suite - -if __name__ == "__main__": - runner = unittest.TextTestRunner() - result = runner.run(suite()) - if not result.wasSuccessful(): - sys.exit(1) - - diff --git a/src/scons/Scanner/__init__.py b/src/scons/Scanner/__init__.py deleted file mode 100644 index 7ce602c..0000000 --- a/src/scons/Scanner/__init__.py +++ /dev/null @@ -1,69 +0,0 @@ -"""scons.Scanner - -The Scanner package for the scons software construction utility. - -""" - -__revision__ = "Scanner/__init__.py __REVISION__ __DATE__ __DEVELOPER__" - -__version__ = "__VERSION__" - -class _Null: - pass - -# This is used instead of None as a default argument value so None can be -# used as an actual argument value. -_null = _Null - -class Scanner: - - def __init__(self, function, argument=_null): - """ - Construct a new scanner object given a scanner function. - - 'function' - a scanner function taking two or three arguments and - returning a list of strings. - - 'argument' - an optional argument that will be passed to the - scanner function if it is given. - - The scanner function's first argument will be the name of a file - that should be scanned for dependencies, the second argument will - be an Environment object, the third argument will be the value - passed into 'argument', and the returned list should contain the - file names of all the direct dependencies of the file. - - Examples: - - s = Scanner(my_scanner_function) - - s = Scanner(function = my_scanner_function) - - s = Scanner(function = my_scanner_function, argument = 'foo') - - """ - - # Note: this class could easily work with scanner functions that take - # something other than a filename as an argument (e.g. a database - # node) and a dependencies list that aren't file names. All that - # would need to be changed is the documentation. - - self.function = function - self.argument = argument - - def scan(self, filename, env): - """ - This method does the actually scanning. 'filename' is the filename - that will be passed to the scanner function, and 'env' is the - environment that will be passed to the scanner function. A list of - dependencies will be returned. - """ - - if not self.argument is _null: - return self.function(filename, env, self.argument) - else: - return self.function(filename, env) - - - - diff --git a/src/scons/Sig/.aeignore b/src/scons/Sig/.aeignore deleted file mode 100644 index 43fe851..0000000 --- a/src/scons/Sig/.aeignore +++ /dev/null @@ -1,4 +0,0 @@ -*,D -*.pyc -.*.swp -.consign diff --git a/src/scons/Sig/MD5.py b/src/scons/Sig/MD5.py deleted file mode 100644 index 36e4230..0000000 --- a/src/scons/Sig/MD5.py +++ /dev/null @@ -1,70 +0,0 @@ -"""scons.Sig.MD5 - -The MD5 signature package for the scons software construction -utility. - -""" - -__revision__ = "Sig/MD5.py __REVISION__ __DATE__ __DEVELOPER__" - -import md5 -import string - - - -def hexdigest(s): - """Return a signature as a string of hex characters. - """ - # NOTE: This routine is a method in the Python 2.0 interface - # of the native md5 module, but we want scons to operate all - # the way back to at least Python 1.5.2, which doesn't have it. - h = string.hexdigits - r = '' - for c in s: - i = ord(c) - r = r + h[(i >> 4) & 0xF] + h[i & 0xF] - return r - - - -def _init(): - pass # XXX - -def _end(): - pass # XXX - -def current(obj, sig): - """Return whether a given object is up-to-date with the - specified signature. - """ - return obj.signature() == sig - -def set(): - pass # XXX - -def invalidate(): - pass # XXX - -def collect(*objects): - """Collect signatures from a list of objects, returning the - aggregate signature of the list. - """ - if len(objects) == 1: - sig = objects[0].signature() - else: - contents = string.join(map(lambda o: o.signature(), objects), ', ') - sig = signature(contents) -# if debug: -# pass - return sig - -def signature(contents): - """Generate a signature for a byte string. - """ - return hexdigest(md5.new(contents).digest()) - -def cmdsig(): - pass # XXX - -def srcsig(): - pass # XXX diff --git a/src/scons/Sig/MD5Tests.py b/src/scons/Sig/MD5Tests.py deleted file mode 100644 index efcec7f..0000000 --- a/src/scons/Sig/MD5Tests.py +++ /dev/null @@ -1,76 +0,0 @@ -__revision__ = "Sig/MD5Tests.py __REVISION__ __DATE__ __DEVELOPER__" - -import sys -import unittest - -import scons.Sig.MD5 - - - -class my_obj: - """A dummy object class that satisfies the interface - requirements of the MD5 class. - """ - - def __init__(self, value = ""): - self.value = value - self.sig = None - - def signature(self): - if not self.sig: - self.sig = scons.Sig.MD5.signature(self.value) - return self.sig - - def current(self, sig): - return scons.Sig.MD5.current(self, sig) - - - -class MD5TestCase(unittest.TestCase): - - def test__init(self): - pass # XXX - - def test__end(self): - pass # XXX - - def test_current(self): - """Test deciding if an object is up-to-date - - Simple comparison of different "signature" values. - """ - o111 = my_obj(value = '111') - assert not o111.current(scons.Sig.MD5.signature('110')) - assert o111.current(scons.Sig.MD5.signature('111')) - assert not o111.current(scons.Sig.MD5.signature('112')) - - def test_set(self): - pass # XXX - - def test_invalidate(self): - pass # XXX - - def test_collect(self): - """Test collecting a list of signatures into a new signature value - """ - o1 = my_obj(value = '111') - o2 = my_obj(value = '222') - o3 = my_obj(value = '333') - assert '698d51a19d8a121ce581499d7b701668' == scons.Sig.MD5.collect(o1) - assert '8980c988edc2c78cc43ccb718c06efd5' == scons.Sig.MD5.collect(o1, o2) - assert '53fd88c84ff8a285eb6e0a687e55b8c7' == scons.Sig.MD5.collect(o1, o2, o3) - - def test_signature(self): - pass # XXX - - def test_cmdsig(self): - pass # XXX - - def test_srcsig(self): - pass # XXX - - -if __name__ == "__main__": - suite = unittest.makeSuite(MD5TestCase, 'test_') - if not unittest.TextTestRunner().run(suite).wasSuccessful(): - sys.exit(1) diff --git a/src/scons/Sig/TimeStamp.py b/src/scons/Sig/TimeStamp.py deleted file mode 100644 index cab44bf..0000000 --- a/src/scons/Sig/TimeStamp.py +++ /dev/null @@ -1,49 +0,0 @@ -"""scons.Sig.TimeStamp - -The TimeStamp signature package for the scons software construction -utility. - -""" - -__revision__ = "Sig/TimeStamp.py __REVISION__ __DATE__ __DEVELOPER__" - -def _init(): - pass # XXX - -def _end(): - pass # XXX - -def current(obj, sig): - """Return whether the object's timestamp is up-to-date. - """ - return obj.signature() >= sig - -def set(): - pass # XXX - -def invalidate(): - pass # XXX - -def collect(*objects): - """Collect timestamps from a list of objects, returning - the most-recent timestamp from the list. - """ - r = 0 - for obj in objects: - s = obj.signature() - if s > r: - r = s - return r - -def signature(contents): - """Generate a timestamp. - """ - pass # XXX -# return md5.new(contents).hexdigest() # 2.0 - return hexdigest(md5.new(contents).digest()) - -def cmdsig(): - pass # XXX - -def srcsig(): - pass # XXX diff --git a/src/scons/Sig/TimeStampTests.py b/src/scons/Sig/TimeStampTests.py deleted file mode 100644 index 4fb1920..0000000 --- a/src/scons/Sig/TimeStampTests.py +++ /dev/null @@ -1,74 +0,0 @@ -__revision__ = "Sig/TimeStampTests.py __REVISION__ __DATE__ __DEVELOPER__" - -import sys -import unittest - -import scons.Sig.TimeStamp - - - -class my_obj: - """A dummy object class that satisfies the interface - requirements of the TimeStamp class. - """ - - def __init__(self, value = ""): - self.value = value - - def signature(self): - return self.value - - - -class TimeStampTestCase(unittest.TestCase): - - def test__init(self): - pass # XXX - - def test__init(self): - pass # XXX - - def test__end(self): - pass # XXX - - def test_current(self): - """Test deciding if an object is up-to-date - - Simple comparison of different timestamp values. - """ - o1 = my_obj(value = 111) - assert scons.Sig.TimeStamp.current(o1, 110) - assert scons.Sig.TimeStamp.current(o1, 111) - assert not scons.Sig.TimeStamp.current(o1, 112) - - def test_set(self): - pass # XXX - - def test_invalidate(self): - pass # XXX - - def test_collect(self): - """Test collecting a list of signatures into a new signature value - into a new timestamp value. - """ - o1 = my_obj(value = 111) - o2 = my_obj(value = 222) - o3 = my_obj(value = 333) - assert 111 == scons.Sig.TimeStamp.collect(o1) - assert 222 == scons.Sig.TimeStamp.collect(o1, o2) - assert 333 == scons.Sig.TimeStamp.collect(o1, o2, o3) - - def test_signature(self): - pass # XXX - - def test_cmdsig(self): - pass # XXX - - def test_srcsig(self): - pass # XXX - - -if __name__ == "__main__": - suite = unittest.makeSuite(TimeStampTestCase, 'test_') - if not unittest.TextTestRunner().run(suite).wasSuccessful(): - sys.exit(1) diff --git a/src/scons/Sig/__init__.py b/src/scons/Sig/__init__.py deleted file mode 100644 index 411a94b..0000000 --- a/src/scons/Sig/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -"""scons.Sig - -The Signature package for the scons software construction utility. - -""" - -__revision__ = "Sig/__init__.py __REVISION__ __DATE__ __DEVELOPER__" diff --git a/src/scons/__init__.py b/src/scons/__init__.py deleted file mode 100644 index 9e279c2..0000000 --- a/src/scons/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -"""scons - -The main package for the scons software construction utility. - -""" - -__revision__ = "__init__.py __REVISION__ __DATE__ __DEVELOPER__" - -__version__ = "__VERSION__" diff --git a/src/scons/exitfuncs.py b/src/scons/exitfuncs.py deleted file mode 100644 index e26a031..0000000 --- a/src/scons/exitfuncs.py +++ /dev/null @@ -1,48 +0,0 @@ -"""scons.exitfuncs - -Register functions which are executed when scons exits for any reason. - -""" - -__revision__ = "exitfuncs.py __REVISION__ __DATE__ __DEVELOPER__" - - - -_exithandlers = [] -def _run_exitfuncs(): - """run any registered exit functions - - _exithandlers is traversed in reverse order so functions are executed - last in, first out. - """ - - while _exithandlers: - func, targs, kargs = _exithandlers.pop() - apply(func, targs, kargs) - -def register(func, *targs, **kargs): - """register a function to be executed upon normal program termination - - func - function to be called at exit - targs - optional arguments to pass to func - kargs - optional keyword arguments to pass to func - """ - _exithandlers.append((func, targs, kargs)) - -import sys - -try: - x = sys.exitfunc - - # if x isn't our own exit func executive, assume it's another - # registered exit function - append it to our list... - if x != _run_exitfuncs: - register(x) - -except AttributeError: - pass - -# make our exit function get run by python when it exits: -sys.exitfunc = _run_exitfuncs - -del sys |
