diff --git a/jam-2.5/Build.com b/jam-2.5/Build.com deleted file mode 100644 index d5c6a72ca..000000000 --- a/jam-2.5/Build.com +++ /dev/null @@ -1,31 +0,0 @@ -! Bootstrap build script for Jam -$ cxx /define=VMS builtins.c -$ cxx /define=VMS command.c -$ cxx /define=VMS compile.c -$ cxx /define=VMS expand.c -$ cxx /define=VMS execvms.c -$ cxx /define=VMS filevms.c -$ cxx /define=VMS glob.c -$ cxx /define=VMS hash.c -$ cxx /define=VMS headers.c -$ cxx /define=VMS jambase.c -$ cxx /define=VMS lists.c -$ cxx /define=VMS make.c -$ cxx /define=VMS make1.c -$ cxx /define=VMS newstr.c -$ cxx /define=VMS option.c -$ cxx /define=VMS parse.c -$ cxx /define=VMS pathvms.c -$ cxx /define=VMS regexp.c -$ cxx /define=VMS rules.c -$ cxx /define=VMS scan.c -$ cxx /define=VMS search.c -$ cxx /define=VMS timestamp.c -$ cxx /define=VMS variable.c -$ cxx /define=VMS jam.c -$ cxx /define=VMS jamgram.c -$ cxxlink/exe=jam.exe command.obj, compile.obj, execvms.obj, expand.obj, - - filevms.obj, glob.obj, hash.obj, headers.obj, lists.obj, make.obj, - - make1.obj, newstr.obj, option.obj, parse.obj, pathvms.obj, regexp.obj, - - rules.obj, scan.obj, search.obj, timestamp.obj, variable.obj, jam.obj, - - jamgram.obj, jambase.obj, builtins.obj diff --git a/jam-2.5/Build.mpw b/jam-2.5/Build.mpw deleted file mode 100644 index 661bd8624..000000000 --- a/jam-2.5/Build.mpw +++ /dev/null @@ -1,47 +0,0 @@ -# This line must be set manually to the CodeWarrior Pro 5 installation. -# Good luck! - -set CW "malyn_apps:CodeWarrior Pro 5:MetroWerks CodeWarrior" - -set -e MWCincludes "{CW}:MacOS Support:Universal:Interfaces:CIncludes,{CW}:MacOS Support:OpenTransport:Open Tpt Client Developer:Includes:CIncludes,{CW}:MacOS Support:Headers:Apple MPW,{CW}:MSL:MSL_C:MSL_Common:Include,{CW}:MSL:MSL_C++:MSL_Common:Include,{CW}:MSL:MSL_C:MSL_MacOS:Include" - -mwcppc -o :bin.mac:command.o -nomapcr -w off command.c -mwcppc -o :bin.mac:compile.o -nomapcr -w off compile.c -mwcppc -o :bin.mac:execmac.o -nomapcr -w off execmac.c -mwcppc -o :bin.mac:filemac.o -nomapcr -w off filemac.c -mwcppc -o :bin.mac:pathmac.o -nomapcr -w off pathmac.c -mwcppc -o :bin.mac:jamgram.o -nomapcr -w off jamgram.c -mwcppc -o :bin.mac:expand.o -nomapcr -w off expand.c -mwcppc -o :bin.mac:glob.o -nomapcr -w off glob.c -mwcppc -o :bin.mac:hash.o -nomapcr -w off hash.c -mwcppc -o :bin.mac:headers.o -nomapcr -w off headers.c -mwcppc -o :bin.mac:lists.o -nomapcr -w off lists.c -mwcppc -o :bin.mac:make.o -nomapcr -w off make.c -mwcppc -o :bin.mac:make1.o -nomapcr -w off make1.c -mwcppc -o :bin.mac:newstr.o -nomapcr -w off newstr.c -mwcppc -o :bin.mac:option.o -nomapcr -w off option.c -mwcppc -o :bin.mac:parse.o -nomapcr -w off parse.c -mwcppc -o :bin.mac:regexp.o -nomapcr -w off regexp.c -mwcppc -o :bin.mac:rules.o -nomapcr -w off rules.c -mwcppc -o :bin.mac:scan.o -nomapcr -w off scan.c -mwcppc -o :bin.mac:search.o -nomapcr -w off search.c -mwcppc -o :bin.mac:timestamp.o -nomapcr -w off timestamp.c -mwcppc -o :bin.mac:variable.o -nomapcr -w off variable.c - -mwlinkppc -library -o :bin.mac:libjam.lib :bin.mac:command.o :bin.mac:compile.o :bin.mac:execmac.o :bin.mac:filemac.o :bin.mac:pathmac.o :bin.mac:jamgram.o :bin.mac:expand.o :bin.mac:glob.o :bin.mac:hash.o :bin.mac:headers.o :bin.mac:lists.o :bin.mac:make.o :bin.mac:make1.o :bin.mac:newstr.o :bin.mac:option.o :bin.mac:parse.o :bin.mac:regexp.o :bin.mac:rules.o :bin.mac:scan.o :bin.mac:search.o :bin.mac:timestamp.o :bin.mac:variable.o -mwcppc -o :bin.mac:mkjambase.o -nomapcr -w off mkjambase.c - -mwlinkppc -o :bin.mac:mkjambase -mpwtool -warn :bin.mac:mkjambase.o "{CW}:MacOS Support:Universal:Libraries:StubLibraries:Interfacelib" "{CW}:MacOS Support:Universal:Libraries:StubLibraries:ThreadsLib" "{CW}:MacOS Support:Universal:Libraries:StubLibraries:Mathlib" "{CW}:MacOS Support:Libraries:Apple MPW PPC:PPCToolLibs.o" "{CW}:MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib" "{CW}:MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW.Lib" -mwcppc -o :bin.mac:jam.o -nomapcr -w off jam.c - -:bin.mac:mkjambase jambase.c Jambase - -mwcppc -o :bin.mac:jambase.o -nomapcr -w off jambase.c - -mwlinkppc -o :bin.mac:jam -mpwtool -warn :bin.mac:jam.o :bin.mac:jambase.o :bin.mac:libjam.lib "{CW}:MacOS Support:Universal:Libraries:StubLibraries:Interfacelib" "{CW}:MacOS Support:Universal:Libraries:StubLibraries:ThreadsLib" "{CW}:MacOS Support:Universal:Libraries:StubLibraries:Mathlib" "{CW}:MacOS Support:Libraries:Apple MPW PPC:PPCToolLibs.o" "{CW}:MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib" "{CW}:MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW.Lib" - - - - - - diff --git a/jam-2.5/Jam.html b/jam-2.5/Jam.html deleted file mode 100644 index aa7c9c7b0..000000000 --- a/jam-2.5/Jam.html +++ /dev/null @@ -1,1329 +0,0 @@ - - - Jam - Make(1) Redux - - - -
- -

Jam - Make(1) Redux

- -

The Jam Executable - -

- -
- -

USAGE

- -
-jam [ -a ] [ -g ] [ -n ] [ -q ] [ -v ]
-    [ -d debug ] 
-    [ -f jambase ] 
-    [ -j jobs ] 
-    [ -o actionsfile ] 
-    [ -s var=value ] 
-    [ -t target ] 
-    [ target ... ]
-
- -

DESCRIPTION

- -

- - Jam is a program construction tool, like make(1). - -

- - Jam recursively builds target files from source files, - using dependency information and updating actions expressed in - the Jambase file, which is written in jam's own interpreted - language. The default Jambase is compiled into jam and - provides a boilerplate for common use, relying on a user-provide - file "Jamfile" to enumerate actual targets and sources. - -

- - The Jambase is described in the Jambase - Reference and the document Using - Jamfiles and Jambase. - -

OPTIONS

- -

- - If target is provided on the command line, jam - builds target; otherwise jam builds the target - 'all'. - -

- - Jam may be invoked with the following options: - -

- -
-a - Build all targets anyway, even if they are up-to-date. - -
-d c - Turn on display option c and off the default - display (summary info and actions): - -
-
a
Show summary info, actions, quiet actions, and the - use of temporary targets -
c
Show the names of files that cause rebuilds, i.e. - new sources, missing targets, etc. -
d
Display a dependency graph (in jam syntax). -
m
Display the dependency analysis, and target/source - timestamps and paths -
x
Show shell arguments -
- -
-d n - Enable cummulative debugging levels from 1 to n. - Interesting values are: - -
-
1
Show actions and summary info (the default) -
3
Old name for -dm (described above) -
5
Show rule invocations and variable expansions -
6
Show directory/header file/archive scans -
7
Show variable settings -
8
Show variable fetches -
9
Show variable manipulation, scanner tokens -
- -
-d +n - Enable debugging level n. - -
-d 0 - Turn off all debugging levels. Only errors are emitted. - -
-f jambase - Read jambase instead of using the built-in Jambase. - Multiple -f flags are permitted. - -
-g - Build targets with the newest sources first, rather than - in the order of appearance in the Jambase/Jamfiles. - -
-j n - Run up to n shell commands concurrently (UNIX - and NT only). The default is 1. - -
-n - Don't actually execute the updating actions, but do - everything else. This changes the debug level to -dax. - -
-o file - Write the updating actions to the specified file instead - of running them (or outputting them, as on the Mac). - -
-q - Quit quickly (as if an interrupt was received) - as soon as any target build fails. - -
-s var=value - Set the variable var to value, overriding - both internal variables and variables imported from the - environment. - -
-t target - Rebuild target and everything that depends on it, - even if it is up-to-date. - -
-v - Print the version of jam and exit. - -
- -

OPERATION

- -

- - Jam has four phases of operation: start-up, parsing, - binding, and updating. - -

Start-up

- -

- - Upon start-up, jam imports environment variable settings - into jam variables. Environment variables are split at - blanks with each word becoming an element in the variable's list - of values. Environment variables whose names end in PATH are - split at $(SPLITPATH) characters (e.g., ":" for Unix). - -

- - To set a variable's value on the command line, overriding the - variable's environment value, use the -s option. To see variable - assignments made during jam's execution, use the -d+7 - option. - -

Parsing

- -

- - In the parsing phase, jam reads and executes the Jambase - file, by default the built-in one. It is written in the jam - language. See Language below. The - last action of the Jambase is to read (via the "include" rule) - a user-provided file called "Jamfile". - -

- - Collectively, the purpose of the Jambase and the Jamfile is to - name built target and source files, construct the dependency - graph among them, and associate build actions with targets. - The Jambase defines boilerplate rules and variable assignments, - and the Jamfile uses these to specify the actual relationship - among the target and source files. See the Jambase Reference and the document Using Jamfiles and Jambase for information. - - -

Binding

- - -

Binding
- - After parsing, jam recursively descends the dependency - graph and binds every file target with a location in the - filesystem. - -

Targets
- - Any string value in jam can represent a target, and it - does so if the DEPENDS or INCLUDES rules make it part of the - dependency graph. Build targets are files to be updated. Source - targets are the files used in updating build targets. Build - targets and source targets are collectively referred to as file - targets, and frequently build targets are source targets for - other build targets. Pseudotargets are symbols which represent - dependencies on other targets, but which are not themselves - associated with any real file. - -

- - A file target's identifier is generally the file's name, which can - be absolutely rooted, relative to the directory of jam's - invocation, or simply local (no directory). Most often it is the - last case, and the actual file path is bound using the $(SEARCH) - and $(LOCATE) special variables. See SEARCH - and LOCATE Variables below. A local filename is optionally - qualified with "grist," a string value used to assure uniqueness. - A file target with an identifier of the form file(member) - is a library member (usually an ar(1) archive on UNIX). - -

- - The use of $(SEARCH) and $(LOCATE) allows jam to separate - the the location of files from their names, so that Jamfiles can - refer to files locally (i.e. relative to the Jamfile's directory), - yet still be usable when jam is invoked from a distant - directory. The use of grist allows files with the same name - to be identified uniquely, so that jam can read a whole - directory tree of Jamfiles and not mix up same-named targets. - -

Update Determination
- - After binding each target, jam determines whether the - target needs updating, and if so marks the target for the updating - phase. A target is normally so marked if it is missing, it is - older than any of its sources, or any of its sources are marked - for updating. This behavior can be modified by the application - of special built-in rules. See Modifying - Binding below. - -

Header File Scanning
- - During the binding phase, jam also performs header file - scanning, where it looks inside source files for the implicit - dependencies on other files caused by C's #include syntax. This - is controlled by the special variables $(HDRSCAN) and $(HDRRULE). - The result of the scan is formed into a rule invocation, with - the scanned file as the target and the found included file names - as the sources. Note that this is the only case where rules - are invoked outside the parsing phase. See HDRSCAN and HDRRULE Variables below. - -

Updating

- -

- - After binding, jam again recursively descends the dependency - graph, this time executing the update actions for each target - marked for update during the binding phase. If a target's - updating actions fail, then all other targets which depend on - that target are skipped. - -

- - The -j flag instructs jam to build more than one target - at a time. If there are multiple actions on a single target, - they are run sequentially. The -g flag reorders builds so that - targets with newest sources are built first. Normally, they are - built in the order of appearance in the Jamfiles. - - -

LANGUAGE

- - -

Overview

- - Jam has a interpreted, procedural language with a few - select features to effect program construction. Statements in - jam are rule (procedure) definitions, rule invocations, - updating action definitions, flow-of-control structures, variable - assignments, and sundry language support. - -

Lexical Features

- -

- - Jam treats its input files as whitespace-separated tokens, - with two exceptions: double quotes (") can enclose whitespace to - embed it into a token, and everything between the matching curly - braces ({}) in the definition of a updating actions is treated - as a single string. A backslash (\) can escape a double quote, - or any single whitespace character. - -

- - Jam requires whitespace (blanks, tabs, or newlines) to - surround all tokens, including the colon (:) and semicolon - (;) tokens. - -

- - Jam keywords (as mentioned in this document) are reserved - and generally must be quoted with double quotes (") to be used - as arbitrary tokens, such as variable or target names. - -

Datatype

- -

- - Jam's only data type is a one-dimensional list of arbitrary - strings. They arise as literal (whitespace-separated) tokens in - the Jambase or included files, as the result of variable expansion - of those tokens, or as the return value from a rule invocation. - -

Rules

- -

- - The basic jam language entity is called a rule. A rule - is simply a procedure definition, with a body of jam - statements to be run when the rule is invoked. The syntax of - rule invocation make it possible to write Jamfiles that look - a bit like Makefiles. - -

- - Rules take up to 9 arguments ($(1) through $(9), each a list) - and can have a return value (a single list). A rule's return - value can be expanded in a list by enclosing the rule invocation - with [ and ]. - -

Updating Actions

- -

- - A rule may have updating actions associated with it, in which - case arguments $(1) and $(2) are treated as built targets and - sources, respectively. Updating actions are the OS shell commands - to execute when updating the built targets of the rule. - -

- - When an rule with updating actions is invoked, those actions are - added to those associated with its built targets ($(1)) before - the rule's procedure is run. Later, to build the targets in the - updating phase, the actions are passed to the OS command shell, - with $(1) and $(2) replaced by bound versions of the target names. - See Binding above. - - -

Statements

- -

- - Jam's langauge has the following statements: - -

- -

- - rulename field1 : field2 : ... - : fieldN ; - - - -

Invoke a rule. A rule is invoked with values in - field1 through fieldN (9 max). They may be - referenced in the procedure's statements as $(1) - through $(<9>N). $(<) and $(>) are synonymous - with $(1) and $(2). - -

- rulename undergoes variable - expansion. If the resulting list is more than one value, - each rule is invoked with the same arguments, and the result - of the invocation is the concatenation of all the results. - -

- - actions [ modifiers ] rulename { commands } - - - -

Define a rule's updating actions, replacing any previous - definition. The first two arguments may be referenced in - the action's commands as $(1) and $(2) or $(<) - and $(>). - -

- - The following action modifiers are understood: - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
actions bind vars $(vars) will be replaced with bound values.
actions existing $(>) includes only source targets currently existing.
actions ignore The return status of the commands is ignored.
actions piecemeal commands are repeatedly invoked with a subset - of $(>) small enough to fit in the command buffer on this - OS.
actions quietly The action is not echoed to the standard output.
actions together The $(>) from multiple invocations of the same action - on the same built target are glommed together.
actions updated $(>) includes only source targets themselves marked - for updating.
- -

- - break - - - -

Breaks out of the closest enclosing for - or while loop. - -

- - continue - - - -

Jumps to the end of the closest enclosing for - or while loop. - -

- - for var in list { statements } - - - -

Executes statements for each element in - list, setting the variable var to the element - value. - - -

- - - if cond { statements } [ else statement ] - - - -

Does the obvious; the else clause is optional. - cond is built of: - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
a true if any a element is a non-zero-length - string
a = b list a matches list b - string-for-string
a != b list a does not match list b
a < b a[i] string is less than b[i] - string, where i is first mismatched element - in lists a and b
a <= b every a string is less than or equal to - its b counterpart
a > b a[i] string is greater than b[i] - string, where i is first mismatched element
a >= b every a string is greater than or equal to - its b counterpart
a in b true if all elements of a can be found - in b, or if a has no elements
! cond condition not true
cond && cond conjunction
cond || cond disjunction
( cond ) precedence grouping
- -

- - include file ; - - - -

Causes jam to read the named file. - The file is bound like a regular target (see Binding above) but unlike a regular - target the include file cannot be built. Marking an include - file target with the NOCARE rule makes it optional: - if it is missing, it causes no error. - -

- - The include file is inserted into the input stream during - the parsing phase. The primary input file and all the included - file(s) are treated as a single file; that is, jam - infers no scope boundaries from included files. - -

- - local vars [ = values ] ; - - - -

Creates new vars inside to the enclosing {} - block, obscuring any previous values they might have. The - previous values for vars are restored when the current - block ends. Any rule called or file included will see the - local and not the previous value (this is sometimes called - Dynamic Scoping). The local statement may appear anywhere, - even outside of a block (in which case the previous value - is restored when the input ends). The vars are - initialized to values if present, or left uninitialized - otherwise. - -

- - on target statement ; - - - -

Run statement under the influence of - target's target-specific variables. These variables - become local copies during statement's run, but they - may be updated as target-specific variables using the usual - "variable on targets =" syntax. - - -

- - return values ; - - - -

Within a rule body, the return statement sets the return - value for an invocation of the rule and terminates the rule's - execution. - -

- - rule rulename [ : vars ] { statements } - - - -

Define a rule's procedure, replacing any previous - definition. If vars are provided, they are assigned - the values of the parameters ($(1) to $(9)) when statements - are executed, as with the local statement. - -

- - - switch value - -
{ -
case pattern1 : statements ; -
case pattern2 : statements ; -
... -
} - -
- -

The switch statement executes zero or one of the - enclosed statements, depending on which, if any, is - the first case whose pattern matches value. - The pattern values are not variable-expanded. The - pattern values may include the following wildcards: - - - - - - - - - - - - - - -
? match any single character
* match zero or more characters
[chars] match any single character in chars
[^chars] match any single character not in chars
\x match x (escapes the other wildcards)
- -

- - while cond { statements } - - - -

Repeatedly execute statements while cond - remains true upon entry. (See the description of cond - expression syntax under if, above). -
- - -

Variables

- -

- - Jam variables are lists of zero or more elements, with - each element being a string value. An undefined variable is - indistinguishable from a variable with an empty list, however, - a defined variable may have one more elements which are null - strings. All variables are referenced as $(variable). - -

- - Variables are either global or target-specific. In the latter - case, the variable takes on the given value only during the - target's binding, header file scanning, and updating; and during - the "on target statement" statement. - -

- - A variable is defined with: - -

- -
- variable = elements ; -
- variable += elements ; -
- variable ?= elements ; -
- variable on targets = elements ; -
- variable on targets += elements ; -
- variable on targets ?= elements ; - -
- -

- - The first three forms set variable globally. The last - three forms set a target-specific variable. The = operator - replaces any previous elements of variable with - elements; the += operation adds elements to - variable's list of elements; the ?= operator sets - variable only if it was previously unset. The last form - "variable on targets ?= elements" checks - to see if the target-specific, not the global, variable is set. - (The ?= operator also has an old form "default =".) - -

- - Variables referenced in updating commands will be replaced with - their values; target-specific values take precedence over global - values. Variables passed as arguments ($(1) and $(2)) to actions - are replaced with their bound values; the "bind" modifier can - be used on actions to cause other variables to be replaced with - bound values. See Action Modifiers - above. - -

- - Jam variables are not re-exported to the environment of - the shell that executes the updating actions, but the updating - actions can reference jam variables with $(variable). - - -

Variable Expansion

- - -

- - During parsing, jam performs variable expansion on each - token that is not a keyword or rule name. Such tokens with - embedded variable references are replaced with zero or more - tokens. Variable references are of the form $(v) or - $(vm), where v is the variable name, and m - are optional modifiers. - -

- - Variable expansion in a rule's actions is similar to variable - expansion in statements, except that the action string is - tokenized at whitespace regardless of quoting. - -

- - The result of a token after variable expansion is the - product of the components of the token, where each - component is a literal substring or a list substituting a variable - reference. For example: - -

- -
$(X) -> a b c -
t$(X) -> ta tb tc -
$(X)z -> az bz cz -
$(X)-$(X) -> a-a a-b a-c b-a b-b b-c c-a c-b c-c - -
- -

- - The variable name and modifiers can themselves contain - a variable reference, and this partakes of the product - as well: - -

- -
$(X) -> a b c -
$(Y) -> 1 2 -
$(Z) -> X Y -
$($(Z)) -> a b c 1 2 - -
- -

- - Because of this product expansion, if any variable reference in - a token is undefined, the result of the expansion is an empty - list. If any variable element is a null string, the result - propagates the non-null elements: - -

- -
$(X) -> a "" -
$(Y) -> "" 1 -
$(Z) -> -
*$(X)$(Y)* -> *a* *a1* ** *1* -
*$(X)$(Z)* -> - -
- -

- - A variable element's string value can be parsed into grist and - filename-related components. Modifiers to a variable are used - to select elements, select components, and replace components. - The modifiers are: - -

- -
[n] - Select element number n (starting at 1). If - the variable contains fewer than n elements, - the result is a zero-element list. - -
[n-m] - Select elements number n through m. - -
[n-] - Select elements number n through the last. - -
:B - Select filename base. - -
:S - Select (last) filename suffix. - -
:M - Select archive member name. - -
:D - Select directory path. - -
:P - Select parent directory. - -
:G - Select grist. - -
:U - Replace lowercase characters with uppercase. - -
:L - Replace uppercase characters with lowercase. - -
:chars - Select the components listed in chars. - -
:G=grist - Replace grist with grist. - -
:D=path - Replace directory with path. - -
:B=base - Replace the base part of file name with base. - -
:S=suf - Replace the suffix of file name with suf. - -
:M=mem - Replace the archive member name with mem. - -
:R=root - Prepend root to the whole file name, if not - already rooted. - -
:E=value - Use value instead if the variable is unset. - -
:J=joinval - Concatentate list elements into single - element, separated by joinval. - -
- -

- - On VMS, $(var:P) is the parent directory of $(var:D); on Unix - and NT, $(var:P) and $(var:D) are the same. - - -

Built-in Rules

- -

- Jam has twelve built-in rules, all of which are pure - procedure rules without updating actions. They are in - three groups: the first builds the dependency graph; - the second modifies it; and the third are just utility - rules. - -

Dependency Building
- -

- -

- DEPENDS targets1 : targets2 ; - - -
Builds a direct dependency: makes each of targets1 - depend on each of targets2. Generally, targets1 - will be rebuilt if targets2 are themselves rebuilt are - or are newer than targets1. - -

- INCLUDES targets1 : targets2 ; - - -
Builds a sibling dependency: makes any target that depends - on any of targets1 also depend on each of targets2. - This reflects the dependencies that arise when one source file - includes another: the object built from the source file depends - both on the original and included source file, but the two - sources files don't depend on each other. For example: - - -

DEPENDS foo.o : foo.c ; -
INCLUDES foo.c : foo.h ; -
- -

- - "foo.o" depends on "foo.c" and "foo.h" in this example. - -

- - -

Modifying Binding
- - -

- - The six rules ALWAYS, LEAVES, NOCARE, NOTFILE, NOUPDATE, and - TEMPORARY modify the dependency graph so that jam treats - the targets differently during its target binding phase. See - Binding above. Normally, jam - updates a target if it is missing, if its filesystem modification - time is older than any of its dependencies (recursively), or if - any of its dependencies are being updated. This basic behavior - can be changed by invoking the following rules: - -

- -

- ALWAYS targets ; - - -
Causes targets to be rebuilt regardless of whether - they are up-to-date (they must still be in the dependency graph). - This is used for the clean and uninstall targets, as they have - no dependencies and would otherwise appear never to need building. - It is best applied to targets that are also NOTFILE targets, - but it can also be used to force a real file to be updated as - well. - -

- LEAVES targets ; - - -
Makes each of targets depend only on its leaf sources, - and not on any intermediate targets. This makes it immune to - its dependencies being updated, as the "leaf" dependencies are - those without their own dependencies and without updating actions. - This allows a target to be updated only if original source files - change. - -

- NOCARE targets ; - - -
Causes jam to ignore targets that neither - can be found nor have updating actions to build them. Normally - for such targets jam issues a warning and then skips - other targets that depend on these missing targets. The HdrRule - in Jambase uses NOCARE on the header file names found during - header file scanning, to let jam know that the included - files may not exist. For example, if a #include is within an - #ifdef, the included file may not actually be around. - -

- NOTFILE targets ; - - -
Marks targets as pseudotargets and not real files. - No timestamp is checked, and so the actions on such a target - are only executed if the target's dependencies are updated, or - if the target is also marked with ALWAYS. The default jam - target "all" is a pseudotarget. In Jambase, NOTFILE is used to - define several addition convenient pseudotargets. - -

- NOUPDATE targets ; - - -
Causes the timestamps on targets to be ignored. - This has two effects: first, once the target has been created - it will never be updated; second, manually updating target will - not cause other targets to be updated. In Jambase, for example, - this rule is applied to directories by the MkDir rule, because - MkDir only cares that the target directory exists, not when it - has last been updated. - -

- TEMPORARY targets ; - - -
Marks targets as temporary, allowing them to be - removed after other targets that depend upon them have been - updated. If a TEMPORARY target is missing, jam uses the - timestamp of the target's parent. Jambase uses TEMPORARY to - mark object files that are archived in a library after they are - built, so that they can be deleted after they are archived. - -
- -

Utility Rules
- - The remaining rules are utility rules. - -

- -

- ECHO args ;
- Echo args ;
- echo args ; -
- -
Blurts out the message args to stdout. - -

- EXIT args ;
- Exit args ;
- exit args ; -
- -
Blurts out the message args to stdout and then exits - with a failure status. - -

- GLOB directories : patterns ; - - -
Scans directories for files matching patterns, - returning the list of matching files (with directory prepended). - patterns uses the same syntax as in the switch - statement. Only useful within the [ ] construct, to - change the result into a list. - -

- MATCH regexps : list ; - - -
Matches the egrep(1) style regular expressions - regexps against the strings in list. The result - is the concatenation of matching () subexpressions for - each string in list, and for each regular expression in - regexps. Only useful within the [ ] construct, - to change the result into a list. - -
- -

Built-in Variables

- -

- - This section discusses variables that have special meaning to - jam. - - -

SEARCH and LOCATE Variables

- - -

- - These two variables control the binding of file target names to - locations in the file system. Generally, $(SEARCH) is used to - find existing sources while $(LOCATE) is used to fix the location - for built targets. - -

- - Rooted (absolute path) file targets are bound as is. Unrooted - file target names are also normally bound as is, and thus relative - to the current directory, but the settings of $(LOCATE) and - $(SEARCH) alter this: - -

- -

- -

- - Both $(SEARCH) and $(LOCATE) should be set target-specific and - not globally. If they were set globally, jam would use - the same paths for all file binding, which is not likely to - produce sane results. When writing your own rules, especially - ones not built upon those in Jambase, you may need to set - $(SEARCH) or $(LOCATE) directly. Almost all of the rules defined - in Jambase set $(SEARCH) and $(LOCATE) to sensible values for - sources they are looking for and targets they create, respectively. - - -

HDRSCAN and HDRRULE Variables

- - -

- - These two variable control header file scanning. $(HDRSCAN) is - an egrep(1) pattern, with ()'s surrounding the file name, - used to find file inclusion statements in source files. Jambase - uses $(HDRPATTERN) as the pattern for $(HDRSCAN). $(HDRRULE) - is the name of a rule to invoke with the results of the scan: - the scanned file is the target, the found files are the sources. - $(HDRRULE) is run under the influence of the scanned file's - target-specific variables. - -

- - Both $(HDRSCAN) and $(HDRRULE) must be set for header file - scanning to take place, and they should be set target-specific - and not globally. If they were set globally, all files, including - executables and libraries, would be scanned for header file - include statements. - -

- - The scanning for header file inclusions is not exact, but it is - at least dynamic, so there is no need to run something like - makedepend(GNU) to create a static dependency file. The - scanning mechanism errs on the side of inclusion (i.e., it is - more likely to return filenames that are not actually used by - the compiler than to miss include files) because it can't tell - if #include lines are inside #ifdefs or other conditional logic. - In Jambase, HdrRule applies the NOCARE rule to each header file - found during scanning so that if the file isn't present yet - doesn't cause the compilation to fail, jam won't care. - -

- - Also, scanning for regular expressions only works where the - included file name is literally in the source file. It can't - handle languages that allow including files using variable names - (as the Jam language itself does). - -

Platform Identifier Variables

- -

- - A number of Jam built-in variables can be used to identify - runtime platform: - -

- - - -
OSOS identifier string -
OSPLATUnderlying architecture, when applicable -
MACtrue on MAC platform -
NTtrue on NT platform -
OS2true on OS2 platform -
UNIXtrue on Unix platforms -
VMStrue on VMS platform - -
- -

Jam Version Variables

- -

- - - -
JAMDATETime and date at jam start-up. -
JAMUNAMEOuput of uname(1) command (Unix only) -
JAMVERSIONjam version, as reported by jam -v. - -
- -

JAMSHELL Variable

- -

- - When jam executes a rule's action block, it forks and - execs a shell, passing the action block as an argument to the - shell. The invocation of the shell can be controlled by - $(JAMSHELL). The default on Unix is, for example: - -

- - JAMSHELL = /bin/sh -c % ; - -

- - The % is replaced with the text of the action block. - -

- - Jam does not directly support building in parallel across - multiple hosts, since that is heavily dependent on the local - environment. To build in parallel across multiple hosts, you - need to write your own shell that provides access to the multiple - hosts. You then reset $(JAMSHELL) to reference it. - -

- - Just as jam expands a % to be the text of the rule's - action block, it expands a ! to be the multi-process slot number. - The slot number varies between 1 and the number of concurrent - jobs permitted by the -j flag given on the command line. Armed - with this, it is possible to write a multiple host shell. For - example: - -

- -
- -
#!/bin/sh -
-
# This sample JAMSHELL uses the SunOS on(1) command to execute a -
# command string with an identical environment on another host. -
-
# Set JAMSHELL = jamshell ! % -
# -
# where jamshell is the name of this shell file. -
# -
# This version handles up to -j6; after that they get executed -
# locally. -
-
case $1 in -
1|4) on winken sh -c "$2";; -
2|5) on blinken sh -c "$2";; -
3|6) on nod sh -c "$2";; -
*) eval "$2";; -
esac - -
- - -

DIAGNOSTICS

- -

- - In addition to generic error messages, jam may emit one of - the following: - -

- -

warning: unknown rule X
- - A rule was invoked that has not been defined with - an "actions" or "rule" statement. - -

using N temp target(s)
- - Targets marked as being temporary (but nonetheless - present) have been found. - -

updating N target(s)
- - Targets are out-of-date and will be updated. - -

can't find N target(s)
- - Source files can't be found and there are no - actions to create them. - -

can't make N target(s)
- - Due to sources not being found, other targets cannot be made. - -

warning: X depends on itself
- - A target depends on itself either directly or - through its sources. - -

don't know how to make X
- - A target is not present and no actions have been - defined to create it. - -

X skipped for lack of Y
- - A source failed to build, and thus a target cannot - be built. - -

warning: using independent target X
- - A target that is not a dependency of any other - target is being referenced with $(<) or $(>). - -

X removed
- - Jam removed a partially built target after being - interrupted. - -
- -

BUGS, LIMITATIONS

- -

- - The -j flag can cause jam to get confused when single - actions update more than one target at a time. jam may - proceed as if the targets were built even though they are still - under construction. - -

- - For parallel building to be successful, the dependencies among - files must be properly spelled out, as targets tend to get built - in a quickest-first ordering. Also, beware of un-parallelizable - commands that drop fixed-named files into the current directory, - like yacc(1) does. - -

- - With the -j flag, errors from failed commands can get staggeringly - mixed up. - -

- - A poorly set $(JAMSHELL) is likely to result in silent failure. - -

SEE ALSO

- -

- -

- -

- - Jam documentation and source are available from the Perforce - Public Depot. - -

AUTHOR

- -

- Jam's author is Christopher Seiwald (seiwald@perforce.com). - Documentation is provided by - Perforce Software, Inc. - -

- -


- -

- - Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. -
- Comments to info@perforce.com -
- Last updated: May, 2002 -
- $Id: Jam.html,v 1.1 2006/04/13 19:03:01 ejcoumans Exp $ - - - - diff --git a/jam-2.5/Jambase b/jam-2.5/Jambase deleted file mode 100644 index 24b7f54bb..000000000 --- a/jam-2.5/Jambase +++ /dev/null @@ -1,2096 +0,0 @@ -# -# /+\ -# +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. -# \+/ -# -# This file is part of Jam - see jam.c for Copyright information. -# - -# -# JAMBASE - jam 2.5 ruleset providing make(1)-like functionality -# -# Supports UNIX, NT, and VMS. -# -# 12/27/93 (seiwald) - purturb library sources with SOURCE_GRIST -# 04/18/94 (seiwald) - use '?=' when setting OS specific vars -# 04/21/94 (seiwald) - do RmTemps together -# 05/05/94 (seiwald) - all supported C compilers support -o: relegate -# RELOCATE as an option; set Ranlib to "" to disable it -# 06/01/94 (seiwald) - new 'actions existing' to do existing sources -# 08/25/94 (seiwald) - new ObjectCcFlags rule to append to per-target CCFLAGS -# 08/29/94 (seiwald) - new ObjectHdrs rule to append to per-target HDRS -# 09/19/94 (seiwald) - LinkLibraries and Undefs now append -# - Rule names downshifted. -# 10/06/94 (seiwald) - Dumb yyacc stuff moved into Jamfile. -# 10/14/94 (seiwald) - (Crude) support for .s, .C, .cc, .cpp, and .f files. -# 01/08/95 (seiwald) - Shell now handled with awk, not sed -# 01/09/95 (seiwald) - Install* now take dest directory as target -# 01/10/95 (seiwald) - All entries sorted. -# 01/10/95 (seiwald) - NT support moved in, with LauraW's help. -# 01/10/95 (seiwald) - VMS support moved in. -# 02/06/95 (seiwald) - ObjectC++Flags and SubDirC++Flags added. -# 02/07/95 (seiwald) - Iron out when HDRSEARCH uses "" or SEARCH_SOURCE. -# 02/08/95 (seiwald) - SubDir works on VMS. -# 02/14/95 (seiwald) - MkDir and entourage. -# 04/30/95 (seiwald) - Use install -c flag so that it copies, not moves. -# 07/10/95 (taylor) - Support for Microsoft C++. -# 11/21/96 (peterk) - Support for BeOS -# 07/19/99 (sickel) - Support for Mac OS X Server (and maybe client) -# 02/18/00 (belmonte)- Support for Cygwin. - -# Special targets defined in this file: -# -# all - parent of first, shell, files, lib, exe -# first - first dependent of 'all', for potential initialization -# shell - parent of all Shell targets -# files - parent of all File targets -# lib - parent of all Library targets -# exe - parent of all Main targets -# dirs - parent of all MkDir targets -# clean - removes all Shell, File, Library, and Main targets -# uninstall - removes all Install targets -# - -# Rules defined by this file: -# -# as obj.o : source.s ; .s -> .o -# Bulk dir : files ; populate directory with many files -# Cc obj.o : source.c ; .c -> .o -# C++ obj.o : source.cc ; .cc -> .o -# Clean clean : sources ; remove sources with 'jam clean' -# File dest : source ; copy file -# Fortran obj.o : source.f ; .f -> .o -# GenFile source.c : program args ; make custom file -# HardLink target : source ; make link from source to target -# HdrRule source : headers ; handle #includes -# InstallInto dir : sources ; install any files -# InstallBin dir : sources ; install binaries -# InstallLib dir : sources ; install files -# InstallFile dir : sources ; install files -# InstallMan dir : sources ; install man pages -# InstallShell dir : sources ; install shell scripts -# Lex source.c : source.l ; .l -> .c -# Library lib : source ; archive library from compiled sources -# LibraryFromObjects lib : objects ; archive library from objects -# LinkLibraries images : libraries ; bag libraries onto Mains -# Main image : source ; link executable from compiled sources -# MainFromObjects image : objects ; link executable from objects -# MkDir dir ; make a directory, if not there -# Object object : source ; compile object from source -# ObjectCcFlags source : flags ; add compiler flags for object -# ObjectC++Flags source : flags ; add compiler flags for object -# ObjectHdrs source : dirs ; add include directories for object -# Objects sources ; compile sources -# RmTemps target : sources ; remove temp sources after target made -# Setuid images ; mark executables Setuid -# SoftLink target : source ; make symlink from source to target -# SubDir TOP d1 d2 ... ; start a subdirectory Jamfile -# SubDirCcFlags flags ; add compiler flags until next SubDir -# SubDirC++Flags flags ; add compiler flags until next SubDir -# SubDirHdrs d1 d2 ... ; add include dir until next SubDir -# SubInclude TOP d1 d2 ... ; include a subdirectory Jamfile -# Shell exe : source ; make a shell executable -# Undefines images : symbols ; save undef's for linking -# UserObject object : source ; handle unknown suffixes for Object -# Yacc source.c : source.y ; .y -> .c -# -# Utility rules that have no side effects (not supported): -# -# FAppendSuffix f1 f2 ... : $(SUF) ; return $(<) with suffixes -# FDirName d1 d2 ... ; return path from root to dir -# FGrist d1 d2 ... ; return d1!d2!... -# FGristFiles value ; return $(value:G=$(SOURCE_GRIST)) -# FGristSourceFiles value ; return $(value:G=$(SOURCE_GRIST)) -# FStripCommon v1 : v2 ; strip common initial parts of v1 v2 -# FReverse a1 a2 ... ; return ... a2 a1 -# FRelPath d1 : d2 ; return rel path from d1 to d2 -# FSubDir d1 d2 ... ; return path to root -# - - -# Brief review of the jam language: -# -# Statements: -# rule RULE - statements to process a rule -# actions RULE - system commands to carry out target update -# -# Modifiers on actions: -# together - multiple instances of same rule on target get executed -# once with their sources ($(>)) concatenated -# updated - refers to updated sources ($(>)) only -# ignore - ignore return status of command -# quietly - don't trace its execution unless verbose -# piecemeal - iterate command each time with a small subset of $(>) -# existing - refers to currently existing sources ($(>)) only -# bind vars - subject to binding before expanding in actions -# -# Special rules: -# Always - always build a target -# Depends - builds the dependency graph -# Echo - blurt out targets on stdout -# Exit - blurt out targets and exit -# Includes - marks sources as headers for target (a codependency) -# NoCare - don't panic if the target can't be built -# NoUpdate - create the target if needed but never update it -# NotFile - ignore the timestamp of the target (it's not a file) -# Temporary - target need not be present if sources haven't changed -# -# Special variables set by jam: -# $(<) - targets of a rule (to the left of the :) -# $(>) - sources of a rule (to the right of the :) -# $(xxx) - true on xxx (UNIX, VMS, NT, OS2, MAC) -# $(OS) - name of OS - varies wildly -# $(JAMVERSION) - version number (2.5) -# -# Special variables used by jam: -# SEARCH - where to find something (used during binding and actions) -# LOCATE - where to plop something not found with SEARCH -# HDRRULE - rule to call to handle include files -# HDRSCAN - egrep regex to extract include files -# -# Special targets: -# all - default if none given on command line -# - -# for perforce use -- jambase version - -JAMBASEDATE = 2002.05.09 ; - -# Initialize variables -# - -# -# OS specific variable settings -# - -if $(NT) -{ - MV ?= move /y ; - CP ?= copy ; - RM ?= del /f/q ; - RMDIR ?= rmdir /s/q ; - SLASH ?= \\ ; - SUFLIB ?= .lib ; - SUFOBJ ?= .obj ; - SUFEXE ?= .exe ; - - if $(BCCROOT) - { - AR ?= tlib /C /P64 ; - CC ?= bcc32 ; - CCFLAGS ?= -v -w- -q -DWIN -tWR -tWM -tWC ; - C++ ?= $(CC) ; - C++FLAGS ?= $(CCFLAGS) -P ; - LINK ?= $(CC) ; - LINKFLAGS ?= $(CCFLAGS) ; - STDLIBPATH ?= $(BCCROOT)\\lib ; - STDHDRS ?= $(BCCROOT)\\include ; - NOARSCAN ?= true ; - } - else if $(MSVC) - { - AR ?= lib /nologo ; - CC ?= cl /nologo ; - CCFLAGS ?= /D \"WIN\" ; - C++ ?= $(CC) ; - C++FLAGS ?= $(CCFLAGS) ; - LINK ?= $(CC) ; - LINKFLAGS ?= $(CCFLAGS) ; - LINKLIBS ?= - $(MSVC)\\lib\\mlibce.lib - $(MSVC)\\lib\\oldnames.lib - ; - LINKLIBS ?= ; - NOARSCAN ?= true ; - OPTIM ?= ; - STDHDRS ?= $(MSVC)\\include ; - UNDEFFLAG ?= "/u _" ; - } - else if $(MSVCNT) || $(MSVCDIR) - { - # Visual C++ 6.0 uses MSVCDIR - - MSVCNT ?= $(MSVCDIR) ; - - # bury IA64 in the path for the SDK - - local I ; if $(OSPLAT) = IA64 { I = ia64\\ ; } else { I = "" ; } - - AR ?= lib ; - AS ?= masm386 ; - CC ?= cl /nologo ; - CCFLAGS ?= "" ; - C++ ?= $(CC) ; - C++FLAGS ?= $(CCFLAGS) ; - LINK ?= link /nologo ; - LINKFLAGS ?= "" ; - LINKLIBS ?= - $(MSVCNT)\\lib\\$(I)libc.lib - $(MSVCNT)\\lib\\$(I)oldnames.lib - $(MSVCNT)\\lib\\$(I)kernel32.lib ; - OPTIM ?= "" ; - STDHDRS ?= $(MSVCNT)\\include ; - UNDEFFLAG ?= "/u _" ; - } - else - { - EXIT On NT, set BCCROOT, MSVCDIR, MSVCNT, or MSVC to the root - of the Borland or Microsoft directories. ; - } - -} -else if $(MINGW) -{ - Echo "MingW32" ; - - CC ?= gcc ; - C++ ?= g++ ; - CCFLAGS += -DMINGW ; - RANLIB ?= "ranlib" ; - SUFEXE ?= .exe ; -} -else if $(OS2) -{ - WATCOM ?= $(watcom) ; - - if ! $(WATCOM) - { - Exit On OS2, set WATCOM to the root of the Watcom directory. ; - } - - AR ?= wlib ; - BINDIR ?= \\os2\\apps ; - CC ?= wcc386 ; - CCFLAGS ?= /zq /DOS2 /I$(WATCOM)\\h ; # zq=quiet - C++ ?= wpp386 ; - C++FLAGS ?= $(CCFLAGS) ; - CP ?= copy ; - DOT ?= . ; - DOTDOT ?= .. ; - LINK ?= wcl386 ; - LINKFLAGS ?= /zq ; # zq=quiet - LINKLIBS ?= ; - MV ?= move ; - NOARSCAN ?= true ; - OPTIM ?= ; - RM ?= del /f ; - SLASH ?= \\ ; - STDHDRS ?= $(WATCOM)\\h ; - SUFEXE ?= .exe ; - SUFLIB ?= .lib ; - SUFOBJ ?= .obj ; - UNDEFFLAG ?= "/u _" ; - -} -else if $(VMS) -{ - C++ ?= cxx ; - C++FLAGS ?= ; - CC ?= cc ; - CCFLAGS ?= ; - CHMOD ?= set file/prot= ; - CP ?= copy/replace ; - CRELIB ?= true ; - DOT ?= [] ; - DOTDOT ?= [-] ; - EXEMODE ?= (w:e) ; - FILEMODE ?= (w:r) ; - HDRS ?= ; - LINK ?= link ; - LINKFLAGS ?= "" ; - LINKLIBS ?= ; - MKDIR ?= create/dir ; - MV ?= rename ; - OPTIM ?= "" ; - RM ?= delete ; - RUNVMS ?= mcr ; - SHELLMODE ?= (w:er) ; - SLASH ?= . ; - STDHDRS ?= decc$library_include ; - SUFEXE ?= .exe ; - SUFLIB ?= .olb ; - SUFOBJ ?= .obj ; - - switch $(OS) - { - case OPENVMS : CCFLAGS ?= /stand=vaxc ; - case VMS : LINKLIBS ?= sys$library:vaxcrtl.olb/lib ; - } -} -else if $(MAC) -{ - local OPT ; - - CW ?= "{CW}" ; - - MACHDRS ?= - "$(UMACHDRS):Universal:Interfaces:CIncludes" - "$(CW):MSL:MSL_C:MSL_Common:Include" - "$(CW):MSL:MSL_C:MSL_MacOS:Include" ; - - MACLIBS ?= - "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib" - "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib" ; - - MPWLIBS ?= - "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib" - "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW.Lib" ; - - MPWNLLIBS ?= - "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib" - "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW(NL).Lib" ; - - SIOUXHDRS ?= ; - - SIOUXLIBS ?= - "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_Runtime_PPC.lib" - "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_SIOUX_PPC.Lib" - "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC.Lib" ; - - C++ ?= mwcppc ; - C++FLAGS ?= -w off ; - CC ?= mwcppc ; - CCFLAGS ?= -w off ; - CP ?= duplicate -y ; - DOT ?= ":" ; - DOTDOT ?= "::" ; - HDRS ?= $(MACHDRS) $(MPWHDRS) ; - LINK ?= mwlinkppc ; - LINKFLAGS ?= -mpwtool -warn ; - LINKLIBS ?= $(MACLIBS) $(MPWLIBS) ; - MKDIR ?= newfolder ; - MV ?= rename -y ; - NOARSCAN ?= true ; - OPTIM ?= ; - RM ?= delete -y ; - SLASH ?= ":" ; - STDHDRS ?= ; - SUFLIB ?= .lib ; - SUFOBJ ?= .o ; -} -else if $(OS) = BEOS && $(OSPLAT) = PPC -{ - AR ?= mwld -xml -o ; - BINDIR ?= /boot/home/config/bin ; - CC ?= mwcc ; - CCFLAGS ?= -nosyspath ; - C++ ?= $(CC) ; - C++FLAGS ?= -nosyspath ; - CHMOD ?= chmod ; - CHGRP ?= chgrp ; - CHOWN ?= chown ; - FORTRAN ?= "" ; - LEX ?= flex ; - LIBDIR ?= /boot/home/config/lib ; - LINK ?= mwld ; - LINKFLAGS ?= "" ; - MANDIR ?= /boot/home/config/man ; - NOARSCAN ?= true ; - RANLIB ?= ranlib ; - STDHDRS ?= /boot/develop/headers/posix ; - YACC ?= bison -y ; - YACCGEN ?= .c ; - YACCFILES ?= y.tab ; - YACCFLAGS ?= -d ; -} -else if $(OS) = BEOS -{ - BINDIR ?= /boot/home/config/bin ; - CC ?= gcc ; - C++ ?= $(CC) ; - CHMOD ?= chmod ; - CHGRP ?= chgrp ; - CHOWN ?= chown ; - FORTRAN ?= "" ; - LEX ?= flex ; - LIBDIR ?= /boot/home/config/lib ; - LINK ?= gcc ; - MANDIR ?= /boot/home/config/man ; - NOARSCAN ?= true ; - RANLIB ?= ranlib ; - STDHDRS ?= /boot/develop/headers/posix ; - YACC ?= bison -y ; - YACCGEN ?= .c ; - YACCFILES ?= y.tab ; - YACCFLAGS ?= -d ; -} -else if $(UNIX) -{ - switch $(OS) - { - case AIX : - LINKLIBS ?= -lbsd ; - - case AMIGA : - CC ?= gcc ; - YACC ?= bison -y ; - - case CYGWIN : - CC ?= gcc ; - CCFLAGS += -D__cygwin__ ; - LEX ?= flex ; - JAMSHELL ?= sh -c ; - RANLIB ?= "" ; - SUFEXE ?= .exe ; - YACC ?= bison -y ; - - case DGUX : - RANLIB ?= "" ; - RELOCATE ?= true ; - - case HPUX : - RANLIB ?= "" ; - - case INTERIX : - CC ?= gcc ; - JAMSHELL ?= sh -c ; - RANLIB ?= "" ; - - case IRIX : - RANLIB ?= "" ; - - case MPEIX : - CC ?= gcc ; - C++ ?= gcc ; - CCFLAGS += -D_POSIX_SOURCE ; - HDRS += /usr/include ; - RANLIB ?= "" ; - NOARSCAN ?= true ; - NOARUPDATE ?= true ; - - case MVS : - RANLIB ?= "" ; - - case NEXT : - AR ?= libtool -o ; - RANLIB ?= "" ; - - case MACOSX : - C++ ?= c++ ; - MANDIR ?= /usr/local/share/man ; - - case NCR : - RANLIB ?= "" ; - - case PTX : - RANLIB ?= "" ; - - case QNX : - AR ?= wlib ; - CC ?= cc ; - CCFLAGS ?= -Q ; # quiet - C++ ?= $(CC) ; - C++FLAGS ?= -Q ; # quiet - LINK ?= $(CC) ; - LINKFLAGS ?= -Q ; # quiet - NOARSCAN ?= true ; - RANLIB ?= "" ; - - case SCO : - RANLIB ?= "" ; - RELOCATE ?= true ; - - case SINIX : - RANLIB ?= "" ; - - case SOLARIS : - RANLIB ?= "" ; - AR ?= "/usr/ccs/bin/ar ru" ; - - case UNICOS : - NOARSCAN ?= true ; - OPTIM ?= -O0 ; - - case UNIXWARE : - RANLIB ?= "" ; - RELOCATE ?= true ; - } - - # UNIX defaults - - CCFLAGS ?= ; - C++FLAGS ?= $(CCFLAGS) ; - CHMOD ?= chmod ; - CHGRP ?= chgrp ; - CHOWN ?= chown ; - LEX ?= lex ; - LINKFLAGS ?= $(CCFLAGS) ; - LINKLIBS ?= ; - OPTIM ?= -O ; - RANLIB ?= ranlib ; - YACC ?= yacc ; - YACCGEN ?= .c ; - YACCFILES ?= y.tab ; - YACCFLAGS ?= -d ; -} - -# -# General defaults; a lot like UNIX -# - - AR ?= ar ru ; - AS ?= as ; - ASFLAGS ?= ; - AWK ?= awk ; - BINDIR ?= /usr/local/bin ; - C++ ?= cc ; - C++FLAGS ?= ; - CC ?= cc ; - CCFLAGS ?= ; - CP ?= cp -f ; - CRELIB ?= ; - DOT ?= . ; - DOTDOT ?= .. ; - EXEMODE ?= 711 ; - FILEMODE ?= 644 ; - FORTRAN ?= f77 ; - FORTRANFLAGS ?= ; - HDRS ?= ; - INSTALLGRIST ?= installed ; - JAMFILE ?= Jamfile ; - JAMRULES ?= Jamrules ; - LEX ?= ; - LIBDIR ?= /usr/local/lib ; - LINK ?= $(CC) ; - LINKFLAGS ?= ; - LINKLIBS ?= ; - LN ?= ln ; - MANDIR ?= /usr/local/man ; - MKDIR ?= mkdir ; - MV ?= mv -f ; - OPTIM ?= ; - RCP ?= rcp ; - RM ?= rm -f ; - RMDIR ?= $(RM) ; - RSH ?= rsh ; - SED ?= sed ; - SHELLHEADER ?= "#!/bin/sh" ; - SHELLMODE ?= 755 ; - SLASH ?= / ; - STDHDRS ?= /usr/include ; - SUBDIRRULES ?= ; - SUBDIRRESET ?= ASFLAGS HDRS C++FLAGS CCFLAGS ; - SUFEXE ?= "" ; - SUFLIB ?= .a ; - SUFOBJ ?= .o ; - UNDEFFLAG ?= "-u _" ; - YACC ?= ; - YACCGEN ?= ; - YACCFILES ?= ; - YACCFLAGS ?= ; - - HDRPATTERN = - "^[ ]*#[ ]*include[ ]*[<\"]([^\">]*)[\">].*$" ; - - OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ; - - -# -# Base dependencies - first for "bootstrap" kinds of rules -# - -Depends all : shell files lib exe obj ; -Depends all shell files lib exe obj : first ; -NotFile all first shell files lib exe obj dirs clean uninstall ; -Always clean uninstall ; - -# -# Rules -# - -rule As -{ - Depends $(<) : $(>) ; - ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ; - ASHDRS on $(<) = [ FIncludes $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ; -} - -rule Bulk -{ - local i ; - - for i in $(>) - { - File $(i:D=$(<)) : $(i) ; - } -} - -rule Cc -{ - Depends $(<) : $(>) ; - - # If the compiler's -o flag doesn't work, relocate the .o - - if $(RELOCATE) - { - CcMv $(<) : $(>) ; - } - - # Just to clarify here: this sets the per-target CCFLAGS to - # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS. - # CCHDRS and CCDEFS must be reformatted each time for some - # compiles (VMS, NT) that malign multiple -D or -I flags. - - CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) $(OPTIM) ; - - CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ; - CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ; -} - -rule C++ -{ - Depends $(<) : $(>) ; - - if $(RELOCATE) - { - CcMv $(<) : $(>) ; - } - - C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) $(OPTIM) ; - - CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ; - CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ; -} - -rule Chmod -{ - if $(CHMOD) { Chmod1 $(<) ; } -} - -rule File -{ - Depends files : $(<) ; - Depends $(<) : $(>) ; - SEARCH on $(>) = $(SEARCH_SOURCE) ; - MODE on $(<) = $(FILEMODE) ; - Chmod $(<) ; -} - -rule Fortran -{ - Depends $(<) : $(>) ; -} - -rule GenFile -{ - local _t = [ FGristSourceFiles $(<) ] ; - local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ; - Depends $(_t) : $(_s) $(>[2-]) ; - GenFile1 $(_t) : $(_s) $(>[2-]) ; - Clean clean : $(_t) ; -} - -rule GenFile1 -{ - MakeLocate $(<) : $(LOCATE_SOURCE) ; - SEARCH on $(>) = $(SEARCH_SOURCE) ; -} - -rule HardLink -{ - Depends files : $(<) ; - Depends $(<) : $(>) ; - SEARCH on $(>) = $(SEARCH_SOURCE) ; -} - -rule HdrRule -{ - # HdrRule source : headers ; - - # N.B. This rule is called during binding, potentially after - # the fate of many targets has been determined, and must be - # used with caution: don't add dependencies to unrelated - # targets, and don't set variables on $(<). - - # Tell Jam that anything depending on $(<) also depends on $(>), - # set SEARCH so Jam can find the headers, but then say we don't - # care if we can't actually find the headers (they may have been - # within ifdefs), - - local s = $(>:G=$(HDRGRIST:E)) ; - - Includes $(<) : $(s) ; - SEARCH on $(s) = $(HDRSEARCH) ; - NoCare $(s) ; - - # Propagate on $(<) to $(>) - - HDRSEARCH on $(s) = $(HDRSEARCH) ; - HDRSCAN on $(s) = $(HDRSCAN) ; - HDRRULE on $(s) = $(HDRRULE) ; - HDRGRIST on $(s) = $(HDRGRIST) ; -} - -rule InstallInto -{ - # InstallInto dir : sources ; - - local i t ; - - t = $(>:G=$(INSTALLGRIST)) ; - - # Arrange for jam install - # Arrange for jam uninstall - # sources are in SEARCH_SOURCE - # targets are in dir - - Depends install : $(t) ; - Clean uninstall : $(t) ; - SEARCH on $(>) = $(SEARCH_SOURCE) ; - MakeLocate $(t) : $(<) ; - - # For each source, make gristed target name - # and Install, Chmod, Chown, and Chgrp - - for i in $(>) - { - local tt = $(i:G=$(INSTALLGRIST)) ; - - Depends $(tt) : $(i) ; - Install $(tt) : $(i) ; - Chmod $(tt) ; - - if $(OWNER) && $(CHOWN) - { - Chown $(tt) ; - OWNER on $(tt) = $(OWNER) ; - } - - if $(GROUP) && $(CHGRP) - { - Chgrp $(tt) ; - GROUP on $(tt) = $(GROUP) ; - } - } -} - -rule InstallBin -{ - local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ; - - InstallInto $(<) : $(_t) ; - MODE on $(_t:G=$(INSTALLGRIST)) = $(EXEMODE) ; -} - -rule InstallFile -{ - InstallInto $(<) : $(>) ; - MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ; -} - -rule InstallLib -{ - InstallInto $(<) : $(>) ; - MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ; -} - -rule InstallMan -{ - # Really this just strips the . from the suffix - - local i s d ; - - for i in $(>) - { - switch $(i:S) - { - case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ; - case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ; - case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ; - case .n : s = n ; case .man : s = 1 ; - } - - d = man$(s) ; - - InstallInto $(d:R=$(<)) : $(i) ; - } - - MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ; -} - -rule InstallShell -{ - InstallInto $(<) : $(>) ; - MODE on $(>:G=$(INSTALLGRIST)) = $(SHELLMODE) ; -} - -rule Lex -{ - LexMv $(<) : $(>) ; - Depends $(<) : $(>) ; - MakeLocate $(<) : $(LOCATE_SOURCE) ; - Clean clean : $(<) ; -} - -rule Library -{ - LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ; - Objects $(>) ; -} - -rule LibraryFromObjects -{ - local _i _l _s ; - - # Add grist to file names - - _s = [ FGristFiles $(>) ] ; - _l = $(<:S=$(SUFLIB)) ; - - # library depends on its member objects - - if $(KEEPOBJS) - { - Depends obj : $(_s) ; - } - else - { - Depends lib : $(_l) ; - } - - # Set LOCATE for the library and its contents. The bound - # value shows up as $(NEEDLIBS) on the Link actions. - # For compatibility, we only do this if the library doesn't - # already have a path. - - if ! $(_l:D) - { - MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ; - } - - if $(NOARSCAN) - { - # If we can't scan the library to timestamp its contents, - # we have to just make the library depend directly on the - # on-disk object files. - - Depends $(_l) : $(_s) ; - } - else - { - # If we can scan the library, we make the library depend - # on its members and each member depend on the on-disk - # object file. - - Depends $(_l) : $(_l)($(_s:BS)) ; - - for _i in $(_s) - { - Depends $(_l)($(_i:BS)) : $(_i) ; - } - } - - Clean clean : $(_l) ; - - if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; } - - Archive $(_l) : $(_s) ; - - if $(RANLIB) { Ranlib $(_l) ; } - - # If we can't scan the library, we have to leave the .o's around. - - if ! ( $(NOARSCAN) || $(NOARUPDATE) ) { RmTemps $(_l) : $(_s) ; } -} - -rule Link -{ - MODE on $(<) = $(EXEMODE) ; - Chmod $(<) ; -} - -rule LinkLibraries -{ - # make library dependencies of target - # set NEEDLIBS variable used by 'actions Main' - - local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ; - - Depends $(_t) : $(>:S=$(SUFLIB)) ; - NEEDLIBS on $(_t) += $(>:S=$(SUFLIB)) ; -} - -rule Main -{ - MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ; - Objects $(>) ; -} - -rule MainFromObjects -{ - local _s _t ; - - # Add grist to file names - # Add suffix to exe - - _s = [ FGristFiles $(>) ] ; - _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ; - - # so 'jam foo' works when it's really foo.exe - - if $(_t) != $(<) - { - Depends $(<) : $(_t) ; - NotFile $(<) ; - } - - # make compiled sources a dependency of target - - Depends exe : $(_t) ; - Depends $(_t) : $(_s) ; - MakeLocate $(_t) : $(LOCATE_TARGET) ; - - Clean clean : $(_t) ; - - Link $(_t) : $(_s) ; -} - -rule MakeLocate -{ - # MakeLocate targets : directory ; - - # Sets special variable LOCATE on targets, and arranges - # with MkDir to create target directory. - - # Note we grist the directory name with 'dir', - # so that directory path components and other - # targets don't conflict. - - if $(>) - { - LOCATE on $(<) = $(>) ; - Depends $(<) : $(>[1]:G=dir) ; - MkDir $(>[1]:G=dir) ; - } -} - -rule MkDir -{ - # MkDir directory ; - - # Make a directory and all its parent directories. - - # Ignore timestamps on directories: we only care if they - # exist. - - NoUpdate $(<) ; - - # Don't create . or any directory already created. - - if $(<:G=) != $(DOT) && ! $($(<)-mkdir) - { - # Cheesy gate to prevent multiple invocations on same dir - # Arrange for jam dirs - # MkDir1 has the actions - - $(<)-mkdir = true ; - Depends dirs : $(<) ; - MkDir1 $(<) ; - - # Recursively make parent directories. - # $(<:P) = $(<)'s parent, & we recurse until root - - local s = $(<:P) ; - - # Don't try to create A: or A:\ on windows - - if $(NT) - { - switch $(s) - { - case *: : s = ; - case *:\\ : s = ; - } - } - - if $(s) = $(<) - { - # The parent is the same as the dir. - # We're at the root, which some OS's can't stat, so we mark - # it as NotFile. - - NotFile $(s) ; - } - else if $(s:G=) - { - # There's a parent; recurse. - - Depends $(<) : $(s) ; - MkDir $(s) ; - } - } -} - -rule Object -{ - # locate object and search for source, if wanted - - Clean clean : $(<) ; - - MakeLocate $(<) : $(LOCATE_TARGET) ; - SEARCH on $(>) = $(SEARCH_SOURCE) ; - - # Save HDRS for -I$(HDRS) on compile. - # We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers - # in the .c file's directory, but generated .c files (from - # yacc, lex, etc) are located in $(LOCATE_TARGET), possibly - # different from $(SEARCH_SOURCE). - - HDRS on $(<) = $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ; - - # handle #includes for source: Jam scans for headers with - # the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE) - # with the scanned file as the target and the found headers - # as the sources. HDRSEARCH is the value of SEARCH used for - # the found header files. Finally, if jam must deal with - # header files of the same name in different directories, - # they can be distinguished with HDRGRIST. - - # $(SEARCH_SOURCE:E) is where cc first looks for #include - # "foo.h" files. If the source file is in a distant directory, - # look there. Else, look in "" (the current directory). - - HDRRULE on $(>) = HdrRule ; - HDRSCAN on $(>) = $(HDRPATTERN) ; - HDRSEARCH on $(>) = - $(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HDRS) $(STDHDRS) ; - - HDRGRIST on $(>) = $(HDRGRIST) ; - - # propagate target specific-defines - - DEFINES on $(<) += $(DEFINES) ; - - # if source is not .c, generate .c with specific rule - - switch $(>:S) - { - case .asm : As $(<) : $(>) ; - case .c : Cc $(<) : $(>) ; - case .C : C++ $(<) : $(>) ; - case .cc : C++ $(<) : $(>) ; - case .cpp : C++ $(<) : $(>) ; - case .f : Fortran $(<) : $(>) ; - case .l : Cc $(<) : $(<:S=.c) ; - Lex $(<:S=.c) : $(>) ; - case .s : As $(<) : $(>) ; - case .y : Cc $(<) : $(<:S=$(YACCGEN)) ; - Yacc $(<:S=$(YACCGEN)) : $(>) ; - case * : UserObject $(<) : $(>) ; - } -} - -rule ObjectCcFlags -{ - CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ; -} - -rule ObjectC++Flags -{ - C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ; -} - -rule ObjectDefines -{ - # must reformat CCDEFS according to current defines - - local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ; - - DEFINES on $(s) += $(>) ; - CCDEFS on $(s) = [ on $(s) FDefines $(DEFINES) ] ; -} - -rule ObjectHdrs -{ - # Add to HDRS for HdrScan's benefit. - # must reformat CCHDRS according to headers - - local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ; - - HDRS on $(s) += $(>) ; - CCHDRS on $(s) = [ on $(s) FIncludes $(HDRS) ] ; -} - -rule Objects -{ - local _i ; - - for _i in [ FGristFiles $(<) ] - { - Object $(_i:S=$(SUFOBJ)) : $(_i) ; - Depends obj : $(_i:S=$(SUFOBJ)) ; - } -} - -rule RmTemps -{ - Temporary $(>) ; -} - -rule Setuid -{ - MODE on [ FAppendSuffix $(<) : $(SUFEXE) ] = 4711 ; -} - -rule Shell -{ - Depends shell : $(<) ; - Depends $(<) : $(>) ; - SEARCH on $(>) = $(SEARCH_SOURCE) ; - MODE on $(<) = $(SHELLMODE) ; - Clean clean : $(<) ; - Chmod $(<) ; -} - -rule SoftLink -{ - Depends files : $(<) ; - Depends $(<) : $(>) ; - SEARCH on $(>) = $(SEARCH_SOURCE) ; - Clean clean : $(<) ; -} - -rule SubDir -{ - # - # SubDir TOP d1 d2 ... ; - # - # Support for a project tree spanning multiple directories. - # - # SubDir declares a Jamfile's location in a project tree, setting - # Jambase variables (SEARCH_SOURCE, LOCATE_TARGET) so that source - # files can be found. - # - # TOP is a user-select variable name for root of the tree, and - # d1 d2 ... are the directory elements that lead from the root - # of the tree to the directory of the Jamfile. - # - # TOP can be set externally, but normally the first SubDir call - # computes TOP as the path up from the current directory; the - # path contains one ../ for each of d1 d2 ... - # - # SubDir reads once the project-specific rules file Jamrules - # in the TOP directory, if present. This can be overridden - # with the variable TOPRULES. - # - # SubDir supports multiple, overlaid project trees: SubDir - # invocations with different TOPs can appear in the same Jamfile. - # The location established by the first SubDir call is used set - # the TOPs for the subsequent SubDir calls. - # - # SubDir's public variables: - # - # $(TOP) = path from CWD to root. - # $(SUBDIR) = path from CWD to the directory SubDir names. - # $(SUBDIR_TOKENS) = path from $(TOP) to $(SUBDIR) as dir names - # $(SEARCH_SOURCE) = $(SUBDIR) - # $(LOCATE_SOURCE) = $(ALL_LOCATE_TARGET) $(SUBDIR) - # $(LOCATE_TARGET) = $(ALL_LOCATE_TARGET) $(SUBDIR) - # $(SOURCE_GRIST) = $(SUBDIR_TOKENS) with !'s - # - - local _top = $(<[1]) ; - local _tokens = $(<[2-]) ; - - # - # First time through sets up relative root and includes Jamrules. - # - - if ! $(_top) - { - Exit SubDir syntax error ; - } - - if ! $($(_top)-SET) - { - $(_top)-SET = true ; - - # First time we've seen this TOP. - # We'll initialize a number of internal variables: - # - # $(TOP-UP) = directories from ROOT to a common point - # $(TOP-DOWN) = directories from common point to TOP - # $(TOP-ROOT) = root directory for UP/DOWN -- normally CWD - # $(SUBDIR_UP) = current value of $(TOP-UP) - # $(SUBDIR_DOWN) = current value of $(TOP-DOWN) - # $(SUBDIR_ROOT) = current value of $(TOP-ROOT) - # - - if $($(_top)) - { - # TOP externally set. - # We'll ignore the relative (UP/DOWN) path that - # got us here, and instead remember the hard ROOT. - - $(_top)-UP = ; - $(_top)-DOWN = ; - $(_top)-ROOT = $($(_top)) ; - } - else - { - # TOP not preset. - - # Establishing a new TOP. In the simplest case, - # (SUBDIR_UP/SUBDIR_DOWN/SUBDIR_ROOT unset), it's - # merely a certain number of directories down from - # the current directory, and FSubDirPath will set - # TOP to a path consisting of ../ for each of the - # elements of _tokens, because that represents how - # far below TOP the current directory sits. - # - # In the more complicated case, the starting directory - # isn't the directory of jam's invocation but an - # location established by previous SubDir call. The - # starting directory is SUBDIR_UP directories up from - # SUBDIR_ROOT, and then SUBDIR_DOWN directories down - # from that. If SUBDIR_ROOT is not set, that means - # SUBDIR_DOWN and SUBDIR_UP represent the path from - # the directory of jam's invocation. - # - # In the most complicated case, the _tokens also - # represents directories down, because TOP is being - # estalished in a directory other than TOP's root. - # Hopefully, _tokens and SUBDIR_DOWN represent the - # same final directory, relative to the new TOP and - # the previous SubDIr's TOP. To find the new TOP, - # we have to chop off any common directories from - # then ends of _tokens and SUBDIR_DOWN. To do so, - # we reverse each of them, call FStripCommon to - # remove the initial common elements, and then - # reverse them again. After this process, if - # both _tokens and SUBDIR_DOWN have elements, it - # means the directory names estalished by the two - # SubDir calls don't match, and a warning is issued. - # All hell will likely break loose at this point, - # since the whole SubDir scheme relies on the SubDir - # calls accurately naming the current directory. - - # Strip common trailing elements of _tokens and SUBDIR_DOWN. - - _tokens = [ FReverse $(_tokens) ] ; - SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ; - FStripCommon _tokens : SUBDIR_DOWN ; - SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ; - _tokens = [ FReverse $(_tokens) ] ; - - if $(SUBDIR_DOWN) && $(_tokens) - { - Echo Warning: SubDir $(<) misplaced! ; - } - - # We'll remember the relative (UP/DOWN) path that - # got us here, plus any hard ROOT starting point - # for the UP/DOWN. If TOP is never set externally, - # ROOT will always be "" (directory of jam's invocation). - - $(_top)-UP = $(SUBDIR_UP) $(_tokens) ; - $(_top)-DOWN = $(SUBDIR_DOWN) ; - $(_top)-ROOT = $(SUBDIR_ROOT:E="") ; - $(_top) = [ FSubDirPath $(_top) ] ; - } - - # Set subdir vars for the inclusion of the Jamrules, - # just in case they have SubDir rules of their own. - # Note that SUBDIR_DOWN is empty: it's all the way - # up where the Jamrules live. These gets overrided - # just after the inclusion. - - SUBDIR_UP = $($(_top)-UP) ; - SUBDIR_DOWN = ; - SUBDIR_ROOT = $($(_top)-ROOT) ; - - # Include $(TOPRULES) or $(TOP)/Jamrules. - # Include $(TOPRULES) if set. - # Otherwise include $(TOP)/Jamrules if present. - - if $($(_top)RULES) { - include $($(_top)RULES) ; - } else { - NoCare $(JAMRULES:R=$($(_top)):G=$(_top)) ; - include $(JAMRULES:R=$($(_top)):G=$(_top)) ; - } - } - - # Get path from $(TOP) to named directory. - # Save dir tokens for other potential uses. - - SUBDIR_UP = $($(_top)-UP) ; - SUBDIR_DOWN = $($(_top)-DOWN) $(_tokens) ; - SUBDIR_ROOT = $($(_top)-ROOT) ; - SUBDIR_TOKENS = $(SUBDIR_DOWN) ; - - SUBDIR = [ FSubDirPath $(<) ] ; - - # Now set up SEARCH_SOURCE, LOCATE_TARGET, SOURCE_GRIST - # These can be reset if needed. For example, if the source - # directory should not hold object files, LOCATE_TARGET can - # subsequently be redefined. - - SEARCH_SOURCE = $(SUBDIR) ; - LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ; - LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ; - SOURCE_GRIST = [ FGrist $(SUBDIR_TOKENS) ] ; - - # Reset per-directory ccflags, hdrs, etc, - # listed in SUBDIRRESET. - # Note use of variable expanded assignment var - - SUBDIR$(SUBDIRRESET) = ; - - # Invoke user-specific SubDir extensions, - # rule names listed in SUBDIRRULES. - # Note use of variable expanded rule invocation - - $(SUBDIRRULES) $(<) ; -} - -rule FSubDirPath -{ - # FSubDirPath TOP d1 ... ; - - # Returns path to named directory. - - # If jam is invoked in a subdirectory of the TOP, then we - # need to prepend a ../ for every level we must climb up - # (TOP-UP), and then append the directory names we must - # climb down (TOP-DOWN), plus the named directories d1 ... - # If TOP was set externally, or computed from another TOP - # that was, we'll have to reroot the whole thing at TOP-ROOT. - - local _r = [ FRelPath $($(<[1])-UP) : $($(<[1])-DOWN) $(<[2-]) ] ; - - return $(_r:R=$($(<[1])-ROOT)) ; -} - -rule SubDirCcFlags -{ - SUBDIRCCFLAGS += $(<) ; -} - -rule SubDirC++Flags -{ - SUBDIRC++FLAGS += $(<) ; -} - -rule SubDirHdrs -{ - SUBDIRHDRS += [ FDirName $(<) ] ; -} - -rule SubInclude -{ - # SubInclude TOP d1 ... ; - # - # Include a subdirectory's Jamfile. - - # We use SubDir to get there, in case the included Jamfile - # either doesn't have its own SubDir (naughty) or is a subtree - # with its own TOP. - - if ! $($(<[1])) - { - Exit SubInclude $(<[1]) without prior SubDir $(<[1]) ; - } - - SubDir $(<) ; - - include $(JAMFILE:D=$(SUBDIR)) ; -} - -rule SubRules -{ - # SubRules TOP d1 ... : Other-TOP ; - # - # Read another tree's Jamrules, by giving it's path according - # to this tree and it's own name. - - if ! $($(<[1])) - { - Exit SubRules $(<[1]) without prior SubDir $(<[1]) ; - } - - SubDir $(<) ; - SubDir $(>) ; -} - -rule Undefines -{ - UNDEFS on [ FAppendSuffix $(<) : $(SUFEXE) ] += $(UNDEFFLAG)$(>) ; -} - -rule UserObject -{ - Exit "Unknown suffix on" $(>) "- see UserObject rule in Jamfile(5)." ; -} - -rule Yacc -{ - local _h ; - - _h = $(<:BS=.h) ; - - # Some places don't have a yacc. - - MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ; - - if $(YACC) - { - Depends $(<) $(_h) : $(>) ; - Yacc1 $(<) $(_h) : $(>) ; - YaccMv $(<) $(_h) : $(>) ; - Clean clean : $(<) $(_h) ; - } - - # make sure someone includes $(_h) else it will be - # a deadly independent target - - Includes $(<) : $(_h) ; -} - -# -# Utility rules; no side effects on these -# - -rule FGrist -{ - return $(<:J=!) ; - -} - -rule FGristFiles -{ - return $(<:G=$(SOURCE_GRIST:E)) ; -} - -rule FGristSourceFiles -{ - # Produce source file name name with grist in it, - # if SOURCE_GRIST is set. - - # Leave header files alone, because they have a global - # visibility. - - if ! $(SOURCE_GRIST) - { - return $(<) ; - } - else - { - local _i _o ; - - for _i in $(<) - { - switch $(_i) - { - case *.h : _o += $(_i) ; - case * : _o += $(_i:G=$(SOURCE_GRIST)) ; - } - } - - return $(_o) ; - } -} - -rule FReverse -{ - # FReverse a1 a2 a3 ... ; - # return ... a3 a2 a1 ; - - if $(1) { return [ FReverse $(1[2-]) ] $(1[1]) ; } -} - -rule FSubDir -{ - # If $(>) is the path to the current directory, compute the - # path (using ../../ etc) back to that root directory. - # Sets result in $(<) - - if ! $(<[1]) - { - return $(DOT) ; - } - else - { - local _i _d ; - - _d = $(DOTDOT) ; - - for _i in $(<[2-]) - { - _d = $(_d:R=$(DOTDOT)) ; - } - - return $(_d) ; - } -} - -rule FStripCommon -{ - # FStripCommon v1 : v2 ; - - # Strip common initial elements of variables v1 and v2. - # Modifies the variable values themselves. - - if $($(<)[1]) && $($(<)[1]) = $($(>)[1]) - { - $(<) = $($(<)[2-]) ; - $(>) = $($(>)[2-]) ; - FStripCommon $(<) : $(>) ; - } -} - -rule FRelPath -{ - local _l _r ; - - # first strip off common parts - - _l = $(<) ; - _r = $(>) ; - - FStripCommon _l : _r ; - - # now make path to root and path down - - _l = [ FSubDir $(_l) ] ; - _r = [ FDirName $(_r) ] ; - - # Concatenate and save - - # XXX This should be better - - if $(_r) = $(DOT) { - return $(_l) ; - } else { - return $(_r:R=$(_l)) ; - } -} - -rule FAppendSuffix -{ - # E.g., "FAppendSuffix yacc lex foo.bat : $(SUFEXE) ;" - # returns (yacc,lex,foo.bat) on Unix and - # (yacc.exe,lex.exe,foo.bat) on NT. - - if $(>) - { - local _i _o ; - - for _i in $(<) - { - if $(_i:S) - { - _o += $(_i) ; - } - else - { - _o += $(_i:S=$(>)) ; - } - } - return $(_o) ; - } - else - { - return $(<) ; - } -} - -# -# Operating system specific utility rules -# First, the (generic) UNIX versions -# - -rule FQuote { return \\\"$(<)\\\" ; } -rule FDefines { return -D$(<) ; } -rule FIncludes { return -I$(<) ; } - -rule FDirName -{ - # Turn individual elements in $(<) into a usable path. - - local _i ; - local _s = $(DOT) ; - - for _i in $(<) - { - _s = $(_i:R=$(_s)) ; - } - - return $(_s) ; -} - -if $(OS2) -{ - rule FQuote { return \"$(<)\" ; } - rule FIncludes { return /I$(<) ; } -} - -else if $(NT) -{ - rule FDefines { return /D$(<) ; } - rule FIncludes { return /I$(<) ; } -} - -else if $(MAC) -{ - rule FQuote { return \"$(<)\" ; } - rule FDefines { return "-define '$(<)'" ; } - rule FIncludes { return \"$(<:J=,)\" ; } -} - -else if $(VMS) -{ - rule FQuote { return \"\"\"$(<)\"\"\" ; } - rule FDefines { return "/define=( $(<:J=,) )" ; } - rule FIncludes { return "/inc=( $(<:J=,) )" ; } - - rule FDirName - { - local _s _i ; - - # Turn individual elements in $(<) into a usable path. - - if ! $(<) - { - _s = $(DOT) ; - } - else - { - # This handles the following cases: - # a -> [.a] - # a b c -> [.a.b.c] - # x: -> x: - # x: a -> x:[a] - # x:[a] b -> x:[a.b] - - switch $(<[1]) - { - case *:* : _s = $(<[1]) ; - case \\[*\\] : _s = $(<[1]) ; - case * : _s = [.$(<[1])] ; - } - - for _i in [.$(<[2-])] - { - _s = $(_i:R=$(_s)) ; - } - } - - return $(_s) ; - } -} - -# -# Actions -# - -# -# First the defaults -# - -actions updated together piecemeal Archive -{ - $(AR) $(<) $(>) -} - -actions As -{ - $(AS) $(ASFLAGS) $(ASHDRS) -o $(<) $(>) -} - -actions C++ -{ - $(C++) -c -o $(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>) -} - -actions Cc -{ - $(CC) -c -o $(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) -} - -actions Chgrp -{ - $(CHGRP) $(GROUP) $(<) -} - -actions Chmod1 -{ - $(CHMOD) $(MODE) $(<) -} - -actions Chown -{ - $(CHOWN) $(OWNER) $(<) -} - -actions piecemeal together existing Clean -{ - $(RM) $(>) -} - -actions File -{ - $(CP) $(>) $(<) -} - -actions GenFile1 -{ - $(>[1]) $(<) $(>[2-]) -} - -actions Fortran -{ - $(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>) -} - -actions HardLink -{ - $(RM) $(<) && $(LN) $(>) $(<) -} - -actions Install -{ - $(CP) $(>) $(<) -} - -actions Lex -{ - $(LEX) $(>) -} - -actions LexMv -{ - $(MV) lex.yy.c $(<) -} - -actions Link bind NEEDLIBS -{ - $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) -} - -actions MkDir1 -{ - $(MKDIR) $(<) -} - -actions together Ranlib -{ - $(RANLIB) $(<) -} - -actions quietly updated piecemeal together RmTemps -{ - $(RM) $(>) -} - -actions Shell -{ - $(AWK) ' - NR == 1 { print "$(SHELLHEADER)" } - NR == 1 && /^[#:]/ { next } - /^##/ { next } - { print } - ' < $(>) > $(<) -} - -actions SoftLink -{ - $(RM) $(<) && $(LN) -s $(>) $(<) -} - -actions Yacc1 -{ - $(YACC) $(YACCFLAGS) $(>) -} - -actions YaccMv -{ - $(MV) $(YACCFILES).c $(<[1]) - $(MV) $(YACCFILES).h $(<[2]) -} - -# -# RELOCATE - for compilers with broken -o flags -# - -if $(RELOCATE) -{ - actions C++ - { - $(C++) -c $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>) - } - - actions Cc - { - $(CC) -c $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) - } - - actions ignore CcMv - { - [ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<) - } -} - -# -# NOARUPDATE - can't update an archive -# - -if $(NOARUPDATE) -{ - actions Archive - { - $(AR) $(<) $(>) - } -} - -# -# UNIX specific actions -# - -if $(UNIX) -{ - actions GenFile1 - { - PATH="$PATH:." - $(>[1]) $(<) $(>[2-]) - } -} - -# -# NT specific actions -# - -if $(NT) && $(MSVCNT) -{ - actions updated together piecemeal Archive - { - if exist $(<) set _$(<:B)_=$(<) - $(AR) /out:$(<) %_$(<:B)_% $(>) - } - - actions As - { - $(AS) /Ml /p /v /w2 $(>) $(<) ,nul,nul; - } - - actions Cc - { - $(CC) /c /Fo$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) $(>) - } - - actions C++ - { - $(C++) /c /Fo$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) /Tp$(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) - } -} -else if $(NT) && $(MSVC) -{ - actions updated together piecemeal Archive - { - $(AR) $(<) -+$(>) - } - - actions Cc - { - $(CC) /c /Fo$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) - } - - actions C++ - { - $(C++) /c /Fo$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) /Tp$(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) - } -} -else if $(NT) && $(BCCROOT) -{ - actions updated together piecemeal Archive - { - $(AR) $(<) -+$(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) -e$(<) $(LINKFLAGS) $(UNDEFS) -L$(LINKLIBS) $(NEEDLIBS) $(>) - } - - actions C++ - { - $(C++) -c -o$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>) - } - - actions Cc - { - $(CC) -c -o$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) - } -} - -# -# OS2 specific actions -# - -else if $(OS2) && $(WATCOM) -{ - actions together piecemeal Archive - { - $(AR) $(<) +-$(>) - } - - actions Cc - { - $(CC) /Fo=$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) - } - - actions C++ - { - $(C++) /Fo=$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) - } - - actions Shell - { - $(CP) $(>) $(<) - } -} - -# -# VMS specific actions -# - -else if $(VMS) -{ - actions updated together piecemeal Archive - { - lib/replace $(<) $(>[1]) ,$(>[2-]) - } - - actions Cc - { - $(CC)/obj=$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) - } - - actions C++ - { - $(C++)/obj=$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>) - } - - actions piecemeal together existing Clean - { - $(RM) $(>[1]);* ,$(>[2-]);* - } - - actions together quietly CreLib - { - if f$search("$(<)") .eqs. "" then lib/create $(<) - } - - actions GenFile1 - { - mcr $(>[1]) $(<) $(>[2-]) - } - - actions Link bind NEEDLIBS - { - $(LINK)/exe=$(<) $(LINKFLAGS) $(>:J=,) ,$(NEEDLIBS)/lib ,$(LINKLIBS) - } - - actions quietly updated piecemeal together RmTemps - { - $(RM) $(>[1]);* ,$(>[2-]);* - } - - actions Shell - { - $(CP) $(>) $(<) - } -} - -# -# Mac specifc actions -# - -else if $(MAC) -{ - actions together Archive - { - $(LINK) -library -o $(<) $(>) - } - - actions Cc - { - set -e MWCincludes $(CCHDRS) - $(CC) -o $(<) $(CCFLAGS) $(CCDEFS) $(>) - } - - actions C++ - { - set -e MWCincludes $(CCHDRS) - $(CC) -o $(<) $(C++FLAGS) $(CCDEFS) $(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) -o $(<) $(LINKFLAGS) $(>) $(NEEDLIBS) "$(LINKLIBS)" - } -} - -if $(WIN98) -{ - actions existing Clean - { - del $(>) - } -} - -# -# Backwards compatibility with jam 1, where rules were uppercased. -# - -rule BULK { Bulk $(<) : $(>) ; } -rule FILE { File $(<) : $(>) ; } -rule HDRRULE { HdrRule $(<) : $(>) ; } -rule INSTALL { Install $(<) : $(>) ; } -rule LIBRARY { Library $(<) : $(>) ; } -rule LIBS { LinkLibraries $(<) : $(>) ; } -rule LINK { Link $(<) : $(>) ; } -rule MAIN { Main $(<) : $(>) ; } -rule SETUID { Setuid $(<) ; } -rule SHELL { Shell $(<) : $(>) ; } -rule UNDEFINES { Undefines $(<) : $(>) ; } - -# Old INSTALL* didn't take dest directory. - -rule INSTALLBIN { InstallBin $(BINDIR) : $(<) ; } -rule INSTALLLIB { InstallLib $(LIBDIR) : $(<) ; } -rule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; } - -# Compatibility with jam 2.2. - -rule addDirName { $(<) += [ FDirName $(>) ] ; } -rule makeCommon { FStripCommon $(<) : $(>) ; } -rule _makeCommon { FStripCommon $(<) : $(>) ; } -rule makeDirName { $(<) = [ FDirName $(>) ] ; } -rule makeGrist { $(<) = [ FGrist $(>) ] ; } -rule makeGristedName { $(<) = [ FGristSourceFiles $(>) ] ; } -rule makeRelPath { $(<[1]) = [ FRelPath $(<[2-]) : $(>) ] ; } -rule makeString { $(<) = $(>:J) ; } -rule makeSubDir { $(<) = [ FSubDir $(>) ] ; } -rule makeSuffixed { $(<[1]) = [ FAppendSuffix $(>) : $(<[2]) ] ; } - -# -# Now include the user's Jamfile. -# - -include $(JAMFILE) ; diff --git a/jam-2.5/Jambase.html b/jam-2.5/Jambase.html deleted file mode 100644 index 4011a042e..000000000 --- a/jam-2.5/Jambase.html +++ /dev/null @@ -1,939 +0,0 @@ - - -Jambase Reference - - -

- -Jam - -

- -Jambase Reference - -

-
-

- Jambase is a base set of Jam rules which - provide roughly make(1)-like functionality for - jam, the Jam executable program. - This document, which started out as the Jambase(5) man page, - is a reference guide to the - rules, - pseudotargets, - and variables - defined in Jambase for use in Jamfiles. -

- For further information see: -

-

-Jam documentation and source are available from the -Perforce Public Depot. -For detailed information about any of the rules summarized below, -see the -Jambase -file itself. -


-

- -Jambase Rules - -

-

- As obj.o : source.s ; -

- Assemble the file source.s. Called by the Object - rule. -
- Bulk directory : sources ; -
- Copies sources into directory. -
- Cc object : source ; -
- Compile the file source into object, using the C - compiler $(CC), its flags $(CCFLAGS) and $(OPTIM), - and the header file directories $(HDRS). Called by - the Object rule. -
- C++ obj.o : source.cc ; -
- Compile the C++ source file source.cc. Called by - the Object rule. -
- Chmod target ; -
- (Unix and VMS only.) - Change file permissions on target to - target-specific $(MODE) value set by Link, File, - Install*, and Shell rules. -
- - Clean clean : targets ; -
- Removes existing targets when clean is built. - clean is not a dependency of all, and must be built - explicitly for targets to be removed. -
- FDefines defines ;
- Expands a list of definitions into a list of compiler - (or preprocessor) switches (such as - -Dsymbol=val on Unix) - to pass the definitions. -
- File target : source ; -
- Copies source into target. -
- FIncludes dirs ;
- Expands a list of directories into a list of compiler - (or preprocessor) switches (such as -Idir on Unix) - to add the directories to the header inclusion search path. -
- Fortran obj.o : source.f ; -
- Compile the Fortran source file source.f. Called - by the Object rule. -
- FQuote files ;
- Returns each of files suitably quoted so as to hide shell - metacharacters (such as whitespace and filename matching wildcards) - from the shell. -
-

- GenFile target : image sources ; -

- Runs the command "image target sources" - to create target from sources and - image. (where image is an - executable built by the Main rule.) -
- HardLink target : source ; -
- Makes target a hard link to source, if it isn't one - already. (Unix only.) -
- HdrRule source : headers ; -
- Arranges the proper dependencies when the file - source includes the files headers through the - "#include" C preprocessor directive. -

- This rule is not intended to be called explicitly. - It is called automatically during header scanning on - sources handled by the Object rule (e.g., sources in - Main or Library rules). -

- InstallBin dir : sources ;
- Copy sources into dir with mode - $(EXEMODE). -
- InstallLib dir : sources ;
- Copy sources into dir with mode - $(FILEMODE). -
- InstallMan dir : sources ;
- Copy sources into the appropriate subdirectory - of dir with mode $(FILEMODE). The subdirectory - is mans, where s is the suffix of - each of sources. -
- InstallShell dir : sources ;
- Copy sources into dir with mode - $(SHELLMODE). -
- Lex source.c : source.l ;
- Process the lex(1) source file source.l and - rename the lex.yy.c to source.c. Called by - the Object rule. -
- Library library : sources ;
- Compiles sources and archives them into - library. The intermediate objects - are deleted. Calls Objects and LibraryFromObjects. -

- If Library is invoked with no suffix on library, - the $(SUFLIB) suffix is used. -

- LibraryFromObjects library : objects ; -
- Archives objects into library. The - objects are then deleted. -

- If library has no suffix, the $(SUFLIB) suffix is used. -

- Link image : objects ; -
- Links image from objects and sets - permissions on image to $(EXEMODE). - Image must be actual filename; suffix is not - supplied. - Called by Main. - -
- LinkLibraries image : libraries ; -
- Makes image depend on libraries and - includes them during the linking. -

- Image may be referenced without a suffix in this - rule invocation; LinkLibraries supplies the suffix. -

- Main image : sources ; -
- Compiles sources and links them into image. - Calls Objects and MainFromObjects. -

- Image may be referenced without a suffix in this - rule invocation; Main supplies the suffix. -

- MainFromObjects image : objects ; -
- Links objects into image. Dependency - of exe. MainFromObjects supplies the suffix on image - filename. -
- MakeLocate target : dir ; -
- Creates dir and causes target to be built - into dir. -
- MkDir dir ; -
- Creates dir and its parent directories. -
- Object object : source ; -
- Compiles a single source file source into - object. The Main and Library rules use - this rule to compile source files. -

- Causes source to be scanned for "#include" - directives and calls HdrRule to make all included - files dependedencies of object. -

- Calls one of the following rules to do the actual - compiling, depending on the suffix of source: -

-		     *.c:   Cc 
-		     *.cc:  C++ 
-		     *.cpp: C++
-		     *.C:   C++ 
-		     *.l:   Lex 
-		     *.y:   Yacc
-		     *.*:   UserObject
-
-
- ObjectC++Flags source : flags ; -
- ObjectCcFlags source : flags ; -
- Add flags to the source-specific - value of $(CCFLAGS) or $(C++FLAGS) when compiling source. - Any file suffix on source is ignored. -
- ObjectDefines object : defines ;
- Adds preprocessor symbol definitions to the (gristed) - target-specific $(CCDEFS) for the object. -
- ObjectHdrs source : dirs ;
- Add dirs to the source-specific value of - $(HDRS) when scanning and compiling source. - Any file suffix on source is ignored. -
- Objects sources ;
- For each source file in sources, calls - Object to compile the source file into a similarly - named object file. -
- RmTemps targets : sources ;
- Marks sources as temporary with the TEMPORARY - rule, and deletes sources once targets - are built. Must be the last rule invoked on - targets. Used internally by LibraryFromObjects rule. -
- Setuid images ;
- Sets the setuid bit on each of images after - linking. (Unix only.) - -
- SoftLink target : source ; -
- Makes target a symbolic link to source, if it isn't one - already. (Unix only.) -
- SubDir TOP d1 ... dn ; -
- Sets up housekeeping for the source files located - in $(TOP)/d1/.../dn: - -

- TOP is the name of a variable; - d1 thru dn are elements - of a directory path. -

- SubDirC++Flags flags ; -
- SubDirCcFlags flags ; -
- Adds flags to the compiler flags for source files - in SubDir's directory. -
- SubDirHdrs d1 ... dn ; -
- Adds the path d1/.../dn/ to the header search paths for - source files in SubDir's directory. d1 through dn - are elements of a directory path. -
- SubInclude VAR d1 ... dn ; -
- Reads the Jamfile in $(VAR)/d1/.../dn/. -
- Shell image : source ;
- Copies source into the executable sh(1) - script image. Ensures that the first line of - the script is $(SHELLHEADER) (default #!/bin/sh). -
- Undefines images : symbols ;
- Adds flags to mark symbols as undefined - on link command for images. - Images may be referenced unsuffixed; the - Undefines rule supplies the suffix. -
- UserObject object : source ;
- This rule is called by Object for source - files with unknown suffixes, and should be defined - in Jamrules - with a user-provided rule to handle the source file - types not handled by the Object rule. - The Jambase UserObject rule merely issues a - complaint when it encounters source with - files suffixes it does not recognize. -
- Yacc source.c : source.y ;
- Process the yacc(1) file source.y and renamed - the resulting y.tab.c and y.tab.h to source.c. - Produces a y.tab.h and renames it to source.h. - Called by the Object rule. -
-

-


- -

-Jambase Pseudotargets -

-
-

-There are two kinds of Jam targets: file targets and pseudotargets. -File targets are objects that can be found in the filesystem. -Pseudotargets are symbolic, and usually represent other targets. -Most Jambase rules that define file targets also define pseudotargets -which are dependent on types of file targets. The Jambase pseudotargets -are: -

- -
exe - Executables linked by the Main or MainFromObjects rules - -
lib - Libraries created by the Library or LibraryFromObjects rules - -
obj - Compiled objects used to create Main or Library targets - -
dirs - Directories where target files are written - -
file - Files copied by File and Bulk rules - -
shell - Files copied by Shell rule - -
clean - Removal of built targets (except files copied by Install* rules) - -
install - Files copied by Install* rules - -
uninstall - Removal of targets copied by Install* rules - -
-
-

-In addition, Jambase makes the jam default target "all" -depend on "exe", "lib", "obj", "files", and "shell". -

- -


- -

-Jambase Variables -

-
-

- Most of the following variables have default values for - each platform; refer to the Jambase file to see what those - defaults are. -

- ALL_LOCATE_TARGET -

- Alternative location of built targets. By default, - Jambase rules locate built targets in the source - tree. By setting $(ALL_LOCATE_TARGET) - in Jamrules, you can cause jam - to write built targets to a location outside - the source tree. -
- - AR - -
- The archive command used to update Library - and LibraryFromObjects targets. -
- AS -
- The assembler for As rule targets. -
- - ASFLAGS - -
- Flags handed to the assembler for As. -
- - AWK - -
- The name of awk interpreter, used when copying a - shell script for the Shell rule. -
- - BCCROOT -
- Selects Borland compile and link actions on NT. -
- - - BINDIR - -
- Not longer used. - (I.e., used only for backward compatibility with the - obsolete INSTALLBIN rule.) -
- - CC - -
- C compiler used for Cc rule targets. -
- - CCFLAGS - -
- Compile flags for Cc rule targets. - The Cc rule sets target-specific $(CCFLAGS) - values on its targets. -
- - C++ - -
- C++ compiler used for C++ rule targets. -
- - C++FLAGS - -
- Compile flags for C++ rule targets. - The C++ rule sets target-specific $(C++FLAGS) - values on its targets. -
- - CHMOD - -
- Program (usually chmod(1)) used to set file - permissions for Chmod rule. -
- - CP - -
- The file copy program, used by File and Install* rules. -
- - CRELIB - -
- If set, causes the Library rule to invoke the CreLib - rule on the target library before attempting to archive - any members, so that the library can be created if - needed. -
- - CW - -
- On Macintosh, the root of the Code Warrior Pro 5 directory. -
- - DEFINES - -
- Preprocessor symbol definitions for Cc and C++ rule targets. - The Cc and C++ rules set target-specific $(CCDEFS) - values on their targets, based on $(DEFINES). (The - "indirection" here is required to support compilers, - like VMS, with baroque command line syntax for - setting symbols). -
- - DOT - -
- The operating system-specific name for the current directory. -
- - DOTDOT - -
- The operating system-specific name for the parent directory. -
- - EXEMODE - -
- Permissions for executables linked with Link, Main, - and MainFromObjects, on platforms with a Chmod action. -
- - FILEMODE - -
- Permissions for files copied by File or Bulk, - on platforms with a Chmod action. -
- - FORTRAN - -
- The Fortran compiler used by Fortran rule. -
- - FORTRANFLAGS - -
- Fortran compiler flags for Fortran rule targets. -
- - GROUP - -
- (Unix only.) - The group owner for Install* rule targets. -
- - HDRGRIST - -
- If set, used by the HdrRule to distinguish header files - with the same name in diffrent directories. -
- - HDRPATTERN - -
- A regular expression pattern that matches - C preprocessor "#include" directives in source files - and returns the name of the included file. -
- - HDRRULE - -
- Name of the rule to invoke with the results of header file - scanning. Default is "HdrRule". -

- This is a jam-special variable. If both HDRRULE and HDRSCAN - are set on a target, - that target will be scanned for lines - matching $(HDRSCAN), and $(HDDRULE) will be - invoked on included files found in the matching $(HDRSCAN) lines. -

- - HDRS - -
- Directories to be searched for header files. - This is used by the Object rule to: - - (See STDHDRS.) -
- - HDRSCAN - -
- Regular expression pattern to use for header file - scanning. The Object rule sets this to $(HDRPATTERN). - This is a jam-special variable; see HDRRULE. -
- - HDRSEARCH - -
- Used by the HdrRule to fix the list of directories where - header files can be found for a given source file. -
- - INSTALLGRIST - -
- Used by the Install* rules to grist paths to installed - files; defaults to "installed". -
- - JAMFILE - -
- Default is "Jamfile"; the name of the user-written - rules file found in each source directory. -
- - JAMRULES - -
- Default is "Jamrules"; the name of a rule definition - file to be read in at the first SubDir rule invocation. -
- - KEEPOBJS - -
- If set, tells the LibraryFromObjects rule not to delete - object files once they are archived. -
- - LEX - -
- The lex(1) command and flags. -
- - LIBDIR - -
- Not longer used. - (I.e., used only for backward compatibility with the - obsolete INSTALLLIB rule.) -
- - LINK - -
- The linker. Defaults to $(CC). -
- - LINKFLAGS - -
- Flags handed to the linker. Defaults to $(CCFLAGS). -
- - LINKLIBS - -
- List of external libraries to link with. The target image - does not depend on these libraries. -
- - LN - -
- The hard link command for HardLink rule. -
- - LOCATE_SOURCE -
- Used to set the location of generated source files. - The Yacc, Lex, and GenFile rules set LOCATE on - their targets to $(LOCATE_SOURCE). - $(LOCATE_SOURCE) is initialized by the SubDir rule - to the source directory itself. - (Also, see ALL_LOCATE_TARGET.) -
- - LOCATE_TARGET -
- Used to set the location of built binary targets. - The Object rule, and hence the Main and Library rules, - set LOCATE on their targets to $(LOCATE_TARGET). - $(LOCATE_TARGET) is initialized by the - SubDir rule to the source directory itself. - (See ALL_LOCATE_TARGET.) -
- - - MANDIR - -
- Not longer used. - (I.e., used only for backward compatibility with the - obsolete INSTALLMAN rule.) -
- - MKDIR - -
- The 'create directory' command used for the MkDir - rule. -
- - MODE - -
- The target-specific file mode (permissions) for targets - of the Shell, Setuid, Link, and Install* rules. - Used by the Chmod action; hence relevant to NT and VMS - only. -
- - MSVC -
- Selects Microsoft Visual C 16-bit compile & link - actions on NT. -
- - MSVCNT -
- Selects Microsoft Visual C NT 5.0 and earlier compile - & link actions on NT. -
- - MSVCDIR -
- Selects Microsoft Visual C NT 6.0 and later compile - & link actions on NT. These are identical to versions - 5.0 and earlier -- it just seems Microsoft changed the - name of the variable. -
- - - MV - -
- The file rename command and options. -
- - NEEDLIBS - -
- The list of libraries used when linking an executable. - Used by the Link rule. -
- - NOARSCAN - -
- If set, indicates that library members' timestamps can't - be found, and prevents the individual objects from being - deleted, so that their timestamps can be used instead. -
- - NOARUPDATE - -
- If set, indicates that libraries can't be updated, but only - created whole. -
- - OPTIM - -
- The C compiler flag for optimization, used by Cc and C++ - rules. -
- - OSFULL - -
- The concatenation of $(OS)$(OSVER)$(OSPLAT), used when jam - builds itself to determine the target binary directory. - $(OS) and $(OSPLAT) are determined by jam at its compile - time (in jam.h). $(OSVER) can optionally be set by the user. - -
- - OWNER - -
- The owner of installed files. Used by Install* rules. -
- - RANLIB - -
- The name of the ranlib command. If set, causes - the Ranlib action to be applied after the - Archive action to targets of the Library rule. -
- - RELOCATE - -
- If set, tells the Cc rule to move the output object - file to its target directory because the cc command - has a broken -o option. -
- - RM - -
- The command and options to remove a file. -
- - SEARCH_SOURCE - -
- The directory to find sources listed with Main, - Library, Object, Bulk, File, Shell, InstallBin, - InstallLib, and InstallMan rules. This works by - setting the jam-special variable SEARCH to the - value of $(SEARCH_SOURCE) for each of the rules' - sources. The SubDir rule initializes SEARCH_SOURCE - for each directory. -
- - SHELLHEADER - -
- A string inserted to the first line of every file - created by the Shell rule. -
- - SHELLMODE - -
- Permissions for files installed by Shell rule. -
- - SOURCE_GRIST - -
- Set by the SubDir to a value derived from the - directory name, and used by Objects and related - rules as 'grist' to perturb file names. -
- - STDHDRS - -
- Directories where headers can be found without - resorting to using the flag to the C compiler. - The $(STDHDRS) directories are used to find - headers during scanning, but are not passed to the - compiler commands as -I paths. -
- - SUBDIR - -
- The path from the current directory to the directory - last named by the SubDir rule. -
- - TOP - -
- The path from the current directory to the directory - that has the Jamrules file. Used by the SubDir rule. -
- - SUFEXE - -
- The suffix for executable files, if none provided. - Used by the Main rule. -
- - SUFLIB - -
- The suffix for libraries. Used by the Library and - related rules. -
- - SUFOBJ - -
- The suffix for object files. Used by the Objects - and related rules. -
- - UNDEFFLAG - -
- The flag prefixed to each symbol for the Undefines - rule (i.e., the compiler flag for undefined symbols). -
- - WATCOM -
- Selects Watcom compile and link actions on OS2. -
- - YACC - -
- The yacc(1) command. -
- - YACCFILES - -
- The base filename generated by yacc(1). -
- - YACCFLAGS - -
- The yacc(1) command flags. -
- - YACCGEN - -
- The suffix used on generated yacc(1) output. -
- -

-


-Back to top. -

- Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. -
- Comments to info@perforce.com -
- Last updated: Dec 31, 2000 -
- $Id: Jambase.html,v 1.1 2006/04/13 19:03:01 ejcoumans Exp $ - - diff --git a/jam-2.5/Jamfile b/jam-2.5/Jamfile deleted file mode 100644 index 6c4b53519..000000000 --- a/jam-2.5/Jamfile +++ /dev/null @@ -1,152 +0,0 @@ -# -# Jamfile to build Jam (a make(1)-like program) -# -# There are no user-serviceable parts in this file. -# -# Put executables in platform-specific subdirectory. - -if $(VMS) { LOCATE_TARGET ?= [.binvms] ; } -else if $(MAC) { LOCATE_TARGET ?= :bin.mac ; } -else { LOCATE_TARGET ?= bin.$(OSFULL[1]:L) ; } - -# Leave generated source in current directory; it would be nice to use -# these lines below to build the source into the platform-specific -# directory, but getting scan.c to include the right jambase.h is -# hard: with ""'s, it always gets the bootstrap version; with <>'s, -# it won't find the bootstrap version. - -# SEARCH_SOURCE ?= $(LOCATE_TARGET) $(DOT) ; -# LOCATE_SOURCE ?= $(LOCATE_TARGET) ; - -# -# We have some different files for UNIX, VMS, and NT. -# - -if $(NT) { code = execunix.c filent.c pathunix.c ; } -else if $(MINGW) { code = execunix.c filent.c pathunix.c ; } -else if $(OS2) { code = execunix.c fileos2.c pathunix.c ; } -else if $(VMS) { code = execvms.c filevms.c pathvms.c ; } -else if $(MAC) { code = execmac.c filemac.c pathmac.c ; } -else { code = execunix.c fileunix.c pathunix.c ; } - -# For jam profiling/debugging. - -if $(PROFILE) -{ - CCFLAGS += -pg ; - LINKFLAGS += -pg ; - LOCATE_TARGET = $(LOCATE_TARGET)/pg ; -} - -if $(DEBUG) -{ - CCFLAGS += -g ; - LINKFLAGS += -g ; - LOCATE_TARGET = $(LOCATE_TARGET)/g ; -} - -# We have to signal jam.h for these - -if $(OS) = NT { CCFLAGS += /DNT ; } - -# Do we know yacc? - -if $(YACC) { code += jamgram.y ; } -else { code += jamgram.c ; } - -# -# Build the jamgram.y from the jamgram.yy -# yyacc is a slippery script that makes grammars a little -# easier to read/maintain. -# - -if $(YACC) && $(SUFEXE) = "" -{ - GenFile jamgram.y jamgramtab.h : yyacc jamgram.yy ; -} - -# -# How to build the compiled in jambase. -# - -Main mkjambase : mkjambase.c ; - -if $(VMS) -{ - CC = cxx ; - LINK = cxxlink ; - CCFLAGS += /define=VMS ; -} - -# -# The guts of the Jamfile: how to build Jam -# - -Main jam : jam.c jambase.c ; -LinkLibraries jam : libjam.a ; -GenFile jambase.c : mkjambase Jambase ; - -Library libjam.a : - builtins.c command.c compile.c $(code) expand.c - glob.c hash.c headers.c lists.c make.c make1.c - newstr.c option.c parse.c regexp.c rules.c scan.c - search.c timestamp.c variable.c ; - - -if $(BINDIR) { InstallBin $(BINDIR) : jam ; } - -# -# Distribution making from here on out. -# - -ALLSOURCE = - Build.com Build.mpw Jam.html Jambase Jambase.html Jamfile - Jamfile.html Makefile Porting README RELNOTES builtins.c builtins.h - command.c command.h compile.c compile.h execcmd.h execmac.c - execunix.c execvms.c expand.c expand.h filemac.c filent.c - fileos2.c filesys.h fileunix.c filevms.c glob.c hash.c hash.h - headers.c headers.h jam.c jam.h jambase.c jambase.h jamgram.c - jamgram.h jamgram.y jamgram.yy jamgramtab.h lists.c lists.h - make.c make.h make1.c mkjambase.c newstr.c newstr.h option.c - option.h parse.c parse.h patchlevel.h pathmac.c pathsys.h - pathunix.c pathvms.c regexp.c regexp.h rules.c rules.h scan.c - scan.h search.c search.h timestamp.c timestamp.h variable.c - variable.h yyacc ; - -rule Ball -{ - NotFile balls ; - Depends balls : $(<) ; - - DEPENDS $(<) : $(>) ; - - switch $(<) - { - case *.tar : Tar $(<) : $(>) ; - case *.shar : Shar $(<) : $(>) ; - case *.zip : Zip $(<) : $(>) ; - } -} - -VERSION = jam-2.5 ; - -actions Tar -{ - ln -s . $(VERSION) - tar cvhf $(<) $(VERSION)/$(>) - rm $(VERSION) -} - -actions Shar -{ - shar $(>) > $(<) -} - -actions Zip -{ - zip $(<) $(>) -} - -Ball $(VERSION).shar : $(ALLSOURCE) ; -Ball $(VERSION).tar : $(ALLSOURCE) ; -Ball $(VERSION).zip : $(ALLSOURCE) ; diff --git a/jam-2.5/Jamfile.html b/jam-2.5/Jamfile.html deleted file mode 100644 index eb0dac315..000000000 --- a/jam-2.5/Jamfile.html +++ /dev/null @@ -1,1450 +0,0 @@ - - -Jamfiles and Jambase - - -

- -Jam - - -

-Using Jamfiles and Jambase -

-
-
-

-This document describes how to write Jamfiles using the Jam Jambase -rules to build software products. -Related documents of interest are: -

-

-Jam documentation and source are available from the -Perforce Public Depot. -


-

-

-Overview -

-

- jam, the Jam executable program, - recursively builds target files from source files - using dependency and build specifications defined - in Jam rules files. - jam parses the rules files to identify targets - and sources, - examines the filesystem to determine which - targets need updating, and issues OS commands to update - targets. -

- A base rules file called "Jambase" is provided with the - Jam distribution. - The Jambase file defines rules and variables which support - standard software build operations, like compiling, linking, - etc. -

- When the Jambase rules are used, - jam reads Jambase, then reads a file called - "Jamfile" in the current directory. - The Jamfile describes what to do with the source files in - its directory. It may also cause - Jamfiles in other directories to be read. -

- Under certain circumstances, the first Jamfile read - also causes a site-specific "Jamrules" file to be read. - The Jamrules file is an optional set of rule and variable - definitions used to define site-specific processing. -

-

-The Basic Jamfile -

-

-Jamfiles contain rule invocations, which usually look like: -

-	RuleName targets : targets ;
-
-The target(s) to the left of the colon usually indicate -what gets built, and the target(s) to the right of the -colon usually indicate what it is built from. -

-

-A Jamfile can be as simple as this: -

-	Main myprog : main.c util.c ;
-
-This specifies that there is a main.c and util.c file in the same -directory as the Jamfile, and that those source files should be -compiled and linked into an executable called myprog. -If you cd to the directory where this Jamfile lives, -you can see the exactly how jam would -build myprog with: -
-	jam -n
-
-Or, you can actually build myprog with the command: -
-	jam
-
- -

-

-Whitespace -

-Jamfile elements are delimited by whitespace (blanks, tabs, or -newlines). Elements to be delimited include rule names, targets, -colons, and semicolons. A common mistake users make is to forget the -whitespace, e.g., -
-	Main myprog: main.c util.c ; #WRONG!
-
-Jam doesn't distinguish between a typo and a target called "myprog:", -so if you get strange results, the first thing -you should check for in your Jamfile is missing whitespace. -

-

-Filenames, Target Identifiers, and Buildable Targets -

-

-Consider this Jamfile: -

-	Main myprog : main.c util.c ;                   
-	LinkLibraries myprog : libtree ;     
-	Library libtree : treemake.c treetrav.c ;    
-
-

-The Main rule specifies that an executable called myprog will be built. -The compiled main.c and util.c objects will be linked to produce -myprog. -The LinkLibraries rule specifies that libtree will -be linked into myprog as well. -The Library rule specifies which source files will be compiled and -archived into the libtree library. -

-The Jamfile above refers to targets like "myprog" and "libtree". -However, depending on the platform you're building on, the actual -filenames of those targets could be "myprog.exe" and "libtree.lib". -Most Jambase rules supply the actual filenames of targets, -so that Jamfiles themselves need not make any -platform-specific filename references. -

-The jam program builds up a list of unique target identifiers. -Unless you are using the SubDir rules (described later), -the default identifier for a file target is its filename. In the above -example, the target identifiers are the filenames: myprog.exe, -libtree.lib, main.obj, etc. -

-While all Jambase rules refer to "targets", -not all targets are buildable. -There are two kinds of buildable targets: -file targets and pseudotargets. -File targets are objects that can be found in the filesystem. -Pseudotargets are symbolic, and represent other targets. -

-You can use any buildable target on the jam command line to -build a subset of defined targets. For example: -

-        jam libtree.a 
-
-on Unix builds the libtree library and all the compiled objects -that go in it. -

-

-Pseudotargets -

-

-Most Jambase rules that define file targets also define pseudotargets -which are dependent on types of file targets. -For example, Jambase defines a pseudotarget called "lib", which -is dependent on file targets created by the Library rule. So -the command: -

-        jam lib
-
-used with the above example would cause the libtree library to be built. -Also, there is one pseudotarget built into jam itself, called -"all". Jambase sets "all" dependent on (almost) all other targets. -

-In the unfortunate case where you have a buildable target whose name -is the same as one of the Jambase pseudotargets, you'll have problems -with the conflicting target name. -Your workaround choices are: -

-

    -
  1. Change the name of your buildable file or directory that conflicts. -

    -

  2. Modify your Jambase and change the name of the conflicting pseudotarget. -(Pseudotargets are defined in Jambase using the NOTFILE rule.) -

    -

  3. Use grist on the conflicting target name in your Jamfile. E.g., instead - of -
    -    File lib : libfoo.a ;
    -    
    - try -
    -    File <dir>lib : libfoo.a ;
    -    
    -
-

- -

-Dependencies -

-

-Jambase rules set dependencies on targets, so that if you update a -source file, all the file targets that depend on that source -file, and only the ones that depend on that source file, -will be updated (rebuilt) the next time you run jam. -

-Here are some of the dependencies -that get set when jam runs on NT using the example Jamfile above: -

- - -
Target   Depends on
myprog.exemain.obj, util.obj, libtree.lib -
libtree.libtreemake.obj, treetrav.obj -
treetrav.objtreetrav.c -
-
-

-Furthermore, the Main and Library rules set up recursive -header scanning on their source targets. -So after jam has finished parsing the Jamfile and -setting the rule-driven dependencies, it scans the source -files for "#include" lines. All #include files found during -this scan become dependencies of the compiled object. -E.g., all header files used to compile treetrav.c would -be made dependencies of treetrav.obj. -

-As a result, when you run jam, it will rebuild targets -if either the source files change or the -header files change. You can't tell by looking at a Jamfile -which header files are dependencies, but you can easily -display those dependencies with: -

-	jam -nd+3
-
-

-Rule Ordering -

-

-Rules which specify dependencies, like the Main, Library, and -LinkLibrary rules, can be invoked in any order. jam -figures out the order in which targets are built from -their dependencies. -

-Some rules, however, set variables which are used by subsequent -rule invocations, and their ordering is important. -For example, the SubDir* rules (discussed -later) must be invoked in a particular order. - -

-

-Detailed Jambase Specifications -

-

-This document describes how to use various Jambase rules -from a functional point of view. -You can see the summary of available Jambase rules in the -Jambase Reference. -The detailed specifications for any Jambase rule -can be found by reading the rule definition itself -in the Jambase file. -

- -


-

-Handling Directory Trees -

- The SubDir* rules are used to - define source code directory hierarchies. - With SubDir and SubInclude, you can use jam - to build software from source files and Jamfiles spread - across many directories, as is typical for large projects. - The SubDir* rules unify an entire - source code tree so that jam can read in - all the Jamfiles in one pass and - compute dependencies across the entire project. -

- To use the SubDir* rules, you must: -

-

    -
  1. Preface the Jamfile in each directory with an invocation - of the SubDir rule. -

    -

  2. Place at the root of the tree a file named Jamrules. - This file could be empty, but in - practice it contains user-provided rules and variable - definitions that are shared throughout the - tree. Examples of such definitions are library - names, header directories, install directories, - compiler flags, etc. This file is good candidate - for automatic customizing with autoconf(GNU). -

    -

  3. Optionally, set an environment variable pointing - to the root directory of the srouce tree. The - variable's name is left up to you, but in these - examples, we use TOP. -
-

-

- SubDir Rule -

-

- The SubDir rule must be invoked before any rules that - refer to the contents of the directory - it is best to put - it at the top of each Jamfile. For example: -

-	# Jamfile in $(TOP)/src/util directory.
-
-	SubDir TOP src util ;
-
-	Main myprog : main.c util.c ;                   
-	LinkLibraries myprog : libtree ;     
-	Library libtree : treemake.c treetrav.c ;    
-
- This compiles four files in $(TOP)/src/util, archives - two of the objects into libtree, and links the whole - thing into myprog. - Outputs are placed in the $(TOP)/src/util - directory. -

- This doesn't appear to be any different from - the previous example that didn't have a SubDir rule, - but two things are happening behind the scenes: -

    -
  1. The SubDir rule causes jam to read - in the $(TOP)/Jamrules file. - (The Jamrules file can alternately be named by the - variable $(xxxRULES), where xxx is the name of the - root variable, e.g., $(TOPRULES)). -

    - The Jamrules file can contain variable definitions - and rule definitions specific to your codeline. - It allows you to completely customize your build - environment without having to rewrite Jambase. - Jamrules is only read - in once, at the first SubDir invocation. -

    -

  2. - The SubDir rule initializes a set of variables - that are used by Main and other rules to - uniquely identify the source files in this - directory and assign locations to the targets - built from files in this directory. -

    - When you have set a root variable, e.g., $(TOP), - SubDir constructs path names rooted with $(TOP), - e.g., $(TOP)/src/util. - Otherwise, SubDir constructs relative pathnames - to the root directory, computed from the number - of arguments to the first SubDir rule, e.g., - ../../src/util. In either case, the SubDir - rule constructs the path names that locate source - files. - You'll see how this is useful later. -

    - - -

    - The SubDir rule takes as its first argument the root - variable's name and takes as subsequent arguments the - directory names leading from the root to the directory of - the current Jamfile. Note that the name of the subdirectory - is given as individual elements: the SubDir rule - does not use system-specific directory name syntax. -

    -

    -

    - SubInclude Rule -

    - The SubInclude rule is used in a Jamfile to cause another - Jamfile to be read in. - Its arguments are in the same format as - SubDir's. -

    - The recommended practice is only to include one level of - subdirectories at a time, and let the Jamfile in each subdirectory - include its own subdirectories. This allows a - user to sit in any arbitrary directory of the source tree - and build that subtree. For example: -

    -       # This is $(TOP)/Jamfile, top level Jamfile for mondo project.
    -
    -       SubInclude TOP src ;
    -       SubInclude TOP man ;
    -       SubInclude TOP misc ;
    -       SubInclude TOP util ;
    -
    - If a directory has both subdirectories of its own as well - as files that need building, the SubIncludes should be - either before the SubDir rule or be at the end of the Jamfile - - not between the SubDir and other rule invocations. - For example: -
    -	# This is $(TOP)/src/Jamfile:
    -
    -	SubDir TOP src ;
    -
    -	Main mondo : mondo.c ;
    -	LinkLibraries mondo : libmisc libutil ;
    -	
    -	SubInclude TOP src misc ;
    -	SubInclude TOP src util ;
    -
    -

    - (jam processes all the Jamfiles it reads as if - it were reading one single, large Jamfile. - Build rules like Main and LinkLibraries rely on the - preceding SubDir rule to set up source file and - output file locations, and SubIncludes rules read in - Jamfiles that contain SubDir rules. So if you put - a SubIncludes rule between a SubDir and a Main - rule, jam will try to find the source files - for the Main rule in the wrong directory.) -

    -

    - Variables Used to Handle Directory Trees -

    - The following variables are set by the SubDir rule - and used by the Jambase rules that define file targets: -

    -

    - -
    - SEARCH_SOURCE - The SubDir targets (e.g., "TOP src util") - are used to construct a pathname (e.g., $(TOP)/src/util), - and that pathname is assigned to $(SEARCH_SOURCE). - Rules like Main and Library use $(SEARCH_SOURCE) - to set search paths on source files. -
    - LOCATE_SOURCE - Initialized by the SubDir rule to the same - value as $(SEARCH_SOURCE), unless ALL_LOCATE_TARGET - is set. - $(LOCATE_SOURCE) is used by rules that build - generated source files (e.g., Yacc and Lex) to - set location of output files. - Thus the default location of built source files - is the directory of the Jamfile that defines them. -
    - LOCATE_TARGET - Initalized by the SubDir rule to the same - value as $(SEARCH_SOURCE), unless ALL_LOCATE_TARGET - is set. - $(LOCATE_TARGET) is used by rules that build - binary objects (e.g., Main and Library) to - set location of output files. - Thus the default location of built binaray files - is the directory of the Jamfile that defines them. -
    - ALL_LOCATE_TARGET - - If $(ALL_LOCATE_TARGET) is set, LOCATE_SOURCE - and and LOCATE_TARGET are set to $(ALL_LOCATE_TARGET) - instead of to $(SEARCH_SOURCE). This can be used to - direct built files to be written to a location outside - of the source tree, and enables building from read-only - source trees. -
    - SOURCE_GRIST - The SubDir targets are formed into a string - like "src!util" and that string is assigned to - SOURCE_GRIST. Rules that define file targets - use $(SOURCE_GRIST) to set the "grist" attribute - on targets. This is used to assure uniqueness - of target identifiers where filenames themselves - are not unique. - For example, the target identifiers of - $(TOP)/src/client/main.c and $(TOP)/src/server/main.c - would be <src!client>main.c and <src!server>main.c. -
    -
    -

    - The $(LOCATE_TARGET) and $(SEARCH_SOURCE) variables are used - extensively by rules in Jambase: most rules that generate - targets (like Main, Object, etc.) set $(LOCATE) to - $(LOCATE_TARGET) for the targets they generate, and rules - that use sources (most all of them) set $(SEARCH) to be - $(SEARCH_SOURCE) for the sources they use. -

    - $(LOCATE) and $(SEARCH) are better explained in - The Jam Executable Program - but in brief they tell jam where to create new targets and - where to find existing ones, respectively. -

    - Note that you can reset these variables - after SubDir sets them. For example, this Jamfile builds - a program called gensrc, then runs it to create a source file - called new.c: -

    -       SubDir TOP src util ;
    -       Main gensrc : gensrc.c ;
    -       LOCATE_SOURCE = $(NEWSRC) ;
    -       GenFile new.c : gensrc ;
    -       
    - By default, new.c would be written into the - $(TOP)/src/util directory, but resetting LOCATE_SOURCE causes - it to be written to the $(NEWSRC) directory. ($(NEWSRC) is assumed - to have been set elsewhere, e.g., in Jamrules.) -

    -

    - VMS Notes -

    - On VMS, the logical name table is not imported as is the - environment on UNIX. To use the SubDir and related rules, - you must set the value of the variable that names the root - directory. For example: -
    -              TOP = USR_DISK:[JONES.SRC] ;
    -
    -              SubInclude TOP util ;
    -
    - The variable must have a value that looks like a directory - or device. If you choose, you can use a concealed logical. - For example: -
    -              TOP = TOP: ;
    -
    -              SubInclude TOP util ;
    -
    - The : at the end of TOP makes the value of $(TOP) look - like a device name, which jam respects as a directory name - and will use when trying to access files. TOP must then - be defined from DCL: -
    -              $ define/job/translation=concealed TOP DK100:[USERS.JONES.SRC.]
    -
    - Note three things: the concealed translation allows the - logical to be used as a device name; the device name in - the logical (here DK100) cannot itself be concealed logical - (VMS rules, man); and the directory component of the - definition must end in a period (more VMS rules). -

    -

    -Building Executables and Libraries -

    -

    -The rules that build executables and libraries are: Main, Library, -and LinkLibraries. -

    - Main Rule -

    - The Main rule compiles source files and links the resulting - objects into an executable. For example: -
    -              Main myprog : main.c util.c ;
    -
    - This compiles main.c and util.c and links main.o and - util.o into myprog. The object files and resulting - executable are named appropriately for the platform. -

    - Main can also be used to build shared libraries and/or - dynamic link libraries, since those are also linked - objects. E.g.: -

    -		Main driver$(SUFSHR) : driver.c ;
    -	
    - Normally, Main uses $(SUFEXE) to determine the suffix on - the filename of the built target. To override it, - you can supply a suffix explicity. - In this case, - $(SUFSHR) is assumed to be the OS-specific shared library - suffix, defined in Jamrules with something - like: -
    -		if $(UNIX)      { SUFSHR = .so ; }
    -		else if $(NT)   { SUFSHR = .dll ; }
    -	
    -

    - Main uses the Objects rule to compile source targets. - -

    - Library Rule -

    - The Library rule compiles source files, archives the - resulting object files into a library, and then deletes - the object files. For example: -
    -              Library libstring : strcmp.c strcpy.c strlen.c ;
    -              Library libtree : treemake.c treetrav.c ;
    -
    - This compiles five source files, archives three of the - object files into libstring and the other two into libtree. - Actual library filenames are formed with the $(SUFLIB) suffix. - Once the objects are safely in the libraries, the - objects are deleted. -

    - Library uses the Objects rule to compile source files. -

    -

    - LinkLibraries Rule -

    - To link executables with built libraries, use - the LinkLibraries rule. For example: -
    -              Main myprog : main.c util.c ;
    -              LinkLibraries myprog : libstring libtree ;
    -
    - The LinkLibraries rule does two things: it makes the - libraries dependencies of the executable, so that they get - built first; and it makes the libraries show up on the - command line that links the executable. The ordering of - the lines above is not important, because jam builds targets - in the order that they are needed. -

    - You can put multiple libraries on a single invocation of - the LinkLibraries rule, or you can provide them in multiple - invocations. In both cases, the libraries appear on - the link command line in the order in which they were - encountered. You can also provide multiple executables to - the LinkLibraries rule, if they need the same libraries, - e.g.: -

    -		LinkLibraries prog1 prog2 prog3 : libstring libtree ;
    -       
    -

    -

    - Variables Used in Building Executables and Libraries -

    -
    - -
    - AR - Archive command, used for Library targets. -
    - SUFEXE - *Suffix on filenames of executables referenced - by Main and LinkLibraries. -
    - LINK - Link command, used for Main targets. -
    - LINKFLAGS - Linker flags. -
    - LINKLIBS - Link libraries that aren't dependencies. (See note - below.) -
    - EXEMODE - *File permissions on Main targets. -
    - MODE - Target-specific file permissions on Main targets - (set from $(EXEMODE)) -
    - RANLIB - Name of ranlib program, if any. -
    -
    - -

    - Variables above marked with "*" are used by the Main, - Library, and LinkLibraries rules. Their values at the - time the rules are invoked are used to set target-specific - variables. -

    - All other variables listed above are globally defined, - and are used in actions that update Main and Library - targets. This means that the global values of those - variables are used, uness target-specific values have - been set. - (For instance, a target-specific MODE value is set by - the Main rule.) - The target-specific values always override - global values. -

    - Note that there are two ways to specify link libraries for - executables: -

    -

    - For example: -

    -	#In Jamrules:
    -              if $(UNIX) { X11LINKLIBS = -lXext -lX11 ; }
    -              if $(NT)   { X11LINKLIBS = libext.lib libX11.lib ; }
    -
    -	#In Jamfile:
    -              Main xprog : xprog.c ;
    -              LINKLIBS on xprog$(SUFEXE) = $(X11LINKLIBS) ;
    -              LinkLibraries xprog : libxutil ;
    -              Library libxutil : xtop.c xbottom.c xutil.c ;
    -
    - This example uses the Jam syntax "variable on target" to - set a target-specific variable. In this way, only xprog - will be linked with this special $(X11LINKLIBS), - even if other executables were going to be built - by the same Jamfile. Note that when you set a variable - on a target, you have to specify the target identifer - exactly, which in this case is the suffixed filename of - the executable. - The actual link command line on Unix, for example, would - look something like this: -
    -              cc -o xprog xprog.o libxutil.a -lXext -lX11
    -
    -

    -Compiling -

    - Compiling of source files occurs normally as a byproduct - of the Main or Library rules, which call the rules - described here. These rules may also be called explicitly - if the Main and Library behavior doesn't satisfy your - requirements. -

    -

    - Objects Rule -

    - The Main and Library rules call the Objects rule on source files. - Compiled object files built by - the Objects rule are a dependency of the obj - pseudotarget, so "jam obj" will build object files used in - Main and Library rules. -

    - Target identifiers created by the Objects rule have grist - set to $(SOURCE_GRIST). So given this Jamfile: -

    -		SubDir TOP src lock ;
    -		Main locker : lock.c ;
    -       
    - the object file created is lock.o (or lock.obj) and - its target identifier is <src!lock>lock.o - (or <src!lock>lock.obj). - -

    - You can also call Objects directly. For example: -

    -              Objects a.c b.c c.c ;
    -
    - This compiles a.c into a.o, b.c into b.o, etc. The object - file suffix is supplied by the Objects rule. -

    -

    - Object Rule -

    - Objects gets its work done by calling the Object rule on - each of the source files. - You could use the Object rule directly. - For example, on Unix, you could use: -
    -              Object foo.o : foo.c ;
    -
    - However, the Object rule does not provide suffixes, and - it does not provide the grist needed to construct target - identifiers if you are using the SubDir* rules. - A portable and robust Jamfile would need to invoke Object thus: -
    -	      Object <src!util>foo$(SUFOBJ) : <src!util>foo.c ;
    -	
    - which is inelegant and clearly shows why using Objects - is better than using Object. -

    - If there's any advantage to the Object rule, it's - that it doesn't require that the object name bear - any relationship to the source. It is thus possible to - compile the same file into different objects. For example: - -

    -              Object a.o : foo.c ;
    -              Object b.o : foo.c ;
    -              Object c.o : foo.c ;
    -
    - This compiles foo.c (three times) into a.o, b.o, and c.o. - Later examples show how this is useful. -

    - The Object rule looks at the suffix of the source file and - calls the appropriate rules to do the actual preprocessing - (if any) and compiling needed to produce the output object file. - The Object rule is - capable of the generating of an object file from any - type of source. For example: -

    -              Object grammar$(SUFOBJ) : grammar.y ;
    -              Object scanner$(SUFOBJ) : scanner.l ;
    -              Object fastf$(SUFOBJ) : fastf.f ;
    -              Object util$(SUFOBJ) : util.c ;
    -
    - An even more elegant way to get the same result is to let the - Objects rule call Object: -
    -              Objects grammar.y scanner.l fastf.f util.c ;
    -	
    -

    - In addition to calling the compile rules, Object sets up - a bunch of variables specific to the source and target - files. (See Variables Used in Compiling, below.) -

    -

    - Cc, C++, Yacc, Lex, Fortran, As, etc. Rules -

    -

    - The Object rule calls compile rules specific to the suffix of - the source file. (You can see which suffixes are supported - by looking at the Object rule definition in Jambase.) - Because the extra work done by the - Object rule, it is not always useful to call the compile - rules directly. But the adventurous user might attempt - it. For example: -

    -              Yacc grammar.c : grammar.y ;
    -              Lex scan.c : scan.l ;
    -              Cc prog.o : prog.c ;
    -
    - These examples individually run yacc(1), lex(1), and the C - compiler on their sources. -

    -

    - UserObject Rule -

    - Any files with suffixes not understood by the Object rule - are passed to the UserObject rule. The default definition - of UserObject simply emits a warning that the suffix is - not understood. This Jambase rule definition is intended to be - overridden in Jamrules with one that recognizes the project-specific - source file suffixes. For example: - -
    -	#In Jamrules:
    -
    -              rule UserObject
    -              {
    -                  switch $(>)
    -                  {
    -                  case *.rc   : ResourceCompiler $(<) : $(>) ;
    -                  case *      : ECHO "unknown suffix on" $(>) ;
    -                  }
    -              }
    -
    -              rule ResourceCompiler
    -              {
    -                  DEPENDS $(<) : $(>) ;
    -		  Clean clean : $(<) ;
    -              }
    -
    -              actions ResourceCompiler
    -              {
    -                  rc /fo $(<) $(RCFLAGS) $(>)
    -              }
    -
    -
    -	#In Jamfile:
    -
    -              Library liblock : lockmgr.c ;
    -	      if $(NT) { Library liblock : lock.rc ; }
    -
    -

    - In this example, the UserObject definition in Jamrules - allows *.rc files to be handle as regular Main and Library - sources. The lock.rc file is compiled into lock.obj - by the "rc" command, and lock.obj is archived into a library - with other compiled objects. -

    - LibraryFromObjects Rule -

    - Sometimes the Library rule's straightforward compiling of - source into object modules to be archived isn't flexible - enough. The LibraryFromObjects rule does the archiving - (and deleting) job of the Library rule, but not the compiling. - The user can make use of the Objects or Object - rule for that. For example: -
    -              LibraryFromObjects libfoo.a : max.o min.o ;
    -              Object max.o : maxmin.c ;
    -              Object min.o : maxmin.c ;
    -              ObjectCcFlags max.o : -DUSEMAX ;
    -              ObjectCcFlags min.o : -DUSEMIN ;
    -
    - This Unix-specific example compiles the same source file into - two different - objects, with different compile flags, and archives them. - (The ObjectCcFlags rule is described shortly.) - Unfortunately, the portable and robust implementation of the - above example is not as pleasant to read: -
    -	      SubDir TOP foo bar ;
    -              LibraryFromObjects libfoo$(SUFLIB) : <foo!bar>max$(SUFOBJ) 
    -			                           <foo!bar>min$(SUFOBJ) ;
    -              Object <foo!bar>min$(SUFOBJ) : <foo!bar>maxmin.c ;
    -              Object <foo!bar>max$(SUFOBJ) : <foo!bar>maxmin.c ;
    -	      ObjectCcFlags <foo!bar>min$(SUFOBJ) : -DUSEMIN ;
    -	      ObjectCcFlags <foo!bar>max$(SUFOBJ) : -DUSEMAX ;
    -       
    - Note that, among other things, you must supply the library - file suffix when using the LibraryFromObjects rule. -

    -

    - MainFromObjects Rule -

    - Similar to LibraryFromObjects, MainFromObjects does the - linking part of the Main rule, but not the compiling. - MainFromObjects can be used when there are no - objects at all, and everything is to be loaded from - libraries. For example: -
    -              MainFromObjects testprog ;
    -              LinkLibraries testprog : libprog ;
    -              Library libprog : main.c util.c ;
    -
    - On Unix, say, this generates a link command that looks like: -
    -              cc -o testprog libprog.a
    -
    - Linking purely from libraries is something that doesn't - work everywhere: it depends on the symbol "main" being - undefined when the linker encounters the library that contains - the definition of "main". -

    -

    - Variables Used in Compiling -

    - The following variables control the compiling of source - files: -

    -

    - -
    - C++ - The C++ compiler command -
    - CC - The C compiler command -
    - C++FLAGS -
    - CCFLAGS -
    Compile flags, used to - create or update compiled objects -
    - SUBDIRC++FLAGS -
    - SUBDIRCCFLAGS -
    Additonal compile flags - for source files in this directory. -
    - OPTIM - Compiler optimization flag. The Cc and C++ - actions use this as well as C++FLAGS or CCFLAGS. -
    - HDRS - Non-standard header directories; i.e., - the directories the compiler will not look in - by default and which therefore must be supplied - to the compile command. These directories are - also used by jam to scan for include files. -
    - STDHDRS - Standard header directories, i.e., the - directories the compiler searches automatically. - These are not passed to the compiler, but they - are used by jam to scan for include files. -
    - SUBDIRHDRS - Additional paths to add to HDRS for source files - in this directory. -
    - LEX - The lex(1) command -
    - YACC - The yacc(1) command -
    -
    -

    - The Cc rule sets a target-specific $(CCFLAGS) to the current - value of $(CCFLAGS) and $(SUBDIRCCFLAGS). Similarly - for the C++ rule. The Object rule sets a target-specific - $(HDRS) to the current value of $(HDRS) and $(SUBDDIRHDRS). - -

    - $(CC), $(C++), $(CCFLAGS), $(C++FLAGS), $(OPTIM), and - $(HDRS) all affect the compiling of C and C++ files. - $(OPTIM) is separate from $(CCFLAGS) and $(C++FLAGS) so - they can be set independently. -

    - $(HDRS) lists the directories to search for header files, - and it is used in two ways: first, it is passed to the C - compiler (with the flag -I prepended); second, it is used - by HdrRule to locate the header files whose names were - found when scanning source files. $(STDHDRS) lists the - header directories that the C compiler already knows - about. It does not need passing to the C compiler, but is - used by HdrRule. -

    - Note that these variables, if set as target-specific variables, - must be set on the target, not the source file. - The target file in this case is the object file to be generated. - For example: -

    -              Library libximage : xtiff.c xjpeg.c xgif.c ;
    -
    -              HDRS on xjpeg$(SUFOBJ) = /usr/local/src/jpeg ;
    -              CCFLAGS on xtiff$(SUFOBJ) = -DHAVE_TIFF ;
    -
    - This can be done more easily with the rules that follow. -

    -

    - ObjectCcFlags, ObjectC++Flags, ObjectHdrs Rules -

    - $(CCFLAGS), $(C++FLAGS) and $(HDRS) can be set on object file - targets - directly, but there are rules that allow these variables - to be set by referring to the original source file name, - rather than to the derived object file name. ObjectCcFlags - adds object-specific flags to the $(CCFLAGS) variable, - ObjectC++Flags adds object-specific flags to the - $(C++FLAGS) variable, and ObjectHdrs add object-specific - directories to the $(HDRS) variable. For example: -
    -	#In Jamrules:
    -		if $(NT) { CCFLAGS_X = /DXVERSION ;	
    -			   HDRS_X = \\\\SPARKY\\X11\\INCLUDE\\X11 ;
    -		         }
    -
    -	#In Jamfile:
    -              Main xviewer : viewer.c ;
    -              ObjectCcFlags viewer.c : $(CCFLAGS_X) ;
    -              ObjectHdrs viewer.c : $(HDRS_X) ;
    -
    - The ObjectCcFlags and ObjectHdrs rules take .c files - as targets, but actually set $(CCFLAGS) and $(HDRS) values - on the .obj (or .o) files. As a result, the action - that updates the target .obj file uses the target-specific - values of $(CCFLAGS) and $(HDRS). -

    -

    - SubDirCcFlags, SubDirC++Flags, SubDirHdrs Rules -

    - These rules set the values of $(SUBDIRCCFLAGS), $(SUBDIRC++FLAGS) - and $(SUBDIRHDRS), which are used by the Cc, - C++, and Object rules when setting the target-specific - values for $(CCFLAGS), $(C++FLAGS) and $(HDRS). The SubDir - rule clears these variables out, and thus they provide - directory-specific values of $(CCFLAGS), $(C++FLAGS) and - $(HDRS). For example: -
    -	#In Jamrules:
    -              GZHDRS = $(TOP)/src/gz/include ;
    -	      GZFLAG = -DGZ ;
    -		
    -	#In Jamfile:
    -              SubDir TOP src gz utils ;
    -
    -              SubDirHdrs $(GZHDRS) ;
    -              SubDirCcFlags $(GZFLAG) ;
    -
    -	      Library libgz : gizmo.c ;
    -	      Main gizmo : main.c ;
    -	      LinkLibraries gizmo : libgz ;
    -
    - All .c files in this directory files will be compiled with - $(GZFLAG) as well as the default $(CCFLAG), and the include - paths used on the compile command will be $(GZHDRS) as well - as the default $(HDRS). -

    -Header File Processing -

    - One of the functions of the Object rule is set up - scanning of source - files for (C style) header file inclusions. To do so, it - sets the special variables $(HDRSCAN) and $(HDRRULE) - as target-specific variables on the source file. The - presence of these variables triggers a special mechanism - in jam for scanning a file for header file inclusions and - invoking a rule with the results of the scan. The - $(HDRSCAN) variable is set to an egrep(1) pattern that - matches "#include" statements in C source files, and the - $(HDRRULE) variable is set to the name of the rule that - gets invoked as such: -
    -              $(HDRRULE) source-file : included-files ;
    -
    - This rule is supposed to set up the dependencies between - the source file and the included files. The Object rule - uses HdrRule to do the job. HdrRule itself expects - another variable, $(HDRSEARCH), to be set to the list of - directories where the included files can be found. Object - does this as well, setting $(HDRSEARCH) to $(HDRS) and - $(STDHDRS). -

    - The header file scanning occurs during the "file binding" - phase of jam, which means that the target-specific - variables (for the source file) are in effect. To accomodate - nested includes, one of the HdrRule's jobs is to pass - the target-specific values of $(HDRRULE), $(HDRSCAN), and - $(HDRSEARCH) onto the included files, so that they will be - scanned as well. -

    -

    - HdrRule Rule -

    - Normally, HdrRule is not invoked directly; the Object rule - (called by Main and Library) invokes it. -

    - If there are special dependencies that need to be set, - and which are not set by HdrRule itself, you can define - another rule and let it invoke HdrRule. For example: - -

    -	#In Jamrules:
    -              rule BuiltHeaders
    -              {
    -                      DEPENDS $(>) : mkhdr$(SUFEXE) ;
    -                      HdrRule $(<) : $(>) ;
    -              }
    -
    -	#In Jamfile:
    -              Main mkhdr : mkhdr.c ;
    -              Main ugly : ugly.c ;
    -
    -              HDRRULE on ugly.c = BuiltHeaders ;
    -
    -
    - This example just says that the files included by "ugly.c" - are generated by the program "mkhdr", which can be built - from "mkhdr.c". During the binding phase, jam will - scan ugly.c, and if it finds an include file, ughdr.h, - for example, it will automatically invoke the rule: -
    -              BuiltHeaders ugly.c : ughdr.h ;
    -       
    - By calling HdrRule at the end of BuiltHeaders, - all the gadgetry of HdrRule takes effect and it - doesn't need to be duplicated. -

    -

    - Variables Used for Header Scanning -

    -
    - -
    - HDRPATTERN - Default scan pattern for "include" lines. -
    - HDRSCAN - Scan pattern to use. - This is a special variable: during binding, if - both HDRSCAN and HDRRULE are set, scanning is activated - on the target being bound. - The HdrRule and Object rules sets this - to $(HDRPATTERN) on their source targets. -
    - HDRRULE - Name of rule to invoked on files found in header - scan. The HdrRule and Object rules set this to "HdrRule" - on their source targets. This is also a special variable; - it's the only jam variable that can hold the - name of a rule to be invoked. -
    - HDRSEARCH - Search paths for files found during header scanning. - This is set from $(HDRS) and $(STDHDRS), which are - described in the Compiling section. - jam will search $(HDRSEARCH) directories for - the files found by header scans. -
    -
    -

    - The Object rule sets HDRRULE and HDRSCAN specifically for - the source files to be scanned, rather than globally. If - they were set globally, jam would attempt to scan all - files, even library archives and executables, for header - file inclusions. That would be slow and probably not - yield desirable results. -

    -

    -Copying Files -

    -

    - File Rule -

    - The File rule copies one file to another. The target name - needn't be the same as the source name. For - example: -
    -	switch $(OS)
    -	{
    -           case NT*  : File config.h : confignt.h ;
    -	   case *    : File config.h : configunix.h ;
    -	}
    -	LOCATE on config.h = $(LOCATE_SOURCE) ;
    -
    - This creates a config.h file from either confignt.h or - configunix.h, depending on the current build platform. -

    - The File rule does not - use the LOCATE_SOURCE variable set by the - SubDir rule (although it does use SEARCH_SOURCE), which - means you have to set the copied file's output directory - yourself. That's done by setting the special - LOCATE variable on the target, as shown above, - or with the MakeLocate rule described below. -

    - Bulk Rule -

    - The Bulk rule is a shorthand for many invocations of the - File rule when all files are going to the same directory. - For example: -
    -	#In Jamrules:
    -              DISTRIB_GROB = d:\\distrib\\grob ;
    -
    -	#In Jamfile:
    -              Bulk $(DISTRIB_GROB) : grobvals.txt grobvars.txt ;
    -
    - This causes gobvals.txt and grobvars.txt to be copied - into the $(DISTRIB_GROB) directory. -

    - HardLink Rule -

    - The Unix-only HardLink rule makes a hard link (using ln(1)) from the - source to the target, if there isn't one already. For - example: -
    -              HardLink config.h : configunix.h ;
    -
    -

    - Shell Rule -

    - The Shell rule is like the File rule, except that on Unix it makes - sure the first line of the target is "#!/bin/sh" and sets - the permission to make the file executable. For example: -
    -              Shell /usr/local/bin/add : add.sh ;
    -
    -

    - You can also use $(SHELLHEADER) to dictate - what the first line of the copied file will be. - For - example: -

    -              Shell /usr/local/bin/add : add.awk ;
    -              SHELLHEADER on /usr/local/bin/add = "#!/bin/awk -f" ;
    -
    - This installs an awk(1) script. -

    -

    - Variables Used When Copying Files -

    -
    - -
    - FILEMODE - Default file permissions for copied files -
    - SHELLMODE - Default file permissions for Shell rule targets -
    - MODE - File permissions set on files copied by - File, Bulk, and Shell rules. - File and Shell sets a target-specific MODE to the current - value of $(FILEMODE) or $(SHELLMODE), respectively. -
    - SHELLHEADER - String to write in first line of Shell targets - (default is #!/bin/sh). - -
    -
    -

    - -

    -Installing Files -

    -Jambase provides a set of Install* rules to copy files -into an destination directory and set permissions on them. -On Unix, the install(1) program is used. -If the destination directory does not exist, jam -creates it first. -

    -All files copied with the Install* rules are dependencies -of the install pseudotarget, which means that the -command "jam install" will cause the installed copies to -be updated. Also, "jam uninstall" will cause the installed -copies to be removed. -

    -The Install* rules are: -

    - -
    InstallBin - Copies file and sets its permission to $(EXEMODE). - You must specify the suffixed executable name. E.g.: -
    InstallBin $(BINDIR) : thing$(SUFEXE) ;
    -		   
    - -
    InstallFile - Copies file and sets its permission to $(FILEMODE). E.g.: -
    InstallFile $(DESTDIR) : readme.txt ;
    -		   
    - -
    InstallLib - Copies file and sets its permission to $(FILEMODE). - You must specify the suffixed library name. E.g.: -
    InstallLib $(LIBDIR) : libzoo$(SUFLIB) ;
    -		   
    - -
    InstallMan - Copies file into the mann - subdirectory of the target directory - and sets its permission to $(FILEMODE). E.g., - this copies foo.5 into the $(DESTDIR)/man5 directory: -
    InstallMan $(DESTDIR) : foo.5 ;
    -		   
    - -
    InstallShell - Copies file and sets its permission to $(SHELLMODE). E.g.: -
    InstallShell $(DESTDIR) : startup ;
    -		   
    - -
    -
    -

    -

    -

    - Variables -

    - The following variables control the installation rules: -

    -

    - -
    - INSTALL - The install program (Unix only) -
    - FILEMODE - Default file permissions on readable files. -
    - EXEMODE - Default file permission executable files. -
    - SHELLMODE - Default file permission on shell script files. -
    - MODE - Target-specific file permissions -
    -
    -

    -

    - The Install rules set a target-specific MODE to the current - value of $(FILEMODE), $(EXEMODE), or $(SHELLMODE), - depending on which Install rule was invoked. -

    - The directory variables are just defined for convenience: - they must be passed as the target to the appropriate - Install rule. The $(INSTALL) and mode variables must be - set (globally) before calling the Install rules in order - to take effect. -

    -

    -Miscellaneous Rules -

    -

    -Clean Rule -

    -

    -The Clean rule defines files to be removed when you run "jam clean". -Any site-specific build rules defined in your Jamrules should invoke -Clean so that outputs can be removed. E.g., -

    -	rule ResourceCompiler
    -	{
    -	   DEPENDS $(<) : $(>) ;
    -	   Clean clean : $(<) ;
    -	}
    -
    -

    -

    -Most Jambase rules invoke the Clean rule on their built targets, -so "jam clean" will remove all compiled objects, libraries, -executables, etc. -

    -

    -MakeLocate Rule -

    - MakeLocate is a single convenient rule that creates a directory, - sets LOCATE on a target to that directory, and makes the directory - a dependency of the target. It is used by many Jambase rules, - and can be invoked directly, e.g.: -
    -		GenFile data.tbl : hxtract data.h ;
    -		MakeLocate data.tbl : $(TABLEDIR) ;
    -      
    - In this example, the File rule creates data.tbl from data.h. - The MakeLocate causes data.tbl to be written into the $(TABLEDIR) - directory; and if the directory doesn't exist, it is created first. -

    - The MakeLocate rule invokes another Jambase rule, MkDir, - to (recursively) create - directories. MkDir uses the $(MKDIR) variable to determine the - platform-specific command that creates directories. -

    -

    -RmTemps Rule -

    - Some intermediate files are meant to be temporary. - The RmTemps rule can be used to cause - jam to delete them after they are used. -

    - RmTemps must be: -

    - For - example: -
    -		SubDir TOP src big ;
    -		GenFile big.y : joinfiles part1.y part2.y part3.y ;
    -		Main bigworld : main.c big.y ;
    -		RmTemps bigworld$(SUFEXE) : <src!big>big.y ;
    -	
    - This causes big.y to be deleted after it has been used to create - the bigworld executable. - The exact target identifier of big.y is <src!big>big.y - (the GenFile and Main rules tack on the grist automatically); - the exact target identifier of the bigworld executable - is bigworld$(SUFEXE). -

    -


    -Back to top. -

    - Copyright 1997, 2000 Perforce Software, Inc. -
    - Comments to info@perforce.com -
    - Last updated: Dec 31, 2000 -
    - $Id: Jamfile.html,v 1.1 2006/04/13 19:03:01 ejcoumans Exp $ - - diff --git a/jam-2.5/Makefile b/jam-2.5/Makefile deleted file mode 100644 index bf60c3b4f..000000000 --- a/jam-2.5/Makefile +++ /dev/null @@ -1,65 +0,0 @@ -# Makefile for jam - -CC = cc -CFLAGS = -EXENAME = ./jam0 -TARGET = -o $(EXENAME) - -# Special flavors - uncomment appropriate lines - -# NCR seems to have a broken readdir() -- use gnu -#CC = gcc - -# AIX needs -lbsd, and has no identifying cpp symbol -# Use _AIX41 if you're not on 3.2 anymore. -#LINKLIBS = -lbsd -#CFLAGS = -D_AIX - -# NT (with Microsoft compiler) -# Use FATFS if building on a DOS FAT file system -#Lib = $(MSVCNT)/lib -#Include = $(MSVCNT)/include -#CC = cl /nologo -#CFLAGS = -I $(Include) -DNT -#TARGET = /Fejam0 -#LINKLIBS = $(Lib)/oldnames.lib $(Lib)/kernel32.lib $(Lib)/libc.lib -#EXENAME = .\jam0.exe - -# NT (with Microsoft compiler) -# People with DevStudio settings already in shell environment. -#CC = cl /nologo -#CFLAGS = -DNT -#TARGET = /Fejam0 -#EXENAME = .\jam0.exe - -# Interix - gcc -#CC = gcc - -# Cygwin - gcc & cygwin -#CC = gcc -#CFLAGS = -D__cygwin__ - -# MingW32 -#CC = gcc -#CFLAGS = -DMINGW - -# MPEIX -#CC = gcc -#CFLAGS = -I/usr/include -D_POSIX_SOURCE - -# QNX rtp (neutrino) -#CC = gcc - -SOURCES = \ - builtins.c \ - command.c compile.c execunix.c execvms.c expand.c \ - filent.c fileos2.c fileunix.c filevms.c glob.c hash.c \ - headers.c jam.c jambase.c jamgram.c lists.c make.c make1.c \ - newstr.c option.c parse.c pathunix.c pathvms.c regexp.c \ - rules.c scan.c search.c timestamp.c variable.c - -all: $(EXENAME) - $(EXENAME) - -$(EXENAME): - $(CC) $(TARGET) $(CFLAGS) $(SOURCES) $(LINKLIBS) diff --git a/jam-2.5/Porting b/jam-2.5/Porting deleted file mode 100644 index 750556572..000000000 --- a/jam-2.5/Porting +++ /dev/null @@ -1,68 +0,0 @@ -Notes on porting Jam - revised 12/31/2000 - -1) Working out system dependencies in the Jam code. - - Jam's OS footprint is fairly small. For OS independent work Jam - liberally uses standard libc functions like stdio, malloc, and - string. The OS dependent interfaces are: - - From filesys.h: - - file_parse() - split a file name into dir/base/suffix/member - file_build() - build a filename given dir/base/suffix/member - file_dirscan() - scan a directory for files - file_archscan() - scan an archive for files - file_time() - get the timestamp of a file, if not already - done by file_dirscan(). - - From execcmd.h: - - execcmd() - execute a shell script - execwait() - wait for any outstanding execcmd()'s. - - The current implementations are: - - filemac.c - mac MPW - filent.c - NT - fileos2.c - OS/2 - fileunix.c - all UNIX - filevms.c - VMS - - execmac.c - mac MPW - execunix.c - UNIX, OS/2, NT - execvms.c - VMS - -2) Defining OSMAJOR, OSMINOR in jam.h - - So that the Jambase and Jamfile know their host, Jam defines $(OS) - to be something useful for each platform. Make sure that there is - code in jam.h to generate a useful value for $(OS), and key it off - the platform specific C-preprocessor symbol. If the C-preprocessor - doesn't itself defines such a symbol, add a define to the Makefile. - - In addition to $(OS), you can also set $(OSPLAT) if the OS runs on - multiple platforms (like Linux or NT). - -3) Working out system dependencies in the Jambase - - With the value of $(OS) available, the Jambase can be extended to - support special variables or rules for new platforms. See the - current support for VMS, NT, and Mac. - -4) Yacc troubles - - The generated files jamgram.h and jamgram.c are distributed for the - poor souls without yacc. - -5) Known problematic systems: - - - Pyramid has no malloc.h, memory.h - - - Encore has no stdlib.h - - - Bull DPX has sys/file.h problems - -6) Send the results back. - - If you do porting work, the result can be integrated into future - releases if you send it back to the author's address in the README. diff --git a/jam-2.5/README b/jam-2.5/README deleted file mode 100644 index a9dd20c38..000000000 --- a/jam-2.5/README +++ /dev/null @@ -1,154 +0,0 @@ -Jam - make(1) redux - - /+\ - +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - \+/ - - This is Release 2.5 of Jam, a make-like program. - - License is hereby granted to use this software and distribute it - freely, as long as this copyright notice is retained and modifications - are clearly marked. - - ALL WARRANTIES ARE HEREBY DISCLAIMED. - -FEATURES - - -> Jam is a make(1) replacement that makes building simple things - simple and building complicated things manageable. - - -> Jam's language is expressive, making Jamfiles (c.f. Makefiles) - compact. Here's a sample: - - Main smail : main.c map.c resolve.c deliver.c - misc.c parser.y alias.c pw.c headers.c - scanner.l getpath.c str.c ; - - This builds "smail" from a dozen source files. Jam handles - header file dependencies automatically and on-the-fly. - - -> Jam is very portable: it runs on UNIX, VMS, Mac, and NT. - Most Jamfiles themselves are portable, like the sample above. - - -> Jam is unintrusive: it is small, it has negligible CPU - overhead, and it doesn't create any of its own funny files - (c.f. Odin, nmake, SunOS make). - - -> Jam can build large projects spread across many directories - in one pass, without recursing, tracking the relationships - among all files. Jam can do this with multiple, concurrent - processes. - - -> Jam isn't under the blinkin GNU copyright, so you can - incorporate it into commercial products. - - -INFORMATION GUIDE - - Jam.html jam and language reference. - - Jambase.html Reference for the Jambase boilerplate file. - - Jamfile.html Easy reading on creating a Jamfile and using jam. - - RELNOTES Release 2.3 release notes. - - Porting Notes on porting jam to wildcat platforms. - - README This file. Includes installation instructions. - - jam.c Contains the jam command's main() as well as an - introduction to the code, for serious hackers. - - -INSTALLING - - The Makefile (UNIX, NT), build.com (VMS), Build.mpw (Mac MPW) are - for bootstrapping. Once jam is built, it can rebuild itself. - - UNIX - - Build jam with make(1) on: - - Platform $(OS) - ------------------------- - AIX AIX * - BSD/386 1.0 BSDI - COHERENT/386 COHERENT - DGUX 5.4 DGUX - FreeBSD FREEBSD - HPUX 9.0 HPUX - IRIX 5.0 IRIX - Linux LINUX - NEXTSTEP 3.2 NEXT - OSF/1 OSF - PTX V2.1.0 PTX - Solaris 2 SOLARIS * - SunOS4.1 SUNOS - Ultrix 4.2 ULTRIX - BeOS BEOS * - - * requires editing Makefile - - Windows - - Build jam with nmake on: - - Platform $(OS) - ------------------------- - NT NT * - OS/2 OS2 * - - The NT MAXLINE (command line length) is still set in jam.h to - 996, which was apparently the NT 3.5 limit. On 4.0, the limit - is somewhere around 10K. For now, you can increase MAXLINE in - jam.h so that a jam running on 4.0 will use the full command - line length, but that jam.exe will fail miserably on the older OS. - - On NT, a variable must be set before invoking jam to tell - it where the C compiler lives. The name of this variable - depends on which compiler you are using: - - BCCROOT: The Borland C compiler - MSVCDIR: The Microsoft Compiler 6.0 (for NT) - MSVCNT: The Microsoft Compiler 5.0 (for NT) - MSVC: The Microsoft Compiler 1.5 (for Windows) - - Only MSVCNT and MSVCDIR have really been tested and are known - to work. - - Macintosh - - Build jam with Build.mpw on: - - Platform $(OS) - ------------------------- - Macintosh MAC - - You'll need to edit Build.mpw to set CW. - - VMS - - Build jam with @build.com on: - - Platform $(OS) - ------------------------- - VMS 5.4 VMS - OPENVMS OPENVMS - -Comments to the author! - -November, 1993 - release 1.0 -March, 1995 - release 2.0 -February, 1996 - release 2.1 -November, 1997 - release 2.2 -December, 2000 - release 2.3 -March, 2002 - release 2.4 -December, 2002 - release 2.5 rc1 -January, 2003 - release 2.5 rc2 -April, 2003 - release 2.5 rc3 -August, 2004 - release 2.5 (rc3 moniker merely dropped) - -Christopher Seiwald - -seiwald@perforce.com diff --git a/jam-2.5/RELNOTES b/jam-2.5/RELNOTES deleted file mode 100644 index 2ba799446..000000000 --- a/jam-2.5/RELNOTES +++ /dev/null @@ -1,1130 +0,0 @@ -=============================================================================== -=============================================================================== - - -Release notes for Jam 2.5 -(aka Jam - make(1) redux) - -1. Release info: - - Jam 2.5 - August 19, 2004 - VERSION 2.5 - - (n.b. Jam 2.5 is merely Jam 2.5rc3 of April 2003 with the rc3 - moniker removed.) - -2. Compatibility - - Jam 2.5 is upward compatible with Jam 2.4 - - The Jam 2.5 language is a superset of the 2.4 language; - Jamfiles, Jambase, and other rulesets used in 2.4 can be used - with the 2.5 language support. - -3. Changes since 2.4. - -3.1. Changes to Jam Language - - The 'return' statement now actually returns, and there are now - break & continue statements for for & while loops. - -3.2. Jambase Changes - - MkDir now grists directories with 'dir', so that directory - targets can be distinguished from other targets. - - SubDir now allows multiple overlapping roots (top level - directories): the first SubDir of a new root uses the CWD of - jam to set that root; subsquent SubDirs use the current SUBDIR - to set the new root. New FSubDirPath to compute a path (given - SubDir arguments) and SubRules to include another root's - Jamrules. Jamrules only included if present; no error issued - if no Jamrules file. - - Using SubDir to include a subpart of an SubDir tree now works. - Previously, you could only include the root of another SubDir - tree. This example includes the ../server/support/Jamfile, - without getting confused as to the current directory: - - SubDir ALL src builds ; - SubInclude ALL src server support ; - - $(RMDIR) has been defined for NT and defaulted to $(RM) - everwhere else. Not much tested. For Michael Champigny. - - GenFile actions (on UNIX) now put . in the PATH for the execution - of the command, so that (at least) when jam builds itself . does - not need to be in the global path. It is the rare case where a - target bound in the current directory can't be used directly, - so we fudge it by setting PATH. - - Undocumented support for SUBDIRRULES, user-provided rules - to invoke at the end of the SubDir rule, and SUBDIRRESET, - SUBDIR variables to reset (like SUBDIRC++FLAGS, SUBDIRHDRS, etc) - for each new SubDir. - -3.3 'jam' Changes (See Jam.html) - - The whole /MR of Jam's name has been dropped. It was intended - to avoid trademark infringement of JYACC's JAM, but as far as - we can tell (a) it wasn't enough to avoid infringement and (b) - the trademark has lapsed anyhow. - - If header dependencies cause an object to be recompiled and - the source file is a temporary, the temporary is now - reconstructed. Previously, headers weren't considered when - deciding when to reconstruct a temporary. - - -d has been reworked to make it easier to display more useful - tracing information separate from the debugging gunk: - - -da - show all actions (formerly -d2) - -dc - show 'causes' for rebuilding (new output) - -dd - show dependencies (new output) - -dm - show make graph (aka -d3) - -dx - show executable text (formerly -d2) - - -dd is new, and more display options are anticipated. - - -n now implies -dax. - - The message "...using xxx..." now only shows up with -da. - - Jam.html was extensively updated, in an attempt at lucidity. - -3.4. Jam internal code changes - - Removed spurious search() in 'on' statement handling, thanks - (again) to Ingo Weinhold. - - Fix 'includes' support so that included files aren't treated - as direct dependencies during the command execution phase. If - an included file failed to build, make1() would bypass the - including file. Now make0() appends each child's 'includes' - onto its own 'depends' list, eliminating 'includes'-specific - code in make0() and make1(). - - Rewrite of the past: updated all jam's source with comments to - reflect changes since about 2.3, very early 2001. - - -4. Fixed bugs - - Fixed the description of the :E modifier in Jam.html. - - Setting target-specific variables while under the influence of - the target's target-specific variables caused the _global_ values - to be modified. This happened both during header file scanning - (HdrRule is called when target-specific variables are in effect) - and with the "on target statement" syntax. Now setting - target-specific variables works again. Thanks to Matt Armstrong. - - Setting "var on target ?= value" now works as expected: if the - variable is already set on the target, it is left unchanged. - Previously, ?= was ignored and the variable was set anyway. - Thanks to Chris Antos. - - Variable expansion in actions has always put an extra blank - space after the last list element, but the expansion is described - in the code as "space separated". Now the last blank is suppressed - to match. From Miklos Fazekas. - - The temp file name used by jam for .bat files on NT now contains - jam's pid, so that multiple jams can run on the same system (with - the same $TEMP). Thanks to Steve Anichini. - - Several uninitialized memory accesses have been corrected in - var_expand() and file_archscan(), thanks to Matt Armstrong. - -5. Porting - - The Makefile now uses $(EXENAME) (./jam0 on UNIX, .\jam0.exe - on NT) instead of just "jam0", so that . doesn't need to be in - your PATH to bootstrap. - - MACOSX updates: use 'ar' instead of libtool, as libtool can't - update a library and we archive too many things to do it in - one go; add piles of code to file_archscan() to handle new - BSD4.4 style "#1/nnnn" archive entry names, where the real - entry name follows the header and nnnn is the length of the - name. - - The jam code underwent a const-ing, to work with compilers - that don't like "" being passed as a non-const char *. - - Compiling on solaris w/ sparc now sets OSPLAT to "sparc". - Previously, it suppressed this, assuming (wrongly) that sparc - was the only solaris platform. Thanks to Michael Champigny - . - - Jambase no longer announces the compiler it is using on - Windows. It doesn't announce anything else, so why? - - Jambase no longer refers to advapi32.lib on NT, as it isn't - needed for linking jam itself and it seems to move from - release to release (of MS Visual Studio). - - Makefile/Jambase: BEOS updates from "Ingo Weinhold" - . - - The NoCare rule can be used to suppress error messages when - an 'include' file can't be found. - - AIX "big" archives are now supported, thanks to suggestions - from Randy Roesler. - - MSVCDIR now works as well as MSVCNT for the Microsoft Visual C - compiler directory. It changed names in VC 6.0. Thanks to - Matt Armstrong. - - Allow jam to build with BorlandC 5.5 - - For WinXP IA64; set MSVCNT to the root of the SDK and MSVCVer - to Win64; change handle type to long long (too much to include - windows.h?); bury IA64 in the library path in Jambase. - - Mac classic MPW Codewarrior 7 upgrades: minor compiling - issues, new paths in Jambase for libraries and includes, and - separate out GenFile1 that sets PATH for UNIX only, as it - does't work under MPW (or anything other than with sh). - - Minor Cray porting: make hashitem()'s key value unsigned so - we're guaranteed no integer overflows. - - Remove NT FQuote rule, as, \" is required to pass quotes on - the command line. - - Remove temp .bat files created on NT. They used to all have - the same name and get reused, but with 2.5 the names were salted - with the PID and they would litter $TEMP. Now they get removed - after being used. - -=============================================================================== -=============================================================================== - - -Release notes for Jam 2.4 -(aka Jam - make(1) redux) - -1. Release info: - - Jam 2.4 - March, 21, 2002 - VERSION 2.4 - -2. Compatibility - - Jam 2.4 is upward compatible with Jam 2.3 - - The Jam 2.4 language is a superset of the 2.3 language; - Jamfiles, Jambase, and other rulesets used in 2.3 can be used - with the 2.4 language support. - -3. Changes since 2.3. - -3.1. Changes to Jam Language - - The mechanism for calling rules that return values - "[ rule - args ...]", (and 'return' in the rule body), is now a - documented part of the language. - - Add "on ..." syntax, to invoke a - rule under the influence of a target's specific variables. - - Add "[ on targ rule ... ]" to call a rule returning a value, - under the influence of a target's specific variables. - - New 'Glob' builtin that returns a list of files, given a list - of directories, and a list of filename patterns. - - New 'while expr { block }' construct. - - New :E=value modifier provides default value if variable unset. - - New :J=joinval modifier concatenates list elements into single - element, separated by joinval. - - \ can now be used to escape a space (or any single whitespace - character), so that you don't have to resort to quotes. - - New 'Match regexp : string' rule matches regexp against string - and returns list of results. - - Rules can now be invoked indirectly, through variable names. - If the variable expands to an empty list, no rule is run. - If the variable expands to multiple entries, each rule is - run with the same arguments. The result of the rule invocation - is the concatenation of the results of the rules invoked. - - 'Echo' and 'Exit' now have aliases 'echo' and 'exit', since it - is really hard to tell that these are built-in rules and not - part of the language, like 'include'. Real rules continue to - start with a capital. - -3.2. Jambase Changes - - Support for YACCGEN, the suffix used on generated yacc output. - - Fix ups to have jam and p4 build with borland C 5.5, - and minor win98 jam support for jam clean - - SubDirHdrs now takes directory names in the same format as - SubInclude : one directory element per word. - - More portable support for specifying includes and #defines: - New ASHDRS, CCHDRS, CCDEFS, DEFINES, ObjectDefines, FQuote, - FIncludes, FDefines. Ordering of cc and c++ flags grossly - rearranged. - - Jambase has been compacted by applying the new E: and J: - expansion modifiers. - - New SoftLink rule, courtesy of David Lindes. It currently - assumes you can pass a -s flag to $(LN). - -3.3 'jam' Changes (See Jam.html) - - Added '-q' (quit quick) option; jam will exit promptly (as if it - received an interrupt), as soon as any target fails. - - Added experimental '-g' (build newest sources first) option: - all things being equal, normally targets are simply built in - the order they appear in the Jamfiles. With this flag, targets - with the newest sources are built first. From an idea by Arnt - Gulbrandsen. Undocumented (outside this note). - -3.4. Jam internal code changes - - jamgram.yy now defines YYMAXDEPTH to 10000, what it is on - FreeBSD, for older yaccs that left it at 150 or so. This is - needed for the right-recursion now used in the grammar. - - Optimize rule compilation, with right-recursion instead of left. - - Split jam's built-in rules out to builtins.c from compile.c, - so that compile.c only deals with the language. - - Split jam's pathsys.h from filesys.h, since they are really - two different pieces. - - evaluate_if(), which evaluated the condition tree for 'if' and - returned an int, has been replaced with compile_eval(), which does - essentially the same but returns a LIST. - -4. Fixed bugs - - Missing TEMPORARY targets with multiple parents no longer spoil one - parent's time with another. The parents' time is used for comparison - with dependents, but no longer taken on as the target's own time. - - 'actions updated', not 'actions together', now protects targets - from being deleted on failed/interrupted updates. - - Fixed broken $(v[1-]), which always returned an empty expansion. - Thanks to Ian Godin . - - Defining a rule within another rule, and invoking the enclosing - rule more than once, would result in giving the first rule a - null definition. Fixed. - - $(d:P) now works properly on the mac, climbing up directories. - Thanks to Miklos Fazekas . - - No longer (sometimes) treat \ as a directory separator on - UNIX. It isn't supposed to be, but was due to bungled ifdefs. - - Applying just :U or :D (or :E, :J) mods no longer causes the - variable value to be treated as a filename (parsed and rebuilt - using the OS specific pathsys routines). Previously, if _any_ - mods were present then the value was parsed and rebuilt as if - a filename, and that could in certain cases munge the value. - Only the file modifiers (:GDBSM) treat the value as a - filename. - - Four rules makeCommon, makeGrist, makeString, makeSubDir from - jam 2.2 missing in 2.3 have been re-added, with apologies to - dtb@cisco.com. - - Return status more likely to be correct when using -d0, now that - targets are could as being built even with no debugging output. - Thanks to Miklos Fazekas . - - yyacc now suffixes all terminals it defines with _t, so that they - don't conflict with other symbols (like RULE with the typedef - in rules.h). Thanks to Michael Allard. - - InstallInto now handles multiple sources properly, rather than - acting as if each installed target depended on all sources to - be installed. $(INSTALLGRIST) is now the default grist for - installed targets, rather than the hardcoded 'installed'. Thanks - to Stephen Goodson. - -5. Porting - - [MACINTOSH] Paths are now downshifted (internally) so as to - handle its case insensitivity. Thanks to Miklos Fazekas - . - - [NT] MS changed the macro for the IA64 Windows NT 64bit - compiler. - - [CYGWIN] Cygwin jam porting: dance around bison and yyacc. - Use bison's -y flag to use yacc's output file naming - conventions, and don't use yyacc on systems whose SUFEXE is - set. - - [VMS] The Jambase itself was not formatting the CCHDRS and - CCDEFS properly: on VMS they can't be appended to, because - multiple /define or /include directives don't work. Instead - now CCHDRS and CCDEFS is reformatted from HDRS and DEFINES - anytime those latter two change. This requires the recent - change to jam to allow access to target-specific variables - when setting other variables. - - [VMS] Remove exception call when file_dirscan() can't, for - some reason, scan a directory. Use a better set of #ifdefs to - determine if we're on a vax, rather than relying on the C - compiler being a specific version: we're able to build with - the C++ compiler now. - - [VMS] Port new jam to run with just cxx compiler. - (The C compiler being a extra-cost item). - - [NT] Add entry for DevStudio when the settings are already in the - system environment. - - [NT] default $(MV) to "move /y" in Jambase. - - [MINGW] Mingw port by Max Blagai. - -=============================================================================== -=============================================================================== - - -Release notes for Jam 2.3 -(aka Jam - make(1) redux) - -0. Bugs fixed since 2.3.1 - - PATCHLEVEL 2 - 3/12/2001 - - NOCARE changed back: it once again does not applies to targets - with sources and/or actions. In 2.3 it was changed to apply to - such targets, but that broke header file builds: files that are - #included get marked with NOCARE, but if they have source or - actions, they still should get built. - -1. Release info: - - Jam 2.3 - November 16, 2000 - VERSION 2.3 - PATCHLEVEL 1 - -2. Compatibility - - Jam 2.3 is upward compatible with Jam 2.2. - - The Jam 2.3 language is a superset of the 2.2 language; - Jamfiles, Jambase, and other rulesets used in 2.2 can be used - with the 2.3 language support. - -3. Changes since 2.2 - -3.1. Changes to Jam Language - - Rules now can have values, which can expanded into a list with - the new "[ rule args ... ]" syntax. A rule's value is the value - of its last statement, though only the following statements have - values: if (value of the leg chosen), switch (ditto), set (value - of the resulting variable), return (its arguments). Note that - 'return' doesn't actually return. This support is EXPERIEMENTAL - and otherwise undocumented. (2.3.1) - - Because of the new way lists are processed, if a rule has no - targets a warning message is no longer issued. - - NOCARE now applies to targets with sources and/or actions, - rather than just those without. - -3.2. Jambase Changes - - The HDRPATTERN variable now allows for leading blanks before - the #include, to keep up with ANSI. By john@nanaon-sha.co.jp - (John Belmonte) (2.2.3). - - HDRPATTERN has been adjusted to avoid mistaking cases like: - - # include /* could be */ - - MkDir now NOUPDATE's $(DOT), so that there are no dependencies - on the current directory's timestamp. By john@nanaon-sha.co.jp - (John Belmonte). - - The old mock functions like makeDirName, which assigned their - results to the variable named as their first argument, have - been replaced with real functions using the new [] syntax. - E.g. "makeDirName foo : bar ola" is now "foo = [ fDirName bar ]" - - Install now always does a cp/chmod/etc, rather than using - the system's install(1), which invariably seems broken. - -3.3. Jam internal code changes - - $JAMUNAME is set on UNIX. (2.2.4). - - Jam ANSI-fied (2.3.0). - - jam.h now defines a bunch of symbols used by the other source - files, so as minimize compiler- and platform-specific ifdefs. - - OSVER is no longer set by jam.h (it was only set for AIX). - Jam does not depend on this variable at all, except to set - $(OSFULL), which is used to determine jam's build directory. - If the user needs to distinguish between various revs of - OSs, he must set OSVER in the environment. - -4. Fixed bugs - - Redefining a rule while it was executing could cause jam to - crash. Reference counts are now used to prevent that, thanks - to Matt Armstrong. - - Logic for computing chunk size when executing PIECEMEAL rules - has been reworked to be a little more accurate, without danger - of overflow, at the cost of being a little more compute intensive. - Instead of computing an estimate chunksize in the (now gone) - make1chunk(), make1cmds() now just goes full bore and tries to - use all args. When that fails, it backs off by 10% of the source - args until the command fits. It takes a little bit more compute - time compared to the old logic, but when you're executing actions - to build all of Shinola it's still pretty small in the scheme - of things. - - The NT handle leak in execunix.c has been fixed, thanks to - Gurusamy Sarathy. (2.2.1). - -5. Porting - - Platforms newly supported or updated: - - AmigaOS (with gcc), courtesy of Alain Penders (2.2.2). - - Beos - - CYGWIN 1.1.4, courtesy of John Belmonte . - - IBM AS400 via Visual Age on NT (primitive) - - IBM OS/390 Unix System Services - - Linux SuSE on OS390 - - Linux Mips, ARM - - Lynx - - HPUX 11, IA64 - - Mac OS X Server, courtesy of Jeff_Sickel@sickel.com (2.2.5). - - Mac Rhapsody - - MPE IX 6.0 - - NetBSD - - QNX RTP (QNX 6.0) - - Siemens Sinix - - UNICOS - - VMS 6.2, 7.1 - - Windows NT IA64 - -5.1. NT Porting Notes - - Always create tmp .bat file for actions if JAMSHELL is set. - That way, if JAMSHELL is a .bat file itself, it can handle - single-command actions with more than 9 cmd line args. - - COMSPEC is no longer examined: cmd.exe is always used - instead. Only cmd.exe can execute the Jambase rules anyhow. - - Jam can be built with Borland C++ 5.5. - - OS2 fixes: InstallBin now works. Filenames are now downshifted, - so mixed case works better there, too. file_dirscan() can now scan - the root ("c:\" or "\") directory, which it couldn't handle before. - - var_defines now ignores OS=Windows_NT, because it conflicts - with Jam's setting of OS (to NT). - -5.2. Mac OS 8/9 Notes - - The support for Mac is curious at best. It runs under MPW. - - It requires CodeWarrior Pro 5, but no longer requires GUSI. - - Use Build.mpw to bootstrap the build. - - The Mac specific definitions in the Jambase are not intended - to be of general purpose, but are sufficient to have Jam build - itself. - -=============================================================================== -=============================================================================== - - -Release Notes for Jam 2.2 - -1. Release info: - - Jam 2.2 - October 22, 1997 - VERSION 2.2 - PATCHLEVEL 1 - -2. Compatibility - - Jam 2.2 is a roll-up of 'Jam - make(1) redux' release 2.1+. - Most of the changes described below were available before this, - in the jam.2.1.plus.tar ball. - - The Jam 2.2 language is a superset of the 2.1 language; - Jamfiles, Jambase, and other rulesets used in 2.1 can be used - with the 2.2 language support. - - See 'Jambase Changes', below, to see if your Jamfiles need any - changes to work with the 2.2 Jambase. - - -3. Changes Since 2.1 - - New product name: Jam. (Executable program is still named 'jam'.) - - Documentation rewritten; HTML versions supplied. - - -3.1 Changes to Jam Language - - Rules may now have more fields than just $(<) and $(>). - - Local variables are now supported. - - The expression 'if $(A) in $(B)' is now supported. - - New variable modifiers :U and :L result in uppercased or lowercased - values. - - New variable modifier :P reliably results in parent directory - of either a file or directory. (Previously, :D was used, but on VMS - :D of a directory name is just the directory name.) - - The :S variable modifier now results in the _last_ suffix if a - filename has more than one dot (.) in it. - - New predefined $(JAMDATE) variable is initialized at runtime for - simple date stamping. - - New predefined variables $(OSVER) and $(OSPLAT) are used to - distinguish among operating system versions and hardware platforms, - when possible. - - New 'bind' qualifier on action definitions allows variables - other than $(<) and $(>) to be bound with SEARCH and LOCATE paths. - - Action buffer size is no longer limited by MAXCMD. Instead, each - line in an action is limited by MAXLINE, defined for each OS, and - the entire action size is limited by CMDBUF. - - -3.2 Jambase Changes (See Jamfile.html) - - Jambase has been reworked to incorporate new language features. - - A handful of new utility rules has been added: makeString, - makeDirName, etc. - - New HDRGRIST variable in Jambase allows for headers with the same - name to be distinguished. - - LOCATE_TARGET now has a new flavor, LOCATE_SOURCE, that is used by - rules that generate source files (e.g., Yacc and Lex). - - Header file includes now happen in the proper order. The limit of - 10 include files has been eliminated. - - The old "Install" rule is no longer available. Use InstallBin, - InstallFile, InstallLib, InstallMan, or InstallShell instead. - - -3.3 'jam' Changes (See Jam.html) - - 'jam' can now be built as a stand-alone program, with Jambase - compiled into the executable. An external or alternate Jambase can - still be referenced explicitly with -f. - - On command failure, 'jam' now emits the text of the command that - failed. This is a compromise between the normal -d1 behavior (where - commands were never seen) and -d2 (where commands are always seen). - - 'jam' now exits non-zero if it doesn't have a total success. A parse - error, sources that can't be found, and targets that can't be built - all generate non-zero exit status. - - The debugging levels (-d flags) have been slightly redefined. - - The supplied Jamfile now builds 'jam' into a platform specific - subdirectory. This lets you use the same source directory to - build 'jam' for more than one platform. - - The supplied Jamfile does not rebuild generated source files by - default. (They are supplied with the distribution.) See Jamfile - for more information. - - -4. Fixed Bugs - - The 'include' bug has finally been fixed, so that include - statements take effect exactly when they are executed, - rather than after the current statement block. This also - corrects the problem where an 'include' within an 'if' - block would wind up including the file one token after the - 'if' block's closing brace. Credit goes to Thomas Woods - for suggesting that the parse tree generation and parse - tree execution be paired in their own loop, rather than - having the parser execute the tree directly. - - The setting and extracting of grist has been regularized: - normally, if you set a component of a filename (using the - :DBSMG= modifiers), you are supposed to include the delimiters - that set off the component: that is, you say "$(x:S=.suffix)", - including the ".". But with grist it was inconsistent - between setting and getting: setting grist required no - <>'s, while getting grist included them. Getting grist - continues to return the <>'s, but now setting grist can - either include them (the new way) or not (the old way). - - 'actions together' now suppresses duplicate sources from - showing up in $(>). - - Accessing variables whose names contained ['s (as happens with - MkDir on VMS) wasn't working, because it treated the [ as an - array subscript. Now [ and ] are, like :, handled specially so - that they can appear in variable values. - - The 'if' statement now compares all elements in expressions; - previously, it only compared the first element of each list. - - If a command line in an action is longer than MAXLINE (formerly - MAXCMD), 'jam' now issues an error and exits rather than dumping - core. - - If a Jamfile ended without a trailing newline, jam dumped core. - This has been fixed. - - -5. Porting - - See jam.h for the definitive list of supported platforms. - Since 2.1, support has been added for: - - Macintosh MPW - Alpha VMS - Alpha NT - NT PowerPC - BeOS - MVS OE - UNIXWARE - QNX - SINIX (Nixdorf) - OS/2 - Interactive UNIX (ISC), courtesy of Matthew Newhook - - -5.1 NT Support Fixes - - The NT command executor now handles multiple line actions, by writing - multi-line actions to a batch file and executing that. - - Targets are universally lowercased on NT. (Matthew Newhook) - - Concurrent process support is fully enabled for NT. - (Gurusamy Sarathy ) - - Path handling: Jam now knows that the directory component of "D:\" - is "D:\", just as on unix it knows that the directory component of - "/" is "/". It also now successfully gets the timestamp for "D:\" - or just plain "\". - - -5.2 VMS Support Fixes - - VMS support is much, much better now. The path name manipulation - routines (in pathvms.c) were more or less rewritten, and they now - handle the vagaries of combining directory and file names properly. - - Targets are universally lowercased on VMS. - - Multi-line command blocks on VMS are now executed in a single system() - call rather than separate ones for each line, so that actions can - be DCL scripts. - -=============================================================================== -=============================================================================== - - -Release notes for Jam 2.1. - -1. Release info: - Jam 2.1 - February 1, 1996 - VERSION 2.1 - PATCHLEVEL 0 - -2. Porting - - Linux is now supported. - - FREEBSD is now supported. - - SCO ("M_XENIX") now supported. - - NCR now supported. - - NEXT support from karthy@dannug.dk (Karsten Thygesen) - - DECC support from zinser@axp614.gsi.de (Martin P.J. Zinser) - - I have changes for OS/2, but no way to test them. Volunteers? - I have VMS multiprocess support, but no way to test it. Volunteers? - -2.1. NT Support fixes. - - The NT support is considerably more real than it was in 2.0. - Filent.c had its syntax error corrected, it no longer skips the - first entry when scanning directories, and it handles string - tables in archives (for long object file names). - - The Jambase was changed a bit to support the various C/C++ - compilers on NT, although it has only been thorougly tested - with MSVC20. - - You still need to set MSVCNT or BCCROOT to the root of the - the compiler's directory tree, and you'll get an error if you - don't set it (rather than getting a pile of mysterious errors). - -2.2. Other porting fixes. - - SPLITPATH now set up for UNIX (:), NT (;), VMS (,) - - Jambase support for Solaris works better now: the location of - AR is hardwired to /usr/ccs/bin/ar and it knowns "install" - doesn't take -c. Solaris -- how the mighty have fallen. - - To handle Linux's wacko yacc, jamgram.h is now included after - scan.h so that YYSTYPE is define. - -3. Jambase Changes (see Jamfile.html) - - SubDir now computes the root directory for the source tree, if - the variable naming the root directory isn't set in the environment. - It counts the number of directory elements leading from the root - to the current directory (as passed to SubDir) and uses that many - "../"'s to identify the root. This means that to use SubDir you - no longer have to have anything special set in the environment. - - InstallFile is now an alias for InstallLib. - - 'first' is now dependency of all pseudo-targets (all, files, - exe, lib, shell), so that jamming any of these pseudo-targets - also builds any dependencies of 'first'. - - The File rule definition in the Jambase was missing an &. - - The File rule now calls the Clean rule, so that installed files - get cleaned. - -4. Jam changes (see Jam.html) - - Variables may now be set on the command line with -svar=value. - - Targets marked with NOUPDATE are now immune to the -a (anyhow) - flag. Previously, the MkDir rule would try to recreate directories - that already exist when jam was invoked with -a. - - A new variable, $(JAMVERSION), joins the small list of built-in - variables. It it set to the release of jam, currently "2.1". - - If an actions fails, jam now deletes the target(s). It won't - delete libraries or other targets that are composites. This is - now consistent with jam's behavior on interrupts (it deletes the - targets). - - Jam had a nasty bug when setting multiple variables to the same - value: if the first two variable names were the same, the variable - value got trashed. This also affected "on target" variables if - the first two targets were the same. For example: - - FOO on bar.c bar.c foo.c = a b c ; - - This would mangle the value of FOO for bar.c and foo.c. This has - been fixed. - - Jam would generate bogus numbers when reporting the number of - targets updated after an interrupt. It now is more careful about - counting. - - The debugging flag -d has been extended. In addition to supporting - -dx (turn on debugging for all levels up to x) there is also now - -d+x (turn on debugging at only level x). The default output - level is -d1 (-or d2 if -n is given); this can be turned off with - -d0. The debug levels are listed in jam.1 and jam.h. - - The parsing debug output now uses indenting to indicate when - one rule invokes another. - -=============================================================================== -=============================================================================== - - -Release notes for Jam 2.0. - -1. Release info: - Jam 2.0 - March 10, 1994 - VERSION 2.0 - PATCHLEVEL 5 - -2. Porting - - Windows/NT is now (crudely) supported, courtesy of Brett Taylor - and Laura Wingerd. - - COHERENT/386 is now supported, courtesy of Fred Smith. - - Solaris archive string table for long archive names is now - supported, thanks to Mike Matrigali. - -3. Compatibility - - Jam 2.0 syntax is a superset of Jam 1.0 syntax, and thus it can - interpret a Jam 1.0 Jambase. - - The Jam 2.0 Jambase is a superset of the Jam 1.0 Jambase, and - thus it can include a Jamfile written for Jam 1.0. - -4. Changes from Jam 1.0 to Jam 2.0 - -4.1. Documentation changes - - New Jamfile.5 manual page, with lots of examples and easy - reading. It replaces both the old "Examples" file as well as - the old Jambase.5 manual page. - - jam.1 edited by Stephen W. Liddle and Diane Holt. - -4.2. Jambase Changes (see Jamfile.5) - -4.2.1. New rules: - - There are new rules to make handling subdirectories easier: - SubDir, SubInclude, SubDirCcFlags, SubDirHdrs. - - There are new rules to handle file-specific CCFLAGS and HDRS: - ObjectCcFlags and ObjectHdrs. - - Misc new rules: HardLink, InstallShell, MkDir. - - New rule "clean" that deletes exactly what jam has built, and - "uninstall" that deletes exactly what was installed. - - New rules for handling suffixes .s, .f, .cc, .cpp, .C. - -4.2.2. Old rules: - - The InstallBin, Lib, Man, and the new Shell rules now take the - destination directory as the target and the files to be copied - as sources. These rules formerly took the files to be copied - as targets, and used built-in destination directories of - $(BINDIR), $(LIBDIR), $(MANDIR), and $(BINDIR). - - The InstallBin, Lib, Man, and Shell rules use the install(1) - program now, instead of doing their own copying. - - The Cc rule now uses -o when possible, rather than moving the - result. Some platforms (Pyramid?) have a broken -o. - - Jambase rules taking libraries, objects, and executables now - all ignore the suffixes provided and use the one defined in the - Jambase for the platform. - - Stupid yyacc support moved out of Jambase, as jam is its only - likely user. - - Jambase now purturbs library sources with a "grist" of - SOURCE_GRIST. - -4.2.3. Misc: - - The names of the default rules defined in Jambase have been - lowercased and un-abbreviated, to be more imake(1) like. - - The Jambase has been reorganized and sorted, with VMS and NT - support moved in from their own files. - - The Jambase has been relocated on UNIX from /usr/local/lib/jam - to /usr/local/lib. - -4.3. Jam changes (see jam.1) - -4.3.1. Flags: - - New -a (anyhow) flag: means build everything. - - New -j flag: run jobs in parallel. - - Old -t now rebuilds the touched target, rather that just the - target's parents. - - -n now implies -d2, so that you see what's happening. The - debug level can be subsequently overridden. - - New -v to dump version. - -4.3.2. Rules: - - New ALWAYS rule behaves like -t: always builds target. - - New EXIT rule makes it possible to raise a fatal error. - - New LEAVES rule which say target depends only on the update - times of the leaf sources. - - New NOUPDATE rule says built targets only if they don't exist. - - NOTIME has been renamed NOTFILE, to more accurately reflect its - meaning (it says a target is not to be bound to a file). - -4.3.3. Variables: - - New special variable JAMSHELL: argv template for command execution - shell. - - Variables, both normal and target-specific, can have their - value appended with the syntax "var += value" or "var on target - += value". - - "?=" is now synonymous with "default =". - - Imported enviroment variable values are now split at blanks - (:'s if the variable name ends in PATH), so that they become - proper list values. - -4.3.4. Misc: - - Files to be sourced with "include" are now bound first, so - $(SEARCH) and $(LOCATE) affect them. They still can't be - built, though. - - New modifier on "actions": "existing" causes $(>) to expand - only those files that currently exist. - -4.3.5. Bug fixes: - - When scanning tokens known to be argument lists (such as the - arguments to rule invocations and variable assignment), the - parser now tells the scanner to ignore alphabetic keywords, as - all such lists terminate with punctuation keywords (like : or - ;). This way, alphabetic keywords don't need to be quoted when - they appear as arguments. - - The scanner has been fixed to handle oversized tokens, - unterminated quotes, unterminated action blocks, and tokens - abutting EOF (i.e. a token with no white space before EOF). - - The progress report "...on xth target..." used to count all - targets, rather than just those with updating actions. Since - the original pronouncement of targets to be udpated included - only those with updating actions, the progress report has been - changed to match. - - 'If' conditionals now must be single arguments. Previously, - they could be zero or more arguments, which didn't make much - sense, and made things like 'foo == bar' true. The comparison - operator is '=', and '==' just looked like the second of three - arguments in the unary "non-empty argument list" conditional. - - Header files indirectly including themselves were mistakenly - reported as being dependent on themselves. Recursing through - header file dependencies is now done after determining the fate - of the target. - - The variable expansion support was expanding $(X)$(UNDEF) as if - it were $(X). It now expands to an empty list, like it - should. - - The UNIX version of file_build() didn't handle "dir/.suffix" - right. Now it does. - - The VMS command buffer was assumed to be as large as 1024 bytes, - which isn't the case everywhere as it is related to some weird - quota. It has been lowered to 256. - - $(>) and $(<) wouldn't expand in action blocks if the targets - were marked with NOTIME. Now they expand properly. - - Malloc() return values are now checked. - - The variable expansion routine var_expand() is now a little - faster, by taking a few often needed shortcuts. - - The VMS version of file_build() used the wrong length when - re-rooting file names that already had directory compoents. - This was fixed. - - Various tracing adjustments were made. - -5. Limitations/Known Bugs - - The new Windows/NT support has only been marginally tested. It - is dependent on certain variables being set depending on which - compiler you are using. You'll need to look in the file - Jambase and see what variables are expected to be set. - - The VMS support has been tested, courtesy of the DEC guest - machine, but has not been hammered fully in release 2.0. It - was used quite a bit in Jam 1.0. - - Jam clean when there is nothing to clean claims it is updating - a target. - - Because the include statement works by pushing a new file in - the input stream of the scanner rather than recursively - invoking the parser on the new file, multiple include - statements in a rule's procedure causes the files to be - included in reverse order. - - If the include statement appears inside an if block, the - parser's attempt to find the else will cause the text of the - included file to appear after the first token following the - statement block. This is rarely what is intended. - - In a rule's actions, only $(<) and $(>) refer to the bound file - names: all other variable references get the unbound names. - This is a pain for $(NEEDLIBS), because it means that library - path can't be bound using $(SEARCH) and $(LOCATE). - - With the -j flag, errors from failed commands can get - staggeringly mixed up. Also, because targets tend to get built - in a quickest-first ordering, dependency information must be - quite exact. Finally, beware of parallelizing commands that - drop fixed-named files into the current directory, like yacc(1) - does. - - A poorly set $(JAMSHELL) is likely to result in silent - failure. diff --git a/jam-2.5/builtins.c b/jam-2.5/builtins.c deleted file mode 100644 index a1b317c9d..000000000 --- a/jam-2.5/builtins.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * builtins.c - builtin jam rules - * - * External routines: - * - * load_builtin() - define builtin rules - * - * Internal routines: - * - * builtin_depends() - DEPENDS/INCLUDES rule - * builtin_echo() - ECHO rule - * builtin_exit() - EXIT rule - * builtin_flags() - NOCARE, NOTFILE, TEMPORARY rule - * builtin_glob() - GLOB rule - * builtin_match() - MATCH rule - * - * 01/10/01 (seiwald) - split from compile.c - * 01/08/01 (seiwald) - new 'Glob' (file expansion) builtin - * 03/02/02 (seiwald) - new 'Match' (regexp match) builtin - * 04/03/02 (seiwald) - Glob matches only filename, not directory - * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() - * 10/22/02 (seiwald) - working return/break/continue statements - * 11/04/02 (seiwald) - const-ing for string literals - * 12/03/02 (seiwald) - fix odd includes support by grafting them onto depends - * 01/14/03 (seiwald) - fix includes fix with new internal includes TARGET - */ - -# include "jam.h" - -# include "lists.h" -# include "parse.h" -# include "builtins.h" -# include "rules.h" -# include "filesys.h" -# include "newstr.h" -# include "regexp.h" -# include "pathsys.h" - -/* - * compile_builtin() - define builtin rules - */ - -# define P0 (PARSE *)0 -# define C0 (char *)0 - -LIST *builtin_depends( PARSE *parse, LOL *args, int *jmp ); -LIST *builtin_echo( PARSE *parse, LOL *args, int *jmp ); -LIST *builtin_exit( PARSE *parse, LOL *args, int *jmp ); -LIST *builtin_flags( PARSE *parse, LOL *args, int *jmp ); -LIST *builtin_glob( PARSE *parse, LOL *args, int *jmp ); -LIST *builtin_match( PARSE *parse, LOL *args, int *jmp ); - -int glob( const char *s, const char *c ); - -void -load_builtins() -{ - bindrule( "Always" )->procedure = - bindrule( "ALWAYS" )->procedure = - parse_make( builtin_flags, P0, P0, P0, C0, C0, T_FLAG_TOUCHED ); - - bindrule( "Depends" )->procedure = - bindrule( "DEPENDS" )->procedure = - parse_make( builtin_depends, P0, P0, P0, C0, C0, 0 ); - - bindrule( "echo" )->procedure = - bindrule( "Echo" )->procedure = - bindrule( "ECHO" )->procedure = - parse_make( builtin_echo, P0, P0, P0, C0, C0, 0 ); - - bindrule( "exit" )->procedure = - bindrule( "Exit" )->procedure = - bindrule( "EXIT" )->procedure = - parse_make( builtin_exit, P0, P0, P0, C0, C0, 0 ); - - bindrule( "Glob" )->procedure = - bindrule( "GLOB" )->procedure = - parse_make( builtin_glob, P0, P0, P0, C0, C0, 0 ); - - bindrule( "Includes" )->procedure = - bindrule( "INCLUDES" )->procedure = - parse_make( builtin_depends, P0, P0, P0, C0, C0, 1 ); - - bindrule( "Leaves" )->procedure = - bindrule( "LEAVES" )->procedure = - parse_make( builtin_flags, P0, P0, P0, C0, C0, T_FLAG_LEAVES ); - - bindrule( "Match" )->procedure = - bindrule( "MATCH" )->procedure = - parse_make( builtin_match, P0, P0, P0, C0, C0, 0 ); - - bindrule( "NoCare" )->procedure = - bindrule( "NOCARE" )->procedure = - parse_make( builtin_flags, P0, P0, P0, C0, C0, T_FLAG_NOCARE ); - - bindrule( "NOTIME" )->procedure = - bindrule( "NotFile" )->procedure = - bindrule( "NOTFILE" )->procedure = - parse_make( builtin_flags, P0, P0, P0, C0, C0, T_FLAG_NOTFILE ); - - bindrule( "NoUpdate" )->procedure = - bindrule( "NOUPDATE" )->procedure = - parse_make( builtin_flags, P0, P0, P0, C0, C0, T_FLAG_NOUPDATE ); - - bindrule( "Temporary" )->procedure = - bindrule( "TEMPORARY" )->procedure = - parse_make( builtin_flags, P0, P0, P0, C0, C0, T_FLAG_TEMP ); -} - -/* - * builtin_depends() - DEPENDS/INCLUDES rule - * - * The DEPENDS builtin rule appends each of the listed sources on the - * dependency list of each of the listed targets. It binds both the - * targets and sources as TARGETs. - */ - -LIST * -builtin_depends( - PARSE *parse, - LOL *args, - int *jmp ) -{ - LIST *targets = lol_get( args, 0 ); - LIST *sources = lol_get( args, 1 ); - LIST *l; - - for( l = targets; l; l = list_next( l ) ) - { - TARGET *t = bindtarget( l->string ); - - /* If doing INCLUDES, switch to the TARGET's include */ - /* TARGET, creating it if needed. The internal include */ - /* TARGET shares the name of its parent. */ - - if( parse->num ) - { - if( !t->includes ) - t->includes = copytarget( t ); - t = t->includes; - } - - t->depends = targetlist( t->depends, sources ); - } - - return L0; -} - -/* - * builtin_echo() - ECHO rule - * - * The ECHO builtin rule echoes the targets to the user. No other - * actions are taken. - */ - -LIST * -builtin_echo( - PARSE *parse, - LOL *args, - int *jmp ) -{ - list_print( lol_get( args, 0 ) ); - printf( "\n" ); - return L0; -} - -/* - * builtin_exit() - EXIT rule - * - * The EXIT builtin rule echoes the targets to the user and exits - * the program with a failure status. - */ - -LIST * -builtin_exit( - PARSE *parse, - LOL *args, - int *jmp ) -{ - list_print( lol_get( args, 0 ) ); - printf( "\n" ); - exit( EXITBAD ); /* yeech */ - return L0; -} - -/* - * builtin_flags() - NOCARE, NOTFILE, TEMPORARY rule - * - * Builtin_flags() marks the target with the appropriate flag, for use - * by make0(). It binds each target as a TARGET. - */ - -LIST * -builtin_flags( - PARSE *parse, - LOL *args, - int *jmp ) -{ - LIST *l = lol_get( args, 0 ); - - for( ; l; l = list_next( l ) ) - bindtarget( l->string )->flags |= parse->num; - - return L0; -} - -/* - * builtin_globbing() - GLOB rule - */ - -struct globbing { - LIST *patterns; - LIST *results; -} ; - -static void -builtin_glob_back( - void *closure, - const char *file, - int status, - time_t time ) -{ - struct globbing *globbing = (struct globbing *)closure; - LIST *l; - PATHNAME f; - char buf[ MAXJPATH ]; - - /* Null out directory for matching. */ - /* We wish we had file_dirscan() pass up a PATHNAME. */ - - path_parse( file, &f ); - f.f_dir.len = 0; - path_build( &f, buf, 0 ); - - for( l = globbing->patterns; l; l = l->next ) - if( !glob( l->string, buf ) ) - { - globbing->results = list_new( globbing->results, file, 0 ); - break; - } -} - -LIST * -builtin_glob( - PARSE *parse, - LOL *args, - int *jmp ) -{ - LIST *l = lol_get( args, 0 ); - LIST *r = lol_get( args, 1 ); - - struct globbing globbing; - - globbing.results = L0; - globbing.patterns = r; - - for( ; l; l = list_next( l ) ) - file_dirscan( l->string, builtin_glob_back, &globbing ); - - return globbing.results; -} - -/* - * builtin_match() - MATCH rule, regexp matching - */ - -LIST * -builtin_match( - PARSE *parse, - LOL *args, - int *jmp ) -{ - LIST *l, *r; - LIST *result = 0; - - /* For each pattern */ - - for( l = lol_get( args, 0 ); l; l = l->next ) - { - regexp *re = regcomp( l->string ); - - /* For each string to match against */ - - for( r = lol_get( args, 1 ); r; r = r->next ) - if( regexec( re, r->string ) ) - { - int i, top; - - /* Find highest parameter */ - - for( top = NSUBEXP; top-- > 1; ) - if( re->startp[top] ) - break; - - /* And add all parameters up to highest onto list. */ - /* Must have parameters to have results! */ - - for( i = 1; i <= top; i++ ) - { - char buf[ MAXSYM ]; - int l = re->endp[i] - re->startp[i]; - memcpy( buf, re->startp[i], l ); - buf[ l ] = 0; - result = list_new( result, buf, 0 ); - } - } - - free( (char *)re ); - } - - return result; -} diff --git a/jam-2.5/builtins.h b/jam-2.5/builtins.h deleted file mode 100644 index beecb32e8..000000000 --- a/jam-2.5/builtins.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * builtins.h - compile parsed jam statements - * - * 01/10/01 (seiwald) - split from compile.h - */ - -void load_builtins(); - diff --git a/jam-2.5/command.c b/jam-2.5/command.c deleted file mode 100644 index 931b4c83a..000000000 --- a/jam-2.5/command.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * command.c - maintain lists of commands - * - * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C - * 09/08/00 (seiwald) - bulletproof PIECEMEAL size computation - */ - -# include "jam.h" - -# include "lists.h" -# include "parse.h" -# include "variable.h" -# include "rules.h" - -# include "command.h" - -/* - * cmd_new() - return a new CMD or 0 if too many args - */ - -CMD * -cmd_new( - RULE *rule, - LIST *targets, - LIST *sources, - LIST *shell, - int maxline ) -{ - CMD *cmd = (CMD *)malloc( sizeof( CMD ) ); - - cmd->rule = rule; - cmd->shell = shell; - cmd->next = 0; - - lol_init( &cmd->args ); - lol_add( &cmd->args, targets ); - lol_add( &cmd->args, sources ); - - /* Bail if the result won't fit in maxline */ - /* We don't free targets/sources/shell if bailing. */ - - if( var_string( rule->actions, cmd->buf, maxline, &cmd->args ) < 0 ) - { - cmd_free( cmd ); - return 0; - } - - return cmd; -} - -/* - * cmd_free() - free a CMD - */ - -void -cmd_free( CMD *cmd ) -{ - lol_free( &cmd->args ); - list_free( cmd->shell ); - free( (char *)cmd ); -} diff --git a/jam-2.5/command.h b/jam-2.5/command.h deleted file mode 100644 index 28ecd7a67..000000000 --- a/jam-2.5/command.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 1994 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * command.h - the CMD structure and routines to manipulate them - * - * Both ACTION and CMD contain a rule, targets, and sources. An - * ACTION describes a rule to be applied to the given targets and - * sources; a CMD is what actually gets executed by the shell. The - * differences are due to: - * - * ACTIONS must be combined if 'actions together' is given. - * ACTIONS must be split if 'actions piecemeal' is given. - * ACTIONS must have current sources omitted for 'actions updated'. - * - * The CMD datatype holds a single command that is to be executed - * against a target, and they can chain together to represent the - * full collection of commands used to update a target. - * - * Structures: - * - * CMD - an action, ready to be formatted into a buffer and executed - * - * External routines: - * - * cmd_new() - return a new CMD or 0 if too many args - * cmd_free() - delete CMD and its parts - * cmd_next() - walk the CMD chain - */ - -/* - * CMD - an action, ready to be formatted into a buffer and executed - */ - -typedef struct _cmd CMD; - -struct _cmd -{ - CMD *next; - CMD *tail; /* valid on in head */ - RULE *rule; /* rule->actions contains shell script */ - LIST *shell; /* $(SHELL) value */ - LOL args; /* LISTs for $(<), $(>) */ - char buf[ MAXLINE ]; /* actual commands */ -} ; - -CMD *cmd_new( - RULE *rule, /* rule (referenced) */ - LIST *targets, /* $(<) (freed) */ - LIST *sources, /* $(>) (freed) */ - LIST *shell, /* $(SHELL) (freed) */ - int maxline ); /* max line length */ - -void cmd_free( CMD *cmd ); - -# define cmd_next( c ) ((c)->next) diff --git a/jam-2.5/compile.c b/jam-2.5/compile.c deleted file mode 100644 index 94c1bdc4b..000000000 --- a/jam-2.5/compile.c +++ /dev/null @@ -1,929 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * compile.c - compile parsed jam statements - * - * External routines: - * - * compile_append() - append list results of two statements - * compile_break() - compile 'break/continue/return' rule - * compile_eval() - evaluate if to determine which leg to compile - * compile_foreach() - compile the "for x in y" statement - * compile_if() - compile 'if' rule - * compile_include() - support for 'include' - call include() on file - * compile_list() - expand and return a list - * compile_local() - declare (and set) local variables - * compile_null() - do nothing -- a stub for parsing - * compile_on() - run rule under influence of on-target variables - * compile_rule() - compile a single user defined rule - * compile_rules() - compile a chain of rules - * compile_set() - compile the "set variable" statement - * compile_setcomp() - support for `rule` - save parse tree - * compile_setexec() - support for `actions` - save execution string - * compile_settings() - compile the "on =" (set variable on exec) statement - * compile_switch() - compile 'switch' rule - * - * Internal routines: - * - * debug_compile() - printf with indent to show rule expansion. - * evaluate_rule() - execute a rule invocation - * - * 02/03/94 (seiwald) - Changed trace output to read "setting" instead of - * the awkward sounding "settings". - * 04/12/94 (seiwald) - Combined build_depends() with build_includes(). - * 04/12/94 (seiwald) - actionlist() now just appends a single action. - * 04/13/94 (seiwald) - added shorthand L0 for null list pointer - * 05/13/94 (seiwald) - include files are now bound as targets, and thus - * can make use of $(SEARCH) - * 06/01/94 (seiwald) - new 'actions existing' does existing sources - * 08/23/94 (seiwald) - Support for '+=' (append to variable) - * 12/20/94 (seiwald) - NOTIME renamed NOTFILE. - * 01/22/95 (seiwald) - Exit rule. - * 02/02/95 (seiwald) - Always rule; LEAVES rule. - * 02/14/95 (seiwald) - NoUpdate rule. - * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C - * 09/07/00 (seiwald) - stop crashing when a rule redefines itself - * 09/11/00 (seiwald) - new evaluate_rule() for headers(). - * 09/11/00 (seiwald) - rules now return values, accessed via [ rule arg ... ] - * 09/12/00 (seiwald) - don't complain about rules invoked without targets - * 01/13/01 (seiwald) - fix case where rule is defined within another - * 01/10/01 (seiwald) - built-ins split out to builtin.c. - * 01/11/01 (seiwald) - optimize compile_rules() for tail recursion - * 01/21/01 (seiwald) - replace evaluate_if() with compile_eval() - * 01/24/01 (seiwald) - 'while' statement - * 03/23/01 (seiwald) - "[ on target rule ]" support - * 02/28/02 (seiwald) - merge EXEC_xxx flags in with RULE_xxx - * 03/02/02 (seiwald) - rules can be invoked via variable names - * 03/12/02 (seiwald) - &&,&,||,|,in now short-circuit again - * 03/25/02 (seiwald) - if ( "" a b ) one again returns true - * 06/21/02 (seiwald) - support for named parameters - * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() - * 10/22/02 (seiwald) - working return/break/continue statements - * 11/04/02 (seiwald) - const-ing for string literals - * 11/18/02 (seiwald) - remove bogus search() in 'on' statement. - * 12/17/02 (seiwald) - new copysettings() to protect target-specific vars - */ - -# include "jam.h" - -# include "lists.h" -# include "parse.h" -# include "compile.h" -# include "variable.h" -# include "expand.h" -# include "rules.h" -# include "newstr.h" -# include "search.h" - -static const char *set_names[] = { "=", "+=", "?=" }; -static void debug_compile( int which, const char *s ); -int glob( const char *s, const char *c ); - - - -/* - * compile_append() - append list results of two statements - * - * parse->left more compile_append() by left-recursion - * parse->right single rule - */ - -LIST * -compile_append( - PARSE *parse, - LOL *args, - int *jmp ) -{ - /* Append right to left. */ - - return list_append( - (*parse->left->func)( parse->left, args, jmp ), - (*parse->right->func)( parse->right, args, jmp ) ); -} - -/* - * compile_break() - compile 'break/continue/return' rule - * - * parse->left results - * parse->num JMP_BREAK/CONTINUE/RETURN - */ - -LIST * -compile_break( - PARSE *parse, - LOL *args, - int *jmp ) -{ - LIST *lv = (*parse->left->func)( parse->left, args, jmp ); - *jmp = parse->num; - return lv; -} - -/* - * compile_eval() - evaluate if to determine which leg to compile - * - * Returns: - * list if expression true - compile 'then' clause - * L0 if expression false - compile 'else' clause - */ - -static int -lcmp( LIST *t, LIST *s ) -{ - int status = 0; - - while( !status && ( t || s ) ) - { - const char *st = t ? t->string : ""; - const char *ss = s ? s->string : ""; - - status = strcmp( st, ss ); - - t = t ? list_next( t ) : t; - s = s ? list_next( s ) : s; - } - - return status; -} - -LIST * -compile_eval( - PARSE *parse, - LOL *args, - int *jmp ) -{ - LIST *ll, *lr, *s, *t; - int status = 0; - - /* Short circuit lr eval for &&, ||, and 'in' */ - - ll = (*parse->left->func)( parse->left, args, jmp ); - lr = 0; - - switch( parse->num ) - { - case EXPR_AND: - case EXPR_IN: if( ll ) goto eval; break; - case EXPR_OR: if( !ll ) goto eval; break; - default: eval: lr = (*parse->right->func)( parse->right, args, jmp ); - } - - /* Now eval */ - - switch( parse->num ) - { - case EXPR_NOT: - if( !ll ) status = 1; - break; - - case EXPR_AND: - if( ll && lr ) status = 1; - break; - - case EXPR_OR: - if( ll || lr ) status = 1; - break; - - case EXPR_IN: - /* "a in b": make sure each of */ - /* ll is equal to something in lr. */ - - for( t = ll; t; t = list_next( t ) ) - { - for( s = lr; s; s = list_next( s ) ) - if( !strcmp( t->string, s->string ) ) - break; - if( !s ) break; - } - - /* No more ll? Success */ - - if( !t ) status = 1; - - break; - - case EXPR_EXISTS: if( lcmp( ll, L0 ) != 0 ) status = 1; break; - case EXPR_EQUALS: if( lcmp( ll, lr ) == 0 ) status = 1; break; - case EXPR_NOTEQ: if( lcmp( ll, lr ) != 0 ) status = 1; break; - case EXPR_LESS: if( lcmp( ll, lr ) < 0 ) status = 1; break; - case EXPR_LESSEQ: if( lcmp( ll, lr ) <= 0 ) status = 1; break; - case EXPR_MORE: if( lcmp( ll, lr ) > 0 ) status = 1; break; - case EXPR_MOREEQ: if( lcmp( ll, lr ) >= 0 ) status = 1; break; - - } - - if( DEBUG_IF ) - { - debug_compile( 0, "if" ); - list_print( ll ); - printf( "(%d) ", status ); - list_print( lr ); - printf( "\n" ); - } - - /* Find something to return. */ - /* In odd circumstances (like "" = "") */ - /* we'll have to return a new string. */ - - if( !status ) t = 0; - else if( ll ) t = ll, ll = 0; - else if( lr ) t = lr, lr = 0; - else t = list_new( L0, "1", 0 ); - - if( ll ) list_free( ll ); - if( lr ) list_free( lr ); - return t; -} - -/* - * compile_foreach() - compile the "for x in y" statement - * - * Compile_foreach() resets the given variable name to each specified - * value, executing the commands enclosed in braces for each iteration. - * - * parse->string index variable - * parse->left variable values - * parse->right rule to compile - */ - -LIST * -compile_foreach( - PARSE *p, - LOL *args, - int *jmp ) -{ - LIST *nv = (*p->left->func)( p->left, args, jmp ); - LIST *result = 0; - LIST *l; - - /* for each value for var */ - - for( l = nv; l && *jmp == JMP_NONE; l = list_next( l ) ) - { - /* Reset $(p->string) for each val. */ - - var_set( p->string, list_new( L0, l->string, 1 ), VAR_SET ); - - /* Keep only last result. */ - - list_free( result ); - result = (*p->right->func)( p->right, args, jmp ); - - /* continue loop? */ - - if( *jmp == JMP_CONTINUE ) - *jmp = JMP_NONE; - } - - /* Here by break/continue? */ - - if( *jmp == JMP_BREAK || *jmp == JMP_CONTINUE ) - *jmp = JMP_NONE; - - list_free( nv ); - - /* Returns result of last loop */ - - return result; -} - -/* - * compile_if() - compile 'if' rule - * - * parse->left condition tree - * parse->right then tree - * parse->third else tree - */ - -LIST * -compile_if( - PARSE *p, - LOL *args, - int *jmp ) -{ - LIST *l = (*p->left->func)( p->left, args, jmp ); - - p = l ? p->right : p->third; - - list_free( l ); - - return (*p->func)( p, args, jmp ); -} - -/* - * compile_include() - support for 'include' - call include() on file - * - * parse->left list of files to include (can only do 1) - */ - -LIST * -compile_include( - PARSE *parse, - LOL *args, - int *jmp ) -{ - LIST *nt = (*parse->left->func)( parse->left, args, jmp ); - - if( DEBUG_COMPILE ) - { - debug_compile( 0, "include" ); - list_print( nt ); - printf( "\n" ); - } - - if( nt ) - { - TARGET *t = bindtarget( nt->string ); - - /* Bind the include file under the influence of */ - /* "on-target" variables. Though they are targets, */ - /* include files are not built with make(). */ - /* Needn't copysettings(), as search sets no vars. */ - - pushsettings( t->settings ); - t->boundname = search( t->name, &t->time ); - popsettings( t->settings ); - - /* Don't parse missing file if NOCARE set */ - - if( t->time || !( t->flags & T_FLAG_NOCARE ) ) - parse_file( t->boundname ); - } - - list_free( nt ); - - return L0; -} - -/* - * compile_list() - expand and return a list - * - * parse->string - character string to expand - */ - -LIST * -compile_list( - PARSE *parse, - LOL *args, - int *jmp ) -{ - /* voodoo 1 means: s is a copyable string */ - const char *s = parse->string; - return var_expand( L0, s, s + strlen( s ), args, 1 ); -} - -/* - * compile_local() - declare (and set) local variables - * - * parse->left list of variables - * parse->right list of values - * parse->third rules to execute - */ - -LIST * -compile_local( - PARSE *parse, - LOL *args, - int *jmp ) -{ - LIST *l; - SETTINGS *s = 0; - LIST *nt = (*parse->left->func)( parse->left, args, jmp ); - LIST *ns = (*parse->right->func)( parse->right, args, jmp ); - LIST *result; - - if( DEBUG_COMPILE ) - { - debug_compile( 0, "local" ); - list_print( nt ); - printf( " = " ); - list_print( ns ); - printf( "\n" ); - } - - /* Initial value is ns */ - - for( l = nt; l; l = list_next( l ) ) - s = addsettings( s, 0, l->string, list_copy( (LIST*)0, ns ) ); - - list_free( ns ); - list_free( nt ); - - /* Note that callees of the current context get this "local" */ - /* variable, making it not so much local as layered. */ - - pushsettings( s ); - result = (*parse->third->func)( parse->third, args, jmp ); - popsettings( s ); - freesettings( s ); - - return result; -} - -/* - * compile_null() - do nothing -- a stub for parsing - */ - -LIST * -compile_null( - PARSE *parse, - LOL *args, - int *jmp ) -{ - return L0; -} - -/* - * compile_on() - run rule under influence of on-target variables - * - * parse->left target list; only first used - * parse->right rule to run - */ - -LIST * -compile_on( - PARSE *parse, - LOL *args, - int *jmp ) -{ - LIST *nt = (*parse->left->func)( parse->left, args, jmp ); - LIST *result = 0; - - if( DEBUG_COMPILE ) - { - debug_compile( 0, "on" ); - list_print( nt ); - printf( "\n" ); - } - - /* - * Copy settings, so that 'on target var on target = val' - * doesn't set var globally. - */ - - if( nt ) - { - TARGET *t = bindtarget( nt->string ); - SETTINGS *s = copysettings( t->settings ); - - pushsettings( s ); - result = (*parse->right->func)( parse->right, args, jmp ); - popsettings( s ); - freesettings( s ); - } - - list_free( nt ); - - return result; -} - -/* - * compile_rule() - compile a single user defined rule - * - * parse->left list of rules to run - * parse->right parameters (list of lists) to rule, recursing left - * - * Wrapped around evaluate_rule() so that headers() can share it. - */ - -LIST * -compile_rule( - PARSE *parse, - LOL *args, - int *jmp ) -{ - LOL nargs[1]; - LIST *result = 0; - LIST *ll, *l; - PARSE *p; - - /* list of rules to run -- normally 1! */ - - ll = (*parse->left->func)( parse->left, args, jmp ); - - /* Build up the list of arg lists */ - - lol_init( nargs ); - - for( p = parse->right; p; p = p->left ) - lol_add( nargs, (*p->right->func)( p->right, args, jmp ) ); - - /* Run rules, appending results from each */ - - for( l = ll; l; l = list_next( l ) ) - result = evaluate_rule( l->string, nargs, result ); - - list_free( ll ); - lol_free( nargs ); - - return result; -} - -/* - * evaluate_rule() - execute a rule invocation - */ - -LIST * -evaluate_rule( - const char *rulename, - LOL *args, - LIST *result ) -{ - RULE *rule = bindrule( rulename ); - - if( DEBUG_COMPILE ) - { - debug_compile( 1, rulename ); - lol_print( args ); - printf( "\n" ); - } - - /* Check traditional targets $(<) and sources $(>) */ - - if( !rule->actions && !rule->procedure ) - printf( "warning: unknown rule %s\n", rule->name ); - - /* If this rule will be executed for updating the targets */ - /* then construct the action for make(). */ - - if( rule->actions ) - { - TARGETS *t; - ACTION *action; - - /* The action is associated with this instance of this rule */ - - action = (ACTION *)malloc( sizeof( ACTION ) ); - memset( (char *)action, '\0', sizeof( *action ) ); - - action->rule = rule; - action->targets = targetlist( (TARGETS *)0, lol_get( args, 0 ) ); - action->sources = targetlist( (TARGETS *)0, lol_get( args, 1 ) ); - - /* Append this action to the actions of each target */ - - for( t = action->targets; t; t = t->next ) - t->target->actions = actionlist( t->target->actions, action ); - } - - /* Now recursively compile any parse tree associated with this rule */ - - if( rule->procedure ) - { - PARSE *parse = rule->procedure; - SETTINGS *s = 0; - int jmp = JMP_NONE; - LIST *l; - int i; - - /* build parameters as local vars */ - - for( l = rule->params, i = 0; l; l = l->next, i++ ) - s = addsettings( s, 0, l->string, - list_copy( L0, lol_get( args, i ) ) ); - - /* Run rule. */ - /* Bring in local params. */ - /* refer/free to ensure rule not freed during use. */ - - parse_refer( parse ); - - pushsettings( s ); - result = list_append( result, (*parse->func)( parse, args, &jmp ) ); - popsettings( s ); - freesettings( s ); - - parse_free( parse ); - } - - if( DEBUG_COMPILE ) - debug_compile( -1, 0 ); - - return result; -} - -/* - * compile_rules() - compile a chain of rules - * - * parse->left single rule - * parse->right more compile_rules() by right-recursion - */ - -LIST * -compile_rules( - PARSE *parse, - LOL *args, - int *jmp ) -{ - /* Ignore result from first statement; return the 2nd. */ - /* Optimize recursion on the right by looping. */ - - LIST *result = 0; - - while( *jmp == JMP_NONE && parse->func == compile_rules ) - { - list_free( result ); - result = (*parse->left->func)( parse->left, args, jmp ); - parse = parse->right; - } - - if( *jmp == JMP_NONE ) - { - list_free( result ); - result = (*parse->func)( parse, args, jmp ); - } - - return result; -} - -/* - * compile_set() - compile the "set variable" statement - * - * parse->left variable names - * parse->right variable values - * parse->num VAR_SET/APPEND/DEFAULT - */ - -LIST * -compile_set( - PARSE *parse, - LOL *args, - int *jmp ) -{ - LIST *nt = (*parse->left->func)( parse->left, args, jmp ); - LIST *ns = (*parse->right->func)( parse->right, args, jmp ); - LIST *l; - - if( DEBUG_COMPILE ) - { - debug_compile( 0, "set" ); - list_print( nt ); - printf( " %s ", set_names[ parse->num ] ); - list_print( ns ); - printf( "\n" ); - } - - /* Call var_set to set variable */ - /* var_set keeps ns, so need to copy it */ - - for( l = nt; l; l = list_next( l ) ) - var_set( l->string, list_copy( L0, ns ), parse->num ); - - list_free( nt ); - - return ns; -} - -/* - * compile_setcomp() - support for `rule` - save parse tree - * - * parse->string rule name - * parse->left list of argument names - * parse->right rules for rule - */ - -LIST * -compile_setcomp( - PARSE *parse, - LOL *args, - int *jmp ) -{ - RULE *rule = bindrule( parse->string ); - LIST *params = 0; - PARSE *p; - - /* Build param list */ - - for( p = parse->left; p; p = p->left ) - params = list_new( params, p->string, 1 ); - - if( DEBUG_COMPILE ) - { - debug_compile( 0, "rule" ); - printf( "%s ", parse->string ); - list_print( params ); - printf( "\n" ); - } - - /* Free old one, if present */ - - if( rule->procedure ) - parse_free( rule->procedure ); - - if( rule->params ) - list_free( rule->params ); - - rule->procedure = parse->right; - rule->params = params; - - /* we now own this parse tree */ - /* don't let parse_free() release it */ - - parse_refer( parse->right ); - - return L0; -} - -/* - * compile_setexec() - support for `actions` - save execution string - * - * parse->string rule name - * parse->string1 OS command string - * parse->num flags - * parse->left `bind` variables - * - * Note that the parse flags (as defined in compile.h) are transfered - * directly to the rule flags (as defined in rules.h). - */ - -LIST * -compile_setexec( - PARSE *parse, - LOL *args, - int *jmp ) -{ - RULE *rule = bindrule( parse->string ); - LIST *bindlist = (*parse->left->func)( parse->left, args, jmp ); - - /* Free old one, if present */ - - if( rule->actions ) - { - freestr( rule->actions ); - list_free( rule->bindlist ); - } - - rule->actions = copystr( parse->string1 ); - rule->bindlist = bindlist; - rule->flags = parse->num; - - return L0; -} - -/* - * compile_settings() - compile the "on =" (set variable on exec) statement - * - * parse->left variable names - * parse->right target name - * parse->third variable value - * parse->num VAR_SET/APPEND/DEFAULT - */ - -LIST * -compile_settings( - PARSE *parse, - LOL *args, - int *jmp ) -{ - LIST *nt = (*parse->left->func)( parse->left, args, jmp ); - LIST *ns = (*parse->third->func)( parse->third, args, jmp ); - LIST *targets = (*parse->right->func)( parse->right, args, jmp ); - LIST *ts; - - if( DEBUG_COMPILE ) - { - debug_compile( 0, "set" ); - list_print( nt ); - printf( "on " ); - list_print( targets ); - printf( " %s ", set_names[ parse->num ] ); - list_print( ns ); - printf( "\n" ); - } - - /* Call addsettings to save variable setting */ - /* addsettings keeps ns, so need to copy it */ - /* Pass append flag to addsettings() */ - - for( ts = targets; ts; ts = list_next( ts ) ) - { - TARGET *t = bindtarget( ts->string ); - LIST *l; - - for( l = nt; l; l = list_next( l ) ) - t->settings = addsettings( t->settings, parse->num, - l->string, list_copy( (LIST*)0, ns ) ); - } - - list_free( nt ); - list_free( targets ); - - return ns; -} - -/* - * compile_switch() - compile 'switch' rule - * - * parse->left switch value (only 1st used) - * parse->right cases - * - * cases->left 1st case - * cases->right next cases - * - * case->string argument to match - * case->left parse tree to execute - */ - -LIST * -compile_switch( - PARSE *parse, - LOL *args, - int *jmp ) -{ - LIST *nt = (*parse->left->func)( parse->left, args, jmp ); - LIST *result = 0; - - if( DEBUG_COMPILE ) - { - debug_compile( 0, "switch" ); - list_print( nt ); - printf( "\n" ); - } - - /* Step through cases */ - - for( parse = parse->right; parse; parse = parse->right ) - { - if( !glob( parse->left->string, nt ? nt->string : "" ) ) - { - /* Get & exec parse tree for this case */ - parse = parse->left->left; - result = (*parse->func)( parse, args, jmp ); - break; - } - } - - list_free( nt ); - - return result; -} - -/* - * compile_while() - compile 'while' rule - * - * parse->left condition tree - * parse->right execution tree - */ - -LIST * -compile_while( - PARSE *p, - LOL *args, - int *jmp ) -{ - LIST *result = 0; - LIST *l; - - /* Returns the value from the last execution of the block */ - - while( ( *jmp == JMP_NONE ) && - ( l = (*p->left->func)( p->left, args, jmp ) ) ) - { - /* Always toss while's expression */ - - list_free( l ); - - /* Keep only last result. */ - - list_free( result ); - result = (*p->right->func)( p->right, args, jmp ); - - /* continue loop? */ - - if( *jmp == JMP_CONTINUE ) - *jmp = JMP_NONE; - } - - /* Here by break/continue? */ - - if( *jmp == JMP_BREAK || *jmp == JMP_CONTINUE ) - *jmp = JMP_NONE; - - /* Returns result of last loop */ - - return result; -} - -/* - * debug_compile() - printf with indent to show rule expansion. - */ - -static void -debug_compile( int which, const char *s ) -{ - static int level = 0; - static char indent[36] = ">>>>|>>>>|>>>>|>>>>|>>>>|>>>>|>>>>|"; - int i = ((1+level) * 2) % 35; - - if( which >= 0 ) - printf( "%*.*s ", i, i, indent ); - - if( s ) - printf( "%s ", s ); - - level += which; -} diff --git a/jam-2.5/compile.h b/jam-2.5/compile.h deleted file mode 100644 index 7d907391d..000000000 --- a/jam-2.5/compile.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * compile.h - compile parsed jam statements - * - * 01/22/01 (seiwald) - replace evaluate_if() with compile_eval() - * 01/24/01 (seiwald) - 'while' statement - * 03/02/02 (seiwald) - rules can be invoked via variable names - * 02/28/02 (seiwald) - merge EXEC_xxx flags in with RULE_xxx - * 10/22/02 (seiwald) - working return/break/continue statements - * 11/04/02 (seiwald) - const-ing for string literals - */ - -void compile_builtins(); - -LIST *compile_append( PARSE *parse, LOL *args, int *jmp ); -LIST *compile_break( PARSE *parse, LOL *args, int *jmp ); -LIST *compile_foreach( PARSE *parse, LOL *args, int *jmp ); -LIST *compile_if( PARSE *parse, LOL *args, int *jmp ); -LIST *compile_eval( PARSE *parse, LOL *args, int *jmp ); -LIST *compile_include( PARSE *parse, LOL *args, int *jmp ); -LIST *compile_list( PARSE *parse, LOL *args, int *jmp ); -LIST *compile_local( PARSE *parse, LOL *args, int *jmp ); -LIST *compile_null( PARSE *parse, LOL *args, int *jmp ); -LIST *compile_on( PARSE *parse, LOL *args, int *jmp ); -LIST *compile_rule( PARSE *parse, LOL *args, int *jmp ); -LIST *compile_rules( PARSE *parse, LOL *args, int *jmp ); -LIST *compile_set( PARSE *parse, LOL *args, int *jmp ); -LIST *compile_setcomp( PARSE *parse, LOL *args, int *jmp ); -LIST *compile_setexec( PARSE *parse, LOL *args, int *jmp ); -LIST *compile_settings( PARSE *parse, LOL *args, int *jmp ); -LIST *compile_switch( PARSE *parse, LOL *args, int *jmp ); -LIST *compile_while( PARSE *parse, LOL *args, int *jmp ); - -LIST *evaluate_rule( const char *rulename, LOL *args, LIST *result ); - -/* Conditions for compile_if() */ - -# define EXPR_NOT 0 /* ! cond */ -# define EXPR_AND 1 /* cond && cond */ -# define EXPR_OR 2 /* cond || cond */ - -# define EXPR_EXISTS 3 /* arg */ -# define EXPR_EQUALS 4 /* arg = arg */ -# define EXPR_NOTEQ 5 /* arg != arg */ -# define EXPR_LESS 6 /* arg < arg */ -# define EXPR_LESSEQ 7 /* arg <= arg */ -# define EXPR_MORE 8 /* arg > arg */ -# define EXPR_MOREEQ 9 /* arg >= arg */ -# define EXPR_IN 10 /* arg in arg */ - -/* Flags for compile_return */ - -# define JMP_NONE 0 /* flow continues */ -# define JMP_BREAK 1 /* break out of loop */ -# define JMP_CONTINUE 2 /* step to end of loop */ -# define JMP_RETURN 3 /* return from rule */ diff --git a/jam-2.5/execcmd.h b/jam-2.5/execcmd.h deleted file mode 100644 index 1e7a60835..000000000 --- a/jam-2.5/execcmd.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * execcmd.h - execute a shell script - * - * 05/04/94 (seiwald) - async multiprocess interface - */ - -void execcmd( - char *string, - void (*func)( void *closure, int status ), - void *closure, - LIST *shell ); - -int execwait(); - -# define EXEC_CMD_OK 0 -# define EXEC_CMD_FAIL 1 -# define EXEC_CMD_INTR 2 diff --git a/jam-2.5/execmac.c b/jam-2.5/execmac.c deleted file mode 100644 index d96358bf9..000000000 --- a/jam-2.5/execmac.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * execunix.c - execute a shell script on UNIX - * - * If $(JAMSHELL) is defined, uses that to formulate execvp(). - * The default is: - * - * /bin/sh -c % - * - * Each word must be an individual element in a jam variable value. - * - * In $(JAMSHELL), % expands to the command string and ! expands to - * the slot number (starting at 1) for multiprocess (-j) invocations. - * If $(JAMSHELL) doesn't include a %, it is tacked on as the last - * argument. - * - * Don't just set JAMSHELL to /bin/sh - it won't work! - * - * External routines: - * execcmd() - launch an async command execution - * execwait() - wait and drive at most one execution completion - * - * Internal routines: - * onintr() - bump intr to note command interruption - * - * 04/08/94 (seiwald) - Coherent/386 support added. - * 05/04/94 (seiwald) - async multiprocess interface - * 01/22/95 (seiwald) - $(JAMSHELL) support - * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C - */ - -# include "jam.h" -# include "lists.h" -# include "execcmd.h" -# include - -# ifdef OS_MAC - -/* - * execcmd() - launch an async command execution - */ - -void -execcmd( - char *string, - void (*func)( void *closure, int status ), - void *closure, - LIST *shell ) -{ - - printf( "%s", string ); - (*func)( closure, EXEC_CMD_OK ); -} - -/* - * execwait() - wait and drive at most one execution completion - */ - -int -execwait() -{ - return 0; -} - -# endif /* OS_MAC */ diff --git a/jam-2.5/execunix.c b/jam-2.5/execunix.c deleted file mode 100644 index 6cde87a1b..000000000 --- a/jam-2.5/execunix.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * execunix.c - execute a shell script on UNIX/WinNT/OS2/AmigaOS - * - * If $(JAMSHELL) is defined, uses that to formulate execvp()/spawnvp(). - * The default is: - * - * /bin/sh -c % [ on UNIX/AmigaOS ] - * cmd.exe /c % [ on OS2/WinNT ] - * - * Each word must be an individual element in a jam variable value. - * - * In $(JAMSHELL), % expands to the command string and ! expands to - * the slot number (starting at 1) for multiprocess (-j) invocations. - * If $(JAMSHELL) doesn't include a %, it is tacked on as the last - * argument. - * - * Don't just set JAMSHELL to /bin/sh or cmd.exe - it won't work! - * - * External routines: - * execcmd() - launch an async command execution - * execwait() - wait and drive at most one execution completion - * - * Internal routines: - * onintr() - bump intr to note command interruption - * - * 04/08/94 (seiwald) - Coherent/386 support added. - * 05/04/94 (seiwald) - async multiprocess interface - * 01/22/95 (seiwald) - $(JAMSHELL) support - * 06/02/97 (gsar) - full async multiprocess support for Win32 - * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C - * 11/04/02 (seiwald) - const-ing for string literals - * 12/27/02 (seiwald) - grist .bat file with pid for system uniqueness - */ - -# include "jam.h" -# include "lists.h" -# include "execcmd.h" -# include - -# ifdef USE_EXECUNIX - -# ifdef OS_OS2 -# define USE_EXECNT -# include -# endif - -# ifdef OS_NT -# define USE_EXECNT -# include -# define WIN32_LEAN_AND_MEAN -# include /* do the ugly deed */ -# define USE_MYWAIT -# if !defined( __BORLANDC__ ) -# define wait my_wait -static int my_wait( int *status ); -# endif -# endif - -static int intr = 0; -static int cmdsrunning = 0; -static void (*istat)( int ); - -static struct -{ - int pid; /* on win32, a real process handle */ - void (*func)( void *closure, int status ); - void *closure; - -# ifdef USE_EXECNT - char *tempfile; -# endif - -} cmdtab[ MAXJOBS ] = {{0}}; - -/* - * onintr() - bump intr to note command interruption - */ - -void -onintr( int disp ) -{ - intr++; - printf( "...interrupted\n" ); -} - -/* - * execcmd() - launch an async command execution - */ - -void -execcmd( - char *string, - void (*func)( void *closure, int status ), - void *closure, - LIST *shell ) -{ - int pid; - int slot; - const char *argv[ MAXARGC + 1 ]; /* +1 for NULL */ - -# ifdef USE_EXECNT - char *p; -# endif - - /* Find a slot in the running commands table for this one. */ - - for( slot = 0; slot < MAXJOBS; slot++ ) - if( !cmdtab[ slot ].pid ) - break; - - if( slot == MAXJOBS ) - { - printf( "no slots for child!\n" ); - exit( EXITBAD ); - } - -# ifdef USE_EXECNT - if( !cmdtab[ slot ].tempfile ) - { - char *tempdir; - - if( !( tempdir = getenv( "TEMP" ) ) && - !( tempdir = getenv( "TMP" ) ) ) - tempdir = "\\temp"; - - /* +32 is room for \jamXXXXXtSS.bat (at least) */ - - cmdtab[ slot ].tempfile = malloc( strlen( tempdir ) + 32 ); - - sprintf( cmdtab[ slot ].tempfile, "%s\\jam%dt%d.bat", - tempdir, GetCurrentProcessId(), slot ); - } - - /* Trim leading, ending white space */ - - while( isspace( *string ) ) - ++string; - - p = strchr( string, '\n' ); - - while( p && isspace( *p ) ) - ++p; - - /* If multi line, or too long, or JAMSHELL is set, write to bat file. */ - /* Otherwise, exec directly. */ - /* Frankly, if it is a single long line I don't think the */ - /* command interpreter will do any better -- it will fail. */ - - if( p && *p || strlen( string ) > MAXLINE || shell ) - { - FILE *f; - - /* Write command to bat file. */ - - f = fopen( cmdtab[ slot ].tempfile, "w" ); - fputs( string, f ); - fclose( f ); - - string = cmdtab[ slot ].tempfile; - } -# endif - - /* Forumulate argv */ - /* If shell was defined, be prepared for % and ! subs. */ - /* Otherwise, use stock /bin/sh (on unix) or cmd.exe (on NT). */ - - if( shell ) - { - int i; - char jobno[4]; - int gotpercent = 0; - - sprintf( jobno, "%d", slot + 1 ); - - for( i = 0; shell && i < MAXARGC; i++, shell = list_next( shell ) ) - { - switch( shell->string[0] ) - { - case '%': argv[i] = string; gotpercent++; break; - case '!': argv[i] = jobno; break; - default: argv[i] = shell->string; - } - if( DEBUG_EXECCMD ) - printf( "argv[%d] = '%s'\n", i, argv[i] ); - } - - if( !gotpercent ) - argv[i++] = string; - - argv[i] = 0; - } - else - { -# ifdef USE_EXECNT - argv[0] = "cmd.exe"; - argv[1] = "/Q/C"; /* anything more is non-portable */ -# else - argv[0] = "/bin/sh"; - argv[1] = "-c"; -# endif - argv[2] = string; - argv[3] = 0; - } - - /* Catch interrupts whenever commands are running. */ - - if( !cmdsrunning++ ) - istat = signal( SIGINT, onintr ); - - /* Start the command */ - -# ifdef USE_EXECNT - if( ( pid = spawnvp( P_NOWAIT, argv[0], argv ) ) == -1 ) - { - perror( "spawn" ); - exit( EXITBAD ); - } -# else -# ifdef NO_VFORK - if ((pid = fork()) == 0) - { - execvp( argv[0], argv ); - _exit(127); - } -# else - if ((pid = vfork()) == 0) - { - execvp( argv[0], argv ); - _exit(127); - } -# endif - - if( pid == -1 ) - { - perror( "vfork" ); - exit( EXITBAD ); - } -# endif - /* Save the operation for execwait() to find. */ - - cmdtab[ slot ].pid = pid; - cmdtab[ slot ].func = func; - cmdtab[ slot ].closure = closure; - - /* Wait until we're under the limit of concurrent commands. */ - /* Don't trust globs.jobs alone. */ - - while( cmdsrunning >= MAXJOBS || cmdsrunning >= globs.jobs ) - if( !execwait() ) - break; -} - -/* - * execwait() - wait and drive at most one execution completion - */ - -int -execwait() -{ - int i; - int status, w; - int rstat; - - /* Handle naive make1() which doesn't know if cmds are running. */ - - if( !cmdsrunning ) - return 0; - - /* Pick up process pid and status */ - - while( ( w = wait( &status ) ) == -1 && errno == EINTR ) - ; - - if( w == -1 ) - { - printf( "child process(es) lost!\n" ); - perror("wait"); - exit( EXITBAD ); - } - - /* Find the process in the cmdtab. */ - - for( i = 0; i < MAXJOBS; i++ ) - if( w == cmdtab[ i ].pid ) - break; - - if( i == MAXJOBS ) - { - printf( "waif child found!\n" ); - exit( EXITBAD ); - } - -# ifdef USE_EXECNT - /* Clear the temp file */ - - unlink( cmdtab[ i ].tempfile ); -# endif - - /* Drive the completion */ - - if( !--cmdsrunning ) - signal( SIGINT, istat ); - - if( intr ) - rstat = EXEC_CMD_INTR; - else if( w == -1 || status != 0 ) - rstat = EXEC_CMD_FAIL; - else - rstat = EXEC_CMD_OK; - - cmdtab[ i ].pid = 0; - - (*cmdtab[ i ].func)( cmdtab[ i ].closure, rstat ); - - return 1; -} - -# ifdef USE_MYWAIT - -static int -my_wait( int *status ) -{ - int i, num_active = 0; - DWORD exitcode, waitcode; - static HANDLE *active_handles = 0; - - if (!active_handles) - active_handles = (HANDLE *)malloc(globs.jobs * sizeof(HANDLE) ); - - /* first see if any non-waited-for processes are dead, - * and return if so. - */ - for ( i = 0; i < globs.jobs; i++ ) { - if ( cmdtab[i].pid ) { - if ( GetExitCodeProcess((HANDLE)cmdtab[i].pid, &exitcode) ) { - if ( exitcode == STILL_ACTIVE ) - active_handles[num_active++] = (HANDLE)cmdtab[i].pid; - else { - CloseHandle((HANDLE)cmdtab[i].pid); - *status = (int)((exitcode & 0xff) << 8); - return cmdtab[i].pid; - } - } - else - goto FAILED; - } - } - - /* if a child exists, wait for it to die */ - if ( !num_active ) { - errno = ECHILD; - return -1; - } - waitcode = WaitForMultipleObjects( num_active, - active_handles, - FALSE, - INFINITE ); - if ( waitcode != WAIT_FAILED ) { - if ( waitcode >= WAIT_ABANDONED_0 - && waitcode < WAIT_ABANDONED_0 + num_active ) - i = waitcode - WAIT_ABANDONED_0; - else - i = waitcode - WAIT_OBJECT_0; - if ( GetExitCodeProcess(active_handles[i], &exitcode) ) { - CloseHandle(active_handles[i]); - *status = (int)((exitcode & 0xff) << 8); - return (int)active_handles[i]; - } - } - -FAILED: - errno = GetLastError(); - return -1; - -} - -# endif /* USE_MYWAIT */ - -# endif /* USE_EXECUNIX */ diff --git a/jam-2.5/execvms.c b/jam-2.5/execvms.c deleted file mode 100644 index f1db2309f..000000000 --- a/jam-2.5/execvms.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * execvms.c - execute a shell script, ala VMS - * - * The approach is this: - * - * If the command is a single line, and shorter than WRTLEN (what we - * believe to be the maximum line length), we just system() it. - * - * If the command is multi-line, or longer than WRTLEN, we write the - * command block to a temp file, splitting long lines (using "-" at - * the end of the line to indicate contiuation), and then source that - * temp file. We use special logic to make sure we don't continue in - * the middle of a quoted string. - * - * 05/04/94 (seiwald) - async multiprocess interface; noop on VMS - * 12/20/96 (seiwald) - rewritten to handle multi-line commands well - * 01/14/96 (seiwald) - don't put -'s between "'s - * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C - */ - -# include "jam.h" -# include "lists.h" -# include "execcmd.h" - -# ifdef OS_VMS - -#include -#include -#include -#include -#include -#include -#include -#include - -#define WRTLEN 240 - -#define MIN( a, b ) ((a) < (b) ? (a) : (b)) - -/* 1 for the @ and 4 for the .com */ - -char tempnambuf[ L_tmpnam + 1 + 4 ] = {0}; - -void -execcmd( - char *string, - void (*func)( void *closure, int status ), - void *closure, - LIST *shell ) -{ - char *s, *e, *p; - int rstat = EXEC_CMD_OK; - int status; - - /* See if string is more than one line */ - /* discounting leading/trailing white space */ - - for( s = string; *s && isspace( *s ); s++ ) - ; - - e = p = strchr( s, '\n' ); - - while( p && isspace( *p ) ) - ++p; - - /* If multi line or long, write to com file. */ - /* Otherwise, exec directly. */ - - if( p && *p || e - s > WRTLEN ) - { - FILE *f; - - /* Create temp file invocation "@sys$scratch:tempfile.com" */ - - if( !*tempnambuf ) - { - tempnambuf[0] = '@'; - (void)tmpnam( tempnambuf + 1 ); - strcat( tempnambuf, ".com" ); - } - - /* Open tempfile */ - - if( !( f = fopen( tempnambuf + 1, "w" ) ) ) - { - printf( "can't open command file\n" ); - (*func)( closure, EXEC_CMD_FAIL ); - return; - } - - /* For each line of the string */ - - while( *string ) - { - char *s = strchr( string, '\n' ); - int len = s ? s + 1 - string : strlen( string ); - - fputc( '$', f ); - - /* For each chunk of a line that needs to be split */ - - while( len > 0 ) - { - char *q = string; - char *qe = string + MIN( len, WRTLEN ); - char *qq = q; - int quote = 0; - - /* Look for matching "'s */ - - for( ; q < qe; q++ ) - if( *q == '"' && ( quote = !quote ) ) - qq = q; - - /* Back up to opening quote, if in one */ - - if( quote ) - q = qq; - - fwrite( string, ( q - string ), 1, f ); - - len -= ( q - string ); - string = q; - - if( len ) - { - fputc( '-', f ); - fputc( '\n', f ); - } - } - } - - fclose( f ); - - status = system( tempnambuf ) & 0x07; - - unlink( tempnambuf + 1 ); - } - else - { - /* Execute single line command */ - /* Strip trailing newline before execing */ - if( e ) *e = 0; - status = system( s ) & 0x07; - } - - /* Fail for error or fatal error */ - /* OK on OK, warning, or info exit */ - - if( status == 2 || status == 4 ) - rstat = EXEC_CMD_FAIL; - - (*func)( closure, rstat ); -} - -int -execwait() -{ - return 0; -} - -# endif /* VMS */ diff --git a/jam-2.5/expand.c b/jam-2.5/expand.c deleted file mode 100644 index 68f882603..000000000 --- a/jam-2.5/expand.c +++ /dev/null @@ -1,534 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * expand.c - expand a buffer, given variable values - * - * External routines: - * - * var_expand() - variable-expand input string into list of strings - * - * Internal routines: - * - * var_edit_parse() - parse : modifiers into PATHNAME structure - * var_edit_file() - copy input target name to output, modifying filename - * var_edit_shift() - do upshift/downshift mods - * - * 01/25/94 (seiwald) - $(X)$(UNDEF) was expanding like plain $(X) - * 04/13/94 (seiwald) - added shorthand L0 for null list pointer - * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C - * 01/11/01 (seiwald) - added support for :E=emptyvalue, :J=joinval - * 01/13/01 (seiwald) - :UDJE work on non-filename strings - * 02/19/01 (seiwald) - make $($(var):J=x) join multiple values of var - * 01/25/02 (seiwald) - fixed broken $(v[1-]), by ian godin - * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() - * 11/04/02 (seiwald) - const-ing for string literals - * 12/30/02 (armstrong) - fix out-of-bounds access in var_expand() - */ - -# include "jam.h" -# include "lists.h" -# include "variable.h" -# include "expand.h" -# include "pathsys.h" -# include "newstr.h" - -typedef struct { - PATHNAME f; /* :GDBSMR -- pieces */ - char parent; /* :P -- go to parent directory */ - char filemods; /* one of the above applied */ - char downshift; /* :L -- downshift result */ - char upshift; /* :U -- upshift result */ - PATHPART empty; /* :E -- default for empties */ - PATHPART join; /* :J -- join list with char */ -} VAR_EDITS ; - -static void var_edit_parse( const char *mods, VAR_EDITS *edits ); -static void var_edit_file( const char *in, char *out, VAR_EDITS *edits ); -static void var_edit_shift( char *out, VAR_EDITS *edits ); - -# define MAGIC_COLON '\001' -# define MAGIC_LEFT '\002' -# define MAGIC_RIGHT '\003' - -/* - * var_expand() - variable-expand input string into list of strings - * - * Would just copy input to output, performing variable expansion, - * except that since variables can contain multiple values the result - * of variable expansion may contain multiple values (a list). Properly - * performs "product" operations that occur in "$(var1)xxx$(var2)" or - * even "$($(var2))". - * - * Returns a newly created list. - */ - -LIST * -var_expand( - LIST *l, - const char *in, - const char *end, - LOL *lol, - int cancopyin ) -{ - char out_buf[ MAXSYM ]; - char *out = out_buf; - const char *inp = in; - char *ov; /* for temp copy of variable in outbuf */ - int depth; - - if( DEBUG_VAREXP ) - printf( "expand '%.*s'\n", end - in, in ); - - /* This gets alot of cases: $(<) and $(>) */ - - if( end - in == 4 && in[0] == '$' && in[1] == '(' && in[3] == ')' ) - { - switch( in[2] ) - { - case '1': - case '<': - return list_copy( l, lol_get( lol, 0 ) ); - - case '2': - case '>': - return list_copy( l, lol_get( lol, 1 ) ); - } - } - - /* Just try simple copy of in to out. */ - - while( in < end ) - if( ( *out++ = *in++ ) == '$' && *in == '(' ) - goto expand; - - /* No variables expanded - just add copy of input string to list. */ - - /* Cancopyin is an optimization: if the input was already a list */ - /* item, we can use the copystr() to put it on the new list. */ - /* Otherwise, we use the slower newstr(). */ - - *out = '\0'; - - if( cancopyin ) - return list_new( l, inp, 1 ); - else - return list_new( l, out_buf, 0 ); - - expand: - /* - * Input so far (ignore blanks): - * - * stuff-in-outbuf $(variable) remainder - * ^ ^ - * in end - * Output so far: - * - * stuff-in-outbuf $ - * ^ ^ - * out_buf out - * - * - * We just copied the $ of $(...), so back up one on the output. - * We now find the matching close paren, copying the variable and - * modifiers between the $( and ) temporarily into out_buf, so that - * we can replace :'s with MAGIC_COLON. This is necessary to avoid - * being confused by modifier values that are variables containing - * :'s. Ugly. - */ - - depth = 1; - out--, in++; - ov = out; - - while( in < end && depth ) - { - switch( *ov++ = *in++ ) - { - case '(': depth++; break; - case ')': depth--; break; - case ':': ov[-1] = MAGIC_COLON; break; - case '[': ov[-1] = MAGIC_LEFT; break; - case ']': ov[-1] = MAGIC_RIGHT; break; - } - } - - /* Copied ) - back up. */ - - ov--; - - /* - * Input so far (ignore blanks): - * - * stuff-in-outbuf $(variable) remainder - * ^ ^ - * in end - * Output so far: - * - * stuff-in-outbuf variable - * ^ ^ ^ - * out_buf out ov - * - * Later we will overwrite 'variable' in out_buf, but we'll be - * done with it by then. 'variable' may be a multi-element list, - * so may each value for '$(variable element)', and so may 'remainder'. - * Thus we produce a product of three lists. - */ - - { - LIST *variables = 0; - LIST *remainder = 0; - LIST *vars; - - /* Recursively expand variable name & rest of input */ - - if( out < ov ) - variables = var_expand( L0, out, ov, lol, 0 ); - if( in < end ) - remainder = var_expand( L0, in, end, lol, 0 ); - - /* Now produce the result chain */ - - /* For each variable name */ - - for( vars = variables; vars; vars = list_next( vars ) ) - { - LIST *value, *evalue = 0; - char *colon; - char *bracket; - char varname[ MAXSYM ]; - int sub1 = 0, sub2 = -1; - VAR_EDITS edits; - - /* Look for a : modifier in the variable name */ - /* Must copy into varname so we can modify it */ - - strcpy( varname, vars->string ); - - if( colon = strchr( varname, MAGIC_COLON ) ) - { - *colon = '\0'; - var_edit_parse( colon + 1, &edits ); - } - - /* Look for [x-y] subscripting */ - /* sub1 is x (0 default) */ - /* sub2 is length (-1 means forever) */ - - if( bracket = strchr( varname, MAGIC_LEFT ) ) - { - char *dash; - - if( dash = strchr( bracket + 1, '-' ) ) - *dash = '\0'; - - sub1 = atoi( bracket + 1 ) - 1; - - if( !dash ) - sub2 = 1; - else if( !dash[1] || dash[1] == MAGIC_RIGHT ) - sub2 = -1; - else - sub2 = atoi( dash + 1 ) - sub1; - - *bracket = '\0'; - } - - /* Get variable value, specially handling $(<), $(>), $(n) */ - - if( varname[0] == '<' && !varname[1] ) - value = lol_get( lol, 0 ); - else if( varname[0] == '>' && !varname[1] ) - value = lol_get( lol, 1 ); - else if( varname[0] >= '1' && varname[0] <= '9' && !varname[1] ) - value = lol_get( lol, varname[0] - '1' ); - else - value = var_get( varname ); - - /* The fast path: $(x) - just copy the variable value. */ - /* This is only an optimization */ - - if( out == out_buf && !bracket && !colon && in == end ) - { - l = list_copy( l, value ); - continue; - } - - /* Handle start subscript */ - - while( sub1 > 0 && value ) - --sub1, value = list_next( value ); - - /* Empty w/ :E=default? */ - - if( !value && colon && edits.empty.ptr ) - evalue = value = list_new( L0, edits.empty.ptr, 0 ); - - /* For each variable value */ - - for( ; value; value = list_next( value ) ) - { - LIST *rem; - char *out1; - - /* Handle end subscript (length actually) */ - - if( sub2 >= 0 && --sub2 < 0 ) - break; - - /* Apply : mods, if present */ - - if( colon && edits.filemods ) - var_edit_file( value->string, out, &edits ); - else - strcpy( out, value->string ); - - if( colon && ( edits.upshift || edits.downshift ) ) - var_edit_shift( out, &edits ); - - /* Handle :J=joinval */ - /* If we have more values for this var, just */ - /* keep appending them (with the join value) */ - /* rather than creating separate LIST elements. */ - - if( colon && edits.join.ptr && - ( list_next( value ) || list_next( vars ) ) ) - { - out += strlen( out ); - strcpy( out, edits.join.ptr ); - out += strlen( out ); - continue; - } - - /* If no remainder, append result to output chain. */ - - if( in == end ) - { - l = list_new( l, out_buf, 0 ); - continue; - } - - /* For each remainder, append the complete string */ - /* to the output chain. */ - /* Remember the end of the variable expansion so */ - /* we can just tack on each instance of 'remainder' */ - - out1 = out + strlen( out ); - - for( rem = remainder; rem; rem = list_next( rem ) ) - { - strcpy( out1, rem->string ); - l = list_new( l, out_buf, 0 ); - } - } - - /* Toss used empty */ - - if( evalue ) - list_free( evalue ); - } - - /* variables & remainder were gifts from var_expand */ - /* and must be freed */ - - if( variables ) - list_free( variables ); - if( remainder) - list_free( remainder ); - - if( DEBUG_VAREXP ) - { - printf( "expanded to " ); - list_print( l ); - printf( "\n" ); - } - - return l; - } -} - -/* - * var_edit_parse() - parse : modifiers into PATHNAME structure - * - * The : modifiers in a $(varname:modifier) currently support replacing - * or omitting elements of a filename, and so they are parsed into a - * PATHNAME structure (which contains pointers into the original string). - * - * Modifiers of the form "X=value" replace the component X with - * the given value. Modifiers without the "=value" cause everything - * but the component X to be omitted. X is one of: - * - * G - * D directory name - * B base name - * S .suffix - * M (member) - * R root directory - prepended to whole path - * - * This routine sets: - * - * f->f_xxx.ptr = 0 - * f->f_xxx.len = 0 - * -> leave the original component xxx - * - * f->f_xxx.ptr = string - * f->f_xxx.len = strlen( string ) - * -> replace component xxx with string - * - * f->f_xxx.ptr = "" - * f->f_xxx.len = 0 - * -> omit component xxx - * - * var_edit_file() below and path_build() obligingly follow this convention. - */ - -static void -var_edit_parse( - const char *mods, - VAR_EDITS *edits ) -{ - int havezeroed = 0; - memset( (char *)edits, 0, sizeof( *edits ) ); - - while( *mods ) - { - char *p; - PATHPART *fp; - - switch( *mods++ ) - { - case 'L': edits->downshift = 1; continue; - case 'U': edits->upshift = 1; continue; - case 'P': edits->parent = edits->filemods = 1; continue; - case 'E': fp = &edits->empty; goto strval; - case 'J': fp = &edits->join; goto strval; - case 'G': fp = &edits->f.f_grist; goto fileval; - case 'R': fp = &edits->f.f_root; goto fileval; - case 'D': fp = &edits->f.f_dir; goto fileval; - case 'B': fp = &edits->f.f_base; goto fileval; - case 'S': fp = &edits->f.f_suffix; goto fileval; - case 'M': fp = &edits->f.f_member; goto fileval; - - default: return; /* should complain, but so what... */ - } - - fileval: - - /* Handle :CHARS, where each char (without a following =) */ - /* selects a particular file path element. On the first such */ - /* char, we deselect all others (by setting ptr = "", len = 0) */ - /* and for each char we select that element (by setting ptr = 0) */ - - edits->filemods = 1; - - if( *mods != '=' ) - { - int i; - - if( !havezeroed++ ) - for( i = 0; i < 6; i++ ) - { - edits->f.part[ i ].len = 0; - edits->f.part[ i ].ptr = ""; - } - - fp->ptr = 0; - continue; - } - - strval: - - /* Handle :X=value, or :X */ - - if( *mods != '=' ) - { - fp->ptr = ""; - fp->len = 0; - } - else if( p = strchr( mods, MAGIC_COLON ) ) - { - *p = 0; - fp->ptr = ++mods; - fp->len = p - mods; - mods = p + 1; - } - else - { - fp->ptr = ++mods; - fp->len = strlen( mods ); - mods += fp->len; - } - } -} - -/* - * var_edit_file() - copy input target name to output, modifying filename - */ - -static void -var_edit_file( - const char *in, - char *out, - VAR_EDITS *edits ) -{ - PATHNAME pathname; - - /* Parse apart original filename, putting parts into "pathname" */ - - path_parse( in, &pathname ); - - /* Replace any pathname with edits->f */ - - if( edits->f.f_grist.ptr ) - pathname.f_grist = edits->f.f_grist; - - if( edits->f.f_root.ptr ) - pathname.f_root = edits->f.f_root; - - if( edits->f.f_dir.ptr ) - pathname.f_dir = edits->f.f_dir; - - if( edits->f.f_base.ptr ) - pathname.f_base = edits->f.f_base; - - if( edits->f.f_suffix.ptr ) - pathname.f_suffix = edits->f.f_suffix; - - if( edits->f.f_member.ptr ) - pathname.f_member = edits->f.f_member; - - /* If requested, modify pathname to point to parent */ - - if( edits->parent ) - path_parent( &pathname ); - - /* Put filename back together */ - - path_build( &pathname, out, 0 ); -} - -/* - * var_edit_shift() - do upshift/downshift mods - */ - -static void -var_edit_shift( - char *out, - VAR_EDITS *edits ) -{ - /* Handle upshifting, downshifting now */ - - if( edits->upshift ) - { - for( ; *out; ++out ) - *out = toupper( *out ); - } - else if( edits->downshift ) - { - for( ; *out; ++out ) - *out = tolower( *out ); - } -} diff --git a/jam-2.5/expand.h b/jam-2.5/expand.h deleted file mode 100644 index 65f3b5f8e..000000000 --- a/jam-2.5/expand.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * expand.h - expand a buffer, given variable values - * - * 11/04/02 (seiwald) - const-ing for string literals - */ - -LIST *var_expand( - LIST *l, - const char *in, - const char *end, - LOL *lol, - int cancopyin ); diff --git a/jam-2.5/filemac.c b/jam-2.5/filemac.c deleted file mode 100644 index 5b3be5a2f..000000000 --- a/jam-2.5/filemac.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * filemac.c - manipulate file names and scan directories on macintosh - * - * External routines: - * - * file_dirscan() - scan a directory for files - * file_time() - get timestamp of file, if not done by file_dirscan() - * file_archscan() - scan an archive for files - * - * File_dirscan() and file_archscan() call back a caller provided function - * for each file found. A flag to this callback function lets file_dirscan() - * and file_archscan() indicate that a timestamp is being provided with the - * file. If file_dirscan() or file_archscan() do not provide the file's - * timestamp, interested parties may later call file_time(). - * - * 04/08/94 (seiwald) - Coherent/386 support added. - * 12/19/94 (mikem) - solaris string table insanity support - * 02/14/95 (seiwald) - parse and build /xxx properly - * 05/03/96 (seiwald) - split into pathunix.c - * 11/21/96 (peterk) - BEOS does not have Unix-style archives - * 01/21/00 (malyn) - divorced from GUSI - * 01/08/01 (seiwald) - closure param for file_dirscan/file_archscan - * 11/04/02 (seiwald) - const-ing for string literals - */ - -# include "jam.h" -# include "filesys.h" -# include "pathsys.h" - -# ifdef OS_MAC - -#include -#include - -# include <:sys:stat.h> - -void CopyC2PStr(const char * cstr, StringPtr pstr) -{ - int len; - - for (len = 0; *cstr && len<255; pstr[++len] = *cstr++) - ; - - pstr[0] = len; -} - -/* - * file_dirscan() - scan a directory for files - */ - -void -file_dirscan( - const char *dir, - scanback func, - void *closure ) -{ - PATHNAME f; - char filename[ MAXJPATH ]; - unsigned char fullPath[ 512 ]; - - FSSpec spec; - WDPBRec vol; - Str63 volName; - CInfoPBRec lastInfo; - int index = 1; - - /* First enter directory itself */ - - memset( (char *)&f, '\0', sizeof( f ) ); - - f.f_dir.ptr = dir; - f.f_dir.len = strlen(dir); - - if( DEBUG_BINDSCAN ) - printf( "scan directory %s\n", dir ); - - /* Special case ":" - enter it */ - - if( f.f_dir.len == 1 && f.f_dir.ptr[0] == ':' ) - (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 ); - - /* Now enter contents of directory */ - - vol.ioNamePtr = volName; - - if( PBHGetVolSync( &vol ) ) - return; - - CopyC2PStr( dir, fullPath ); - - if( FSMakeFSSpec( vol.ioWDVRefNum, vol.ioWDDirID, fullPath, &spec ) ) - return; - - lastInfo.dirInfo.ioVRefNum = spec.vRefNum; - lastInfo.dirInfo.ioDrDirID = spec.parID; - lastInfo.dirInfo.ioNamePtr = spec.name; - lastInfo.dirInfo.ioFDirIndex = 0; - lastInfo.dirInfo.ioACUser = 0; - - if( PBGetCatInfoSync(&lastInfo) ) - return; - - if (!(lastInfo.dirInfo.ioFlAttrib & 0x10)) - return; - - // ioDrDirID must be reset each time. - - spec.parID = lastInfo.dirInfo.ioDrDirID; - - for( ;; ) - { - lastInfo.dirInfo.ioVRefNum = spec.vRefNum; - lastInfo.dirInfo.ioDrDirID = spec.parID; - lastInfo.dirInfo.ioNamePtr = fullPath; - lastInfo.dirInfo.ioFDirIndex = index++; - - if( PBGetCatInfoSync(&lastInfo) ) - return; - - f.f_base.ptr = (char *)fullPath + 1; - f.f_base.len = *fullPath; - - path_build( &f, filename, 0 ); - - (*func)( closure, filename, 0 /* not stat()'ed */, (time_t)0 ); - } -} - -/* - * file_time() - get timestamp of file, if not done by file_dirscan() - */ - -int -file_time( - const char *filename, - time_t *time ) -{ - struct stat statbuf; - - if( stat( filename, &statbuf ) < 0 ) - return -1; - - *time = statbuf.st_mtime; - - return 0; -} - -/* - * file_archscan() - scan an archive for files - */ - -void -file_archscan( - const char *archive, - scanback func, - void *closure ) -{ -} - - -# endif /* macintosh */ - diff --git a/jam-2.5/filent.c b/jam-2.5/filent.c deleted file mode 100644 index 7a335818a..000000000 --- a/jam-2.5/filent.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * filent.c - scan directories and archives on NT - * - * External routines: - * - * file_dirscan() - scan a directory for files - * file_time() - get timestamp of file, if not done by file_dirscan() - * file_archscan() - scan an archive for files - * - * File_dirscan() and file_archscan() call back a caller provided function - * for each file found. A flag to this callback function lets file_dirscan() - * and file_archscan() indicate that a timestamp is being provided with the - * file. If file_dirscan() or file_archscan() do not provide the file's - * timestamp, interested parties may later call file_time(). - * - * 07/10/95 (taylor) Findfirst() returns the first file on NT. - * 05/03/96 (seiwald) split apart into pathnt.c - * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C - * 10/03/00 (anton) - Porting for Borland C++ 5.5 - * 01/08/01 (seiwald) - closure param for file_dirscan/file_archscan - * 11/04/02 (seiwald) - const-ing for string literals - * 01/23/03 (seiwald) - long long handles for NT IA64 - */ - -# include "jam.h" -# include "filesys.h" -# include "pathsys.h" - -# ifdef OS_NT - -# ifdef __BORLANDC__ -# if __BORLANDC__ < 0x550 -# include -# include -# endif -# undef PATHNAME /* cpp namespace collision */ -# define _finddata_t ffblk -# endif - -# include -# include - -/* - * file_dirscan() - scan a directory for files - */ - -# ifdef _M_IA64 -# define FINDTYPE long long -# else -# define FINDTYPE long -# endif - -void -file_dirscan( - const char *dir, - scanback func, - void *closure ) -{ - PATHNAME f; - char filespec[ MAXJPATH ]; - char filename[ MAXJPATH ]; - FINDTYPE handle; - int ret; - struct _finddata_t finfo[1]; - - /* First enter directory itself */ - - memset( (char *)&f, '\0', sizeof( f ) ); - - f.f_dir.ptr = dir; - f.f_dir.len = strlen(dir); - - dir = *dir ? dir : "."; - - /* Special case \ or d:\ : enter it */ - - if( f.f_dir.len == 1 && f.f_dir.ptr[0] == '\\' ) - (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 ); - else if( f.f_dir.len == 3 && f.f_dir.ptr[1] == ':' ) - (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 ); - - /* Now enter contents of directory */ - - sprintf( filespec, "%s/*", dir ); - - if( DEBUG_BINDSCAN ) - printf( "scan directory %s\n", dir ); - -# if defined(__BORLANDC__) && __BORLANDC__ < 0x550 - if ( ret = findfirst( filespec, finfo, FA_NORMAL | FA_DIREC ) ) - return; - - while( !ret ) - { - time_t time_write = finfo->ff_fdate; - - time_write = (time_write << 16) | finfo->ff_ftime; - f.f_base.ptr = finfo->ff_name; - f.f_base.len = strlen( finfo->ff_name ); - - path_build( &f, filename ); - - (*func)( closure, filename, 1 /* stat()'ed */, time_write ); - - ret = findnext( finfo ); - } -# else - handle = _findfirst( filespec, finfo ); - - if( ret = ( handle == (FINDTYPE)(-1) ) ) - return; - - while( !ret ) - { - f.f_base.ptr = finfo->name; - f.f_base.len = strlen( finfo->name ); - - path_build( &f, filename, 0 ); - - (*func)( closure, filename, 1 /* stat()'ed */, finfo->time_write ); - - ret = _findnext( handle, finfo ); - } - - _findclose( handle ); -# endif - -} - -/* - * file_time() - get timestamp of file, if not done by file_dirscan() - */ - -int -file_time( - const char *filename, - time_t *time ) -{ - /* On NT this is called only for C:/ */ - - struct stat statbuf; - - if( stat( filename, &statbuf ) < 0 ) - return -1; - - *time = statbuf.st_mtime; - - return 0; -} - -/* - * file_archscan() - scan an archive for files - */ - -/* Straight from SunOS */ - -#define ARMAG "!\n" -#define SARMAG 8 - -#define ARFMAG "`\n" - -struct ar_hdr { - char ar_name[16]; - char ar_date[12]; - char ar_uid[6]; - char ar_gid[6]; - char ar_mode[8]; - char ar_size[10]; - char ar_fmag[2]; -}; - -# define SARFMAG 2 -# define SARHDR sizeof( struct ar_hdr ) - -void -file_archscan( - const char *archive, - scanback func, - void *closure ) -{ - struct ar_hdr ar_hdr; - char *string_table = 0; - char buf[ MAXJPATH ]; - long offset; - int fd; - - if( ( fd = open( archive, O_RDONLY | O_BINARY, 0 ) ) < 0 ) - return; - - if( read( fd, buf, SARMAG ) != SARMAG || - strncmp( ARMAG, buf, SARMAG ) ) - { - close( fd ); - return; - } - - offset = SARMAG; - - if( DEBUG_BINDSCAN ) - printf( "scan archive %s\n", archive ); - - while( read( fd, &ar_hdr, SARHDR ) == SARHDR && - !memcmp( ar_hdr.ar_fmag, ARFMAG, SARFMAG ) ) - { - long lar_date; - long lar_size; - char *name = 0; - char *endname; - char *c; - - sscanf( ar_hdr.ar_date, "%ld", &lar_date ); - sscanf( ar_hdr.ar_size, "%ld", &lar_size ); - - lar_size = ( lar_size + 1 ) & ~1; - - if (ar_hdr.ar_name[0] == '/' && ar_hdr.ar_name[1] == '/' ) - { - /* this is the "string table" entry of the symbol table, - ** which holds strings of filenames that are longer than - ** 15 characters (ie. don't fit into a ar_name - */ - - string_table = malloc(lar_size); - if (read(fd, string_table, lar_size) != lar_size) - printf("error reading string table\n"); - offset += SARHDR + lar_size; - continue; - } - else if (ar_hdr.ar_name[0] == '/' && ar_hdr.ar_name[1] != ' ') - { - /* Long filenames are recognized by "/nnnn" where nnnn is - ** the offset of the string in the string table represented - ** in ASCII decimals. - */ - - name = string_table + atoi( ar_hdr.ar_name + 1 ); - endname = name + strlen( name ); - } - else - { - /* normal name */ - name = ar_hdr.ar_name; - endname = name + sizeof( ar_hdr.ar_name ); - } - - /* strip trailing space, slashes, and backslashes */ - - while( endname-- > name ) - if( *endname != ' ' && *endname != '\\' && *endname != '/' ) - break; - *++endname = 0; - - /* strip leading directory names, an NT specialty */ - - if( c = strrchr( name, '/' ) ) - name = c + 1; - if( c = strrchr( name, '\\' ) ) - name = c + 1; - - sprintf( buf, "%s(%.*s)", archive, endname - name, name ); - (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date ); - - offset += SARHDR + lar_size; - lseek( fd, offset, 0 ); - } - - close( fd ); -} - -# endif /* NT */ diff --git a/jam-2.5/fileos2.c b/jam-2.5/fileos2.c deleted file mode 100644 index 18477574f..000000000 --- a/jam-2.5/fileos2.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * fileos2.c - scan directories and archives on NT - * - * External routines: - * - * file_dirscan() - scan a directory for files - * file_time() - get timestamp of file, if not done by file_dirscan() - * file_archscan() - scan an archive for files - * - * File_dirscan() and file_archscan() call back a caller provided function - * for each file found. A flag to this callback function lets file_dirscan() - * and file_archscan() indicate that a timestamp is being provided with the - * file. If file_dirscan() or file_archscan() do not provide the file's - * timestamp, interested parties may later call file_time(). - * - * 07/10/95 (taylor) Findfirst() returns the first file on NT. - * 05/03/96 (seiwald) split apart into pathnt.c - * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C - * 09/22/00 (seiwald) handle \ and c:\ specially: don't add extra / - * 01/08/01 (seiwald) - closure param for file_dirscan/file_archscan - * 11/04/02 (seiwald) - const-ing for string literals - */ - -# include "jam.h" -# include "filesys.h" -# include "pathsys.h" - -# ifdef OS_OS2 - -# include -# include - -/* - * file_dirscan() - scan a directory for files - */ - -void -file_dirscan( - const char *dir, - scanback func, - void *closure ) -{ - PATHNAME f; - char filespec[ MAXJPATH ]; - char filename[ MAXJPATH ]; - long handle; - int ret; - struct _find_t finfo[1]; - - /* First enter directory itself */ - - memset( (char *)&f, '\0', sizeof( f ) ); - - f.f_dir.ptr = dir; - f.f_dir.len = strlen(dir); - - dir = *dir ? dir : "."; - - /* Special case \ or d:\ : enter it */ - - strcpy( filespec, dir ); - - if( f.f_dir.len == 1 && f.f_dir.ptr[0] == '\\' ) - (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 ); - else if( f.f_dir.len == 3 && f.f_dir.ptr[1] == ':' ) - (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 ); - else - strcat( filespec, "/" ); - - strcat( filespec, "*" ); - - /* Now enter contents of directory */ - - if( DEBUG_BINDSCAN ) - printf( "scan directory %s\n", filespec ); - - /* Time info in dos find_t is not very useful. It consists */ - /* of a separate date and time, and putting them together is */ - /* not easy. So we leave that to a later stat() call. */ - - if( !_dos_findfirst( filespec, _A_NORMAL|_A_RDONLY|_A_SUBDIR, finfo ) ) - { - do - { - f.f_base.ptr = finfo->name; - f.f_base.len = strlen( finfo->name ); - - path_build( &f, filename, 0 ); - - (*func)( closure, filename, 0 /* not stat()'ed */, (time_t)0 ); - } - while( !_dos_findnext( finfo ) ); - } - -} - -/* - * file_time() - get timestamp of file, if not done by file_dirscan() - */ - -int -file_time( - const char *filename, - time_t *time ) -{ - /* This is called on OS2, not NT. */ - /* NT fills in the time in the dirscan. */ - - struct stat statbuf; - - if( stat( filename, &statbuf ) < 0 ) - return -1; - - *time = statbuf.st_mtime; - - return 0; -} - -void -file_archscan( - const char *archive, - scanback func, - void *closure ) -{ -} - -# endif /* OS2 */ - diff --git a/jam-2.5/filesys.h b/jam-2.5/filesys.h deleted file mode 100644 index e424f29e0..000000000 --- a/jam-2.5/filesys.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * filesys.h - OS specific file routines - * - * 11/04/02 (seiwald) - const-ing for string literals - */ - -typedef void (*scanback)( void *closure, const char *file, int found, time_t t ); - -void file_dirscan( const char *dir, scanback func, void *closure ); -void file_archscan( const char *arch, scanback func, void *closure ); - -int file_time( const char *filename, time_t *time ); diff --git a/jam-2.5/fileunix.c b/jam-2.5/fileunix.c deleted file mode 100644 index 41127a293..000000000 --- a/jam-2.5/fileunix.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * fileunix.c - manipulate file names and scan directories on UNIX/AmigaOS - * - * External routines: - * - * file_dirscan() - scan a directory for files - * file_time() - get timestamp of file, if not done by file_dirscan() - * file_archscan() - scan an archive for files - * - * File_dirscan() and file_archscan() call back a caller provided function - * for each file found. A flag to this callback function lets file_dirscan() - * and file_archscan() indicate that a timestamp is being provided with the - * file. If file_dirscan() or file_archscan() do not provide the file's - * timestamp, interested parties may later call file_time(). - * - * 04/08/94 (seiwald) - Coherent/386 support added. - * 12/19/94 (mikem) - solaris string table insanity support - * 02/14/95 (seiwald) - parse and build /xxx properly - * 05/03/96 (seiwald) - split into pathunix.c - * 11/21/96 (peterk) - BEOS does not have Unix-style archives - * 01/08/01 (seiwald) - closure param for file_dirscan/file_archscan - * 04/03/01 (seiwald) - AIX uses SARMAG - * 07/16/02 (seiwald) - Support BSD style long filename in archives. - * 11/04/02 (seiwald) - const-ing for string literals - * 12/27/02 (seiwald) - support for AIX big archives - * 12/30/02 (seiwald) - terminate ar_hdr for solaris sscanf() - * 12/30/02 (seiwald) - skip solaris' empty archive member names (/, //xxx) - */ - -# include "jam.h" -# include "filesys.h" -# include "pathsys.h" - -# ifdef USE_FILEUNIX - -# if defined( OS_SEQUENT ) || \ - defined( OS_DGUX ) || \ - defined( OS_SCO ) || \ - defined( OS_ISC ) -# define PORTAR 1 -# endif - -# if defined( OS_RHAPSODY ) || \ - defined( OS_MACOSX ) || \ - defined( OS_NEXT ) -/* need unistd for rhapsody's proper lseek */ -# include -# include -# define STRUCT_DIRENT struct direct -# else -# include -# define STRUCT_DIRENT struct dirent -# endif - -# ifdef OS_COHERENT -# include -# define HAVE_AR -# endif - -# if defined( OS_MVS ) || \ - defined( OS_INTERIX ) - -#define ARMAG "!\n" -#define SARMAG 8 -#define ARFMAG "`\n" - -struct ar_hdr /* archive file member header - printable ascii */ -{ - char ar_name[16]; /* file member name - `/' terminated */ - char ar_date[12]; /* file member date - decimal */ - char ar_uid[6]; /* file member user id - decimal */ - char ar_gid[6]; /* file member group id - decimal */ - char ar_mode[8]; /* file member mode - octal */ - char ar_size[10]; /* file member size - decimal */ - char ar_fmag[2]; /* ARFMAG - string to end header */ -}; - -# define HAVE_AR -# endif - -# if defined( OS_QNX ) || \ - defined( OS_BEOS ) || \ - defined( OS_MPEIX ) -# define NO_AR -# define HAVE_AR -# endif - -# ifndef HAVE_AR -# ifdef _AIX43 -/* AIX 43 ar SUPPORTs only __AR_BIG__ */ -# define __AR_BIG__ -# endif -# include -# endif - -/* - * file_dirscan() - scan a directory for files - */ - -void -file_dirscan( - const char *dir, - scanback func, - void *closure ) -{ - PATHNAME f; - DIR *d; - STRUCT_DIRENT *dirent; - char filename[ MAXJPATH ]; - - /* First enter directory itself */ - - memset( (char *)&f, '\0', sizeof( f ) ); - - f.f_dir.ptr = dir; - f.f_dir.len = strlen(dir); - - dir = *dir ? dir : "."; - - /* Special case / : enter it */ - - if( f.f_dir.len == 1 && f.f_dir.ptr[0] == '/' ) - (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 ); - - /* Now enter contents of directory */ - - if( !( d = opendir( dir ) ) ) - return; - - if( DEBUG_BINDSCAN ) - printf( "scan directory %s\n", dir ); - - while( dirent = readdir( d ) ) - { -# ifdef old_sinix - /* Broken structure definition on sinix. */ - f.f_base.ptr = dirent->d_name - 2; -# else - f.f_base.ptr = dirent->d_name; -# endif - f.f_base.len = strlen( f.f_base.ptr ); - - path_build( &f, filename, 0 ); - - (*func)( closure, filename, 0 /* not stat()'ed */, (time_t)0 ); - } - - closedir( d ); -} - -/* - * file_time() - get timestamp of file, if not done by file_dirscan() - */ - -int -file_time( - const char *filename, - time_t *time ) -{ - struct stat statbuf; - - if( stat( filename, &statbuf ) < 0 ) - return -1; - - *time = statbuf.st_mtime; - return 0; -} - -/* - * file_archscan() - scan an archive for files - */ - -# ifndef AIAMAG /* God-fearing UNIX */ - -# define SARFMAG 2 -# define SARHDR sizeof( struct ar_hdr ) - -void -file_archscan( - const char *archive, - scanback func, - void *closure ) -{ -# ifndef NO_AR - struct ar_hdr ar_hdr; - char buf[ MAXJPATH ]; - long offset; - char *string_table = 0; - int fd; - - if( ( fd = open( archive, O_RDONLY, 0 ) ) < 0 ) - return; - - if( read( fd, buf, SARMAG ) != SARMAG || - strncmp( ARMAG, buf, SARMAG ) ) - { - close( fd ); - return; - } - - offset = SARMAG; - - if( DEBUG_BINDSCAN ) - printf( "scan archive %s\n", archive ); - - while( read( fd, &ar_hdr, SARHDR ) == SARHDR && - !memcmp( ar_hdr.ar_fmag, ARFMAG, SARFMAG ) ) - { - long lar_date; - long lar_size; - char lar_name[256]; - char *dst = lar_name; - - /* solaris sscanf() does strlen first, so terminate somewhere */ - - ar_hdr.ar_fmag[0] = 0; - - /* Get date & size */ - - sscanf( ar_hdr.ar_date, "%ld", &lar_date ); - sscanf( ar_hdr.ar_size, "%ld", &lar_size ); - - /* Handle solaris string table. - ** The entry under the name // is the table, - ** and entries with the name /nnnn refer to the table. - */ - - if( ar_hdr.ar_name[0] != '/' ) - { - /* traditional archive entry names: - ** ends at the first space, /, or null. - */ - - char *src = ar_hdr.ar_name; - const char *e = src + sizeof( ar_hdr.ar_name ); - - while( src < e && *src && *src != ' ' && *src != '/' ) - *dst++ = *src++; - } - else if( ar_hdr.ar_name[1] == '/' ) - { - /* this is the "string table" entry of the symbol table, - ** which holds strings of filenames that are longer than - ** 15 characters (ie. don't fit into a ar_name) - */ - - string_table = (char *)malloc(lar_size); - - lseek(fd, offset + SARHDR, 0); - if( read(fd, string_table, lar_size) != lar_size ) - printf( "error reading string table\n" ); - } - else if( string_table && ar_hdr.ar_name[1] != ' ' ) - { - /* Long filenames are recognized by "/nnnn" where nnnn is - ** the offset of the string in the string table represented - ** in ASCII decimals. - */ - - char *src = string_table + atoi( ar_hdr.ar_name + 1 ); - - while( *src != '/' ) - *dst++ = *src++; - } - - /* Terminate lar_name */ - - *dst = 0; - - /* Modern (BSD4.4) long names: if the name is "#1/nnnn", - ** then the actual name is the nnnn bytes after the header. - */ - - if( !strcmp( lar_name, "#1" ) ) - { - int len = atoi( ar_hdr.ar_name + 3 ); - if( read( fd, lar_name, len ) != len ) - printf("error reading archive entry\n"); - lar_name[len] = 0; - } - - /* Build name and pass it on. */ - - if( lar_name[0] ) - { - if( DEBUG_BINDSCAN ) - printf( "archive name %s found\n", lar_name ); - - sprintf( buf, "%s(%s)", archive, lar_name ); - - (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date ); - } - - /* Position at next member */ - - offset += SARHDR + ( ( lar_size + 1 ) & ~1 ); - lseek( fd, offset, 0 ); - } - - if (string_table) - free(string_table); - - close( fd ); - -# endif /* NO_AR */ - -} - -# else /* AIAMAG - RS6000 AIX */ - -void -file_archscan( - const char *archive, - scanback func, - void *closure ) -{ - struct fl_hdr fl_hdr; - - struct { - struct ar_hdr hdr; - char pad[ 256 ]; - } ar_hdr ; - - char buf[ MAXJPATH ]; - long offset; - int fd; - - if( ( fd = open( archive, O_RDONLY, 0 ) ) < 0 ) - return; - -# ifdef __AR_BIG__ - - if( read( fd, (char *)&fl_hdr, FL_HSZ ) != FL_HSZ || - strncmp( AIAMAGBIG, fl_hdr.fl_magic, SAIAMAG ) ) - { - if( strncmp( AIAMAG, fl_hdr.fl_magic, SAIAMAG ) ) - printf( "Can't read new archive %s before AIX 4.3.\n" ); - - close( fd ); - return; - } - -# else - - if( read( fd, (char *)&fl_hdr, FL_HSZ ) != FL_HSZ || - strncmp( AIAMAG, fl_hdr.fl_magic, SAIAMAG ) ) - { - close( fd ); - return; - } - -# endif - - sscanf( fl_hdr.fl_fstmoff, "%ld", &offset ); - - if( DEBUG_BINDSCAN ) - printf( "scan archive %s\n", archive ); - - while( offset > 0 && - lseek( fd, offset, 0 ) >= 0 && - read( fd, &ar_hdr, sizeof( ar_hdr ) ) >= sizeof( ar_hdr.hdr ) ) - { - long lar_date; - int lar_namlen; - - sscanf( ar_hdr.hdr.ar_namlen, "%d", &lar_namlen ); - sscanf( ar_hdr.hdr.ar_date, "%ld", &lar_date ); - sscanf( ar_hdr.hdr.ar_nxtmem, "%ld", &offset ); - - if( !lar_namlen ) - continue; - - ar_hdr.hdr._ar_name.ar_name[ lar_namlen ] = '\0'; - - sprintf( buf, "%s(%s)", archive, ar_hdr.hdr._ar_name.ar_name ); - - (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date ); - } - - close( fd ); -} - -# endif /* AIAMAG - RS6000 AIX */ - -# endif /* USE_FILEUNIX */ - diff --git a/jam-2.5/filevms.c b/jam-2.5/filevms.c deleted file mode 100644 index 3699976c1..000000000 --- a/jam-2.5/filevms.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * filevms.c - scan directories and libaries on VMS - * - * External routines: - * - * file_dirscan() - scan a directory for files - * file_time() - get timestamp of file, if not done by file_dirscan() - * file_archscan() - scan an archive for files - * - * File_dirscan() and file_archscan() call back a caller provided function - * for each file found. A flag to this callback function lets file_dirscan() - * and file_archscan() indicate that a timestamp is being provided with the - * file. If file_dirscan() or file_archscan() do not provide the file's - * timestamp, interested parties may later call file_time(). - * - * 02/09/95 (seiwald) - bungled R=[xxx] - was using directory length! - * 05/03/96 (seiwald) - split into pathvms.c - * 01/08/01 (seiwald) - closure param for file_dirscan/file_archscan - * 03/23/01 (seiwald) - VMS C++ changes. - * 11/04/02 (seiwald) - const-ing for string literals - */ - -# include "jam.h" -# include "filesys.h" -# include "pathsys.h" - -# ifdef OS_VMS - -# include -# include -# include -# include -# include -# include -# include - -#include -#include -#include -#include -#include -#include - -/* Supply missing prototypes for lbr$-routines*/ - -extern "C" { - -int lbr$set_module( - void **, - unsigned long *, - struct dsc$descriptor_s *, - unsigned short *, - void * ); - -int lbr$open( void **, - struct dsc$descriptor_s *, - void *, - void *, - void *, - void *, - void * ); - -int lbr$ini_control( - void **, - unsigned long *, - unsigned long *, - void * ); - -int lbr$get_index( - void **, - unsigned long *, - int (*func)( struct dsc$descriptor_s *, unsigned long *), - void * ); - -int lbr$close( - void ** ); - -} - -static void -file_cvttime( - unsigned int *curtime, - time_t *unixtime ) -{ - static const size_t divisor = 10000000; - static unsigned int bastim[2] = { 0x4BEB4000, 0x007C9567 }; /* 1/1/1970 */ - int delta[2], remainder; - - lib$subx( curtime, bastim, delta ); - lib$ediv( &divisor, delta, unixtime, &remainder ); -} - -# define DEFAULT_FILE_SPECIFICATION "[]*.*;0" - -# define min( a,b ) ((a)<(b)?(a):(b)) - -void -file_dirscan( - const char *dir, - scanback func, - void *closure ) -{ - - struct FAB xfab; - struct NAM xnam; - struct XABDAT xab; - char esa[256]; - char filename[256]; - char filename2[256]; - char dirname[256]; - register int status; - PATHNAME f; - - memset( (char *)&f, '\0', sizeof( f ) ); - - f.f_root.ptr = dir; - f.f_root.len = strlen( dir ); - - /* get the input file specification - */ - xnam = cc$rms_nam; - xnam.nam$l_esa = esa; - xnam.nam$b_ess = sizeof( esa ) - 1; - xnam.nam$l_rsa = filename; - xnam.nam$b_rss = min( sizeof( filename ) - 1, NAM$C_MAXRSS ); - - xab = cc$rms_xabdat; /* initialize extended attributes */ - xab.xab$b_cod = XAB$C_DAT; /* ask for date */ - xab.xab$l_nxt = NULL; /* terminate XAB chain */ - - xfab = cc$rms_fab; - xfab.fab$l_dna = DEFAULT_FILE_SPECIFICATION; - xfab.fab$b_dns = sizeof( DEFAULT_FILE_SPECIFICATION ) - 1; - xfab.fab$l_fop = FAB$M_NAM; - xfab.fab$l_fna = (char *)dir; /* address of file name */ - xfab.fab$b_fns = strlen( dir ); /* length of file name */ - xfab.fab$l_nam = &xnam; /* address of NAB block */ - xfab.fab$l_xab = (char *)&xab; /* address of XAB block */ - - - status = sys$parse( &xfab ); - - if( DEBUG_BINDSCAN ) - printf( "scan directory %s\n", dir ); - - if ( !( status & 1 ) ) - return; - - - - /* Add bogus directory for [000000] */ - - if( !strcmp( dir, "[000000]" ) ) - { - (*func)( closure, "[000000]", 1 /* time valid */, 1 /* old but true */ ); - } - - /* Add bogus directory for [] */ - - if( !strcmp( dir, "[]" ) ) - { - (*func)( closure, "[]", 1 /* time valid */, 1 /* old but true */ ); - (*func)( closure, "[-]", 1 /* time valid */, 1 /* old but true */ ); - } - - while ( (status = sys$search( &xfab )) & 1 ) - { - char *s; - time_t time; - - /* "I think that might work" - eml */ - - sys$open( &xfab ); - sys$close( &xfab ); - - file_cvttime( (unsigned int *)&xab.xab$q_rdt, &time ); - - filename[xnam.nam$b_rsl] = '\0'; - - /* What we do with the name depends on the suffix: */ - /* .dir is a directory */ - /* .xxx is a file with a suffix */ - /* . is no suffix at all */ - - if( xnam.nam$b_type == 4 && !strncmp( xnam.nam$l_type, ".DIR", 4 ) ) - { - /* directory */ - sprintf( dirname, "[.%.*s]", xnam.nam$b_name, xnam.nam$l_name ); - f.f_dir.ptr = dirname; - f.f_dir.len = strlen( dirname ); - f.f_base.ptr = 0; - f.f_base.len = 0; - f.f_suffix.ptr = 0; - f.f_suffix.len = 0; - } - else - { - /* normal file with a suffix */ - f.f_dir.ptr = 0; - f.f_dir.len = 0; - f.f_base.ptr = xnam.nam$l_name; - f.f_base.len = xnam.nam$b_name; - f.f_suffix.ptr = xnam.nam$l_type; - f.f_suffix.len = xnam.nam$b_type; - } - - path_build( &f, filename2, 0 ); - - /* - if( DEBUG_SEARCH ) - printf("root '%s' base %.*s suf %.*s = %s\n", - dir, - xnam.nam$b_name, xnam.nam$l_name, - xnam.nam$b_type, xnam.nam$l_type, - filename2); - */ - - (*func)( closure, filename2, 1 /* time valid */, time ); - } -} - -int -file_time( - const char *filename, - time_t *time ) -{ - /* This should never be called, as all files are */ - /* timestampped in file_dirscan() and file_archscan() */ - return -1; -} - -static char *VMS_archive = 0; -static scanback VMS_func; -static void *VMS_closure; -static void *context; - -static int -file_archmember( - struct dsc$descriptor_s *module, - unsigned long *rfa ) -{ - static struct dsc$descriptor_s bufdsc = - {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL}; - - struct mhddef *mhd; - char filename[128]; - char buf[ MAXJPATH ]; - - int status; - time_t library_date; - - register int i; - register char *p; - - bufdsc.dsc$a_pointer = filename; - bufdsc.dsc$w_length = sizeof( filename ); - status = lbr$set_module( &context, rfa, &bufdsc, - &bufdsc.dsc$w_length, NULL ); - - if ( !(status & 1) ) - return ( 1 ); - - mhd = (struct mhddef *)filename; - - file_cvttime( &mhd->mhd$l_datim, &library_date ); - - for ( i = 0, p = module->dsc$a_pointer; i < module->dsc$w_length; i++, p++ ) - filename[i] = *p; - - filename[i] = '\0'; - - sprintf( buf, "%s(%s.obj)", VMS_archive, filename ); - - (*VMS_func)( VMS_closure, buf, 1 /* time valid */, (time_t)library_date ); - - return ( 1 ); -} - -void -file_archscan( - const char *archive, - scanback func, - void *closure ) -{ - static struct dsc$descriptor_s library = - {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL}; - - unsigned long lfunc = LBR$C_READ; - unsigned long typ = LBR$C_TYP_UNK; - unsigned long index = 1; - - register int status; - - VMS_archive = (char *)archive; - VMS_func = func; - VMS_closure = closure; - - status = lbr$ini_control( &context, &lfunc, &typ, NULL ); - if ( !( status & 1 ) ) - return; - - library.dsc$a_pointer = (char *)archive; - library.dsc$w_length = strlen( archive ); - - status = lbr$open( &context, &library, NULL, NULL, NULL, NULL, NULL ); - if ( !( status & 1 ) ) - return; - - (void) lbr$get_index( &context, &index, file_archmember, NULL ); - - (void) lbr$close( &context ); -} - -# endif /* VMS */ - diff --git a/jam-2.5/glob.c b/jam-2.5/glob.c deleted file mode 100644 index 74d6e7e0f..000000000 --- a/jam-2.5/glob.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 1994 Christopher Seiwald. All rights reserved. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * glob.c - match a string against a simple pattern - * - * Understands the following patterns: - * - * * any number of characters - * ? any single character - * [a-z] any single character in the range a-z - * [^a-z] any single character not in the range a-z - * \x match x - * - * External functions: - * - * glob() - match a string against a simple pattern - * - * Internal functions: - * - * globchars() - build a bitlist to check for character group match - * - * 11/04/02 (seiwald) - const-ing for string literals - */ - -# include "jam.h" - -# define CHECK_BIT( tab, bit ) ( tab[ (bit)/8 ] & (1<<( (bit)%8 )) ) -# define BITLISTSIZE 16 /* bytes used for [chars] in compiled expr */ - -static void globchars( const char *s, const char *e, char *b ); - -/* - * glob() - match a string against a simple pattern - */ - -int -glob( - const char *c, - const char *s ) -{ - char bitlist[ BITLISTSIZE ]; - const char *here; - - for( ;; ) - switch( *c++ ) - { - case '\0': - return *s ? -1 : 0; - - case '?': - if( !*s++ ) - return 1; - break; - - case '[': - /* scan for matching ] */ - - here = c; - do if( !*c++ ) - return 1; - while( here == c || *c != ']' ); - c++; - - /* build character class bitlist */ - - globchars( here, c, bitlist ); - - if( !CHECK_BIT( bitlist, *(unsigned char *)s ) ) - return 1; - s++; - break; - - case '*': - here = s; - - while( *s ) - s++; - - /* Try to match the rest of the pattern in a recursive */ - /* call. If the match fails we'll back up chars, retrying. */ - - while( s != here ) - { - int r; - - /* A fast path for the last token in a pattern */ - - r = *c ? glob( c, s ) : *s ? -1 : 0; - - if( !r ) - return 0; - else if( r < 0 ) - return 1; - - --s; - } - break; - - case '\\': - /* Force literal match of next char. */ - - if( !*c || *s++ != *c++ ) - return 1; - break; - - default: - if( *s++ != c[-1] ) - return 1; - break; - } -} - -/* - * globchars() - build a bitlist to check for character group match - */ - -static void -globchars( - const char *s, - const char *e, - char *b ) -{ - int neg = 0; - - memset( b, '\0', BITLISTSIZE ); - - if( *s == '^') - neg++, s++; - - while( s < e ) - { - int c; - - if( s+2 < e && s[1] == '-' ) - { - for( c = s[0]; c <= s[2]; c++ ) - b[ c/8 ] |= (1<<(c%8)); - s += 3; - } else { - c = *s++; - b[ c/8 ] |= (1<<(c%8)); - } - } - - if( neg ) - { - int i; - for( i = 0; i < BITLISTSIZE; i++ ) - b[ i ] ^= 0377; - } - - /* Don't include \0 in either $[chars] or $[^chars] */ - - b[0] &= 0376; -} diff --git a/jam-2.5/hash.c b/jam-2.5/hash.c deleted file mode 100644 index 015181c0e..000000000 --- a/jam-2.5/hash.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * hash.c - simple in-memory hashing routines - * - * External routines: - * - * hashinit() - initialize a hash table, returning a handle - * hashitem() - find a record in the table, and optionally enter a new one - * hashdone() - free a hash table, given its handle - * - * Internal routines: - * - * hashrehash() - resize and rebuild hp->tab, the hash table - * - * 4/29/93 - ensure ITEM's are aligned - * 11/04/02 (seiwald) - const-ing for string literals - * 01/31/02 (seiwald) - keyval now unsigned (cray-ziness) - */ - -# include "jam.h" -# include "hash.h" - -/* Header attached to all data items entered into a hash table. */ - -struct hashhdr { - struct item *next; - unsigned int keyval; /* for quick comparisons */ -} ; - -/* This structure overlays the one handed to hashenter(). */ -/* It's actual size is given to hashinit(). */ - -struct hashdata { - char *key; - /* rest of user data */ -} ; - -typedef struct item { - struct hashhdr hdr; - struct hashdata data; -} ITEM ; - -# define MAX_LISTS 32 - -struct hash -{ - /* - * the hash table, just an array of item pointers - */ - struct { - int nel; - ITEM **base; - } tab; - - int bloat; /* tab.nel / items.nel */ - int inel; /* initial number of elements */ - - /* - * the array of records, maintained by these routines - * essentially a microallocator - */ - struct { - int more; /* how many more ITEMs fit in lists[ list ] */ - char *next; /* where to put more ITEMs in lists[ list ] */ - int datalen; /* length of records in this hash table */ - int size; /* sizeof( ITEM ) + aligned datalen */ - int nel; /* total ITEMs held by all lists[] */ - int list; /* index into lists[] */ - - struct { - int nel; /* total ITEMs held by this list */ - char *base; /* base of ITEMs array */ - } lists[ MAX_LISTS ]; - } items; - - const char *name; /* just for hashstats() */ -} ; - -static void hashrehash( struct hash *hp ); -static void hashstat( struct hash *hp ); - -/* - * hashitem() - find a record in the table, and optionally enter a new one - */ - -int -hashitem( - register struct hash *hp, - HASHDATA **data, - int enter ) -{ - ITEM **base; - register ITEM *i; - unsigned char *b = (unsigned char *)(*data)->key; - unsigned int keyval; - - if( enter && !hp->items.more ) - hashrehash( hp ); - - if( !enter && !hp->items.nel ) - return 0; - - keyval = *b; - - while( *b ) - keyval = keyval * 2147059363 + *b++; - - base = hp->tab.base + ( keyval % hp->tab.nel ); - - for( i = *base; i; i = i->hdr.next ) - if( keyval == i->hdr.keyval && - !strcmp( i->data.key, (*data)->key ) ) - { - *data = &i->data; - return !0; - } - - if( enter ) - { - i = (ITEM *)hp->items.next; - hp->items.next += hp->items.size; - hp->items.more--; - memcpy( (char *)&i->data, (char *)*data, hp->items.datalen ); - i->hdr.keyval = keyval; - i->hdr.next = *base; - *base = i; - *data = &i->data; - } - - return 0; -} - -/* - * hashrehash() - resize and rebuild hp->tab, the hash table - */ - -static void hashrehash( register struct hash *hp ) -{ - int i = ++hp->items.list; - - hp->items.more = i ? 2 * hp->items.nel : hp->inel; - hp->items.next = (char *)malloc( hp->items.more * hp->items.size ); - - hp->items.lists[i].nel = hp->items.more; - hp->items.lists[i].base = hp->items.next; - hp->items.nel += hp->items.more; - - if( hp->tab.base ) - free( (char *)hp->tab.base ); - - hp->tab.nel = hp->items.nel * hp->bloat; - hp->tab.base = (ITEM **)malloc( hp->tab.nel * sizeof(ITEM **) ); - - memset( (char *)hp->tab.base, '\0', hp->tab.nel * sizeof( ITEM * ) ); - - for( i = 0; i < hp->items.list; i++ ) - { - int nel = hp->items.lists[i].nel; - char *next = hp->items.lists[i].base; - - for( ; nel--; next += hp->items.size ) - { - register ITEM *i = (ITEM *)next; - ITEM **ip = hp->tab.base + i->hdr.keyval % hp->tab.nel; - - i->hdr.next = *ip; - *ip = i; - } - } -} - -/* --- */ - -# define ALIGNED(x) ( ( x + sizeof( ITEM ) - 1 ) & ~( sizeof( ITEM ) - 1 ) ) - -/* - * hashinit() - initialize a hash table, returning a handle - */ - -struct hash * -hashinit( - int datalen, - const char *name ) -{ - struct hash *hp = (struct hash *)malloc( sizeof( *hp ) ); - - hp->bloat = 3; - hp->tab.nel = 0; - hp->tab.base = (ITEM **)0; - hp->items.more = 0; - hp->items.datalen = datalen; - hp->items.size = sizeof( struct hashhdr ) + ALIGNED( datalen ); - hp->items.list = -1; - hp->items.nel = 0; - hp->inel = 11; - hp->name = name; - - return hp; -} - -/* - * hashdone() - free a hash table, given its handle - */ - -void -hashdone( struct hash *hp ) -{ - int i; - - if( !hp ) - return; - - if( DEBUG_MEM ) - hashstat( hp ); - - if( hp->tab.base ) - free( (char *)hp->tab.base ); - for( i = 0; i <= hp->items.list; i++ ) - free( hp->items.lists[i].base ); - free( (char *)hp ); -} - -/* ---- */ - -static void -hashstat( struct hash *hp ) -{ - ITEM **tab = hp->tab.base; - int nel = hp->tab.nel; - int count = 0; - int sets = 0; - int run = ( tab[ nel - 1 ] != (ITEM *)0 ); - int i, here; - - for( i = nel; i > 0; i-- ) - { - if( here = ( *tab++ != (ITEM *)0 ) ) - count++; - if( here && !run ) - sets++; - run = here; - } - - printf( "%s table: %d+%d+%d (%dK+%dK) items+table+hash, %f density\n", - hp->name, - count, - hp->items.nel, - hp->tab.nel, - hp->items.nel * hp->items.size / 1024, - hp->tab.nel * sizeof( ITEM ** ) / 1024, - (float)count / (float)sets ); -} diff --git a/jam-2.5/hash.h b/jam-2.5/hash.h deleted file mode 100644 index 28149e2be..000000000 --- a/jam-2.5/hash.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * hash.h - simple in-memory hashing routines - * - * 11/04/02 (seiwald) - const-ing for string literals - */ - -typedef struct hashdata HASHDATA; - -struct hash * hashinit( int datalen, const char *name ); -int hashitem( struct hash *hp, HASHDATA **data, int enter ); -void hashdone( struct hash *hp ); - -# define hashenter( hp, data ) !hashitem( hp, data, !0 ) -# define hashcheck( hp, data ) hashitem( hp, data, 0 ) diff --git a/jam-2.5/headers.c b/jam-2.5/headers.c deleted file mode 100644 index 525e5ccb4..000000000 --- a/jam-2.5/headers.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 1993, 2000 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * headers.c - handle #includes in source files - * - * Using regular expressions provided as the variable $(HDRSCAN), - * headers() searches a file for #include files and phonies up a - * rule invocation: - * - * $(HDRRULE) : ; - * - * External routines: - * headers() - scan a target for include files and call HDRRULE - * - * Internal routines: - * headers1() - using regexp, scan a file and build include LIST - * - * 04/13/94 (seiwald) - added shorthand L0 for null list pointer - * 09/10/00 (seiwald) - replaced call to compile_rule with evaluate_rule, - * so that headers() doesn't have to mock up a parse structure - * just to invoke a rule. - * 03/02/02 (seiwald) - rules can be invoked via variable names - * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() - * 11/04/02 (seiwald) - const-ing for string literals - * 12/09/02 (seiwald) - push regexp creation down to headers1(). - */ - -# include "jam.h" -# include "lists.h" -# include "parse.h" -# include "compile.h" -# include "rules.h" -# include "variable.h" -# include "regexp.h" -# include "headers.h" -# include "newstr.h" - -static LIST *headers1( const char *file, LIST *hdrscan ); - -/* - * headers() - scan a target for include files and call HDRRULE - */ - -# define MAXINC 10 - -void -headers( TARGET *t ) -{ - LIST *hdrscan; - LIST *hdrrule; - LIST *hdrcache; - LOL lol; - - if( !( hdrscan = var_get( "HDRSCAN" ) ) || - !( hdrrule = var_get( "HDRRULE" ) ) ) - return; - - /* Doctor up call to HDRRULE rule */ - /* Call headers1() to get LIST of included files. */ - - if( DEBUG_HEADER ) - printf( "header scan %s\n", t->name ); - - lol_init( &lol ); - - lol_add( &lol, list_new( L0, t->name, 1 ) ); - lol_add( &lol, headers1( t->boundname, hdrscan ) ); - - if( lol_get( &lol, 1 ) ) - list_free( evaluate_rule( hdrrule->string, &lol, L0 ) ); - - /* Clean up */ - - lol_free( &lol ); -} - -/* - * headers1() - using regexp, scan a file and build include LIST - */ - -static LIST * -headers1( - const char *file, - LIST *hdrscan ) -{ - FILE *f; - int i; - int rec = 0; - LIST *result = 0; - regexp *re[ MAXINC ]; - char buf[ 1024 ]; - - if( !( f = fopen( file, "r" ) ) ) - return result; - - while( rec < MAXINC && hdrscan ) - { - re[rec++] = regcomp( hdrscan->string ); - hdrscan = list_next( hdrscan ); - } - - while( fgets( buf, sizeof( buf ), f ) ) - { - for( i = 0; i < rec; i++ ) - if( regexec( re[i], buf ) && re[i]->startp[1] ) - { - /* Copy and terminate extracted string. */ - - char buf2[ MAXSYM ]; - int l = re[i]->endp[1] - re[i]->startp[1]; - memcpy( buf2, re[i]->startp[1], l ); - buf2[ l ] = 0; - result = list_new( result, buf2, 0 ); - - if( DEBUG_HEADER ) - printf( "header found: %s\n", buf2 ); - } - } - - while( rec ) - free( (char *)re[--rec] ); - - fclose( f ); - - return result; -} diff --git a/jam-2.5/headers.h b/jam-2.5/headers.h deleted file mode 100644 index 8c33735c6..000000000 --- a/jam-2.5/headers.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * headers.h - handle #includes in source files - */ - -void headers( TARGET *t ); diff --git a/jam-2.5/jam.c b/jam-2.5/jam.c deleted file mode 100644 index 4bc1b90ab..000000000 --- a/jam-2.5/jam.c +++ /dev/null @@ -1,377 +0,0 @@ -/* - * /+\ - * +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * \+/ - * - * This file is part of jam. - * - * License is hereby granted to use this software and distribute it - * freely, as long as this copyright notice is retained and modifications - * are clearly marked. - * - * ALL WARRANTIES ARE HEREBY DISCLAIMED. - */ - -/* - * jam.c - make redux - * - * See Jam.html for usage information. - * - * These comments document the code. - * - * The top half of the code is structured such: - * - * jam - * / | \ - * +---+ | \ - * / | \ - * jamgram option \ - * / | \ \ - * / | \ \ - * / | \ | - * scan | compile make - * | | / | \ / | \ - * | | / | \ / | \ - * | | / | \ / | \ - * jambase parse | rules search make1 - * | | | \ - * | | | \ - * | | | \ - * builtins timestamp command execute - * | - * | - * | - * filesys - * - * - * The support routines are called by all of the above, but themselves - * are layered thus: - * - * variable|expand - * / | | | - * / | | | - * / | | | - * lists | | pathsys - * \ | | - * \ | | - * \ | | - * newstr | - * \ | - * \ | - * \ | - * hash - * - * Roughly, the modules are: - * - * builtins.c - jam's built-in rules - * command.c - maintain lists of commands - * compile.c - compile parsed jam statements - * execunix.c - execute a shell script on UNIX - * execvms.c - execute a shell script, ala VMS - * expand.c - expand a buffer, given variable values - * file*.c - scan directories and archives on * - * hash.c - simple in-memory hashing routines - * headers.c - handle #includes in source files - * jambase.c - compilable copy of Jambase - * jamgram.y - jam grammar - * lists.c - maintain lists of strings - * make.c - bring a target up to date, once rules are in place - * make1.c - execute command to bring targets up to date - * newstr.c - string manipulation routines - * option.c - command line option processing - * parse.c - make and destroy parse trees as driven by the parser - * path*.c - manipulate file names on * - * hash.c - simple in-memory hashing routines - * regexp.c - Henry Spencer's regexp - * rules.c - access to RULEs, TARGETs, and ACTIONs - * scan.c - the jam yacc scanner - * search.c - find a target along $(SEARCH) or $(LOCATE) - * timestamp.c - get the timestamp of a file or archive member - * variable.c - handle jam multi-element variables - * - * 05/04/94 (seiwald) - async multiprocess (-j) support - * 02/08/95 (seiwald) - -n implies -d2. - * 02/22/95 (seiwald) - -v for version info. - * 09/11/00 (seiwald) - PATCHLEVEL folded into VERSION. - * 01/10/01 (seiwald) - pathsys.h split from filesys.h - * 01/21/02 (seiwald) - new -q to quit quickly on build failure - * 03/16/02 (seiwald) - support for -g (reorder builds by source time) - * 09/19/02 (seiwald) - new -d displays - * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() - * 11/04/02 (seiwald) - const-ing for string literals - */ - -# include "jam.h" -# include "option.h" -# include "patchlevel.h" - -/* These get various function declarations. */ - -# include "lists.h" -# include "parse.h" -# include "variable.h" -# include "compile.h" -# include "builtins.h" -# include "rules.h" -# include "newstr.h" -# include "scan.h" -# include "timestamp.h" -# include "make.h" - -/* Macintosh is "special" */ - -# ifdef OS_MAC -# include -# endif - -/* And UNIX for this */ - -# ifdef unix -# include -# endif - -struct globs globs = { - 0, /* noexec */ - 1, /* jobs */ - 0, /* quitquick */ - 0, /* newestfirst */ -# ifdef OS_MAC - { 0 }, /* display - suppress actions output */ -# else - { 0, 1 }, /* display actions */ -# endif - 0 /* output commands, not run them */ -} ; - -/* Symbols to be defined as true for use in Jambase */ - -static const char *othersyms[] = { OSMAJOR, OSMINOR, OSPLAT, JAMVERSYM, 0 } ; - -/* Known for sure: - * mac needs arg_enviro - * OS2 needs extern environ - */ - -# ifdef OS_MAC -# define use_environ arg_environ -# ifdef MPW -QDGlobals qd; -# endif -# endif - -# ifndef use_environ -# define use_environ environ -# if !defined( __WATCOM__ ) && !defined( OS_OS2 ) && !defined( OS_NT ) -extern char **environ; -# endif -# endif - -main( int argc, char **argv, char **arg_environ ) -{ - int n; - const char *s; - struct option optv[N_OPTS]; - const char *all = "all"; - int anyhow = 0; - int status; - -# ifdef OS_MAC - InitGraf(&qd.thePort); -# endif - - argc--, argv++; - - if( ( n = getoptions( argc, argv, "d:j:f:gs:t:ano:qv", optv ) ) < 0 ) - { - printf( "\nusage: jam [ options ] targets...\n\n" ); - - printf( "-a Build all targets, even if they are current.\n" ); - printf( "-dx Display (a)actions (c)causes (d)dependencies\n" ); - printf( " (m)make tree (x)commands (0-9) debug levels.\n" ); - printf( "-fx Read x instead of Jambase.\n" ); - printf( "-g Build from newest sources first.\n" ); - printf( "-jx Run up to x shell commands concurrently.\n" ); - printf( "-n Don't actually execute the updating actions.\n" ); - printf( "-ox Write the updating actions to file x.\n" ); - printf( "-q Quit quickly as soon as a target fails.\n" ); - printf( "-sx=y Set variable x=y, overriding environment.\n" ); - printf( "-tx Rebuild x, even if it is up-to-date.\n" ); - printf( "-v Print the version of jam and exit.\n\n" ); - - exit( EXITBAD ); - } - - argc -= n, argv += n; - - /* Version info. */ - - if( ( s = getoptval( optv, 'v', 0 ) ) ) - { - printf( "Jam %s. %s. ", VERSION, OSMINOR ); - printf( "Copyright 1993-2002 Christopher Seiwald.\n" ); - - return EXITOK; - } - - /* Pick up interesting options */ - - if( ( s = getoptval( optv, 'n', 0 ) ) ) - globs.noexec++, DEBUG_MAKE = DEBUG_MAKEQ = DEBUG_EXEC = 1; - - if( ( s = getoptval( optv, 'q', 0 ) ) ) - globs.quitquick = 1; - - if( ( s = getoptval( optv, 'a', 0 ) ) ) - anyhow++; - - if( ( s = getoptval( optv, 'j', 0 ) ) ) - globs.jobs = atoi( s ); - - if( ( s = getoptval( optv, 'g', 0 ) ) ) - globs.newestfirst = 1; - - /* Turn on/off debugging */ - - for( n = 0; s = getoptval( optv, 'd', n ); n++ ) - { - int i = atoi( s ); - - /* First -d, turn off defaults. */ - - if( !n ) - DEBUG_MAKE = DEBUG_MAKEQ = DEBUG_EXEC = 0; - - /* n turns on levels 1-n */ - /* +n turns on level n */ - /* c turns on named display c */ - - if( i < 0 || i >= DEBUG_MAX ) - { - printf( "Invalid debug level '%s'.\n", s ); - } - else if( *s == '+' ) - { - globs.debug[i] = 1; - } - else if( i ) while( i ) - { - globs.debug[i--] = 1; - } - else while( *s ) switch( *s++ ) - { - case 'a': DEBUG_MAKE = DEBUG_MAKEQ = 1; break; - case 'c': DEBUG_CAUSES = 1; break; - case 'd': DEBUG_DEPENDS = 1; break; - case 'm': DEBUG_MAKEPROG = 1; break; - case 'x': DEBUG_EXEC = 1; break; - case '0': break; - default: printf( "Invalid debug flag '%c'.\n", s[-1] ); - } - } - - /* Set JAMDATE first */ - - { - char buf[ 128 ]; - time_t clock; - time( &clock ); - strcpy( buf, ctime( &clock ) ); - - /* Trim newline from date */ - - if( strlen( buf ) == 25 ) - buf[ 24 ] = 0; - - var_set( "JAMDATE", list_new( L0, buf, 0 ), VAR_SET ); - } - - /* And JAMUNAME */ -# ifdef unix - { - struct utsname u; - - if( uname( &u ) >= 0 ) - { - LIST *l = L0; - l = list_new( l, u.machine, 0 ); - l = list_new( l, u.version, 0 ); - l = list_new( l, u.release, 0 ); - l = list_new( l, u.nodename, 0 ); - l = list_new( l, u.sysname, 0 ); - var_set( "JAMUNAME", l, VAR_SET ); - } - } -# endif /* unix */ - - /* - * Jam defined variables OS, OSPLAT - */ - - var_defines( othersyms ); - - /* load up environment variables */ - - var_defines( (const char **)use_environ ); - - /* Load up variables set on command line. */ - - for( n = 0; s = getoptval( optv, 's', n ); n++ ) - { - const char *symv[2]; - symv[0] = s; - symv[1] = 0; - var_defines( symv ); - } - - /* Initialize built-in rules */ - - load_builtins(); - - /* Parse ruleset */ - - for( n = 0; s = getoptval( optv, 'f', n ); n++ ) - parse_file( s ); - - if( !n ) - parse_file( "+" ); - - status = yyanyerrors(); - - /* Manually touch -t targets */ - - for( n = 0; s = getoptval( optv, 't', n ); n++ ) - touchtarget( s ); - - /* If an output file is specified, set globs.cmdout to that */ - - if( s = getoptval( optv, 'o', 0 ) ) - { - if( !( globs.cmdout = fopen( s, "w" ) ) ) - { - printf( "Failed to write to '%s'\n", s ); - exit( EXITBAD ); - } - globs.noexec++; - } - - /* Now make target */ - - if( !argc ) - status |= make( 1, &all, anyhow ); - else - status |= make( argc, (const char **)argv, anyhow ); - - /* Widely scattered cleanup */ - - var_done(); - donerules(); - donestamps(); - donestr(); - - /* close cmdout */ - - if( globs.cmdout ) - fclose( globs.cmdout ); - - return status ? EXITBAD : EXITOK; -} diff --git a/jam-2.5/jam.h b/jam-2.5/jam.h deleted file mode 100644 index f8080ffae..000000000 --- a/jam-2.5/jam.h +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * jam.h - includes and globals for jam - * - * 04/08/94 (seiwald) - Coherent/386 support added. - * 04/21/94 (seiwald) - DGUX is __DGUX__, not just __DGUX. - * 05/04/94 (seiwald) - new globs.jobs (-j jobs) - * 11/01/94 (wingerd) - let us define path of Jambase at compile time. - * 12/30/94 (wingerd) - changed command buffer size for NT (MS-DOS shell). - * 02/22/95 (seiwald) - Jambase now in /usr/local/lib. - * 04/30/95 (seiwald) - FreeBSD added. Live Free or Die. - * 05/10/95 (seiwald) - SPLITPATH character set up here. - * 08/20/95 (seiwald) - added LINUX. - * 08/21/95 (seiwald) - added NCR. - * 10/23/95 (seiwald) - added SCO. - * 01/03/96 (seiwald) - SINIX (nixdorf) added. - * 03/13/96 (seiwald) - Jambase now compiled in; remove JAMBASE variable. - * 04/29/96 (seiwald) - AIX now has 31 and 42 OSVERs. - * 11/21/96 (peterk) - added BeOS with MW CW mwcc - * 12/21/96 (seiwald) - OSPLAT now defined for NT. - * 07/19/99 (sickel) - Mac OS X Server and Client support added - * 02/22/01 (seiwald) - downshift paths on case-insensitive macintosh - * 03/23/01 (seiwald) - VMS C++ changes. - * 10/29/01 (brett) - More IA64 ifdefs for MS. - * 02/18/00 (belmonte)- Support for Cygwin. - * 09/12/00 (seiwald) - OSSYMS split to OSMAJOR/OSMINOR/OSPLAT - * 12/29/00 (seiwald) - OSVER dropped. - * 01/21/02 (seiwald) - new -q to quit quickly on build failure - * 03/16/02 (seiwald) - support for -g (reorder builds by source time) - * 03/20/02 (seiwald) - MINGW porting from Max Blagai - * 08/16/02 (seiwald) - BEOS porting from Ingo Weinhold - * 09/19/02 (seiwald) - new -d displays - * 11/05/02 (seiwald) - OSPLAT now set to sparc on solaris. - */ - -/* - * VMS, OPENVMS - */ - -# ifdef VMS - -# define unlink remove - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# define OSMINOR "OS=VMS" -# define OSMAJOR "VMS=true" -# define OS_VMS -# define MAXLINE 1024 /* longest 'together' actions */ -# define SPLITPATH ',' -# define EXITOK 1 -# define EXITBAD 0 -# define DOWNSHIFT_PATHS - -/* Do any of these work? */ -# if defined( VAX ) || defined( __VAX ) || defined( vax ) -# define OSPLAT "OSPLAT=VAX" -# endif - -# endif - -/* - * Windows NT - */ - -# ifdef NT - -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# define OSMAJOR "NT=true" -# define OSMINOR "OS=NT" -# define OS_NT -# define SPLITPATH ';' -# define MAXLINE 996 /* longest 'together' actions */ -# define USE_EXECUNIX -# define USE_PATHUNIX -# define PATH_DELIM '\\' -# define DOWNSHIFT_PATHS - -/* AS400 cross-compile from NT */ - -# ifdef AS400 -# undef OSMINOR -# undef OSMAJOR -# define OSMAJOR "AS400=true" -# define OSMINOR "OS=AS400" -# define OS_AS400 -# endif - -# endif - -/* - * Windows MingW32 - */ - -# ifdef MINGW - -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# define OSMAJOR "MINGW=true" -# define OSMINOR "OS=MINGW" -# define OS_NT -# define SPLITPATH ';' -# define MAXLINE 996 /* longest 'together' actions */ -# define USE_EXECUNIX -# define USE_PATHUNIX -# define PATH_DELIM '\\' -# define DOWNSHIFT_PATHS - -# endif - -/* - * OS2 - */ - -# ifdef __OS2__ - -# include -# include -# include -# include -# include -# include -# include -# include - -# define OSMAJOR "OS2=true" -# define OSMINOR "OS=OS2" -# define OS_OS2 -# define SPLITPATH ';' -# define MAXLINE 996 /* longest 'together' actions */ -# define USE_EXECUNIX -# define USE_PATHUNIX -# define PATH_DELIM '\\' -# define DOWNSHIFT_PATHS - -# endif - -/* - * Macintosh MPW - */ - -# ifdef macintosh - -# include -# include -# include -# include -# include - -# define OSMAJOR "MAC=true" -# define OSMINOR "OS=MAC" -# define OS_MAC -# define SPLITPATH ',' -# define DOWNSHIFT_PATHS - -# endif - -/* - * God fearing UNIX - */ - -# ifndef OSMINOR - -# define OSMAJOR "UNIX=true" -# define USE_EXECUNIX -# define USE_FILEUNIX -# define USE_PATHUNIX -# define PATH_DELIM '/' - -# ifdef _AIX -# define unix -# define OSMINOR "OS=AIX" -# define OS_AIX -# define NO_VFORK -# endif -# ifdef AMIGA -# define OSMINOR "OS=AMIGA" -# define OS_AMIGA -# endif -# ifdef __BEOS__ -# define unix -# define OSMINOR "OS=BEOS" -# define OS_BEOS -# define NO_VFORK -# endif -# ifdef __bsdi__ -# define OSMINOR "OS=BSDI" -# define OS_BSDI -# endif -# if defined (COHERENT) && defined (_I386) -# define OSMINOR "OS=COHERENT" -# define OS_COHERENT -# define NO_VFORK -# endif -# ifdef __cygwin__ -# define OSMINOR "OS=CYGWIN" -# define OS_CYGWIN -# endif -# ifdef __FreeBSD__ -# define OSMINOR "OS=FREEBSD" -# define OS_FREEBSD -# endif -# ifdef __DGUX__ -# define OSMINOR "OS=DGUX" -# define OS_DGUX -# endif -# ifdef __hpux -# define OSMINOR "OS=HPUX" -# define OS_HPUX -# endif -# ifdef __OPENNT -# define unix -# define OSMINOR "OS=INTERIX" -# define OS_INTERIX -# define NO_VFORK -# endif -# ifdef __sgi -# define OSMINOR "OS=IRIX" -# define OS_IRIX -# define NO_VFORK -# endif -# ifdef __ISC -# define OSMINOR "OS=ISC" -# define OS_ISC -# define NO_VFORK -# endif -# ifdef linux -# define OSMINOR "OS=LINUX" -# define OS_LINUX -# endif -# ifdef __Lynx__ -# define OSMINOR "OS=LYNX" -# define OS_LYNX -# define NO_VFORK -# define unix -# endif -# ifdef __MACHTEN__ -# define OSMINOR "OS=MACHTEN" -# define OS_MACHTEN -# endif -# ifdef mpeix -# define unix -# define OSMINOR "OS=MPEIX" -# define OS_MPEIX -# define NO_VFORK -# endif -# ifdef __MVS__ -# define unix -# define OSMINOR "OS=MVS" -# define OS_MVS -# endif -# ifdef _ATT4 -# define OSMINOR "OS=NCR" -# define OS_NCR -# endif -# ifdef __NetBSD__ -# define unix -# define OSMINOR "OS=NETBSD" -# define OS_NETBSD -# define NO_VFORK -# endif -# ifdef __QNX__ -# ifdef __QNXNTO__ -# define OSMINOR "OS=QNXNTO" -# define OS_QNXNTO -# else -# define unix -# define OSMINOR "OS=QNX" -# define OS_QNX -# define NO_VFORK -# define MAXLINE 996 -# endif -# endif -# ifdef NeXT -# ifdef __APPLE__ -# define OSMINOR "OS=RHAPSODY" -# define OS_RHAPSODY -# else -# define OSMINOR "OS=NEXT" -# define OS_NEXT -# endif -# endif -# ifdef __APPLE__ -# define unix -# define OSMINOR "OS=MACOSX" -# define OS_MACOSX -# endif -# ifdef __osf__ -# define OSMINOR "OS=OSF" -# define OS_OSF -# endif -# ifdef _SEQUENT_ -# define OSMINOR "OS=PTX" -# define OS_PTX -# endif -# ifdef M_XENIX -# define OSMINOR "OS=SCO" -# define OS_SCO -# define NO_VFORK -# endif -# ifdef sinix -# define unix -# define OSMINOR "OS=SINIX" -# define OS_SINIX -# endif -# ifdef sun -# if defined(__svr4__) || defined(__SVR4) -# define OSMINOR "OS=SOLARIS" -# define OS_SOLARIS -# else -# define OSMINOR "OS=SUNOS" -# define OS_SUNOS -# endif -# endif -# ifdef ultrix -# define OSMINOR "OS=ULTRIX" -# define OS_ULTRIX -# endif -# ifdef _UNICOS -# define OSMINOR "OS=UNICOS" -# define OS_UNICOS -# endif -# if defined(__USLC__) && !defined(M_XENIX) -# define OSMINOR "OS=UNIXWARE" -# define OS_UNIXWARE -# endif -# ifndef OSMINOR -# define OSMINOR "OS=UNKNOWN" -# endif - -/* All the UNIX includes */ - -# include -# include - -# ifndef OS_MPEIX -# include -# endif - -# include -# include -# include -# include -# include -# include - -# ifndef OS_QNX -# include -# endif - -# ifndef OS_ULTRIX -# include -# endif - -# if !defined(OS_BSDI) && \ - !defined(OS_FREEBSD) && \ - !defined(OS_NEXT) && \ - !defined(OS_MACHTEN) && \ - !defined(OS_MACOSX) && \ - !defined(OS_RHAPSODY) && \ - !defined(OS_MVS) -# include -# endif - -# endif - -/* - * OSPLAT definitions - suppressed when it's a one-of-a-kind - */ - -# if defined( _M_PPC ) || \ - defined( PPC ) || \ - defined( ppc ) || \ - defined( __powerpc__ ) || \ - defined( __POWERPC__ ) || \ - defined( __ppc__ ) -# define OSPLAT "OSPLAT=PPC" -# endif - -# if defined( _ALPHA_ ) || \ - defined( __alpha__ ) -# define OSPLAT "OSPLAT=AXP" -# endif - -# if defined( _i386_ ) || \ - defined( __i386__ ) || \ - defined( _M_IX86 ) -# if !defined( OS_FREEBSD ) && \ - !defined( OS_OS2 ) && \ - !defined( OS_AS400 ) -# define OSPLAT "OSPLAT=X86" -# endif -# endif - -# ifdef __sparc__ -# if !defined( OS_SUNOS ) -# define OSPLAT "OSPLAT=SPARC" -# endif -# endif - -# ifdef __mips__ -# if !defined( OS_SGI ) -# define OSPLAT "OSPLAT=MIPS" -# endif -# endif - -# ifdef __arm__ -# define OSPLAT "OSPLAT=ARM" -# endif - -# if defined( __ia64__ ) || \ - defined( __IA64__ ) || \ - defined( _M_IA64 ) -# define OSPLAT "OSPLAT=IA64" -# endif - -# ifdef __s390__ -# define OSPLAT "OSPLAT=390" -# endif - -# ifndef OSPLAT -# define OSPLAT "" -# endif - -/* - * Jam implementation misc. - */ - -# ifndef MAXLINE -# define MAXLINE 10240 /* longest 'together' actions' */ -# endif - -# ifndef EXITOK -# define EXITOK 0 -# define EXITBAD 1 -# endif - -# ifndef SPLITPATH -# define SPLITPATH ':' -# endif - -/* You probably don't need to muck with these. */ - -# define MAXSYM 1024 /* longest symbol in the environment */ -# define MAXJPATH 1024 /* longest filename */ - -# define MAXJOBS 64 /* silently enforce -j limit */ -# define MAXARGC 32 /* words in $(JAMSHELL) */ - -/* Jam private definitions below. */ - -# define DEBUG_MAX 15 - -struct globs { - int noexec; - int jobs; - int quitquick; - int newestfirst; /* build newest sources first */ - char debug[DEBUG_MAX]; - FILE *cmdout; /* print cmds, not run them */ -} ; - -extern struct globs globs; - -# define DEBUG_MAKE ( globs.debug[ 1 ] ) /* -da show actions when executed */ -# define DEBUG_MAKEPROG ( globs.debug[ 3 ] ) /* -dm show progress of make0 */ - -# define DEBUG_EXECCMD ( globs.debug[ 4 ] ) /* show execcmds()'s work */ - -# define DEBUG_COMPILE ( globs.debug[ 5 ] ) /* show rule invocations */ - -# define DEBUG_HEADER ( globs.debug[ 6 ] ) /* show result of header scan */ -# define DEBUG_BINDSCAN ( globs.debug[ 6 ] ) /* show result of dir scan */ -# define DEBUG_SEARCH ( globs.debug[ 6 ] ) /* show attempts at binding */ - -# define DEBUG_VARSET ( globs.debug[ 7 ] ) /* show variable settings */ -# define DEBUG_VARGET ( globs.debug[ 8 ] ) /* show variable fetches */ -# define DEBUG_VAREXP ( globs.debug[ 8 ] ) /* show variable expansions */ -# define DEBUG_IF ( globs.debug[ 8 ] ) /* show 'if' calculations */ -# define DEBUG_LISTS ( globs.debug[ 9 ] ) /* show list manipulation */ -# define DEBUG_SCAN ( globs.debug[ 9 ] ) /* show scanner tokens */ -# define DEBUG_MEM ( globs.debug[ 9 ] ) /* show memory use */ - -# define DEBUG_MAKEQ ( globs.debug[ 11 ] ) /* -da show even quiet actions */ -# define DEBUG_EXEC ( globs.debug[ 12 ] ) /* -dx show text of actions */ -# define DEBUG_DEPENDS ( globs.debug[ 13 ] ) /* -dd show dependency graph */ -# define DEBUG_CAUSES ( globs.debug[ 14 ] ) /* -dc show dependency graph */ - diff --git a/jam-2.5/jambase.c b/jam-2.5/jambase.c deleted file mode 100644 index 358d07645..000000000 --- a/jam-2.5/jambase.c +++ /dev/null @@ -1,1292 +0,0 @@ -/* Generated by mkjambase from Jambase */ -const char *jambase[] = { -/* Jambase */ -"JAMBASEDATE = 2002.05.09 ;\n", -"if $(NT)\n", -"{\n", -"MV ?= move /y ;\n", -"CP ?= copy ;\n", -"RM ?= del /f/q ;\n", -"RMDIR ?= rmdir /s/q ;\n", -"SLASH ?= \\\\ ;\n", -"SUFLIB ?= .lib ;\n", -"SUFOBJ ?= .obj ;\n", -"SUFEXE ?= .exe ;\n", -"if $(BCCROOT)\n", -"{\n", -"AR ?= tlib /C /P64 ;\n", -"CC ?= bcc32 ;\n", -"CCFLAGS ?= -v -w- -q -DWIN -tWR -tWM -tWC ;\n", -"C++ ?= $(CC) ;\n", -"C++FLAGS ?= $(CCFLAGS) -P ;\n", -"LINK ?= $(CC) ;\n", -"LINKFLAGS ?= $(CCFLAGS) ;\n", -"STDLIBPATH ?= $(BCCROOT)\\\\lib ;\n", -"STDHDRS ?= $(BCCROOT)\\\\include ;\n", -"NOARSCAN ?= true ;\n", -"}\n", -"else if $(MSVC)\n", -"{\n", -"AR ?= lib /nologo ;\n", -"CC ?= cl /nologo ;\n", -"CCFLAGS ?= /D \\\"WIN\\\" ;\n", -"C++ ?= $(CC) ;\n", -"C++FLAGS ?= $(CCFLAGS) ;\n", -"LINK ?= $(CC) ;\n", -"LINKFLAGS ?= $(CCFLAGS) ;\n", -"LINKLIBS ?= \n", -"$(MSVC)\\\\lib\\\\mlibce.lib\n", -"$(MSVC)\\\\lib\\\\oldnames.lib\n", -";\n", -"LINKLIBS ?= ;\n", -"NOARSCAN ?= true ;\n", -"OPTIM ?= ;\n", -"STDHDRS ?= $(MSVC)\\\\include ;\n", -"UNDEFFLAG ?= \"/u _\" ;\n", -"}\n", -"else if $(MSVCNT) || $(MSVCDIR)\n", -"{\n", -"MSVCNT ?= $(MSVCDIR) ; \n", -"local I ; if $(OSPLAT) = IA64 { I = ia64\\\\ ; } else { I = \"\" ; }\n", -"AR ?= lib ;\n", -"AS ?= masm386 ;\n", -"CC ?= cl /nologo ;\n", -"CCFLAGS ?= \"\" ;\n", -"C++ ?= $(CC) ;\n", -"C++FLAGS ?= $(CCFLAGS) ;\n", -"LINK ?= link /nologo ;\n", -"LINKFLAGS ?= \"\" ;\n", -"LINKLIBS ?= \n", -"$(MSVCNT)\\\\lib\\\\$(I)libc.lib\n", -"$(MSVCNT)\\\\lib\\\\$(I)oldnames.lib\n", -"$(MSVCNT)\\\\lib\\\\$(I)kernel32.lib ;\n", -"OPTIM ?= \"\" ;\n", -"STDHDRS ?= $(MSVCNT)\\\\include ;\n", -"UNDEFFLAG ?= \"/u _\" ;\n", -"}\n", -"else\n", -"{\n", -"EXIT On NT, set BCCROOT, MSVCDIR, MSVCNT, or MSVC to the root\n", -"of the Borland or Microsoft directories. ;\n", -"}\n", -"}\n", -"else if $(MINGW)\n", -"{\n", -"Echo \"MingW32\" ;\n", -"CC ?= gcc ;\n", -"C++ ?= g++ ;\n", -"CCFLAGS += -DMINGW ;\n", -"RANLIB ?= \"ranlib\" ;\n", -"SUFEXE ?= .exe ;\n", -"}\n", -"else if $(OS2)\n", -"{\n", -"WATCOM ?= $(watcom) ;\n", -"if ! $(WATCOM)\n", -"{\n", -"Exit On OS2, set WATCOM to the root of the Watcom directory. ;\n", -"}\n", -"AR ?= wlib ;\n", -"BINDIR ?= \\\\os2\\\\apps ;\n", -"CC ?= wcc386 ;\n", -"CCFLAGS ?= /zq /DOS2 /I$(WATCOM)\\\\h ; # zq=quiet\n", -"C++ ?= wpp386 ;\n", -"C++FLAGS ?= $(CCFLAGS) ;\n", -"CP ?= copy ;\n", -"DOT ?= . ;\n", -"DOTDOT ?= .. ;\n", -"LINK ?= wcl386 ;\n", -"LINKFLAGS ?= /zq ; # zq=quiet\n", -"LINKLIBS ?= ;\n", -"MV ?= move ;\n", -"NOARSCAN ?= true ;\n", -"OPTIM ?= ;\n", -"RM ?= del /f ;\n", -"SLASH ?= \\\\ ;\n", -"STDHDRS ?= $(WATCOM)\\\\h ;\n", -"SUFEXE ?= .exe ;\n", -"SUFLIB ?= .lib ;\n", -"SUFOBJ ?= .obj ;\n", -"UNDEFFLAG ?= \"/u _\" ;\n", -"}\n", -"else if $(VMS)\n", -"{\n", -"C++ ?= cxx ;\n", -"C++FLAGS ?= ;\n", -"CC ?= cc ;\n", -"CCFLAGS ?= ;\n", -"CHMOD ?= set file/prot= ;\n", -"CP ?= copy/replace ;\n", -"CRELIB ?= true ;\n", -"DOT ?= [] ;\n", -"DOTDOT ?= [-] ;\n", -"EXEMODE ?= (w:e) ;\n", -"FILEMODE ?= (w:r) ;\n", -"HDRS ?= ;\n", -"LINK ?= link ;\n", -"LINKFLAGS ?= \"\" ;\n", -"LINKLIBS ?= ;\n", -"MKDIR ?= create/dir ;\n", -"MV ?= rename ;\n", -"OPTIM ?= \"\" ;\n", -"RM ?= delete ;\n", -"RUNVMS ?= mcr ;\n", -"SHELLMODE ?= (w:er) ;\n", -"SLASH ?= . ;\n", -"STDHDRS ?= decc$library_include ;\n", -"SUFEXE ?= .exe ;\n", -"SUFLIB ?= .olb ;\n", -"SUFOBJ ?= .obj ;\n", -"switch $(OS) \n", -"{\n", -"case OPENVMS : CCFLAGS ?= /stand=vaxc ;\n", -"case VMS : LINKLIBS ?= sys$library:vaxcrtl.olb/lib ;\n", -"}\n", -"}\n", -"else if $(MAC)\n", -"{\n", -"local OPT ;\n", -"CW ?= \"{CW}\" ;\n", -"MACHDRS ?=\n", -"\"$(UMACHDRS):Universal:Interfaces:CIncludes\"\n", -"\"$(CW):MSL:MSL_C:MSL_Common:Include\"\n", -"\"$(CW):MSL:MSL_C:MSL_MacOS:Include\" ;\n", -"MACLIBS ?=\n", -"\"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib\"\n", -"\"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib\" ;\n", -"MPWLIBS ?= \n", -"\"$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib\"\n", -"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW.Lib\" ;\n", -"MPWNLLIBS ?= \n", -"\"$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib\"\n", -"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW(NL).Lib\" ;\n", -"SIOUXHDRS ?= ;\n", -"SIOUXLIBS ?= \n", -"\"$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_Runtime_PPC.lib\"\n", -"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_SIOUX_PPC.Lib\" \n", -"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC.Lib\" ;\n", -"C++ ?= mwcppc ;\n", -"C++FLAGS ?= -w off ;\n", -"CC ?= mwcppc ;\n", -"CCFLAGS ?= -w off ;\n", -"CP ?= duplicate -y ;\n", -"DOT ?= \":\" ;\n", -"DOTDOT ?= \"::\" ;\n", -"HDRS ?= $(MACHDRS) $(MPWHDRS) ;\n", -"LINK ?= mwlinkppc ;\n", -"LINKFLAGS ?= -mpwtool -warn ; \n", -"LINKLIBS ?= $(MACLIBS) $(MPWLIBS) ; \n", -"MKDIR ?= newfolder ;\n", -"MV ?= rename -y ;\n", -"NOARSCAN ?= true ;\n", -"OPTIM ?= ;\n", -"RM ?= delete -y ;\n", -"SLASH ?= \":\" ;\n", -"STDHDRS ?= ; \n", -"SUFLIB ?= .lib ;\n", -"SUFOBJ ?= .o ;\n", -"}\n", -"else if $(OS) = BEOS && $(OSPLAT) = PPC\n", -"{\n", -"AR ?= mwld -xml -o ;\n", -"BINDIR ?= /boot/home/config/bin ;\n", -"CC ?= mwcc ;\n", -"CCFLAGS ?= -nosyspath ;\n", -"C++ ?= $(CC) ;\n", -"C++FLAGS ?= -nosyspath ;\n", -"CHMOD ?= chmod ;\n", -"CHGRP ?= chgrp ;\n", -"CHOWN ?= chown ;\n", -"FORTRAN ?= \"\" ;\n", -"LEX ?= flex ;\n", -"LIBDIR ?= /boot/home/config/lib ;\n", -"LINK ?= mwld ;\n", -"LINKFLAGS ?= \"\" ;\n", -"MANDIR ?= /boot/home/config/man ;\n", -"NOARSCAN ?= true ;\n", -"RANLIB ?= ranlib ;\n", -"STDHDRS ?= /boot/develop/headers/posix ;\n", -"YACC ?= bison -y ;\n", -"YACCGEN ?= .c ;\n", -"YACCFILES ?= y.tab ;\n", -"YACCFLAGS ?= -d ;\n", -"}\n", -"else if $(OS) = BEOS \n", -"{\n", -"BINDIR ?= /boot/home/config/bin ;\n", -"CC ?= gcc ;\n", -"C++ ?= $(CC) ;\n", -"CHMOD ?= chmod ;\n", -"CHGRP ?= chgrp ;\n", -"CHOWN ?= chown ;\n", -"FORTRAN ?= \"\" ;\n", -"LEX ?= flex ;\n", -"LIBDIR ?= /boot/home/config/lib ;\n", -"LINK ?= gcc ;\n", -"MANDIR ?= /boot/home/config/man ;\n", -"NOARSCAN ?= true ;\n", -"RANLIB ?= ranlib ;\n", -"STDHDRS ?= /boot/develop/headers/posix ;\n", -"YACC ?= bison -y ;\n", -"YACCGEN ?= .c ;\n", -"YACCFILES ?= y.tab ;\n", -"YACCFLAGS ?= -d ;\n", -"}\n", -"else if $(UNIX)\n", -"{\n", -"switch $(OS)\n", -"{\n", -"case AIX :\n", -"LINKLIBS ?= -lbsd ;\n", -"case AMIGA :\n", -"CC ?= gcc ;\n", -"YACC ?= bison -y ;\n", -"case CYGWIN : \n", -"CC ?= gcc ;\n", -"CCFLAGS += -D__cygwin__ ;\n", -"LEX ?= flex ;\n", -"JAMSHELL ?= sh -c ;\n", -"RANLIB ?= \"\" ;\n", -"SUFEXE ?= .exe ;\n", -"YACC ?= bison -y ;\n", -"case DGUX :\n", -"RANLIB ?= \"\" ;\n", -"RELOCATE ?= true ;\n", -"case HPUX :\n", -"RANLIB ?= \"\" ;\n", -"case INTERIX :\n", -"CC ?= gcc ;\n", -"JAMSHELL ?= sh -c ;\n", -"RANLIB ?= \"\" ;\n", -"case IRIX :\n", -"RANLIB ?= \"\" ;\n", -"case MPEIX :\n", -"CC ?= gcc ;\n", -"C++ ?= gcc ;\n", -"CCFLAGS += -D_POSIX_SOURCE ;\n", -"HDRS += /usr/include ;\n", -"RANLIB ?= \"\" ; \n", -"NOARSCAN ?= true ;\n", -"NOARUPDATE ?= true ;\n", -"case MVS :\n", -"RANLIB ?= \"\" ; \n", -"case NEXT :\n", -"AR ?= libtool -o ;\n", -"RANLIB ?= \"\" ;\n", -"case MACOSX :\n", -"C++ ?= c++ ;\n", -"MANDIR ?= /usr/local/share/man ;\n", -"case NCR :\n", -"RANLIB ?= \"\" ;\n", -"case PTX :\n", -"RANLIB ?= \"\" ;\n", -"case QNX :\n", -"AR ?= wlib ;\n", -"CC ?= cc ;\n", -"CCFLAGS ?= -Q ; # quiet\n", -"C++ ?= $(CC) ;\n", -"C++FLAGS ?= -Q ; # quiet\n", -"LINK ?= $(CC) ;\n", -"LINKFLAGS ?= -Q ; # quiet\n", -"NOARSCAN ?= true ;\n", -"RANLIB ?= \"\" ;\n", -"case SCO :\n", -"RANLIB ?= \"\" ;\n", -"RELOCATE ?= true ;\n", -"case SINIX :\n", -"RANLIB ?= \"\" ;\n", -"case SOLARIS :\n", -"RANLIB ?= \"\" ;\n", -"AR ?= \"/usr/ccs/bin/ar ru\" ;\n", -"case UNICOS :\n", -"NOARSCAN ?= true ;\n", -"OPTIM ?= -O0 ;\n", -"case UNIXWARE :\n", -"RANLIB ?= \"\" ;\n", -"RELOCATE ?= true ;\n", -"}\n", -"CCFLAGS ?= ;\n", -"C++FLAGS ?= $(CCFLAGS) ;\n", -"CHMOD ?= chmod ;\n", -"CHGRP ?= chgrp ;\n", -"CHOWN ?= chown ;\n", -"LEX ?= lex ;\n", -"LINKFLAGS ?= $(CCFLAGS) ;\n", -"LINKLIBS ?= ;\n", -"OPTIM ?= -O ;\n", -"RANLIB ?= ranlib ;\n", -"YACC ?= yacc ;\n", -"YACCGEN ?= .c ;\n", -"YACCFILES ?= y.tab ;\n", -"YACCFLAGS ?= -d ;\n", -"}\n", -"AR ?= ar ru ;\n", -"AS ?= as ;\n", -"ASFLAGS ?= ;\n", -"AWK ?= awk ;\n", -"BINDIR ?= /usr/local/bin ;\n", -"C++ ?= cc ;\n", -"C++FLAGS ?= ;\n", -"CC ?= cc ;\n", -"CCFLAGS ?= ;\n", -"CP ?= cp -f ;\n", -"CRELIB ?= ;\n", -"DOT ?= . ;\n", -"DOTDOT ?= .. ;\n", -"EXEMODE ?= 711 ;\n", -"FILEMODE ?= 644 ;\n", -"FORTRAN ?= f77 ;\n", -"FORTRANFLAGS ?= ;\n", -"HDRS ?= ;\n", -"INSTALLGRIST ?= installed ;\n", -"JAMFILE ?= Jamfile ;\n", -"JAMRULES ?= Jamrules ;\n", -"LEX ?= ;\n", -"LIBDIR ?= /usr/local/lib ;\n", -"LINK ?= $(CC) ;\n", -"LINKFLAGS ?= ;\n", -"LINKLIBS ?= ;\n", -"LN ?= ln ;\n", -"MANDIR ?= /usr/local/man ;\n", -"MKDIR ?= mkdir ;\n", -"MV ?= mv -f ;\n", -"OPTIM ?= ;\n", -"RCP ?= rcp ;\n", -"RM ?= rm -f ;\n", -"RMDIR ?= $(RM) ;\n", -"RSH ?= rsh ;\n", -"SED ?= sed ;\n", -"SHELLHEADER ?= \"#!/bin/sh\" ;\n", -"SHELLMODE ?= 755 ;\n", -"SLASH ?= / ;\n", -"STDHDRS ?= /usr/include ;\n", -"SUBDIRRULES ?= ;\n", -"SUBDIRRESET ?= ASFLAGS HDRS C++FLAGS CCFLAGS ;\n", -"SUFEXE ?= \"\" ;\n", -"SUFLIB ?= .a ;\n", -"SUFOBJ ?= .o ;\n", -"UNDEFFLAG ?= \"-u _\" ;\n", -"YACC ?= ;\n", -"YACCGEN ?= ;\n", -"YACCFILES ?= ;\n", -"YACCFLAGS ?= ;\n", -"HDRPATTERN = \n", -"\"^[ ]*#[ ]*include[ ]*[<\\\"]([^\\\">]*)[\\\">].*$\" ;\n", -"OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;\n", -"Depends all : shell files lib exe obj ;\n", -"Depends all shell files lib exe obj : first ;\n", -"NotFile all first shell files lib exe obj dirs clean uninstall ;\n", -"Always clean uninstall ;\n", -"rule As\n", -"{\n", -"Depends $(<) : $(>) ;\n", -"ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ;\n", -"ASHDRS on $(<) = [ FIncludes $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ;\n", -"}\n", -"rule Bulk\n", -"{\n", -"local i ;\n", -"for i in $(>)\n", -"{\n", -"File $(i:D=$(<)) : $(i) ;\n", -"}\n", -"}\n", -"rule Cc\n", -"{\n", -"Depends $(<) : $(>) ;\n", -"if $(RELOCATE)\n", -"{\n", -"CcMv $(<) : $(>) ;\n", -"}\n", -"CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) $(OPTIM) ;\n", -"CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;\n", -"CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;\n", -"}\n", -"rule C++\n", -"{\n", -"Depends $(<) : $(>) ;\n", -"if $(RELOCATE)\n", -"{\n", -"CcMv $(<) : $(>) ;\n", -"}\n", -"C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) $(OPTIM) ;\n", -"CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;\n", -"CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;\n", -"}\n", -"rule Chmod\n", -"{\n", -"if $(CHMOD) { Chmod1 $(<) ; }\n", -"}\n", -"rule File\n", -"{\n", -"Depends files : $(<) ;\n", -"Depends $(<) : $(>) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"MODE on $(<) = $(FILEMODE) ;\n", -"Chmod $(<) ;\n", -"}\n", -"rule Fortran\n", -"{\n", -"Depends $(<) : $(>) ;\n", -"}\n", -"rule GenFile \n", -"{\n", -"local _t = [ FGristSourceFiles $(<) ] ;\n", -"local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ;\n", -"Depends $(_t) : $(_s) $(>[2-]) ;\n", -"GenFile1 $(_t) : $(_s) $(>[2-]) ;\n", -"Clean clean : $(_t) ;\n", -"}\n", -"rule GenFile1\n", -"{\n", -"MakeLocate $(<) : $(LOCATE_SOURCE) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"}\n", -"rule HardLink\n", -"{\n", -"Depends files : $(<) ;\n", -"Depends $(<) : $(>) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"}\n", -"rule HdrRule\n", -"{\n", -"local s = $(>:G=$(HDRGRIST:E)) ;\n", -"Includes $(<) : $(s) ;\n", -"SEARCH on $(s) = $(HDRSEARCH) ;\n", -"NoCare $(s) ;\n", -"HDRSEARCH on $(s) = $(HDRSEARCH) ;\n", -"HDRSCAN on $(s) = $(HDRSCAN) ;\n", -"HDRRULE on $(s) = $(HDRRULE) ;\n", -"HDRGRIST on $(s) = $(HDRGRIST) ;\n", -"}\n", -"rule InstallInto\n", -"{\n", -"local i t ;\n", -"t = $(>:G=$(INSTALLGRIST)) ;\n", -"Depends install : $(t) ;\n", -"Clean uninstall : $(t) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"MakeLocate $(t) : $(<) ;\n", -"for i in $(>)\n", -"{\n", -"local tt = $(i:G=$(INSTALLGRIST)) ;\n", -"Depends $(tt) : $(i) ;\n", -"Install $(tt) : $(i) ;\n", -"Chmod $(tt) ;\n", -"if $(OWNER) && $(CHOWN) \n", -"{ \n", -"Chown $(tt) ;\n", -"OWNER on $(tt) = $(OWNER) ;\n", -"}\n", -"if $(GROUP) && $(CHGRP) \n", -"{ \n", -"Chgrp $(tt) ;\n", -"GROUP on $(tt) = $(GROUP) ;\n", -"}\n", -"}\n", -"}\n", -"rule InstallBin\n", -"{\n", -"local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ;\n", -"InstallInto $(<) : $(_t) ;\n", -"MODE on $(_t:G=$(INSTALLGRIST)) = $(EXEMODE) ;\n", -"}\n", -"rule InstallFile\n", -"{\n", -"InstallInto $(<) : $(>) ;\n", -"MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;\n", -"}\n", -"rule InstallLib\n", -"{\n", -"InstallInto $(<) : $(>) ;\n", -"MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;\n", -"}\n", -"rule InstallMan\n", -"{\n", -"local i s d ;\n", -"for i in $(>)\n", -"{\n", -"switch $(i:S)\n", -"{\n", -"case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ;\n", -"case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ;\n", -"case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ;\n", -"case .n : s = n ; case .man : s = 1 ;\n", -"}\n", -"d = man$(s) ;\n", -"InstallInto $(d:R=$(<)) : $(i) ;\n", -"}\n", -"MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;\n", -"}\n", -"rule InstallShell\n", -"{\n", -"InstallInto $(<) : $(>) ;\n", -"MODE on $(>:G=$(INSTALLGRIST)) = $(SHELLMODE) ;\n", -"}\n", -"rule Lex\n", -"{\n", -"LexMv $(<) : $(>) ;\n", -"Depends $(<) : $(>) ;\n", -"MakeLocate $(<) : $(LOCATE_SOURCE) ;\n", -"Clean clean : $(<) ;\n", -"}\n", -"rule Library\n", -"{\n", -"LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ;\n", -"Objects $(>) ;\n", -"}\n", -"rule LibraryFromObjects\n", -"{\n", -"local _i _l _s ;\n", -"_s = [ FGristFiles $(>) ] ;\n", -"_l = $(<:S=$(SUFLIB)) ;\n", -"if $(KEEPOBJS)\n", -"{\n", -"Depends obj : $(_s) ;\n", -"}\n", -"else\n", -"{\n", -"Depends lib : $(_l) ;\n", -"}\n", -"if ! $(_l:D)\n", -"{\n", -"MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;\n", -"}\n", -"if $(NOARSCAN) \n", -"{ \n", -"Depends $(_l) : $(_s) ;\n", -"}\n", -"else\n", -"{\n", -"Depends $(_l) : $(_l)($(_s:BS)) ;\n", -"for _i in $(_s)\n", -"{\n", -"Depends $(_l)($(_i:BS)) : $(_i) ;\n", -"}\n", -"}\n", -"Clean clean : $(_l) ;\n", -"if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }\n", -"Archive $(_l) : $(_s) ;\n", -"if $(RANLIB) { Ranlib $(_l) ; }\n", -"if ! ( $(NOARSCAN) || $(NOARUPDATE) ) { RmTemps $(_l) : $(_s) ; }\n", -"}\n", -"rule Link\n", -"{\n", -"MODE on $(<) = $(EXEMODE) ;\n", -"Chmod $(<) ;\n", -"}\n", -"rule LinkLibraries\n", -"{\n", -"local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;\n", -"Depends $(_t) : $(>:S=$(SUFLIB)) ;\n", -"NEEDLIBS on $(_t) += $(>:S=$(SUFLIB)) ;\n", -"}\n", -"rule Main\n", -"{\n", -"MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;\n", -"Objects $(>) ;\n", -"}\n", -"rule MainFromObjects\n", -"{\n", -"local _s _t ;\n", -"_s = [ FGristFiles $(>) ] ;\n", -"_t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;\n", -"if $(_t) != $(<)\n", -"{\n", -"Depends $(<) : $(_t) ;\n", -"NotFile $(<) ;\n", -"}\n", -"Depends exe : $(_t) ;\n", -"Depends $(_t) : $(_s) ;\n", -"MakeLocate $(_t) : $(LOCATE_TARGET) ;\n", -"Clean clean : $(_t) ;\n", -"Link $(_t) : $(_s) ;\n", -"}\n", -"rule MakeLocate\n", -"{\n", -"if $(>)\n", -"{\n", -"LOCATE on $(<) = $(>) ;\n", -"Depends $(<) : $(>[1]:G=dir) ;\n", -"MkDir $(>[1]:G=dir) ;\n", -"}\n", -"}\n", -"rule MkDir\n", -"{\n", -"NoUpdate $(<) ;\n", -"if $(<:G=) != $(DOT) && ! $($(<)-mkdir) \n", -"{\n", -"$(<)-mkdir = true ;\n", -"Depends dirs : $(<) ;\n", -"MkDir1 $(<) ;\n", -"local s = $(<:P) ;\n", -"if $(NT)\n", -"{\n", -"switch $(s)\n", -"{\n", -"case *: : s = ;\n", -"case *:\\\\ : s = ;\n", -"}\n", -"}\n", -"if $(s) = $(<)\n", -"{\n", -"NotFile $(s) ;\n", -"}\n", -"else if $(s:G=)\n", -"{\n", -"Depends $(<) : $(s) ;\n", -"MkDir $(s) ;\n", -"}\n", -"}\n", -"}\n", -"rule Object\n", -"{\n", -"Clean clean : $(<) ;\n", -"MakeLocate $(<) : $(LOCATE_TARGET) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"HDRS on $(<) = $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ;\n", -"HDRRULE on $(>) = HdrRule ;\n", -"HDRSCAN on $(>) = $(HDRPATTERN) ;\n", -"HDRSEARCH on $(>) = \n", -"$(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HDRS) $(STDHDRS) ;\n", -"HDRGRIST on $(>) = $(HDRGRIST) ;\n", -"DEFINES on $(<) += $(DEFINES) ;\n", -"switch $(>:S)\n", -"{\n", -"case .asm : As $(<) : $(>) ;\n", -"case .c : Cc $(<) : $(>) ;\n", -"case .C : C++ $(<) : $(>) ;\n", -"case .cc : C++ $(<) : $(>) ;\n", -"case .cpp : C++ $(<) : $(>) ;\n", -"case .f : Fortran $(<) : $(>) ;\n", -"case .l : Cc $(<) : $(<:S=.c) ;\n", -"Lex $(<:S=.c) : $(>) ;\n", -"case .s : As $(<) : $(>) ;\n", -"case .y : Cc $(<) : $(<:S=$(YACCGEN)) ;\n", -"Yacc $(<:S=$(YACCGEN)) : $(>) ;\n", -"case * : UserObject $(<) : $(>) ;\n", -"}\n", -"}\n", -"rule ObjectCcFlags\n", -"{\n", -"CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;\n", -"}\n", -"rule ObjectC++Flags\n", -"{\n", -"C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;\n", -"}\n", -"rule ObjectDefines\n", -"{\n", -"local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ;\n", -"DEFINES on $(s) += $(>) ;\n", -"CCDEFS on $(s) = [ on $(s) FDefines $(DEFINES) ] ;\n", -"}\n", -"rule ObjectHdrs\n", -"{\n", -"local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ;\n", -"HDRS on $(s) += $(>) ;\n", -"CCHDRS on $(s) = [ on $(s) FIncludes $(HDRS) ] ;\n", -"}\n", -"rule Objects\n", -"{\n", -"local _i ;\n", -"for _i in [ FGristFiles $(<) ]\n", -"{\n", -"Object $(_i:S=$(SUFOBJ)) : $(_i) ;\n", -"Depends obj : $(_i:S=$(SUFOBJ)) ;\n", -"}\n", -"}\n", -"rule RmTemps\n", -"{\n", -"Temporary $(>) ;\n", -"}\n", -"rule Setuid\n", -"{\n", -"MODE on [ FAppendSuffix $(<) : $(SUFEXE) ] = 4711 ;\n", -"}\n", -"rule Shell\n", -"{\n", -"Depends shell : $(<) ;\n", -"Depends $(<) : $(>) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"MODE on $(<) = $(SHELLMODE) ;\n", -"Clean clean : $(<) ;\n", -"Chmod $(<) ;\n", -"}\n", -"rule SoftLink\n", -"{\n", -"Depends files : $(<) ;\n", -"Depends $(<) : $(>) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"Clean clean : $(<) ;\n", -"}\n", -"rule SubDir\n", -"{\n", -"local _top = $(<[1]) ;\n", -"local _tokens = $(<[2-]) ;\n", -"if ! $(_top)\n", -"{\n", -"Exit SubDir syntax error ;\n", -"}\n", -"if ! $($(_top)-SET)\n", -"{\n", -"$(_top)-SET = true ;\n", -"if $($(_top))\n", -"{\n", -"$(_top)-UP = ;\n", -"$(_top)-DOWN = ;\n", -"$(_top)-ROOT = $($(_top)) ;\n", -"}\n", -"else\n", -"{\n", -"_tokens = [ FReverse $(_tokens) ] ;\n", -"SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;\n", -"FStripCommon _tokens : SUBDIR_DOWN ;\n", -"SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;\n", -"_tokens = [ FReverse $(_tokens) ] ;\n", -"if $(SUBDIR_DOWN) && $(_tokens) \n", -"{ \n", -"Echo Warning: SubDir $(<) misplaced! ; \n", -"}\n", -"$(_top)-UP = $(SUBDIR_UP) $(_tokens) ;\n", -"$(_top)-DOWN = $(SUBDIR_DOWN) ;\n", -"$(_top)-ROOT = $(SUBDIR_ROOT:E=\"\") ;\n", -"$(_top) = [ FSubDirPath $(_top) ] ;\n", -"}\n", -"SUBDIR_UP = $($(_top)-UP) ;\n", -"SUBDIR_DOWN = ;\n", -"SUBDIR_ROOT = $($(_top)-ROOT) ;\n", -"if $($(_top)RULES) { \n", -"include $($(_top)RULES) ;\n", -"} else { \n", -"NoCare $(JAMRULES:R=$($(_top)):G=$(_top)) ;\n", -"include $(JAMRULES:R=$($(_top)):G=$(_top)) ;\n", -"}\n", -"}\n", -"SUBDIR_UP = $($(_top)-UP) ;\n", -"SUBDIR_DOWN = $($(_top)-DOWN) $(_tokens) ;\n", -"SUBDIR_ROOT = $($(_top)-ROOT) ;\n", -"SUBDIR_TOKENS = $(SUBDIR_DOWN) ;\n", -"SUBDIR = [ FSubDirPath $(<) ] ;\n", -"SEARCH_SOURCE = $(SUBDIR) ;\n", -"LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ;\n", -"LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ;\n", -"SOURCE_GRIST = [ FGrist $(SUBDIR_TOKENS) ] ;\n", -"SUBDIR$(SUBDIRRESET) = ;\n", -"$(SUBDIRRULES) $(<) ;\n", -"}\n", -"rule FSubDirPath\n", -"{\n", -"local _r = [ FRelPath $($(<[1])-UP) : $($(<[1])-DOWN) $(<[2-]) ] ;\n", -"return $(_r:R=$($(<[1])-ROOT)) ;\n", -"}\n", -"rule SubDirCcFlags\n", -"{\n", -"SUBDIRCCFLAGS += $(<) ;\n", -"}\n", -"rule SubDirC++Flags\n", -"{\n", -"SUBDIRC++FLAGS += $(<) ;\n", -"}\n", -"rule SubDirHdrs\n", -"{\n", -"SUBDIRHDRS += [ FDirName $(<) ] ;\n", -"}\n", -"rule SubInclude\n", -"{\n", -"if ! $($(<[1]))\n", -"{\n", -"Exit SubInclude $(<[1]) without prior SubDir $(<[1]) ;\n", -"}\n", -"SubDir $(<) ;\n", -"include $(JAMFILE:D=$(SUBDIR)) ;\n", -"}\n", -"rule SubRules\n", -"{\n", -"if ! $($(<[1]))\n", -"{\n", -"Exit SubRules $(<[1]) without prior SubDir $(<[1]) ;\n", -"}\n", -"SubDir $(<) ;\n", -"SubDir $(>) ;\n", -"}\n", -"rule Undefines\n", -"{\n", -"UNDEFS on [ FAppendSuffix $(<) : $(SUFEXE) ] += $(UNDEFFLAG)$(>) ;\n", -"}\n", -"rule UserObject\n", -"{\n", -"Exit \"Unknown suffix on\" $(>) \"- see UserObject rule in Jamfile(5).\" ;\n", -"}\n", -"rule Yacc\n", -"{\n", -"local _h ;\n", -"_h = $(<:BS=.h) ;\n", -"MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ;\n", -"if $(YACC)\n", -"{\n", -"Depends $(<) $(_h) : $(>) ;\n", -"Yacc1 $(<) $(_h) : $(>) ;\n", -"YaccMv $(<) $(_h) : $(>) ;\n", -"Clean clean : $(<) $(_h) ;\n", -"}\n", -"Includes $(<) : $(_h) ;\n", -"}\n", -"rule FGrist\n", -"{\n", -"return $(<:J=!) ;\n", -"}\n", -"rule FGristFiles \n", -"{\n", -"return $(<:G=$(SOURCE_GRIST:E)) ;\n", -"}\n", -"rule FGristSourceFiles\n", -"{\n", -"if ! $(SOURCE_GRIST)\n", -"{\n", -"return $(<) ;\n", -"}\n", -"else \n", -"{\n", -"local _i _o ;\n", -"for _i in $(<)\n", -"{\n", -"switch $(_i)\n", -"{\n", -"case *.h : _o += $(_i) ;\n", -"case * : _o += $(_i:G=$(SOURCE_GRIST)) ;\n", -"}\n", -"}\n", -"return $(_o) ;\n", -"}\n", -"}\n", -"rule FReverse \n", -"{\n", -"if $(1) { return [ FReverse $(1[2-]) ] $(1[1]) ; }\n", -"}\n", -"rule FSubDir\n", -"{\n", -"if ! $(<[1]) \n", -"{\n", -"return $(DOT) ;\n", -"} \n", -"else\n", -"{\n", -"local _i _d ;\n", -"_d = $(DOTDOT) ;\n", -"for _i in $(<[2-])\n", -"{\n", -"_d = $(_d:R=$(DOTDOT)) ;\n", -"}\n", -"return $(_d) ;\n", -"}\n", -"}\n", -"rule FStripCommon\n", -"{\n", -"if $($(<)[1]) && $($(<)[1]) = $($(>)[1])\n", -"{\n", -"$(<) = $($(<)[2-]) ;\n", -"$(>) = $($(>)[2-]) ;\n", -"FStripCommon $(<) : $(>) ;\n", -"}\n", -"}\n", -"rule FRelPath\n", -"{\n", -"local _l _r ;\n", -"_l = $(<) ;\n", -"_r = $(>) ;\n", -"FStripCommon _l : _r ;\n", -"_l = [ FSubDir $(_l) ] ;\n", -"_r = [ FDirName $(_r) ] ;\n", -"if $(_r) = $(DOT) {\n", -"return $(_l) ;\n", -"} else {\n", -"return $(_r:R=$(_l)) ;\n", -"}\n", -"}\n", -"rule FAppendSuffix\n", -"{\n", -"if $(>)\n", -"{\n", -"local _i _o ;\n", -"for _i in $(<)\n", -"{\n", -"if $(_i:S)\n", -"{\n", -"_o += $(_i) ;\n", -"}\n", -"else\n", -"{\n", -"_o += $(_i:S=$(>)) ;\n", -"}\n", -"}\n", -"return $(_o) ;\n", -"}\n", -"else\n", -"{\n", -"return $(<) ;\n", -"}\n", -"}\n", -"rule FQuote { return \\\\\\\"$(<)\\\\\\\" ; }\n", -"rule FDefines { return -D$(<) ; }\n", -"rule FIncludes { return -I$(<) ; }\n", -"rule FDirName\n", -"{\n", -"local _i ;\n", -"local _s = $(DOT) ;\n", -"for _i in $(<)\n", -"{\n", -"_s = $(_i:R=$(_s)) ;\n", -"}\n", -"return $(_s) ;\n", -"}\n", -"if $(OS2)\n", -"{\n", -"rule FQuote { return \\\"$(<)\\\" ; }\n", -"rule FIncludes { return /I$(<) ; }\n", -"}\n", -"else if $(NT)\n", -"{\n", -"rule FDefines { return /D$(<) ; }\n", -"rule FIncludes { return /I$(<) ; }\n", -"}\n", -"else if $(MAC)\n", -"{\n", -"rule FQuote { return \\\"$(<)\\\" ; }\n", -"rule FDefines { return \"-define '$(<)'\" ; }\n", -"rule FIncludes { return \\\"$(<:J=,)\\\" ; }\n", -"}\n", -"else if $(VMS)\n", -"{\n", -"rule FQuote { return \\\"\\\"\\\"$(<)\\\"\\\"\\\" ; }\n", -"rule FDefines { return \"/define=( $(<:J=,) )\" ; }\n", -"rule FIncludes { return \"/inc=( $(<:J=,) )\" ; }\n", -"rule FDirName\n", -"{\n", -"local _s _i ;\n", -"if ! $(<)\n", -"{\n", -"_s = $(DOT) ;\n", -"}\n", -"else \n", -"{\n", -"switch $(<[1])\n", -"{\n", -"case *:* : _s = $(<[1]) ;\n", -"case \\\\[*\\\\] : _s = $(<[1]) ;\n", -"case * : _s = [.$(<[1])] ;\n", -"}\n", -"for _i in [.$(<[2-])]\n", -"{\n", -"_s = $(_i:R=$(_s)) ;\n", -"}\n", -"}\n", -"return $(_s) ;\n", -"}\n", -"}\n", -"actions updated together piecemeal Archive\n", -"{\n", -"$(AR) $(<) $(>)\n", -"}\n", -"actions As\n", -"{\n", -"$(AS) $(ASFLAGS) $(ASHDRS) -o $(<) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) -c -o $(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) -c -o $(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>)\n", -"}\n", -"actions Chgrp\n", -"{\n", -"$(CHGRP) $(GROUP) $(<)\n", -"}\n", -"actions Chmod1\n", -"{\n", -"$(CHMOD) $(MODE) $(<)\n", -"}\n", -"actions Chown\n", -"{\n", -"$(CHOWN) $(OWNER) $(<)\n", -"}\n", -"actions piecemeal together existing Clean\n", -"{\n", -"$(RM) $(>)\n", -"}\n", -"actions File\n", -"{\n", -"$(CP) $(>) $(<)\n", -"}\n", -"actions GenFile1\n", -"{\n", -"$(>[1]) $(<) $(>[2-])\n", -"}\n", -"actions Fortran\n", -"{\n", -"$(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>)\n", -"}\n", -"actions HardLink\n", -"{\n", -"$(RM) $(<) && $(LN) $(>) $(<)\n", -"}\n", -"actions Install\n", -"{\n", -"$(CP) $(>) $(<) \n", -"}\n", -"actions Lex\n", -"{\n", -"$(LEX) $(>)\n", -"}\n", -"actions LexMv\n", -"{\n", -"$(MV) lex.yy.c $(<)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) \n", -"}\n", -"actions MkDir1\n", -"{\n", -"$(MKDIR) $(<)\n", -"}\n", -"actions together Ranlib\n", -"{\n", -"$(RANLIB) $(<)\n", -"}\n", -"actions quietly updated piecemeal together RmTemps\n", -"{\n", -"$(RM) $(>)\n", -"}\n", -"actions Shell\n", -"{\n", -"$(AWK) '\n", -"NR == 1 { print \"$(SHELLHEADER)\" }\n", -"NR == 1 && /^[#:]/ { next }\n", -"/^##/ { next }\n", -"{ print }\n", -"' < $(>) > $(<)\n", -"}\n", -"actions SoftLink\n", -"{\n", -"$(RM) $(<) && $(LN) -s $(>) $(<)\n", -"}\n", -"actions Yacc1\n", -"{\n", -"$(YACC) $(YACCFLAGS) $(>)\n", -"}\n", -"actions YaccMv\n", -"{\n", -"$(MV) $(YACCFILES).c $(<[1])\n", -"$(MV) $(YACCFILES).h $(<[2])\n", -"}\n", -"if $(RELOCATE)\n", -"{\n", -"actions C++\n", -"{\n", -"$(C++) -c $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) -c $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>)\n", -"}\n", -"actions ignore CcMv\n", -"{\n", -"[ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<)\n", -"}\n", -"}\n", -"if $(NOARUPDATE)\n", -"{\n", -"actions Archive\n", -"{\n", -"$(AR) $(<) $(>)\n", -"}\n", -"}\n", -"if $(UNIX)\n", -"{\n", -"actions GenFile1\n", -"{\n", -"PATH=\"$PATH:.\"\n", -"$(>[1]) $(<) $(>[2-])\n", -"}\n", -"}\n", -"if $(NT) && $(MSVCNT)\n", -"{\n", -"actions updated together piecemeal Archive\n", -"{\n", -"if exist $(<) set _$(<:B)_=$(<)\n", -"$(AR) /out:$(<) %_$(<:B)_% $(>)\n", -"}\n", -"actions As\n", -"{\n", -"$(AS) /Ml /p /v /w2 $(>) $(<) ,nul,nul;\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) /c /Fo$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) /c /Fo$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) /Tp$(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", -"}\n", -"}\n", -"else if $(NT) && $(MSVC)\n", -"{\n", -"actions updated together piecemeal Archive\n", -"{\n", -"$(AR) $(<) -+$(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) /c /Fo$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) /c /Fo$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) /Tp$(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", -"}\n", -"}\n", -"else if $(NT) && $(BCCROOT)\n", -"{\n", -"actions updated together piecemeal Archive\n", -"{\n", -"$(AR) $(<) -+$(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) -e$(<) $(LINKFLAGS) $(UNDEFS) -L$(LINKLIBS) $(NEEDLIBS) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) -c -o$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) -c -o$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>)\n", -"}\n", -"}\n", -"else if $(OS2) && $(WATCOM)\n", -"{\n", -"actions together piecemeal Archive\n", -"{\n", -"$(AR) $(<) +-$(>) \n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) /Fo=$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) /Fo=$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", -"}\n", -"actions Shell\n", -"{\n", -"$(CP) $(>) $(<)\n", -"}\n", -"}\n", -"else if $(VMS)\n", -"{\n", -"actions updated together piecemeal Archive \n", -"{\n", -"lib/replace $(<) $(>[1]) ,$(>[2-])\n", -"}\n", -"actions Cc\n", -"{ \n", -"$(CC)/obj=$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) \n", -"}\n", -"actions C++\n", -"{ \n", -"$(C++)/obj=$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>) \n", -"}\n", -"actions piecemeal together existing Clean\n", -"{\n", -"$(RM) $(>[1]);* ,$(>[2-]);*\n", -"}\n", -"actions together quietly CreLib\n", -"{\n", -"if f$search(\"$(<)\") .eqs. \"\" then lib/create $(<)\n", -"}\n", -"actions GenFile1\n", -"{\n", -"mcr $(>[1]) $(<) $(>[2-])\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK)/exe=$(<) $(LINKFLAGS) $(>:J=,) ,$(NEEDLIBS)/lib ,$(LINKLIBS)\n", -"}\n", -"actions quietly updated piecemeal together RmTemps\n", -"{\n", -"$(RM) $(>[1]);* ,$(>[2-]);*\n", -"}\n", -"actions Shell\n", -"{\n", -"$(CP) $(>) $(<)\n", -"}\n", -"}\n", -"else if $(MAC)\n", -"{\n", -"actions together Archive \n", -"{\n", -"$(LINK) -library -o $(<) $(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"set -e MWCincludes $(CCHDRS)\n", -"$(CC) -o $(<) $(CCFLAGS) $(CCDEFS) $(>) \n", -"}\n", -"actions C++\n", -"{\n", -"set -e MWCincludes $(CCHDRS)\n", -"$(CC) -o $(<) $(C++FLAGS) $(CCDEFS) $(>) \n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) -o $(<) $(LINKFLAGS) $(>) $(NEEDLIBS) \"$(LINKLIBS)\"\n", -"}\n", -"}\n", -"if $(WIN98)\n", -"{\n", -"actions existing Clean\n", -"{\n", -"del $(>)\n", -"}\n", -"}\n", -"rule BULK { Bulk $(<) : $(>) ; }\n", -"rule FILE { File $(<) : $(>) ; }\n", -"rule HDRRULE { HdrRule $(<) : $(>) ; }\n", -"rule INSTALL { Install $(<) : $(>) ; }\n", -"rule LIBRARY { Library $(<) : $(>) ; }\n", -"rule LIBS { LinkLibraries $(<) : $(>) ; }\n", -"rule LINK { Link $(<) : $(>) ; }\n", -"rule MAIN { Main $(<) : $(>) ; }\n", -"rule SETUID { Setuid $(<) ; }\n", -"rule SHELL { Shell $(<) : $(>) ; }\n", -"rule UNDEFINES { Undefines $(<) : $(>) ; }\n", -"rule INSTALLBIN { InstallBin $(BINDIR) : $(<) ; }\n", -"rule INSTALLLIB { InstallLib $(LIBDIR) : $(<) ; }\n", -"rule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; }\n", -"rule addDirName { $(<) += [ FDirName $(>) ] ; }\n", -"rule makeCommon { FStripCommon $(<) : $(>) ; }\n", -"rule _makeCommon { FStripCommon $(<) : $(>) ; }\n", -"rule makeDirName { $(<) = [ FDirName $(>) ] ; }\n", -"rule makeGrist { $(<) = [ FGrist $(>) ] ; }\n", -"rule makeGristedName { $(<) = [ FGristSourceFiles $(>) ] ; }\n", -"rule makeRelPath { $(<[1]) = [ FRelPath $(<[2-]) : $(>) ] ; }\n", -"rule makeString { $(<) = $(>:J) ; }\n", -"rule makeSubDir { $(<) = [ FSubDir $(>) ] ; }\n", -"rule makeSuffixed { $(<[1]) = [ FAppendSuffix $(>) : $(<[2]) ] ; }\n", -"include $(JAMFILE) ;\n", -0 }; diff --git a/jam-2.5/jambase.h b/jam-2.5/jambase.h deleted file mode 100644 index 75393f4cc..000000000 --- a/jam-2.5/jambase.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * jambase.h - declaration for the internal jambase - * - * The file Jambase is turned into a C array of strings in jambase.c - * so that it can be built in to the executable. This is the - * declaration for that array. - */ - -extern char *jambase[]; diff --git a/jam-2.5/jamgram.c b/jam-2.5/jamgram.c deleted file mode 100644 index 49788b4d5..000000000 --- a/jam-2.5/jamgram.c +++ /dev/null @@ -1,932 +0,0 @@ -#ifndef lint -static char const -yyrcsid[] = "$FreeBSD: src/usr.bin/yacc/skeleton.c,v 1.28.2.1 2001/07/19 05:46:39 peter Exp $"; -#endif -#include -#define YYBYACC 1 -#define YYMAJOR 1 -#define YYMINOR 9 -#define YYLEX yylex() -#define YYEMPTY -1 -#define yyclearin (yychar=(YYEMPTY)) -#define yyerrok (yyerrflag=0) -#define YYRECOVERING() (yyerrflag!=0) -#if defined(__cplusplus) || __STDC__ -static int yygrowstack(void); -#else -static int yygrowstack(); -#endif -#define YYPREFIX "yy" -#line 85 "jamgram.y" -#include "jam.h" - -#include "lists.h" -#include "variable.h" -#include "parse.h" -#include "scan.h" -#include "compile.h" -#include "newstr.h" -#include "rules.h" - -# define YYMAXDEPTH 10000 /* for OSF and other less endowed yaccs */ - -# define F0 (LIST *(*)(PARSE *, LOL *, int *))0 -# define P0 (PARSE *)0 -# define S0 (char *)0 - -# define pappend( l,r ) parse_make( compile_append,l,r,P0,S0,S0,0 ) -# define pbreak( l,f ) parse_make( compile_break,l,P0,P0,S0,S0,f ) -# define peval( c,l,r ) parse_make( compile_eval,l,r,P0,S0,S0,c ) -# define pfor( s,l,r ) parse_make( compile_foreach,l,r,P0,s,S0,0 ) -# define pif( l,r,t ) parse_make( compile_if,l,r,t,S0,S0,0 ) -# define pincl( l ) parse_make( compile_include,l,P0,P0,S0,S0,0 ) -# define plist( s ) parse_make( compile_list,P0,P0,P0,s,S0,0 ) -# define plocal( l,r,t ) parse_make( compile_local,l,r,t,S0,S0,0 ) -# define pnull() parse_make( compile_null,P0,P0,P0,S0,S0,0 ) -# define pon( l,r ) parse_make( compile_on,l,r,P0,S0,S0,0 ) -# define prule( a,p ) parse_make( compile_rule,a,p,P0,S0,S0,0 ) -# define prules( l,r ) parse_make( compile_rules,l,r,P0,S0,S0,0 ) -# define pset( l,r,a ) parse_make( compile_set,l,r,P0,S0,S0,a ) -# define pset1( l,r,t,a ) parse_make( compile_settings,l,r,t,S0,S0,a ) -# define psetc( s,l,r ) parse_make( compile_setcomp,l,r,P0,s,S0,0 ) -# define psete( s,l,s1,f ) parse_make( compile_setexec,l,P0,P0,s,s1,f ) -# define pswitch( l,r ) parse_make( compile_switch,l,r,P0,S0,S0,0 ) -# define pwhile( l,r ) parse_make( compile_while,l,r,P0,S0,S0,0 ) - -# define pnode( l,r ) parse_make( F0,l,r,P0,S0,S0,0 ) -# define psnode( s,l ) parse_make( F0,l,P0,P0,s,S0,0 ) - -#line 60 "y.tab.c" -#define YYERRCODE 256 -#define _BANG_t 257 -#define _BANG_EQUALS_t 258 -#define _AMPER_t 259 -#define _AMPERAMPER_t 260 -#define _LPAREN_t 261 -#define _RPAREN_t 262 -#define _PLUS_EQUALS_t 263 -#define _COLON_t 264 -#define _SEMIC_t 265 -#define _LANGLE_t 266 -#define _LANGLE_EQUALS_t 267 -#define _EQUALS_t 268 -#define _RANGLE_t 269 -#define _RANGLE_EQUALS_t 270 -#define _QUESTION_EQUALS_t 271 -#define _LBRACKET_t 272 -#define _RBRACKET_t 273 -#define ACTIONS_t 274 -#define BIND_t 275 -#define BREAK_t 276 -#define CASE_t 277 -#define CONTINUE_t 278 -#define DEFAULT_t 279 -#define ELSE_t 280 -#define EXISTING_t 281 -#define FOR_t 282 -#define IF_t 283 -#define IGNORE_t 284 -#define IN_t 285 -#define INCLUDE_t 286 -#define LOCAL_t 287 -#define MAXLINE_t 288 -#define ON_t 289 -#define PIECEMEAL_t 290 -#define QUIETLY_t 291 -#define RETURN_t 292 -#define RULE_t 293 -#define SWITCH_t 294 -#define TOGETHER_t 295 -#define UPDATED_t 296 -#define WHILE_t 297 -#define _LBRACE_t 298 -#define _BAR_t 299 -#define _BARBAR_t 300 -#define _RBRACE_t 301 -#define ARG 302 -#define STRING 303 -const short yylhs[] = { -1, - 0, 0, 2, 2, 1, 1, 1, 1, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 13, 14, 3, 7, 7, 7, 7, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 8, 8, 15, 10, 10, 10, - 6, 6, 4, 16, 16, 5, 18, 5, 17, 17, - 17, 11, 11, 19, 19, 19, 19, 19, 19, 19, - 12, 12, -}; -const short yylen[] = { 2, - 0, 1, 0, 1, 1, 2, 4, 6, 3, 3, - 3, 4, 6, 3, 3, 3, 7, 5, 5, 7, - 5, 6, 3, 0, 0, 9, 1, 1, 1, 2, - 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 2, 3, 0, 2, 4, 0, 3, 1, - 1, 3, 1, 0, 2, 1, 0, 4, 2, 4, - 4, 0, 2, 1, 1, 1, 1, 1, 1, 2, - 0, 2, -}; -const short yydefred[] = { 0, - 57, 62, 54, 54, 0, 0, 54, 54, 0, 54, - 0, 54, 0, 0, 56, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4, 0, 6, 28, - 27, 29, 0, 54, 0, 0, 54, 0, 54, 0, - 69, 66, 0, 68, 67, 65, 64, 0, 63, 14, - 55, 15, 54, 43, 0, 54, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 10, 0, 54, - 23, 16, 0, 0, 0, 0, 9, 30, 0, 54, - 11, 0, 0, 59, 58, 70, 54, 0, 0, 44, - 42, 0, 0, 0, 34, 35, 0, 36, 37, 0, - 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, - 54, 52, 12, 54, 54, 72, 24, 0, 0, 0, - 49, 0, 0, 18, 46, 21, 0, 61, 60, 0, - 0, 0, 8, 22, 0, 13, 25, 17, 20, 47, - 0, 26, -}; -const short yydgoto[] = { 16, - 37, 38, 18, 45, 28, 46, 47, 118, 29, 84, - 21, 98, 140, 151, 119, 23, 50, 20, 59, -}; -const short yysindex[] = { -40, - 0, 0, 0, 0, -295, -233, 0, 0, -240, 0, - -284, 0, -233, -40, 0, 0, 0, -40, -7, -241, - 49, -242, -240, -232, -239, -233, -233, -231, -75, -220, - -195, 34, -210, -243, -226, -59, 0, -223, 0, 0, - 0, 0, -174, 0, -165, -164, 0, -240, 0, -173, - 0, 0, -199, 0, 0, 0, 0, -166, 0, 0, - 0, 0, 0, 0, -154, 0, -233, -233, -233, -233, - -233, -233, -233, -233, -40, -233, -233, 0, -40, 0, - 0, 0, -153, -179, -157, -40, 0, 0, -42, 0, - 0, -144, -185, 0, 0, 0, 0, -171, -170, 0, - 0, -54, 94, 94, 0, 0, -54, 0, 0, -160, - 88, 88, 0, -140, -243, -40, -151, -139, -157, -134, - 0, 0, 0, 0, 0, 0, 0, -40, -149, -40, - 0, -131, -93, 0, 0, 0, -85, 0, 0, -121, - -115, 34, 0, 0, -40, 0, 0, 0, 0, 0, - -105, 0, -}; -const short yyrindex[] = { 197, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, -103, 0, 0, 0, 3, -235, 0, - 0, 0, -110, 0, 0, 0, 0, -94, 0, 0, - 0, 0, 0, -96, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -246, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -95, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -103, 0, 0, 0, 4, 0, - 0, 0, -84, 0, -79, -103, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, -202, -224, -176, 0, 0, -81, 0, 0, 0, - -257, -209, 0, 0, -96, -103, 0, 0, -79, 0, - 0, 0, 0, 0, 0, 0, 0, -103, 1, 4, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -237, 0, 0, 0, 0, 0, - 0, 0, -}; -const short yygindex[] = { 0, - 26, -65, -32, 5, 2, -43, 131, 108, 66, 113, - 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; -#define YYTABLESIZE 364 -const short yytable[] = { 81, - 19, 19, 5, 3, 40, 94, 25, 22, 24, 110, - 32, 30, 31, 113, 33, 19, 35, 34, 51, 19, - 120, 49, 60, 26, 61, 17, 51, 27, 54, 54, - 1, 1, 62, 19, 38, 38, 54, 38, 1, 3, - 40, 40, 40, 39, 78, 63, 122, 48, 89, 93, - 132, 92, 41, 66, 82, 33, 33, 33, 83, 33, - 15, 15, 141, 3, 143, 33, 54, 99, 15, 79, - 101, 85, 80, 38, 38, 38, 19, 87, 36, 150, - 19, 139, 39, 39, 114, 39, 1, 19, 41, 41, - 41, 64, 65, 88, 125, 33, 33, 33, 90, 95, - 91, 126, 96, 67, 68, 69, 124, 100, 97, 149, - 115, 70, 71, 72, 73, 74, 15, 19, 116, 117, - 123, 39, 39, 39, 130, 137, 127, 128, 138, 19, - 142, 19, 102, 103, 104, 105, 106, 107, 108, 109, - 129, 111, 112, 19, 76, 77, 19, 53, 53, 53, - 133, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 134, 53, 31, 31, 31, 136, 31, 53, 144, - 145, 31, 31, 31, 31, 31, 32, 32, 32, 146, - 32, 147, 67, 68, 69, 148, 32, 53, 53, 53, - 70, 71, 72, 73, 74, 152, 1, 3, 67, 68, - 69, 48, 71, 31, 31, 31, 70, 71, 72, 73, - 74, 70, 71, 50, 73, 74, 32, 32, 32, 121, - 40, 45, 75, 76, 77, 41, 135, 131, 42, 0, - 0, 1, 0, 2, 0, 3, 43, 4, 86, 76, - 77, 5, 6, 0, 0, 7, 8, 0, 9, 0, - 0, 10, 11, 12, 0, 40, 13, 14, 0, 0, - 41, 15, 0, 42, 0, 0, 0, 0, 0, 0, - 0, 43, 19, 0, 19, 0, 19, 19, 19, 5, - 3, 44, 19, 19, 0, 0, 19, 19, 0, 19, - 0, 0, 19, 19, 19, 0, 0, 19, 19, 0, - 0, 19, 19, 5, 3, 1, 0, 2, 0, 3, - 0, 4, 0, 0, 0, 5, 6, 0, 0, 7, - 0, 0, 9, 0, 0, 10, 11, 12, 0, 51, - 13, 14, 52, 0, 0, 15, 53, 0, 54, 55, - 0, 0, 0, 56, 57, 67, 68, 69, 0, 0, - 58, 67, 0, 70, 71, 72, 73, 74, 0, 70, - 71, 72, 73, 74, -}; -const short yycheck[] = { 32, - 0, 0, 0, 0, 262, 49, 302, 3, 4, 75, - 9, 7, 8, 79, 10, 14, 12, 302, 265, 18, - 86, 20, 265, 257, 23, 0, 273, 261, 264, 265, - 272, 272, 265, 32, 259, 260, 272, 262, 272, 277, - 298, 299, 300, 18, 265, 285, 90, 289, 44, 48, - 116, 47, 262, 285, 265, 258, 259, 260, 302, 262, - 302, 302, 128, 301, 130, 268, 302, 63, 302, 265, - 66, 298, 268, 298, 299, 300, 75, 301, 13, 145, - 79, 125, 259, 260, 80, 262, 272, 86, 298, 299, - 300, 26, 27, 268, 93, 298, 299, 300, 264, 273, - 265, 97, 302, 258, 259, 260, 292, 262, 275, 142, - 264, 266, 267, 268, 269, 270, 302, 116, 298, 277, - 265, 298, 299, 300, 265, 121, 298, 298, 124, 128, - 280, 130, 67, 68, 69, 70, 71, 72, 73, 74, - 301, 76, 77, 142, 299, 300, 145, 258, 259, 260, - 302, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 301, 273, 258, 259, 260, 301, 262, 279, 301, - 264, 266, 267, 268, 269, 270, 258, 259, 260, 265, - 262, 303, 258, 259, 260, 301, 268, 298, 299, 300, - 266, 267, 268, 269, 270, 301, 0, 301, 258, 259, - 260, 298, 298, 298, 299, 300, 266, 267, 268, 269, - 270, 266, 267, 298, 269, 270, 298, 299, 300, 89, - 263, 301, 298, 299, 300, 268, 119, 115, 271, -1, - -1, 272, -1, 274, -1, 276, 279, 278, 298, 299, - 300, 282, 283, -1, -1, 286, 287, -1, 289, -1, - -1, 292, 293, 294, -1, 263, 297, 298, -1, -1, - 268, 302, -1, 271, -1, -1, -1, -1, -1, -1, - -1, 279, 272, -1, 274, -1, 276, 277, 278, 277, - 277, 289, 282, 283, -1, -1, 286, 287, -1, 289, - -1, -1, 292, 293, 294, -1, -1, 297, 298, -1, - -1, 301, 302, 301, 301, 272, -1, 274, -1, 276, - -1, 278, -1, -1, -1, 282, 283, -1, -1, 286, - -1, -1, 289, -1, -1, 292, 293, 294, -1, 281, - 297, 298, 284, -1, -1, 302, 288, -1, 290, 291, - -1, -1, -1, 295, 296, 258, 259, 260, -1, -1, - 302, 258, -1, 266, 267, 268, 269, 270, -1, 266, - 267, 268, 269, 270, -}; -#define YYFINAL 16 -#ifndef YYDEBUG -#define YYDEBUG 0 -#endif -#define YYMAXTOKEN 303 -#if YYDEBUG -const char * const yyname[] = { -"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"_BANG_t","_BANG_EQUALS_t", -"_AMPER_t","_AMPERAMPER_t","_LPAREN_t","_RPAREN_t","_PLUS_EQUALS_t","_COLON_t", -"_SEMIC_t","_LANGLE_t","_LANGLE_EQUALS_t","_EQUALS_t","_RANGLE_t", -"_RANGLE_EQUALS_t","_QUESTION_EQUALS_t","_LBRACKET_t","_RBRACKET_t","ACTIONS_t", -"BIND_t","BREAK_t","CASE_t","CONTINUE_t","DEFAULT_t","ELSE_t","EXISTING_t", -"FOR_t","IF_t","IGNORE_t","IN_t","INCLUDE_t","LOCAL_t","MAXLINE_t","ON_t", -"PIECEMEAL_t","QUIETLY_t","RETURN_t","RULE_t","SWITCH_t","TOGETHER_t", -"UPDATED_t","WHILE_t","_LBRACE_t","_BAR_t","_BARBAR_t","_RBRACE_t","ARG", -"STRING", -}; -const char * const yyrule[] = { -"$accept : run", -"run :", -"run : rules", -"block :", -"block : rules", -"rules : rule", -"rules : rule rules", -"rules : LOCAL_t list _SEMIC_t block", -"rules : LOCAL_t list _EQUALS_t list _SEMIC_t block", -"rule : _LBRACE_t block _RBRACE_t", -"rule : INCLUDE_t list _SEMIC_t", -"rule : arg lol _SEMIC_t", -"rule : arg assign list _SEMIC_t", -"rule : arg ON_t list assign list _SEMIC_t", -"rule : BREAK_t list _SEMIC_t", -"rule : CONTINUE_t list _SEMIC_t", -"rule : RETURN_t list _SEMIC_t", -"rule : FOR_t ARG IN_t list _LBRACE_t block _RBRACE_t", -"rule : SWITCH_t list _LBRACE_t cases _RBRACE_t", -"rule : IF_t expr _LBRACE_t block _RBRACE_t", -"rule : IF_t expr _LBRACE_t block _RBRACE_t ELSE_t rule", -"rule : WHILE_t expr _LBRACE_t block _RBRACE_t", -"rule : RULE_t ARG params _LBRACE_t block _RBRACE_t", -"rule : ON_t arg rule", -"$$1 :", -"$$2 :", -"rule : ACTIONS_t eflags ARG bindlist _LBRACE_t $$1 STRING $$2 _RBRACE_t", -"assign : _EQUALS_t", -"assign : _PLUS_EQUALS_t", -"assign : _QUESTION_EQUALS_t", -"assign : DEFAULT_t _EQUALS_t", -"expr : arg", -"expr : expr _EQUALS_t expr", -"expr : expr _BANG_EQUALS_t expr", -"expr : expr _LANGLE_t expr", -"expr : expr _LANGLE_EQUALS_t expr", -"expr : expr _RANGLE_t expr", -"expr : expr _RANGLE_EQUALS_t expr", -"expr : expr _AMPER_t expr", -"expr : expr _AMPERAMPER_t expr", -"expr : expr _BAR_t expr", -"expr : expr _BARBAR_t expr", -"expr : arg IN_t list", -"expr : _BANG_t expr", -"expr : _LPAREN_t expr _RPAREN_t", -"cases :", -"cases : case cases", -"case : CASE_t ARG _COLON_t block", -"params :", -"params : ARG _COLON_t params", -"params : ARG", -"lol : list", -"lol : list _COLON_t lol", -"list : listp", -"listp :", -"listp : listp arg", -"arg : ARG", -"$$3 :", -"arg : _LBRACKET_t $$3 func _RBRACKET_t", -"func : arg lol", -"func : ON_t arg arg lol", -"func : ON_t arg RETURN_t list", -"eflags :", -"eflags : eflags eflag", -"eflag : UPDATED_t", -"eflag : TOGETHER_t", -"eflag : IGNORE_t", -"eflag : QUIETLY_t", -"eflag : PIECEMEAL_t", -"eflag : EXISTING_t", -"eflag : MAXLINE_t ARG", -"bindlist :", -"bindlist : BIND_t list", -}; -#endif -#ifndef YYSTYPE -typedef int YYSTYPE; -#endif -#if YYDEBUG -#include -#endif -#ifdef YYSTACKSIZE -#undef YYMAXDEPTH -#define YYMAXDEPTH YYSTACKSIZE -#else -#ifdef YYMAXDEPTH -#define YYSTACKSIZE YYMAXDEPTH -#else -#define YYSTACKSIZE 10000 -#define YYMAXDEPTH 10000 -#endif -#endif -#define YYINITSTACKSIZE 200 -int yydebug; -int yynerrs; -int yyerrflag; -int yychar; -short *yyssp; -YYSTYPE *yyvsp; -YYSTYPE yyval; -YYSTYPE yylval; -short *yyss; -short *yysslim; -YYSTYPE *yyvs; -int yystacksize; -/* allocate initial stack or double stack size, up to YYMAXDEPTH */ -static int yygrowstack() -{ - int newsize, i; - short *newss; - YYSTYPE *newvs; - - if ((newsize = yystacksize) == 0) - newsize = YYINITSTACKSIZE; - else if (newsize >= YYMAXDEPTH) - return -1; - else if ((newsize *= 2) > YYMAXDEPTH) - newsize = YYMAXDEPTH; - i = yyssp - yyss; - newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) : - (short *)malloc(newsize * sizeof *newss); - if (newss == NULL) - return -1; - yyss = newss; - yyssp = newss + i; - newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) : - (YYSTYPE *)malloc(newsize * sizeof *newvs); - if (newvs == NULL) - return -1; - yyvs = newvs; - yyvsp = newvs + i; - yystacksize = newsize; - yysslim = yyss + newsize - 1; - return 0; -} - -#define YYABORT goto yyabort -#define YYREJECT goto yyabort -#define YYACCEPT goto yyaccept -#define YYERROR goto yyerrlab - -#ifndef YYPARSE_PARAM -#if defined(__cplusplus) || __STDC__ -#define YYPARSE_PARAM_ARG void -#define YYPARSE_PARAM_DECL -#else /* ! ANSI-C/C++ */ -#define YYPARSE_PARAM_ARG -#define YYPARSE_PARAM_DECL -#endif /* ANSI-C/C++ */ -#else /* YYPARSE_PARAM */ -#ifndef YYPARSE_PARAM_TYPE -#define YYPARSE_PARAM_TYPE void * -#endif -#if defined(__cplusplus) || __STDC__ -#define YYPARSE_PARAM_ARG YYPARSE_PARAM_TYPE YYPARSE_PARAM -#define YYPARSE_PARAM_DECL -#else /* ! ANSI-C/C++ */ -#define YYPARSE_PARAM_ARG YYPARSE_PARAM -#define YYPARSE_PARAM_DECL YYPARSE_PARAM_TYPE YYPARSE_PARAM; -#endif /* ANSI-C/C++ */ -#endif /* ! YYPARSE_PARAM */ - -int -yyparse (YYPARSE_PARAM_ARG) - YYPARSE_PARAM_DECL -{ - register int yym, yyn, yystate; -#if YYDEBUG - register const char *yys; - - if ((yys = getenv("YYDEBUG"))) - { - yyn = *yys; - if (yyn >= '0' && yyn <= '9') - yydebug = yyn - '0'; - } -#endif - - yynerrs = 0; - yyerrflag = 0; - yychar = (-1); - - if (yyss == NULL && yygrowstack()) goto yyoverflow; - yyssp = yyss; - yyvsp = yyvs; - *yyssp = yystate = 0; - -yyloop: - if ((yyn = yydefred[yystate])) goto yyreduce; - if (yychar < 0) - { - if ((yychar = yylex()) < 0) yychar = 0; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, reading %d (%s)\n", - YYPREFIX, yystate, yychar, yys); - } -#endif - } - if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yychar) - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, shifting to state %d\n", - YYPREFIX, yystate, yytable[yyn]); -#endif - if (yyssp >= yysslim && yygrowstack()) - { - goto yyoverflow; - } - *++yyssp = yystate = yytable[yyn]; - *++yyvsp = yylval; - yychar = (-1); - if (yyerrflag > 0) --yyerrflag; - goto yyloop; - } - if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yychar) - { - yyn = yytable[yyn]; - goto yyreduce; - } - if (yyerrflag) goto yyinrecovery; -#if defined(lint) || defined(__GNUC__) - goto yynewerror; -#endif -yynewerror: - yyerror("syntax error"); -#if defined(lint) || defined(__GNUC__) - goto yyerrlab; -#endif -yyerrlab: - ++yynerrs; -yyinrecovery: - if (yyerrflag < 3) - { - yyerrflag = 3; - for (;;) - { - if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, error recovery shifting\ - to state %d\n", YYPREFIX, *yyssp, yytable[yyn]); -#endif - if (yyssp >= yysslim && yygrowstack()) - { - goto yyoverflow; - } - *++yyssp = yystate = yytable[yyn]; - *++yyvsp = yylval; - goto yyloop; - } - else - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: error recovery discarding state %d\n", - YYPREFIX, *yyssp); -#endif - if (yyssp <= yyss) goto yyabort; - --yyssp; - --yyvsp; - } - } - } - else - { - if (yychar == 0) goto yyabort; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, error recovery discards token %d (%s)\n", - YYPREFIX, yystate, yychar, yys); - } -#endif - yychar = (-1); - goto yyloop; - } -yyreduce: -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, reducing by rule %d (%s)\n", - YYPREFIX, yystate, yyn, yyrule[yyn]); -#endif - yym = yylen[yyn]; - yyval = yyvsp[1-yym]; - switch (yyn) - { -case 2: -#line 130 "jamgram.y" -{ parse_save( yyvsp[0].parse ); } -break; -case 3: -#line 141 "jamgram.y" -{ yyval.parse = pnull(); } -break; -case 4: -#line 143 "jamgram.y" -{ yyval.parse = yyvsp[0].parse; } -break; -case 5: -#line 147 "jamgram.y" -{ yyval.parse = yyvsp[0].parse; } -break; -case 6: -#line 149 "jamgram.y" -{ yyval.parse = prules( yyvsp[-1].parse, yyvsp[0].parse ); } -break; -case 7: -#line 151 "jamgram.y" -{ yyval.parse = plocal( yyvsp[-2].parse, pnull(), yyvsp[0].parse ); } -break; -case 8: -#line 153 "jamgram.y" -{ yyval.parse = plocal( yyvsp[-4].parse, yyvsp[-2].parse, yyvsp[0].parse ); } -break; -case 9: -#line 157 "jamgram.y" -{ yyval.parse = yyvsp[-1].parse; } -break; -case 10: -#line 159 "jamgram.y" -{ yyval.parse = pincl( yyvsp[-1].parse ); } -break; -case 11: -#line 161 "jamgram.y" -{ yyval.parse = prule( yyvsp[-2].parse, yyvsp[-1].parse ); } -break; -case 12: -#line 163 "jamgram.y" -{ yyval.parse = pset( yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); } -break; -case 13: -#line 165 "jamgram.y" -{ yyval.parse = pset1( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); } -break; -case 14: -#line 167 "jamgram.y" -{ yyval.parse = pbreak( yyvsp[-1].parse, JMP_BREAK ); } -break; -case 15: -#line 169 "jamgram.y" -{ yyval.parse = pbreak( yyvsp[-1].parse, JMP_CONTINUE ); } -break; -case 16: -#line 171 "jamgram.y" -{ yyval.parse = pbreak( yyvsp[-1].parse, JMP_RETURN ); } -break; -case 17: -#line 173 "jamgram.y" -{ yyval.parse = pfor( yyvsp[-5].string, yyvsp[-3].parse, yyvsp[-1].parse ); } -break; -case 18: -#line 175 "jamgram.y" -{ yyval.parse = pswitch( yyvsp[-3].parse, yyvsp[-1].parse ); } -break; -case 19: -#line 177 "jamgram.y" -{ yyval.parse = pif( yyvsp[-3].parse, yyvsp[-1].parse, pnull() ); } -break; -case 20: -#line 179 "jamgram.y" -{ yyval.parse = pif( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[0].parse ); } -break; -case 21: -#line 181 "jamgram.y" -{ yyval.parse = pwhile( yyvsp[-3].parse, yyvsp[-1].parse ); } -break; -case 22: -#line 183 "jamgram.y" -{ yyval.parse = psetc( yyvsp[-4].string, yyvsp[-3].parse, yyvsp[-1].parse ); } -break; -case 23: -#line 185 "jamgram.y" -{ yyval.parse = pon( yyvsp[-1].parse, yyvsp[0].parse ); } -break; -case 24: -#line 187 "jamgram.y" -{ yymode( SCAN_STRING ); } -break; -case 25: -#line 189 "jamgram.y" -{ yymode( SCAN_NORMAL ); } -break; -case 26: -#line 191 "jamgram.y" -{ yyval.parse = psete( yyvsp[-6].string,yyvsp[-5].parse,yyvsp[-2].string,yyvsp[-7].number ); } -break; -case 27: -#line 199 "jamgram.y" -{ yyval.number = VAR_SET; } -break; -case 28: -#line 201 "jamgram.y" -{ yyval.number = VAR_APPEND; } -break; -case 29: -#line 203 "jamgram.y" -{ yyval.number = VAR_DEFAULT; } -break; -case 30: -#line 205 "jamgram.y" -{ yyval.number = VAR_DEFAULT; } -break; -case 31: -#line 213 "jamgram.y" -{ yyval.parse = peval( EXPR_EXISTS, yyvsp[0].parse, pnull() ); } -break; -case 32: -#line 215 "jamgram.y" -{ yyval.parse = peval( EXPR_EQUALS, yyvsp[-2].parse, yyvsp[0].parse ); } -break; -case 33: -#line 217 "jamgram.y" -{ yyval.parse = peval( EXPR_NOTEQ, yyvsp[-2].parse, yyvsp[0].parse ); } -break; -case 34: -#line 219 "jamgram.y" -{ yyval.parse = peval( EXPR_LESS, yyvsp[-2].parse, yyvsp[0].parse ); } -break; -case 35: -#line 221 "jamgram.y" -{ yyval.parse = peval( EXPR_LESSEQ, yyvsp[-2].parse, yyvsp[0].parse ); } -break; -case 36: -#line 223 "jamgram.y" -{ yyval.parse = peval( EXPR_MORE, yyvsp[-2].parse, yyvsp[0].parse ); } -break; -case 37: -#line 225 "jamgram.y" -{ yyval.parse = peval( EXPR_MOREEQ, yyvsp[-2].parse, yyvsp[0].parse ); } -break; -case 38: -#line 227 "jamgram.y" -{ yyval.parse = peval( EXPR_AND, yyvsp[-2].parse, yyvsp[0].parse ); } -break; -case 39: -#line 229 "jamgram.y" -{ yyval.parse = peval( EXPR_AND, yyvsp[-2].parse, yyvsp[0].parse ); } -break; -case 40: -#line 231 "jamgram.y" -{ yyval.parse = peval( EXPR_OR, yyvsp[-2].parse, yyvsp[0].parse ); } -break; -case 41: -#line 233 "jamgram.y" -{ yyval.parse = peval( EXPR_OR, yyvsp[-2].parse, yyvsp[0].parse ); } -break; -case 42: -#line 235 "jamgram.y" -{ yyval.parse = peval( EXPR_IN, yyvsp[-2].parse, yyvsp[0].parse ); } -break; -case 43: -#line 237 "jamgram.y" -{ yyval.parse = peval( EXPR_NOT, yyvsp[0].parse, pnull() ); } -break; -case 44: -#line 239 "jamgram.y" -{ yyval.parse = yyvsp[-1].parse; } -break; -case 45: -#line 249 "jamgram.y" -{ yyval.parse = P0; } -break; -case 46: -#line 251 "jamgram.y" -{ yyval.parse = pnode( yyvsp[-1].parse, yyvsp[0].parse ); } -break; -case 47: -#line 255 "jamgram.y" -{ yyval.parse = psnode( yyvsp[-2].string, yyvsp[0].parse ); } -break; -case 48: -#line 264 "jamgram.y" -{ yyval.parse = P0; } -break; -case 49: -#line 266 "jamgram.y" -{ yyval.parse = psnode( yyvsp[-2].string, yyvsp[0].parse ); } -break; -case 50: -#line 268 "jamgram.y" -{ yyval.parse = psnode( yyvsp[0].string, P0 ); } -break; -case 51: -#line 277 "jamgram.y" -{ yyval.parse = pnode( P0, yyvsp[0].parse ); } -break; -case 52: -#line 279 "jamgram.y" -{ yyval.parse = pnode( yyvsp[0].parse, yyvsp[-2].parse ); } -break; -case 53: -#line 289 "jamgram.y" -{ yyval.parse = yyvsp[0].parse; yymode( SCAN_NORMAL ); } -break; -case 54: -#line 293 "jamgram.y" -{ yyval.parse = pnull(); yymode( SCAN_PUNCT ); } -break; -case 55: -#line 295 "jamgram.y" -{ yyval.parse = pappend( yyvsp[-1].parse, yyvsp[0].parse ); } -break; -case 56: -#line 299 "jamgram.y" -{ yyval.parse = plist( yyvsp[0].string ); } -break; -case 57: -#line 300 "jamgram.y" -{ yymode( SCAN_NORMAL ); } -break; -case 58: -#line 301 "jamgram.y" -{ yyval.parse = yyvsp[-1].parse; } -break; -case 59: -#line 310 "jamgram.y" -{ yyval.parse = prule( yyvsp[-1].parse, yyvsp[0].parse ); } -break; -case 60: -#line 312 "jamgram.y" -{ yyval.parse = pon( yyvsp[-2].parse, prule( yyvsp[-1].parse, yyvsp[0].parse ) ); } -break; -case 61: -#line 314 "jamgram.y" -{ yyval.parse = pon( yyvsp[-2].parse, yyvsp[0].parse ); } -break; -case 62: -#line 323 "jamgram.y" -{ yyval.number = 0; } -break; -case 63: -#line 325 "jamgram.y" -{ yyval.number = yyvsp[-1].number | yyvsp[0].number; } -break; -case 64: -#line 329 "jamgram.y" -{ yyval.number = RULE_UPDATED; } -break; -case 65: -#line 331 "jamgram.y" -{ yyval.number = RULE_TOGETHER; } -break; -case 66: -#line 333 "jamgram.y" -{ yyval.number = RULE_IGNORE; } -break; -case 67: -#line 335 "jamgram.y" -{ yyval.number = RULE_QUIETLY; } -break; -case 68: -#line 337 "jamgram.y" -{ yyval.number = RULE_PIECEMEAL; } -break; -case 69: -#line 339 "jamgram.y" -{ yyval.number = RULE_EXISTING; } -break; -case 70: -#line 341 "jamgram.y" -{ yyval.number = atoi( yyvsp[0].string ) * RULE_MAXLINE; } -break; -case 71: -#line 350 "jamgram.y" -{ yyval.parse = pnull(); } -break; -case 72: -#line 352 "jamgram.y" -{ yyval.parse = yyvsp[0].parse; } -break; -#line 877 "y.tab.c" - } - yyssp -= yym; - yystate = *yyssp; - yyvsp -= yym; - yym = yylhs[yyn]; - if (yystate == 0 && yym == 0) - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: after reduction, shifting from state 0 to\ - state %d\n", YYPREFIX, YYFINAL); -#endif - yystate = YYFINAL; - *++yyssp = YYFINAL; - *++yyvsp = yyval; - if (yychar < 0) - { - if ((yychar = yylex()) < 0) yychar = 0; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, reading %d (%s)\n", - YYPREFIX, YYFINAL, yychar, yys); - } -#endif - } - if (yychar == 0) goto yyaccept; - goto yyloop; - } - if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yystate) - yystate = yytable[yyn]; - else - yystate = yydgoto[yym]; -#if YYDEBUG - if (yydebug) - printf("%sdebug: after reduction, shifting from state %d \ -to state %d\n", YYPREFIX, *yyssp, yystate); -#endif - if (yyssp >= yysslim && yygrowstack()) - { - goto yyoverflow; - } - *++yyssp = yystate; - *++yyvsp = yyval; - goto yyloop; -yyoverflow: - yyerror("yacc stack overflow"); -yyabort: - return (1); -yyaccept: - return (0); -} diff --git a/jam-2.5/jamgram.h b/jam-2.5/jamgram.h deleted file mode 100644 index f87bc88cd..000000000 --- a/jam-2.5/jamgram.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef YYERRCODE -#define YYERRCODE 256 -#endif - -#define _BANG_t 257 -#define _BANG_EQUALS_t 258 -#define _AMPER_t 259 -#define _AMPERAMPER_t 260 -#define _LPAREN_t 261 -#define _RPAREN_t 262 -#define _PLUS_EQUALS_t 263 -#define _COLON_t 264 -#define _SEMIC_t 265 -#define _LANGLE_t 266 -#define _LANGLE_EQUALS_t 267 -#define _EQUALS_t 268 -#define _RANGLE_t 269 -#define _RANGLE_EQUALS_t 270 -#define _QUESTION_EQUALS_t 271 -#define _LBRACKET_t 272 -#define _RBRACKET_t 273 -#define ACTIONS_t 274 -#define BIND_t 275 -#define BREAK_t 276 -#define CASE_t 277 -#define CONTINUE_t 278 -#define DEFAULT_t 279 -#define ELSE_t 280 -#define EXISTING_t 281 -#define FOR_t 282 -#define IF_t 283 -#define IGNORE_t 284 -#define IN_t 285 -#define INCLUDE_t 286 -#define LOCAL_t 287 -#define MAXLINE_t 288 -#define ON_t 289 -#define PIECEMEAL_t 290 -#define QUIETLY_t 291 -#define RETURN_t 292 -#define RULE_t 293 -#define SWITCH_t 294 -#define TOGETHER_t 295 -#define UPDATED_t 296 -#define WHILE_t 297 -#define _LBRACE_t 298 -#define _BAR_t 299 -#define _BARBAR_t 300 -#define _RBRACE_t 301 -#define ARG 302 -#define STRING 303 diff --git a/jam-2.5/jamgram.y b/jam-2.5/jamgram.y deleted file mode 100644 index 8e9238bbe..000000000 --- a/jam-2.5/jamgram.y +++ /dev/null @@ -1,355 +0,0 @@ -%token _BANG_t -%token _BANG_EQUALS_t -%token _AMPER_t -%token _AMPERAMPER_t -%token _LPAREN_t -%token _RPAREN_t -%token _PLUS_EQUALS_t -%token _COLON_t -%token _SEMIC_t -%token _LANGLE_t -%token _LANGLE_EQUALS_t -%token _EQUALS_t -%token _RANGLE_t -%token _RANGLE_EQUALS_t -%token _QUESTION_EQUALS_t -%token _LBRACKET_t -%token _RBRACKET_t -%token ACTIONS_t -%token BIND_t -%token BREAK_t -%token CASE_t -%token CONTINUE_t -%token DEFAULT_t -%token ELSE_t -%token EXISTING_t -%token FOR_t -%token IF_t -%token IGNORE_t -%token IN_t -%token INCLUDE_t -%token LOCAL_t -%token MAXLINE_t -%token ON_t -%token PIECEMEAL_t -%token QUIETLY_t -%token RETURN_t -%token RULE_t -%token SWITCH_t -%token TOGETHER_t -%token UPDATED_t -%token WHILE_t -%token _LBRACE_t -%token _BAR_t -%token _BARBAR_t -%token _RBRACE_t -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * jamgram.yy - jam grammar - * - * 04/13/94 (seiwald) - added shorthand L0 for null list pointer - * 06/01/94 (seiwald) - new 'actions existing' does existing sources - * 08/23/94 (seiwald) - Support for '+=' (append to variable) - * 08/31/94 (seiwald) - Allow ?= as alias for "default =". - * 09/15/94 (seiwald) - if conditionals take only single arguments, so - * that 'if foo == bar' gives syntax error (use =). - * 02/11/95 (seiwald) - when scanning arguments to rules, only treat - * punctuation keywords as keywords. All arg lists - * are terminated with punctuation keywords. - * 09/11/00 (seiwald) - Support for function calls; rules return LIST *. - * 01/22/01 (seiwald) - replace evaluate_if() with compile_eval() - * 01/24/01 (seiwald) - 'while' statement - * 03/23/01 (seiwald) - "[ on target rule ]" support - * 02/27/02 (seiwald) - un-break "expr : arg in list" syntax - * 03/02/02 (seiwald) - rules can be invoked via variable names - * 03/12/02 (seiwald) - set YYMAXDEPTH for big, right-recursive rules - * 02/28/02 (seiwald) - merge EXEC_xxx flags in with RULE_xxx - * 06/21/02 (seiwald) - support for named parameters - * 10/22/02 (seiwald) - working return/break/continue statements - */ - -%token ARG STRING - -%left _BARBAR_t _BAR_t -%left _AMPERAMPER_t _AMPER_t -%left _EQUALS_t _BANG_EQUALS_t IN_t -%left _LANGLE_t _LANGLE_EQUALS_t _RANGLE_t _RANGLE_EQUALS_t -%left _BANG_t - -%{ -#include "jam.h" - -#include "lists.h" -#include "variable.h" -#include "parse.h" -#include "scan.h" -#include "compile.h" -#include "newstr.h" -#include "rules.h" - -# define YYMAXDEPTH 10000 /* for OSF and other less endowed yaccs */ - -# define F0 (LIST *(*)(PARSE *, LOL *, int *))0 -# define P0 (PARSE *)0 -# define S0 (char *)0 - -# define pappend( l,r ) parse_make( compile_append,l,r,P0,S0,S0,0 ) -# define pbreak( l,f ) parse_make( compile_break,l,P0,P0,S0,S0,f ) -# define peval( c,l,r ) parse_make( compile_eval,l,r,P0,S0,S0,c ) -# define pfor( s,l,r ) parse_make( compile_foreach,l,r,P0,s,S0,0 ) -# define pif( l,r,t ) parse_make( compile_if,l,r,t,S0,S0,0 ) -# define pincl( l ) parse_make( compile_include,l,P0,P0,S0,S0,0 ) -# define plist( s ) parse_make( compile_list,P0,P0,P0,s,S0,0 ) -# define plocal( l,r,t ) parse_make( compile_local,l,r,t,S0,S0,0 ) -# define pnull() parse_make( compile_null,P0,P0,P0,S0,S0,0 ) -# define pon( l,r ) parse_make( compile_on,l,r,P0,S0,S0,0 ) -# define prule( a,p ) parse_make( compile_rule,a,p,P0,S0,S0,0 ) -# define prules( l,r ) parse_make( compile_rules,l,r,P0,S0,S0,0 ) -# define pset( l,r,a ) parse_make( compile_set,l,r,P0,S0,S0,a ) -# define pset1( l,r,t,a ) parse_make( compile_settings,l,r,t,S0,S0,a ) -# define psetc( s,l,r ) parse_make( compile_setcomp,l,r,P0,s,S0,0 ) -# define psete( s,l,s1,f ) parse_make( compile_setexec,l,P0,P0,s,s1,f ) -# define pswitch( l,r ) parse_make( compile_switch,l,r,P0,S0,S0,0 ) -# define pwhile( l,r ) parse_make( compile_while,l,r,P0,S0,S0,0 ) - -# define pnode( l,r ) parse_make( F0,l,r,P0,S0,S0,0 ) -# define psnode( s,l ) parse_make( F0,l,P0,P0,s,S0,0 ) - -%} - -%% - -run : /* empty */ - /* do nothing */ - | rules - { parse_save( $1.parse ); } - ; - -/* - * block - zero or more rules - * rules - one or more rules - * rule - any one of jam's rules - * right-recursive so rules execute in order. - */ - -block : /* empty */ - { $$.parse = pnull(); } - | rules - { $$.parse = $1.parse; } - ; - -rules : rule - { $$.parse = $1.parse; } - | rule rules - { $$.parse = prules( $1.parse, $2.parse ); } - | LOCAL_t list _SEMIC_t block - { $$.parse = plocal( $2.parse, pnull(), $4.parse ); } - | LOCAL_t list _EQUALS_t list _SEMIC_t block - { $$.parse = plocal( $2.parse, $4.parse, $6.parse ); } - ; - -rule : _LBRACE_t block _RBRACE_t - { $$.parse = $2.parse; } - | INCLUDE_t list _SEMIC_t - { $$.parse = pincl( $2.parse ); } - | arg lol _SEMIC_t - { $$.parse = prule( $1.parse, $2.parse ); } - | arg assign list _SEMIC_t - { $$.parse = pset( $1.parse, $3.parse, $2.number ); } - | arg ON_t list assign list _SEMIC_t - { $$.parse = pset1( $1.parse, $3.parse, $5.parse, $4.number ); } - | BREAK_t list _SEMIC_t - { $$.parse = pbreak( $2.parse, JMP_BREAK ); } - | CONTINUE_t list _SEMIC_t - { $$.parse = pbreak( $2.parse, JMP_CONTINUE ); } - | RETURN_t list _SEMIC_t - { $$.parse = pbreak( $2.parse, JMP_RETURN ); } - | FOR_t ARG IN_t list _LBRACE_t block _RBRACE_t - { $$.parse = pfor( $2.string, $4.parse, $6.parse ); } - | SWITCH_t list _LBRACE_t cases _RBRACE_t - { $$.parse = pswitch( $2.parse, $4.parse ); } - | IF_t expr _LBRACE_t block _RBRACE_t - { $$.parse = pif( $2.parse, $4.parse, pnull() ); } - | IF_t expr _LBRACE_t block _RBRACE_t ELSE_t rule - { $$.parse = pif( $2.parse, $4.parse, $7.parse ); } - | WHILE_t expr _LBRACE_t block _RBRACE_t - { $$.parse = pwhile( $2.parse, $4.parse ); } - | RULE_t ARG params _LBRACE_t block _RBRACE_t - { $$.parse = psetc( $2.string, $3.parse, $5.parse ); } - | ON_t arg rule - { $$.parse = pon( $2.parse, $3.parse ); } - | ACTIONS_t eflags ARG bindlist _LBRACE_t - { yymode( SCAN_STRING ); } - STRING - { yymode( SCAN_NORMAL ); } - _RBRACE_t - { $$.parse = psete( $3.string,$4.parse,$7.string,$2.number ); } - ; - -/* - * assign - = or += - */ - -assign : _EQUALS_t - { $$.number = VAR_SET; } - | _PLUS_EQUALS_t - { $$.number = VAR_APPEND; } - | _QUESTION_EQUALS_t - { $$.number = VAR_DEFAULT; } - | DEFAULT_t _EQUALS_t - { $$.number = VAR_DEFAULT; } - ; - -/* - * expr - an expression for if - */ - -expr : arg - { $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); } - | expr _EQUALS_t expr - { $$.parse = peval( EXPR_EQUALS, $1.parse, $3.parse ); } - | expr _BANG_EQUALS_t expr - { $$.parse = peval( EXPR_NOTEQ, $1.parse, $3.parse ); } - | expr _LANGLE_t expr - { $$.parse = peval( EXPR_LESS, $1.parse, $3.parse ); } - | expr _LANGLE_EQUALS_t expr - { $$.parse = peval( EXPR_LESSEQ, $1.parse, $3.parse ); } - | expr _RANGLE_t expr - { $$.parse = peval( EXPR_MORE, $1.parse, $3.parse ); } - | expr _RANGLE_EQUALS_t expr - { $$.parse = peval( EXPR_MOREEQ, $1.parse, $3.parse ); } - | expr _AMPER_t expr - { $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); } - | expr _AMPERAMPER_t expr - { $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); } - | expr _BAR_t expr - { $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); } - | expr _BARBAR_t expr - { $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); } - | arg IN_t list - { $$.parse = peval( EXPR_IN, $1.parse, $3.parse ); } - | _BANG_t expr - { $$.parse = peval( EXPR_NOT, $2.parse, pnull() ); } - | _LPAREN_t expr _RPAREN_t - { $$.parse = $2.parse; } - ; - -/* - * cases - action elements inside a 'switch' - * case - a single action element inside a 'switch' - * right-recursive rule so cases can be examined in order. - */ - -cases : /* empty */ - { $$.parse = P0; } - | case cases - { $$.parse = pnode( $1.parse, $2.parse ); } - ; - -case : CASE_t ARG _COLON_t block - { $$.parse = psnode( $2.string, $4.parse ); } - ; - -/* - * params - optional parameter names to rule definition - * right-recursive rule so that params can be added in order. - */ - -params : /* empty */ - { $$.parse = P0; } - | ARG _COLON_t params - { $$.parse = psnode( $1.string, $3.parse ); } - | ARG - { $$.parse = psnode( $1.string, P0 ); } - ; - -/* - * lol - list of lists - * right-recursive rule so that lists can be added in order. - */ - -lol : list - { $$.parse = pnode( P0, $1.parse ); } - | list _COLON_t lol - { $$.parse = pnode( $3.parse, $1.parse ); } - ; - -/* - * list - zero or more args in a LIST - * listp - list (in puncutation only mode) - * arg - one ARG or function call - */ - -list : listp - { $$.parse = $1.parse; yymode( SCAN_NORMAL ); } - ; - -listp : /* empty */ - { $$.parse = pnull(); yymode( SCAN_PUNCT ); } - | listp arg - { $$.parse = pappend( $1.parse, $2.parse ); } - ; - -arg : ARG - { $$.parse = plist( $1.string ); } - | _LBRACKET_t { yymode( SCAN_NORMAL ); } func _RBRACKET_t - { $$.parse = $3.parse; } - ; - -/* - * func - a function call (inside []) - * This needs to be split cleanly out of 'rule' - */ - -func : arg lol - { $$.parse = prule( $1.parse, $2.parse ); } - | ON_t arg arg lol - { $$.parse = pon( $2.parse, prule( $3.parse, $4.parse ) ); } - | ON_t arg RETURN_t list - { $$.parse = pon( $2.parse, $4.parse ); } - ; - -/* - * eflags - zero or more modifiers to 'executes' - * eflag - a single modifier to 'executes' - */ - -eflags : /* empty */ - { $$.number = 0; } - | eflags eflag - { $$.number = $1.number | $2.number; } - ; - -eflag : UPDATED_t - { $$.number = RULE_UPDATED; } - | TOGETHER_t - { $$.number = RULE_TOGETHER; } - | IGNORE_t - { $$.number = RULE_IGNORE; } - | QUIETLY_t - { $$.number = RULE_QUIETLY; } - | PIECEMEAL_t - { $$.number = RULE_PIECEMEAL; } - | EXISTING_t - { $$.number = RULE_EXISTING; } - | MAXLINE_t ARG - { $$.number = atoi( $2.string ) * RULE_MAXLINE; } - ; - - -/* - * bindlist - list of variable to bind for an action - */ - -bindlist : /* empty */ - { $$.parse = pnull(); } - | BIND_t list - { $$.parse = $2.parse; } - ; - - diff --git a/jam-2.5/jamgram.yy b/jam-2.5/jamgram.yy deleted file mode 100644 index 6a085e22f..000000000 --- a/jam-2.5/jamgram.yy +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * jamgram.yy - jam grammar - * - * 04/13/94 (seiwald) - added shorthand L0 for null list pointer - * 06/01/94 (seiwald) - new 'actions existing' does existing sources - * 08/23/94 (seiwald) - Support for '+=' (append to variable) - * 08/31/94 (seiwald) - Allow ?= as alias for "default =". - * 09/15/94 (seiwald) - if conditionals take only single arguments, so - * that 'if foo == bar' gives syntax error (use =). - * 02/11/95 (seiwald) - when scanning arguments to rules, only treat - * punctuation keywords as keywords. All arg lists - * are terminated with punctuation keywords. - * 09/11/00 (seiwald) - Support for function calls; rules return LIST *. - * 01/22/01 (seiwald) - replace evaluate_if() with compile_eval() - * 01/24/01 (seiwald) - 'while' statement - * 03/23/01 (seiwald) - "[ on target rule ]" support - * 02/27/02 (seiwald) - un-break "expr : arg in list" syntax - * 03/02/02 (seiwald) - rules can be invoked via variable names - * 03/12/02 (seiwald) - set YYMAXDEPTH for big, right-recursive rules - * 02/28/02 (seiwald) - merge EXEC_xxx flags in with RULE_xxx - * 06/21/02 (seiwald) - support for named parameters - * 10/22/02 (seiwald) - working return/break/continue statements - */ - -%token ARG STRING - -%left `||` `|` -%left `&&` `&` -%left `=` `!=` `in` -%left `<` `<=` `>` `>=` -%left `!` - -%{ -#include "jam.h" - -#include "lists.h" -#include "variable.h" -#include "parse.h" -#include "scan.h" -#include "compile.h" -#include "newstr.h" -#include "rules.h" - -# define YYMAXDEPTH 10000 /* for OSF and other less endowed yaccs */ - -# define F0 (LIST *(*)(PARSE *, LOL *, int *))0 -# define P0 (PARSE *)0 -# define S0 (char *)0 - -# define pappend( l,r ) parse_make( compile_append,l,r,P0,S0,S0,0 ) -# define pbreak( l,f ) parse_make( compile_break,l,P0,P0,S0,S0,f ) -# define peval( c,l,r ) parse_make( compile_eval,l,r,P0,S0,S0,c ) -# define pfor( s,l,r ) parse_make( compile_foreach,l,r,P0,s,S0,0 ) -# define pif( l,r,t ) parse_make( compile_if,l,r,t,S0,S0,0 ) -# define pincl( l ) parse_make( compile_include,l,P0,P0,S0,S0,0 ) -# define plist( s ) parse_make( compile_list,P0,P0,P0,s,S0,0 ) -# define plocal( l,r,t ) parse_make( compile_local,l,r,t,S0,S0,0 ) -# define pnull() parse_make( compile_null,P0,P0,P0,S0,S0,0 ) -# define pon( l,r ) parse_make( compile_on,l,r,P0,S0,S0,0 ) -# define prule( a,p ) parse_make( compile_rule,a,p,P0,S0,S0,0 ) -# define prules( l,r ) parse_make( compile_rules,l,r,P0,S0,S0,0 ) -# define pset( l,r,a ) parse_make( compile_set,l,r,P0,S0,S0,a ) -# define pset1( l,r,t,a ) parse_make( compile_settings,l,r,t,S0,S0,a ) -# define psetc( s,l,r ) parse_make( compile_setcomp,l,r,P0,s,S0,0 ) -# define psete( s,l,s1,f ) parse_make( compile_setexec,l,P0,P0,s,s1,f ) -# define pswitch( l,r ) parse_make( compile_switch,l,r,P0,S0,S0,0 ) -# define pwhile( l,r ) parse_make( compile_while,l,r,P0,S0,S0,0 ) - -# define pnode( l,r ) parse_make( F0,l,r,P0,S0,S0,0 ) -# define psnode( s,l ) parse_make( F0,l,P0,P0,s,S0,0 ) - -%} - -%% - -run : /* empty */ - /* do nothing */ - | rules - { parse_save( $1.parse ); } - ; - -/* - * block - zero or more rules - * rules - one or more rules - * rule - any one of jam's rules - * right-recursive so rules execute in order. - */ - -block : /* empty */ - { $$.parse = pnull(); } - | rules - { $$.parse = $1.parse; } - ; - -rules : rule - { $$.parse = $1.parse; } - | rule rules - { $$.parse = prules( $1.parse, $2.parse ); } - | `local` list `;` block - { $$.parse = plocal( $2.parse, pnull(), $4.parse ); } - | `local` list `=` list `;` block - { $$.parse = plocal( $2.parse, $4.parse, $6.parse ); } - ; - -rule : `{` block `}` - { $$.parse = $2.parse; } - | `include` list `;` - { $$.parse = pincl( $2.parse ); } - | arg lol `;` - { $$.parse = prule( $1.parse, $2.parse ); } - | arg assign list `;` - { $$.parse = pset( $1.parse, $3.parse, $2.number ); } - | arg `on` list assign list `;` - { $$.parse = pset1( $1.parse, $3.parse, $5.parse, $4.number ); } - | `break` list `;` - { $$.parse = pbreak( $2.parse, JMP_BREAK ); } - | `continue` list `;` - { $$.parse = pbreak( $2.parse, JMP_CONTINUE ); } - | `return` list `;` - { $$.parse = pbreak( $2.parse, JMP_RETURN ); } - | `for` ARG `in` list `{` block `}` - { $$.parse = pfor( $2.string, $4.parse, $6.parse ); } - | `switch` list `{` cases `}` - { $$.parse = pswitch( $2.parse, $4.parse ); } - | `if` expr `{` block `}` - { $$.parse = pif( $2.parse, $4.parse, pnull() ); } - | `if` expr `{` block `}` `else` rule - { $$.parse = pif( $2.parse, $4.parse, $7.parse ); } - | `while` expr `{` block `}` - { $$.parse = pwhile( $2.parse, $4.parse ); } - | `rule` ARG params `{` block `}` - { $$.parse = psetc( $2.string, $3.parse, $5.parse ); } - | `on` arg rule - { $$.parse = pon( $2.parse, $3.parse ); } - | `actions` eflags ARG bindlist `{` - { yymode( SCAN_STRING ); } - STRING - { yymode( SCAN_NORMAL ); } - `}` - { $$.parse = psete( $3.string,$4.parse,$7.string,$2.number ); } - ; - -/* - * assign - = or += - */ - -assign : `=` - { $$.number = VAR_SET; } - | `+=` - { $$.number = VAR_APPEND; } - | `?=` - { $$.number = VAR_DEFAULT; } - | `default` `=` - { $$.number = VAR_DEFAULT; } - ; - -/* - * expr - an expression for if - */ - -expr : arg - { $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); } - | expr `=` expr - { $$.parse = peval( EXPR_EQUALS, $1.parse, $3.parse ); } - | expr `!=` expr - { $$.parse = peval( EXPR_NOTEQ, $1.parse, $3.parse ); } - | expr `<` expr - { $$.parse = peval( EXPR_LESS, $1.parse, $3.parse ); } - | expr `<=` expr - { $$.parse = peval( EXPR_LESSEQ, $1.parse, $3.parse ); } - | expr `>` expr - { $$.parse = peval( EXPR_MORE, $1.parse, $3.parse ); } - | expr `>=` expr - { $$.parse = peval( EXPR_MOREEQ, $1.parse, $3.parse ); } - | expr `&` expr - { $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); } - | expr `&&` expr - { $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); } - | expr `|` expr - { $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); } - | expr `||` expr - { $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); } - | arg `in` list - { $$.parse = peval( EXPR_IN, $1.parse, $3.parse ); } - | `!` expr - { $$.parse = peval( EXPR_NOT, $2.parse, pnull() ); } - | `(` expr `)` - { $$.parse = $2.parse; } - ; - -/* - * cases - action elements inside a 'switch' - * case - a single action element inside a 'switch' - * right-recursive rule so cases can be examined in order. - */ - -cases : /* empty */ - { $$.parse = P0; } - | case cases - { $$.parse = pnode( $1.parse, $2.parse ); } - ; - -case : `case` ARG `:` block - { $$.parse = psnode( $2.string, $4.parse ); } - ; - -/* - * params - optional parameter names to rule definition - * right-recursive rule so that params can be added in order. - */ - -params : /* empty */ - { $$.parse = P0; } - | ARG `:` params - { $$.parse = psnode( $1.string, $3.parse ); } - | ARG - { $$.parse = psnode( $1.string, P0 ); } - ; - -/* - * lol - list of lists - * right-recursive rule so that lists can be added in order. - */ - -lol : list - { $$.parse = pnode( P0, $1.parse ); } - | list `:` lol - { $$.parse = pnode( $3.parse, $1.parse ); } - ; - -/* - * list - zero or more args in a LIST - * listp - list (in puncutation only mode) - * arg - one ARG or function call - */ - -list : listp - { $$.parse = $1.parse; yymode( SCAN_NORMAL ); } - ; - -listp : /* empty */ - { $$.parse = pnull(); yymode( SCAN_PUNCT ); } - | listp arg - { $$.parse = pappend( $1.parse, $2.parse ); } - ; - -arg : ARG - { $$.parse = plist( $1.string ); } - | `[` { yymode( SCAN_NORMAL ); } func `]` - { $$.parse = $3.parse; } - ; - -/* - * func - a function call (inside []) - * This needs to be split cleanly out of 'rule' - */ - -func : arg lol - { $$.parse = prule( $1.parse, $2.parse ); } - | `on` arg arg lol - { $$.parse = pon( $2.parse, prule( $3.parse, $4.parse ) ); } - | `on` arg `return` list - { $$.parse = pon( $2.parse, $4.parse ); } - ; - -/* - * eflags - zero or more modifiers to 'executes' - * eflag - a single modifier to 'executes' - */ - -eflags : /* empty */ - { $$.number = 0; } - | eflags eflag - { $$.number = $1.number | $2.number; } - ; - -eflag : `updated` - { $$.number = RULE_UPDATED; } - | `together` - { $$.number = RULE_TOGETHER; } - | `ignore` - { $$.number = RULE_IGNORE; } - | `quietly` - { $$.number = RULE_QUIETLY; } - | `piecemeal` - { $$.number = RULE_PIECEMEAL; } - | `existing` - { $$.number = RULE_EXISTING; } - | `maxline` ARG - { $$.number = atoi( $2.string ) * RULE_MAXLINE; } - ; - - -/* - * bindlist - list of variable to bind for an action - */ - -bindlist : /* empty */ - { $$.parse = pnull(); } - | `bind` list - { $$.parse = $2.parse; } - ; - - diff --git a/jam-2.5/jamgramtab.h b/jam-2.5/jamgramtab.h deleted file mode 100644 index 6d593a9f7..000000000 --- a/jam-2.5/jamgramtab.h +++ /dev/null @@ -1,45 +0,0 @@ - { "!", _BANG_t }, - { "!=", _BANG_EQUALS_t }, - { "&", _AMPER_t }, - { "&&", _AMPERAMPER_t }, - { "(", _LPAREN_t }, - { ")", _RPAREN_t }, - { "+=", _PLUS_EQUALS_t }, - { ":", _COLON_t }, - { ";", _SEMIC_t }, - { "<", _LANGLE_t }, - { "<=", _LANGLE_EQUALS_t }, - { "=", _EQUALS_t }, - { ">", _RANGLE_t }, - { ">=", _RANGLE_EQUALS_t }, - { "?=", _QUESTION_EQUALS_t }, - { "[", _LBRACKET_t }, - { "]", _RBRACKET_t }, - { "actions", ACTIONS_t }, - { "bind", BIND_t }, - { "break", BREAK_t }, - { "case", CASE_t }, - { "continue", CONTINUE_t }, - { "default", DEFAULT_t }, - { "else", ELSE_t }, - { "existing", EXISTING_t }, - { "for", FOR_t }, - { "if", IF_t }, - { "ignore", IGNORE_t }, - { "in", IN_t }, - { "include", INCLUDE_t }, - { "local", LOCAL_t }, - { "maxline", MAXLINE_t }, - { "on", ON_t }, - { "piecemeal", PIECEMEAL_t }, - { "quietly", QUIETLY_t }, - { "return", RETURN_t }, - { "rule", RULE_t }, - { "switch", SWITCH_t }, - { "together", TOGETHER_t }, - { "updated", UPDATED_t }, - { "while", WHILE_t }, - { "{", _LBRACE_t }, - { "|", _BAR_t }, - { "||", _BARBAR_t }, - { "}", _RBRACE_t }, diff --git a/jam-2.5/lists.c b/jam-2.5/lists.c deleted file mode 100644 index 92f3f9f16..000000000 --- a/jam-2.5/lists.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * lists.c - maintain lists of strings - * - * This implementation essentially uses a singly linked list, but - * guarantees that the head element of every list has a valid pointer - * to the tail of the list, so the new elements can efficiently and - * properly be appended to the end of a list. - * - * To avoid massive allocation, list_free() just tacks the whole freed - * chain onto freelist and list_new() looks on freelist first for an - * available list struct. list_free() does not free the strings in the - * chain: it lazily lets list_new() do so. - * - * 08/23/94 (seiwald) - new list_append() - * 09/07/00 (seiwald) - documented lol_*() functions - * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() - * 11/04/02 (seiwald) - const-ing for string literals - * 12/09/02 (seiwald) - new list_printq() for writing lists to Jambase - */ - -# include "jam.h" -# include "newstr.h" -# include "lists.h" - -static LIST *freelist = 0; /* junkpile for list_free() */ - -/* - * list_append() - append a list onto another one, returning total - */ - -LIST * -list_append( - LIST *l, - LIST *nl ) -{ - if( !nl ) - { - /* Just return l */ - } - else if( !l ) - { - l = nl; - } - else - { - /* Graft two non-empty lists. */ - l->tail->next = nl; - l->tail = nl->tail; - } - - return l; -} - -/* - * list_new() - tack a string onto the end of a list of strings - */ - -LIST * -list_new( - LIST *head, - const char *string, - int copy ) -{ - LIST *l; - - if( DEBUG_LISTS ) - printf( "list > %s <\n", string ); - - /* Copy/newstr as needed */ - - string = copy ? copystr( string ) : newstr( string ); - - /* Get list struct from freelist, if one available. */ - /* Otherwise allocate. */ - /* If from freelist, must free string first */ - - if( freelist ) - { - l = freelist; - freestr( l->string ); - freelist = freelist->next; - } - else - { - l = (LIST *)malloc( sizeof( *l ) ); - } - - /* If first on chain, head points here. */ - /* If adding to chain, tack us on. */ - /* Tail must point to this new, last element. */ - - if( !head ) head = l; - else head->tail->next = l; - head->tail = l; - l->next = 0; - - l->string = string; - - return head; -} - -/* - * list_copy() - copy a whole list of strings (nl) onto end of another (l) - */ - -LIST * -list_copy( - LIST *l, - LIST *nl ) -{ - for( ; nl; nl = list_next( nl ) ) - l = list_new( l, nl->string, 1 ); - - return l; -} - -/* - * list_sublist() - copy a subset of a list of strings - */ - -LIST * -list_sublist( - LIST *l, - int start, - int count ) -{ - LIST *nl = 0; - - for( ; l && start--; l = list_next( l ) ) - ; - - for( ; l && count--; l = list_next( l ) ) - nl = list_new( nl, l->string, 1 ); - - return nl; -} - -/* - * list_free() - free a list of strings - */ - -void -list_free( LIST *head ) -{ - /* Just tack onto freelist. */ - - if( head ) - { - head->tail->next = freelist; - freelist = head; - } -} - -/* - * list_print() - print a list of strings to stdout - */ - -void -list_print( LIST *l ) -{ - for( ; l; l = list_next( l ) ) - printf( "%s ", l->string ); -} - -/* - * list_printq() - print a list of safely quoted strings to a file - */ - -void -list_printq( FILE *out, LIST *l ) -{ - /* Dump each word, enclosed in "s */ - /* Suitable for Jambase use. */ - - for( ; l; l = list_next( l ) ) - { - const char *p = l->string; - const char *ep = p + strlen( p ); - const char *op = p; - - fputc( '\n', out ); - fputc( '\t', out ); - fputc( '"', out ); - - /* Any embedded "'s? Escape them */ - - while( p = (char *)memchr( op, '"', ep - op ) ) - { - fwrite( op, p - op, 1, out ); - fputc( '\\', out ); - fputc( '"', out ); - op = p + 1; - } - - /* Write remainder */ - - fwrite( op, ep - op, 1, out ); - fputc( '"', out ); - fputc( ' ', out ); - } -} - -/* - * list_length() - return the number of items in the list - */ - -int -list_length( LIST *l ) -{ - int n = 0; - - for( ; l; l = list_next( l ), ++n ) - ; - - return n; -} - -/* - * lol_init() - initialize a LOL (list of lists) - */ - -void -lol_init( LOL *lol ) -{ - lol->count = 0; -} - -/* - * lol_add() - append a LIST onto an LOL - */ - -void -lol_add( - LOL *lol, - LIST *l ) -{ - if( lol->count < LOL_MAX ) - lol->list[ lol->count++ ] = l; -} - -/* - * lol_free() - free the LOL and its LISTs - */ - -void -lol_free( LOL *lol ) -{ - int i; - - for( i = 0; i < lol->count; i++ ) - list_free( lol->list[i] ); - - lol->count = 0; -} - -/* - * lol_get() - return one of the LISTs in the LOL - */ - -LIST * -lol_get( - LOL *lol, - int i ) -{ - return i < lol->count ? lol->list[i] : 0; -} - -/* - * lol_print() - debug print LISTS separated by ":" - */ - -void -lol_print( LOL *lol ) -{ - int i; - - for( i = 0; i < lol->count; i++ ) - { - if( i ) - printf( " : " ); - list_print( lol->list[i] ); - } -} diff --git a/jam-2.5/lists.h b/jam-2.5/lists.h deleted file mode 100644 index 0b02d7426..000000000 --- a/jam-2.5/lists.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * lists.h - the LIST structure and routines to manipulate them - * - * The whole of jam relies on lists of strings as a datatype. This - * module, in conjunction with newstr.c, handles these relatively - * efficiently. - * - * Structures defined: - * - * LIST - list of strings - * LOL - list of LISTs - * - * External routines: - * - * list_append() - append a list onto another one, returning total - * list_new() - tack a string onto the end of a list of strings - * list_copy() - copy a whole list of strings - * list_sublist() - copy a subset of a list of strings - * list_free() - free a list of strings - * list_print() - print a list of strings to stdout - * list_printq() - print a list of safely quoted strings to a file - * list_length() - return the number of items in the list - * - * lol_init() - initialize a LOL (list of lists) - * lol_add() - append a LIST onto an LOL - * lol_free() - free the LOL and its LISTs - * lol_get() - return one of the LISTs in the LOL - * lol_print() - debug print LISTS separated by ":" - * - * 04/13/94 (seiwald) - added shorthand L0 for null list pointer - * 08/23/94 (seiwald) - new list_append() - * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() - * 11/04/02 (seiwald) - const-ing for string literals - * 12/09/02 (seiwald) - new list_printq() for writing lists to Jambase - */ - -/* - * LIST - list of strings - */ - -typedef struct _list LIST; - -struct _list { - LIST *next; - LIST *tail; /* only valid in head node */ - const char *string; /* private copy */ -} ; - -/* - * LOL - list of LISTs - */ - -typedef struct _lol LOL; - -# define LOL_MAX 9 - -struct _lol { - int count; - LIST *list[ LOL_MAX ]; -} ; - -LIST * list_append( LIST *l, LIST *nl ); -LIST * list_copy( LIST *l, LIST *nl ); -void list_free( LIST *head ); -LIST * list_new( LIST *head, const char *string, int copy ); -void list_print( LIST *l ); -int list_length( LIST *l ); -LIST * list_sublist( LIST *l, int start, int count ); - -# define list_next( l ) ((l)->next) - -# define L0 ((LIST *)0) - -void lol_add( LOL *lol, LIST *l ); -void lol_init( LOL *lol ); -void lol_free( LOL *lol ); -LIST * lol_get( LOL *lol, int i ); -void lol_print( LOL *lol ); diff --git a/jam-2.5/make.c b/jam-2.5/make.c deleted file mode 100644 index b8cb5fda0..000000000 --- a/jam-2.5/make.c +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * make.c - bring a target up to date, once rules are in place - * - * This modules controls the execution of rules to bring a target and - * its dependencies up to date. It is invoked after the targets, rules, - * et. al. described in rules.h are created by the interpreting of the - * jam files. - * - * This file contains the main make() entry point and the first pass - * make0(). The second pass, make1(), which actually does the command - * execution, is in make1.c. - * - * External routines: - * make() - make a target, given its name - * - * Internal routines: - * make0() - bind and scan everything to make a TARGET - * make0sort() - reorder TARGETS chain by their time (newest to oldest) - * - * 12/26/93 (seiwald) - allow NOTIME targets to be expanded via $(<), $(>) - * 01/04/94 (seiwald) - print all targets, bounded, when tracing commands - * 04/08/94 (seiwald) - progress report now reflects only targets with actions - * 04/11/94 (seiwald) - Combined deps & headers into deps[2] in TARGET. - * 12/20/94 (seiwald) - NOTIME renamed NOTFILE. - * 12/20/94 (seiwald) - make0() headers after determining fate of target, so - * that headers aren't seen as dependents on themselves. - * 01/19/95 (seiwald) - distinguish between CANTFIND/CANTMAKE targets. - * 02/02/95 (seiwald) - propagate leaf source time for new LEAVES rule. - * 02/14/95 (seiwald) - NOUPDATE rule means don't update existing target. - * 08/22/95 (seiwald) - NOUPDATE targets immune to anyhow (-a) flag. - * 09/06/00 (seiwald) - NOCARE affects targets with sources/actions. - * 03/02/01 (seiwald) - reverse NOCARE change. - * 03/14/02 (seiwald) - TEMPORARY targets no longer take on parents age - * 03/16/02 (seiwald) - support for -g (reorder builds by source time) - * 07/17/02 (seiwald) - TEMPORARY sources for headers now get built - * 09/19/02 (seiwald) - new -d displays - * 09/23/02 (seiwald) - suppress "...using temp..." in default output - * 09/28/02 (seiwald) - make0() takes parent pointer; new -dc display - * 11/04/02 (seiwald) - const-ing for string literals - * 12/03/02 (seiwald) - fix odd includes support by grafting them onto depends - * 12/17/02 (seiwald) - new copysettings() to protect target-specific vars - * 01/03/03 (seiwald) - T_FATE_NEWER once again gets set with missing parent - * 01/14/03 (seiwald) - fix includes fix with new internal includes TARGET - * 04/04/03 (seiwald) - fix INTERNAL node binding to avoid T_BIND_PARENTS - */ - -# include "jam.h" - -# include "lists.h" -# include "parse.h" -# include "variable.h" -# include "rules.h" - -# include "search.h" -# include "newstr.h" -# include "make.h" -# include "headers.h" -# include "command.h" - -# ifndef max -# define max( a,b ) ((a)>(b)?(a):(b)) -# endif - -typedef struct { - int temp; - int updating; - int cantfind; - int cantmake; - int targets; - int made; -} COUNTS ; - -static void make0( TARGET *t, TARGET *p, int depth, - COUNTS *counts, int anyhow ); - -static TARGETS *make0sort( TARGETS *c ); - -static const char *target_fate[] = -{ - "init", /* T_FATE_INIT */ - "making", /* T_FATE_MAKING */ - "stable", /* T_FATE_STABLE */ - "newer", /* T_FATE_NEWER */ - "temp", /* T_FATE_ISTMP */ - "touched", /* T_FATE_TOUCHED */ - "missing", /* T_FATE_MISSING */ - "needtmp", /* T_FATE_NEEDTMP */ - "old", /* T_FATE_OUTDATED */ - "update", /* T_FATE_UPDATE */ - "nofind", /* T_FATE_CANTFIND */ - "nomake" /* T_FATE_CANTMAKE */ -} ; - -static const char *target_bind[] = -{ - "unbound", - "missing", - "parents", - "exists", -} ; - -# define spaces(x) ( " " + 16 - ( x > 16 ? 16 : x ) ) - -/* - * make() - make a target, given its name - */ - -int -make( - int n_targets, - const char **targets, - int anyhow ) -{ - int i; - COUNTS counts[1]; - int status = 0; /* 1 if anything fails */ - - memset( (char *)counts, 0, sizeof( *counts ) ); - - for( i = 0; i < n_targets; i++ ) - { - TARGET *t = bindtarget( targets[i] ); - - make0( t, 0, 0, counts, anyhow ); - } - - if( DEBUG_MAKE ) - { - if( counts->targets ) - printf( "...found %d target(s)...\n", counts->targets ); - if( counts->temp ) - printf( "...using %d temp target(s)...\n", counts->temp ); - if( counts->updating ) - printf( "...updating %d target(s)...\n", counts->updating ); - if( counts->cantfind ) - printf( "...can't find %d target(s)...\n", counts->cantfind ); - if( counts->cantmake ) - printf( "...can't make %d target(s)...\n", counts->cantmake ); - } - - status = counts->cantfind || counts->cantmake; - - for( i = 0; i < n_targets; i++ ) - status |= make1( bindtarget( targets[i] ) ); - - return status; -} - -/* - * make0() - bind and scan everything to make a TARGET - * - * Make0() recursively binds a target, searches for #included headers, - * calls itself on those headers, and calls itself on any dependents. - */ - -static void -make0( - TARGET *t, - TARGET *p, /* parent */ - int depth, /* for display purposes */ - COUNTS *counts, /* for reporting */ - int anyhow ) /* forcibly touch all (real) targets */ -{ - TARGETS *c, *d, *incs; - TARGET *ptime = t; - time_t last, leaf, hlast; - int fate; - const char *flag = ""; - SETTINGS *s; - - /* - * Step 1: initialize - */ - - if( DEBUG_MAKEPROG ) - printf( "make\t--\t%s%s\n", spaces( depth ), t->name ); - - t->fate = T_FATE_MAKING; - - /* - * Step 2: under the influence of "on target" variables, - * bind the target and search for headers. - */ - - /* Step 2a: set "on target" variables. */ - - s = copysettings( t->settings ); - pushsettings( s ); - - /* Step 2b: find and timestamp the target file (if it's a file). */ - - if( t->binding == T_BIND_UNBOUND && !( t->flags & T_FLAG_NOTFILE ) ) - { - t->boundname = search( t->name, &t->time ); - t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING; - } - - /* INTERNAL, NOTFILE header nodes have the time of their parents */ - - if( p && t->flags & T_FLAG_INTERNAL ) - ptime = p; - - /* If temp file doesn't exist but parent does, use parent */ - - if( p && t->flags & T_FLAG_TEMP && - t->binding == T_BIND_MISSING && - p->binding != T_BIND_MISSING ) - { - t->binding = T_BIND_PARENTS; - ptime = p; - } - - /* Step 2c: If its a file, search for headers. */ - - if( t->binding == T_BIND_EXISTS ) - headers( t ); - - /* Step 2d: reset "on target" variables */ - - popsettings( s ); - freesettings( s ); - - /* - * Pause for a little progress reporting - */ - - if( DEBUG_MAKEPROG ) - { - if( strcmp( t->name, t->boundname ) ) - { - printf( "bind\t--\t%s%s: %s\n", - spaces( depth ), t->name, t->boundname ); - } - - switch( t->binding ) - { - case T_BIND_UNBOUND: - case T_BIND_MISSING: - case T_BIND_PARENTS: - printf( "time\t--\t%s%s: %s\n", - spaces( depth ), t->name, target_bind[ t->binding ] ); - break; - - case T_BIND_EXISTS: - printf( "time\t--\t%s%s: %s", - spaces( depth ), t->name, ctime( &t->time ) ); - break; - } - } - - /* - * Step 3: recursively make0() dependents & headers - */ - - /* Step 3a: recursively make0() dependents */ - - for( c = t->depends; c; c = c->next ) - { - int internal = t->flags & T_FLAG_INTERNAL; - - if( DEBUG_DEPENDS ) - printf( "%s \"%s\" : \"%s\" ;\n", - internal ? "Includes" : "Depends", - t->name, c->target->name ); - - /* Warn about circular deps, except for includes, */ - /* which include each other alot. */ - - if( c->target->fate == T_FATE_INIT ) - make0( c->target, ptime, depth + 1, counts, anyhow ); - else if( c->target->fate == T_FATE_MAKING && !internal ) - printf( "warning: %s depends on itself\n", c->target->name ); - } - - /* Step 3b: recursively make0() internal includes node */ - - if( t->includes ) - make0( t->includes, p, depth + 1, counts, anyhow ); - - /* Step 3c: add dependents' includes to our direct dependencies */ - - incs = 0; - - for( c = t->depends; c; c = c->next ) - if( c->target->includes ) - incs = targetentry( incs, c->target->includes ); - - t->depends = targetchain( t->depends, incs ); - - /* - * Step 4: compute time & fate - */ - - /* Step 4a: pick up dependents' time and fate */ - - last = 0; - leaf = 0; - fate = T_FATE_STABLE; - - for( c = t->depends; c; c = c->next ) - { - /* If LEAVES has been applied, we only heed the timestamps of */ - /* the leaf source nodes. */ - - leaf = max( leaf, c->target->leaf ); - - if( t->flags & T_FLAG_LEAVES ) - { - last = leaf; - continue; - } - - last = max( last, c->target->time ); - fate = max( fate, c->target->fate ); - } - - /* Step 4b: pick up included headers time */ - - /* - * If a header is newer than a temp source that includes it, - * the temp source will need building. - */ - - hlast = t->includes ? t->includes->time : 0; - - /* Step 4c: handle NOUPDATE oddity */ - - /* - * If a NOUPDATE file exists, make dependents eternally old. - * Don't inherit our fate from our dependents. Decide fate - * based only upon other flags and our binding (done later). - */ - - if( t->flags & T_FLAG_NOUPDATE ) - { - last = 0; - t->time = 0; - fate = T_FATE_STABLE; - } - - /* Step 4d: determine fate: rebuild target or what? */ - - /* - In English: - If can't find or make child, can't make target. - If children changed, make target. - If target missing, make it. - If children newer, make target. - If temp's children newer than parent, make temp. - If temp's headers newer than parent, make temp. - If deliberately touched, make it. - If up-to-date temp file present, use it. - If target newer than non-notfile parent, mark target newer. - Otherwise, stable! - - Note this block runs from least to most stable: - as we make it further down the list, the target's - fate is getting stabler. - */ - - if( fate >= T_FATE_BROKEN ) - { - fate = T_FATE_CANTMAKE; - } - else if( fate >= T_FATE_SPOIL ) - { - fate = T_FATE_UPDATE; - } - else if( t->binding == T_BIND_MISSING ) - { - fate = T_FATE_MISSING; - } - else if( t->binding == T_BIND_EXISTS && last > t->time ) - { - fate = T_FATE_OUTDATED; - } - else if( t->binding == T_BIND_PARENTS && last > p->time ) - { - fate = T_FATE_NEEDTMP; - } - else if( t->binding == T_BIND_PARENTS && hlast > p->time ) - { - fate = T_FATE_NEEDTMP; - } - else if( t->flags & T_FLAG_TOUCHED ) - { - fate = T_FATE_TOUCHED; - } - else if( anyhow && !( t->flags & T_FLAG_NOUPDATE ) ) - { - fate = T_FATE_TOUCHED; - } - else if( t->binding == T_BIND_EXISTS && t->flags & T_FLAG_TEMP ) - { - fate = T_FATE_ISTMP; - } - else if( t->binding == T_BIND_EXISTS && p && - p->binding != T_BIND_UNBOUND && t->time > p->time ) - { - fate = T_FATE_NEWER; - } - else - { - fate = T_FATE_STABLE; - } - - /* Step 4e: handle missing files */ - /* If it's missing and there are no actions to create it, boom. */ - /* If we can't make a target we don't care about, 'sokay */ - /* We could insist that there are updating actions for all missing */ - /* files, but if they have dependents we just pretend it's NOTFILE. */ - - if( fate == T_FATE_MISSING && !t->actions && !t->depends ) - { - if( t->flags & T_FLAG_NOCARE ) - { - fate = T_FATE_STABLE; - } - else - { - printf( "don't know how to make %s\n", t->name ); - - fate = T_FATE_CANTFIND; - } - } - - /* Step 4f: propagate dependents' time & fate. */ - /* Set leaf time to be our time only if this is a leaf. */ - - t->time = max( t->time, last ); - t->leaf = leaf ? leaf : t->time ; - t->fate = fate; - - /* - * Step 5: sort dependents by their update time. - */ - - if( globs.newestfirst ) - t->depends = make0sort( t->depends ); - - /* - * Step 6: a little harmless tabulating for tracing purposes - */ - - /* Don't count or report interal includes nodes. */ - - if( t->flags & T_FLAG_INTERNAL ) - return; - - if( !( ++counts->targets % 1000 ) && DEBUG_MAKE ) - printf( "...patience...\n" ); - - if( fate == T_FATE_ISTMP ) - counts->temp++; - else if( fate == T_FATE_CANTFIND ) - counts->cantfind++; - else if( fate == T_FATE_CANTMAKE && t->actions ) - counts->cantmake++; - else if( fate >= T_FATE_BUILD && fate < T_FATE_BROKEN && t->actions ) - counts->updating++; - - if( !( t->flags & T_FLAG_NOTFILE ) && fate >= T_FATE_SPOIL ) - flag = "+"; - else if( t->binding == T_BIND_EXISTS && p && t->time > p->time ) - flag = "*"; - - if( DEBUG_MAKEPROG ) - printf( "made%s\t%s\t%s%s\n", - flag, target_fate[ t->fate ], - spaces( depth ), t->name ); - - if( DEBUG_CAUSES && - t->fate >= T_FATE_NEWER && - t->fate <= T_FATE_MISSING ) - printf( "%s %s\n", target_fate[ t->fate ], t->name ); -} - -/* - * make0sort() - reorder TARGETS chain by their time (newest to oldest) - */ - -static TARGETS * -make0sort( TARGETS *chain ) -{ - TARGETS *result = 0; - - /* We walk chain, taking each item and inserting it on the */ - /* sorted result, with newest items at the front. This involves */ - /* updating each TARGETS' c->next and c->tail. Note that we */ - /* make c->tail a valid prev pointer for every entry. Normally, */ - /* it is only valid at the head, where prev == tail. Note also */ - /* that while tail is a loop, next ends at the end of the chain. */ - - /* Walk current target list */ - - while( chain ) - { - TARGETS *c = chain; - TARGETS *s = result; - - chain = chain->next; - - /* Find point s in result for c */ - - while( s && s->target->time > c->target->time ) - s = s->next; - - /* Insert c in front of s (might be 0). */ - /* Don't even think of deciphering this. */ - - c->next = s; /* good even if s = 0 */ - if( result == s ) result = c; /* new head of chain? */ - if( !s ) s = result; /* wrap to ensure a next */ - if( result != c ) s->tail->next = c; /* not head? be prev's next */ - c->tail = s->tail; /* take on next's prev */ - s->tail = c; /* make next's prev us */ - } - - return result; -} diff --git a/jam-2.5/make.h b/jam-2.5/make.h deleted file mode 100644 index 9fa0b73d0..000000000 --- a/jam-2.5/make.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * make.h - bring a target up to date, once rules are in place - * - * 11/04/02 (seiwald) - const-ing for string literals - */ - -int make( int n_targets, const char **targets, int anyhow ); -int make1( TARGET *t ); diff --git a/jam-2.5/make1.c b/jam-2.5/make1.c deleted file mode 100644 index b12ca3cef..000000000 --- a/jam-2.5/make1.c +++ /dev/null @@ -1,659 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * make1.c - execute command to bring targets up to date - * - * This module contains make1(), the entry point called by make() to - * recursively decend the dependency graph executing update actions as - * marked by make0(). - * - * External routines: - * - * make1() - execute commands to update a TARGET and all its dependents - * - * Internal routines, the recursive/asynchronous command executors: - * - * make1a() - recursively traverse target tree, calling make1b() - * make1b() - dependents of target built, now build target with make1c() - * make1c() - launch target's next command, call make1b() when done - * make1d() - handle command execution completion and call back make1c() - * - * Internal support routines: - * - * make1cmds() - turn ACTIONS into CMDs, grouping, splitting, etc - * make1list() - turn a list of targets into a LIST, for $(<) and $(>) - * make1settings() - for vars that get bound, build up replacement lists - * make1bind() - bind targets that weren't bound in dependency analysis - * - * 04/16/94 (seiwald) - Split from make.c. - * 04/21/94 (seiwald) - Handle empty "updated" actions. - * 05/04/94 (seiwald) - async multiprocess (-j) support - * 06/01/94 (seiwald) - new 'actions existing' does existing sources - * 12/20/94 (seiwald) - NOTIME renamed NOTFILE. - * 01/19/95 (seiwald) - distinguish between CANTFIND/CANTMAKE targets. - * 01/22/94 (seiwald) - pass per-target JAMSHELL down to execcmd(). - * 02/28/95 (seiwald) - Handle empty "existing" actions. - * 03/10/95 (seiwald) - Fancy counts. - * 02/07/01 (seiwald) - Fix jam -d0 return status. - * 01/21/02 (seiwald) - new -q to quit quickly on build failure - * 02/28/02 (seiwald) - don't delete 'actions updated' targets on failure - * 02/28/02 (seiwald) - merge EXEC_xxx flags in with RULE_xxx - * 07/17/02 (seiwald) - TEMPORARY sources for headers now get built - * 09/23/02 (seiwald) - "...using temp..." only displayed on -da now. - * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() - * 11/04/02 (seiwald) - const-ing for string literals - * 12/03/02 (seiwald) - fix odd includes support by grafting them onto depends - */ - -# include "jam.h" - -# include "lists.h" -# include "parse.h" -# include "variable.h" -# include "rules.h" - -# include "search.h" -# include "newstr.h" -# include "make.h" -# include "command.h" -# include "execcmd.h" - -static void make1a( TARGET *t, TARGET *parent ); -static void make1b( TARGET *t ); -static void make1c( TARGET *t ); -static void make1d( void *closure, int status ); - -static CMD *make1cmds( ACTIONS *a0 ); -static LIST *make1list( LIST *l, TARGETS *targets, int flags ); -static SETTINGS *make1settings( LIST *vars ); -static void make1bind( TARGET *t, int warn ); - -/* Ugly static - it's too hard to carry it through the callbacks. */ - -static struct { - int failed; - int skipped; - int total; - int made; -} counts[1] ; - -/* - * make1() - execute commands to update a TARGET and all its dependents - */ - -static int intr = 0; - -int -make1( TARGET *t ) -{ - memset( (char *)counts, 0, sizeof( *counts ) ); - - /* Recursively make the target and its dependents */ - - make1a( t, (TARGET *)0 ); - - /* Wait for any outstanding commands to finish running. */ - - while( execwait() ) - ; - - /* Talk about it */ - - if( DEBUG_MAKE && counts->failed ) - printf( "...failed updating %d target(s)...\n", counts->failed ); - - if( DEBUG_MAKE && counts->skipped ) - printf( "...skipped %d target(s)...\n", counts->skipped ); - - if( DEBUG_MAKE && counts->made ) - printf( "...updated %d target(s)...\n", counts->made ); - - return counts->total != counts->made; -} - -/* - * make1a() - recursively traverse target tree, calling make1b() - */ - -static void -make1a( - TARGET *t, - TARGET *parent ) -{ - TARGETS *c; - - /* If the parent is the first to try to build this target */ - /* or this target is in the make1c() quagmire, arrange for the */ - /* parent to be notified when this target is built. */ - - if( parent ) - switch( t->progress ) - { - case T_MAKE_INIT: - case T_MAKE_ACTIVE: - case T_MAKE_RUNNING: - t->parents = targetentry( t->parents, parent ); - parent->asynccnt++; - } - - if( t->progress != T_MAKE_INIT ) - return; - - /* Asynccnt counts the dependents preventing this target from */ - /* proceeding to make1b() for actual building. We start off with */ - /* a count of 1 to prevent anything from happening until we can */ - /* call all dependents. This 1 is accounted for when we call */ - /* make1b() ourselves, below. */ - - t->asynccnt = 1; - - /* Recurse on our dependents, manipulating progress to guard */ - /* against circular dependency. */ - - t->progress = T_MAKE_ONSTACK; - - for( c = t->depends; c && !intr; c = c->next ) - make1a( c->target, t ); - - t->progress = T_MAKE_ACTIVE; - - /* Now that all dependents have bumped asynccnt, we now allow */ - /* decrement our reference to asynccnt. */ - - make1b( t ); -} - -/* - * make1b() - dependents of target built, now build target with make1c() - */ - -static void -make1b( TARGET *t ) -{ - TARGETS *c; - const char *failed = "dependents"; - - /* If any dependents are still outstanding, wait until they */ - /* call make1b() to signal their completion. */ - - if( --t->asynccnt ) - return; - - /* Now ready to build target 't'... if dependents built ok. */ - - /* Collect status from dependents */ - - for( c = t->depends; c; c = c->next ) - if( c->target->status > t->status ) - { - failed = c->target->name; - t->status = c->target->status; - } - - /* If actions on deps have failed, bail. */ - /* Otherwise, execute all actions to make target */ - - if( t->status == EXEC_CMD_FAIL && t->actions ) - { - ++counts->skipped; - printf( "...skipped %s for lack of %s...\n", t->name, failed ); - } - - if( t->status == EXEC_CMD_OK ) - switch( t->fate ) - { - case T_FATE_INIT: - case T_FATE_MAKING: - /* shouldn't happen */ - - case T_FATE_STABLE: - case T_FATE_NEWER: - break; - - case T_FATE_CANTFIND: - case T_FATE_CANTMAKE: - t->status = EXEC_CMD_FAIL; - break; - - case T_FATE_ISTMP: - if( DEBUG_MAKEQ ) - printf( "...using %s...\n", t->name ); - break; - - case T_FATE_TOUCHED: - case T_FATE_MISSING: - case T_FATE_NEEDTMP: - case T_FATE_OUTDATED: - case T_FATE_UPDATE: - /* Set "on target" vars, build actions, unset vars */ - /* Set "progress" so that make1c() counts this target among */ - /* the successes/failures. */ - - if( t->actions ) - { - ++counts->total; - - if( DEBUG_MAKE && !( counts->total % 100 ) ) - printf( "...on %dth target...\n", counts->total ); - - pushsettings( t->settings ); - t->cmds = (char *)make1cmds( t->actions ); - popsettings( t->settings ); - - t->progress = T_MAKE_RUNNING; - } - - break; - } - - /* Call make1c() to begin the execution of the chain of commands */ - /* needed to build target. If we're not going to build target */ - /* (because of dependency failures or because no commands need to */ - /* be run) the chain will be empty and make1c() will directly */ - /* signal the completion of target. */ - - make1c( t ); -} - -/* - * make1c() - launch target's next command, call make1b() when done - */ - -static void -make1c( TARGET *t ) -{ - CMD *cmd = (CMD *)t->cmds; - - /* If there are (more) commands to run to build this target */ - /* (and we haven't hit an error running earlier comands) we */ - /* launch the command with execcmd(). */ - - /* If there are no more commands to run, we collect the status */ - /* from all the actions then report our completion to all the */ - /* parents. */ - - if( cmd && t->status == EXEC_CMD_OK ) - { - if( DEBUG_MAKE ) - if( DEBUG_MAKEQ || ! ( cmd->rule->flags & RULE_QUIETLY ) ) - { - printf( "%s ", cmd->rule->name ); - list_print( lol_get( &cmd->args, 0 ) ); - printf( "\n" ); - } - - if( DEBUG_EXEC ) - printf( "%s\n", cmd->buf ); - - if( globs.cmdout ) - fprintf( globs.cmdout, "%s", cmd->buf ); - - if( globs.noexec ) - { - make1d( t, EXEC_CMD_OK ); - } - else - { - fflush( stdout ); - execcmd( cmd->buf, make1d, t, cmd->shell ); - } - } - else - { - TARGETS *c; - ACTIONS *actions; - - /* Collect status from actions, and distribute it as well */ - - for( actions = t->actions; actions; actions = actions->next ) - if( actions->action->status > t->status ) - t->status = actions->action->status; - - for( actions = t->actions; actions; actions = actions->next ) - if( t->status > actions->action->status ) - actions->action->status = t->status; - - /* Tally success/failure for those we tried to update. */ - - if( t->progress == T_MAKE_RUNNING ) - switch( t->status ) - { - case EXEC_CMD_OK: - ++counts->made; - break; - case EXEC_CMD_FAIL: - ++counts->failed; - break; - } - - /* Tell parents dependent has been built */ - - t->progress = T_MAKE_DONE; - - for( c = t->parents; c; c = c->next ) - make1b( c->target ); - } -} - -/* - * make1d() - handle command execution completion and call back make1c() - */ - -static void -make1d( - void *closure, - int status ) -{ - TARGET *t = (TARGET *)closure; - CMD *cmd = (CMD *)t->cmds; - - /* Execcmd() has completed. All we need to do is fiddle with the */ - /* status and signal our completion so make1c() can run the next */ - /* command. On interrupts, we bail heavily. */ - - if( status == EXEC_CMD_FAIL && ( cmd->rule->flags & RULE_IGNORE ) ) - status = EXEC_CMD_OK; - - /* On interrupt, set intr so _everything_ fails */ - - if( status == EXEC_CMD_INTR ) - ++intr; - - if( status == EXEC_CMD_FAIL && DEBUG_MAKE ) - { - /* Print command text on failure */ - - if( !DEBUG_EXEC ) - printf( "%s\n", cmd->buf ); - - printf( "...failed %s ", cmd->rule->name ); - list_print( lol_get( &cmd->args, 0 ) ); - printf( "...\n" ); - - if( globs.quitquick ) ++intr; - } - - /* If the command was interrupted or failed and the target */ - /* is not "precious", remove the targets. */ - /* Precious == 'actions updated' -- the target maintains state. */ - - if( status != EXEC_CMD_OK && !( cmd->rule->flags & RULE_UPDATED ) ) - { - LIST *targets = lol_get( &cmd->args, 0 ); - - for( ; targets; targets = list_next( targets ) ) - if( !unlink( targets->string ) ) - printf( "...removing %s\n", targets->string ); - } - - /* Free this command and call make1c() to move onto next command. */ - - t->status = status; - t->cmds = (char *)cmd_next( cmd ); - - cmd_free( cmd ); - - make1c( t ); -} - -/* - * make1cmds() - turn ACTIONS into CMDs, grouping, splitting, etc - * - * Essentially copies a chain of ACTIONs to a chain of CMDs, - * grouping RULE_TOGETHER actions, splitting RULE_PIECEMEAL actions, - * and handling RULE_UPDATED actions. The result is a chain of - * CMDs which can be expanded by var_string() and executed with - * execcmd(). - */ - -static CMD * -make1cmds( ACTIONS *a0 ) -{ - CMD *cmds = 0; - LIST *shell = var_get( "JAMSHELL" ); /* shell is per-target */ - - /* Step through actions */ - /* Actions may be shared with other targets or grouped with */ - /* RULE_TOGETHER, so actions already seen are skipped. */ - - for( ; a0; a0 = a0->next ) - { - RULE *rule = a0->action->rule; - SETTINGS *boundvars; - LIST *nt, *ns; - ACTIONS *a1; - CMD *cmd; - int start, chunk, length, maxline; - - /* Only do rules with commands to execute. */ - /* If this action has already been executed, use saved status */ - - if( !rule->actions || a0->action->running ) - continue; - - a0->action->running = 1; - - /* Make LISTS of targets and sources */ - /* If `execute together` has been specified for this rule, tack */ - /* on sources from each instance of this rule for this target. */ - - nt = make1list( L0, a0->action->targets, 0 ); - ns = make1list( L0, a0->action->sources, rule->flags ); - - if( rule->flags & RULE_TOGETHER ) - for( a1 = a0->next; a1; a1 = a1->next ) - if( a1->action->rule == rule && !a1->action->running ) - { - ns = make1list( ns, a1->action->sources, rule->flags ); - a1->action->running = 1; - } - - /* If doing only updated (or existing) sources, but none have */ - /* been updated (or exist), skip this action. */ - - if( !ns && ( rule->flags & ( RULE_UPDATED | RULE_EXISTING ) ) ) - { - list_free( nt ); - continue; - } - - /* If we had 'actions xxx bind vars' we bind the vars now */ - - boundvars = make1settings( rule->bindlist ); - pushsettings( boundvars ); - - /* - * Build command, starting with all source args. - * - * If cmd_new returns 0, it's because the resulting command - * length is > MAXLINE. In this case, we'll slowly reduce - * the number of source arguments presented until it does - * fit. This only applies to actions that allow PIECEMEAL - * commands. - * - * While reducing slowly takes a bit of compute time to get - * things just right, it's worth it to get as close to MAXLINE - * as possible, because launching the commands we're executing - * is likely to be much more compute intensive! - * - * Note we loop through at least once, for sourceless actions. - * - * Max line length is the action specific maxline or, if not - * given or bigger than MAXLINE, MAXLINE. - */ - - start = 0; - chunk = length = list_length( ns ); - maxline = rule->flags / RULE_MAXLINE; - maxline = maxline && maxline < MAXLINE ? maxline : MAXLINE; - - do - { - /* Build cmd: cmd_new consumes its lists. */ - - CMD *cmd = cmd_new( rule, - list_copy( L0, nt ), - list_sublist( ns, start, chunk ), - list_copy( L0, shell ), - maxline ); - - if( cmd ) - { - /* It fit: chain it up. */ - - if( !cmds ) cmds = cmd; - else cmds->tail->next = cmd; - cmds->tail = cmd; - start += chunk; - } - else if( ( rule->flags & RULE_PIECEMEAL ) && chunk > 1 ) - { - /* Reduce chunk size slowly. */ - - chunk = chunk * 9 / 10; - } - else - { - /* Too long and not splittable. */ - - printf( "%s actions too long (max %d)!\n", - rule->name, maxline ); - exit( EXITBAD ); - } - } - while( start < length ); - - /* These were always copied when used. */ - - list_free( nt ); - list_free( ns ); - - /* Free the variables whose values were bound by */ - /* 'actions xxx bind vars' */ - - popsettings( boundvars ); - freesettings( boundvars ); - } - - return cmds; -} - -/* - * make1list() - turn a list of targets into a LIST, for $(<) and $(>) - */ - -static LIST * -make1list( - LIST *l, - TARGETS *targets, - int flags ) -{ - for( ; targets; targets = targets->next ) - { - TARGET *t = targets->target; - - /* Sources to 'actions existing' are never in the dependency */ - /* graph (if they were, they'd get built and 'existing' would */ - /* be superfluous, so throttle warning message about independent */ - /* targets. */ - - if( t->binding == T_BIND_UNBOUND ) - make1bind( t, !( flags & RULE_EXISTING ) ); - - if( ( flags & RULE_EXISTING ) && t->binding != T_BIND_EXISTS ) - continue; - - if( ( flags & RULE_UPDATED ) && t->fate <= T_FATE_STABLE ) - continue; - - /* Prohibit duplicates for RULE_TOGETHER */ - - if( flags & RULE_TOGETHER ) - { - LIST *m; - - for( m = l; m; m = m->next ) - if( !strcmp( m->string, t->boundname ) ) - break; - - if( m ) - continue; - } - - /* Build new list */ - - l = list_new( l, t->boundname, 1 ); - } - - return l; -} - -/* - * make1settings() - for vars that get bound values, build up replacement lists - */ - -static SETTINGS * -make1settings( LIST *vars ) -{ - SETTINGS *settings = 0; - - for( ; vars; vars = list_next( vars ) ) - { - LIST *l = var_get( vars->string ); - LIST *nl = 0; - - for( ; l; l = list_next( l ) ) - { - TARGET *t = bindtarget( l->string ); - - /* Make sure the target is bound, warning if it is not in the */ - /* dependency graph. */ - - if( t->binding == T_BIND_UNBOUND ) - make1bind( t, 1 ); - - /* Build new list */ - - nl = list_new( nl, t->boundname, 1 ); - } - - /* Add to settings chain */ - - settings = addsettings( settings, 0, vars->string, nl ); - } - - return settings; -} - -/* - * make1bind() - bind targets that weren't bound in dependency analysis - * - * Spot the kludge! If a target is not in the dependency tree, it didn't - * get bound by make0(), so we have to do it here. Ugly. - */ - -static void -make1bind( - TARGET *t, - int warn ) -{ - if( t->flags & T_FLAG_NOTFILE ) - return; - - /* Sources to 'actions existing' are never in the dependency */ - /* graph (if they were, they'd get built and 'existing' would */ - /* be superfluous, so throttle warning message about independent */ - /* targets. */ - - if( warn ) - printf( "warning: using independent target %s\n", t->name ); - - pushsettings( t->settings ); - t->boundname = search( t->name, &t->time ); - t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING; - popsettings( t->settings ); -} diff --git a/jam-2.5/mkjambase.c b/jam-2.5/mkjambase.c deleted file mode 100644 index 26224c977..000000000 --- a/jam-2.5/mkjambase.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * mkjambase.c - turn Jambase into a big C structure - * - * Usage: mkjambase jambase.c Jambase ... - * - * Results look like this: - * - * char *jambase[] = { - * "...\n", - * ... - * 0 }; - * - * Handles \'s and "'s specially; knows to delete blank and comment lines. - * - * 11/04/02 (seiwald) - const-ing for string literals - */ - -# include -# include - -main( int argc, char **argv, char **envp ) -{ - char buf[ 1024 ]; - FILE *fin; - FILE *fout; - char *p; - int doDotC = 0; - - if( argc < 3 ) - { - fprintf( stderr, "usage: %s jambase.c Jambase ...\n", argv[0] ); - return -1; - } - - if( !( fout = fopen( argv[1], "w" ) ) ) - { - perror( argv[1] ); - return -1; - } - - /* If the file ends in .c generate a C source file */ - - if( ( p = strrchr( argv[1], '.' ) ) && !strcmp( p, ".c" ) ) - doDotC++; - - /* Now process the files */ - - argc -= 2, argv += 2; - - if( doDotC ) - { - fprintf( fout, "/* Generated by mkjambase from Jambase */\n" ); - fprintf( fout, "const char *jambase[] = {\n" ); - } - - for( ; argc--; argv++ ) - { - if( !( fin = fopen( *argv, "r" ) ) ) - { - perror( *argv ); - return -1; - } - - if( doDotC ) - { - fprintf( fout, "/* %s */\n", *argv ); - } - else - { - fprintf( fout, "### %s ###\n", *argv ); - } - - while( fgets( buf, sizeof( buf ), fin ) ) - { - if( doDotC ) - { - char *p = buf; - - /* Strip leading whitespace. */ - - while( *p == ' ' || *p == '\t' || *p == '\n' ) - p++; - - /* Drop comments and empty lines. */ - - if( *p == '#' || !*p ) - continue; - - /* Copy */ - - putc( '"', fout ); - - for( ; *p && *p != '\n'; p++ ) - switch( *p ) - { - case '\\': putc( '\\', fout ); putc( '\\', fout ); break; - case '"': putc( '\\', fout ); putc( '"', fout ); break; - default: putc( *p, fout ); break; - } - - fprintf( fout, "\\n\",\n" ); - } - else - { - fprintf( fout, "%s", buf ); - } - - } - - fclose( fin ); - } - - if( doDotC ) - fprintf( fout, "0 };\n" ); - - fclose( fout ); - - return 0; -} diff --git a/jam-2.5/newstr.c b/jam-2.5/newstr.c deleted file mode 100644 index c3c2d3bdb..000000000 --- a/jam-2.5/newstr.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * newstr.c - string manipulation routines - * - * To minimize string copying, string creation, copying, and freeing - * is done through newstr. - * - * External functions: - * - * newstr() - return a malloc'ed copy of a string - * copystr() - return a copy of a string previously returned by newstr() - * freestr() - free a string returned by newstr() or copystr() - * donestr() - free string tables - * - * Once a string is passed to newstr(), the returned string is readonly. - * - * This implementation builds a hash table of all strings, so that multiple - * calls of newstr() on the same string allocate memory for the string once. - * Strings are never actually freed. - * - * 11/04/02 (seiwald) - const-ing for string literals - */ - -# include "jam.h" -# include "newstr.h" -# include "hash.h" - -typedef const char *STRING; - -static struct hash *strhash = 0; -static int strtotal = 0; - -/* - * newstr() - return a malloc'ed copy of a string - */ - -const char * -newstr( const char *string ) -{ - STRING str, *s = &str; - - if( !strhash ) - strhash = hashinit( sizeof( STRING ), "strings" ); - - *s = string; - - if( hashenter( strhash, (HASHDATA **)&s ) ) - { - int l = strlen( string ); - char *m = (char *)malloc( l + 1 ); - - if (DEBUG_MEM) - printf("newstr: allocating %d bytes\n", l + 1 ); - - strtotal += l + 1; - memcpy( m, string, l + 1 ); - *s = m; - } - - return *s; -} - -/* - * copystr() - return a copy of a string previously returned by newstr() - */ - -const char * -copystr( const char *s ) -{ - return s; -} - -/* - * freestr() - free a string returned by newstr() or copystr() - */ - -void -freestr( const char *s ) -{ -} - -/* - * donestr() - free string tables - */ - -void -donestr() -{ - hashdone( strhash ); - - if( DEBUG_MEM ) - printf( "%dK in strings\n", strtotal / 1024 ); -} diff --git a/jam-2.5/newstr.h b/jam-2.5/newstr.h deleted file mode 100644 index 87d59a85c..000000000 --- a/jam-2.5/newstr.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * newstr.h - string manipulation routines - * - * 11/04/02 (seiwald) - const-ing for string literals - */ - -const char *newstr( const char *string ); -const char *copystr( const char *s ); -void freestr( const char *s ); -void donestr(); diff --git a/jam-2.5/option.c b/jam-2.5/option.c deleted file mode 100644 index ad3825f19..000000000 --- a/jam-2.5/option.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * option.c - command line option processing - * - * {o >o - * \<>) "Process command line options as defined in . - * Return the number of argv[] elements used up by options, - * or -1 if an invalid option flag was given or an argument - * was supplied for an option that does not require one." - * - * 11/04/02 (seiwald) - const-ing for string literals - */ - -# include "jam.h" -# include "option.h" - -int -getoptions( - int argc, - char **argv, - const char *opts, - option *optv ) -{ - int i; - int optc = N_OPTS; - - memset( (char *)optv, '\0', sizeof( *optv ) * N_OPTS ); - - for( i = 0; i < argc; i++ ) - { - char *arg; - - if( argv[i][0] != '-' || !isalpha( argv[i][1] ) ) - break; - - if( !optc-- ) - { - printf( "too many options (%d max)\n", N_OPTS ); - return -1; - } - - for( arg = &argv[i][1]; *arg; arg++ ) - { - const char *f; - - for( f = opts; *f; f++ ) - if( *f == *arg ) - break; - - if( !*f ) - { - printf( "Invalid option: -%c\n", *arg ); - return -1; - } - - optv->flag = *f; - - if( f[1] != ':' ) - { - optv++->val = "true"; - } - else if( arg[1] ) - { - optv++->val = &arg[1]; - break; - } - else if( ++i < argc ) - { - optv++->val = argv[i]; - break; - } - else - { - printf( "option: -%c needs argument\n", *f ); - return -1; - } - } - } - - return i; -} - -/* - * Name: getoptval() - find an option given its character - */ - -const char * -getoptval( - option *optv, - char opt, - int subopt ) -{ - int i; - - for( i = 0; i < N_OPTS; i++, optv++ ) - if( optv->flag == opt && !subopt-- ) - return optv->val; - - return 0; -} diff --git a/jam-2.5/option.h b/jam-2.5/option.h deleted file mode 100644 index beb461f9e..000000000 --- a/jam-2.5/option.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * option.h - command line option processing - * - * {o >o - * \ -) "Command line option." - * - * 11/04/02 (seiwald) - const-ing for string literals - */ - -typedef struct option -{ - char flag; /* filled in by getoption() */ - const char *val; /* set to random address if true */ -} option; - -# define N_OPTS 256 - -int getoptions( int argc, char **argv, const char *opts, option *optv ); -const char * getoptval( option *optv, char opt, int subopt ); diff --git a/jam-2.5/parse.c b/jam-2.5/parse.c deleted file mode 100644 index 7df64509d..000000000 --- a/jam-2.5/parse.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 1993, 2000 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * parse.c - make and destroy parse trees as driven by the parser - * - * 09/07/00 (seiwald) - ref count on PARSE to avoid freeing when used, - * as per Matt Armstrong. - * 09/11/00 (seiwald) - structure reworked to reflect that (*func)() - * returns a LIST *. - * 10/22/02 (seiwald) - working return/break/continue statements - * 11/04/02 (seiwald) - const-ing for string literals - */ - -# include "jam.h" -# include "lists.h" -# include "parse.h" -# include "scan.h" -# include "newstr.h" - -static PARSE *yypsave; - -void -parse_file( const char *f ) -{ - /* Suspend scan of current file */ - /* and push this new file in the stream */ - - yyfparse(f); - - /* Now parse each block of rules and execute it. */ - /* Execute it outside of the parser so that recursive */ - /* calls to yyrun() work (no recursive yyparse's). */ - - for(;;) - { - LOL l; - PARSE *p; - int jmp = 0; /* JMP_NONE */ - - /* $(<) and $(>) empty in outer scope. */ - - lol_init( &l ); - - /* Filled by yyparse() calling parse_save() */ - - yypsave = 0; - - /* If parse error or empty parse, outta here */ - - if( yyparse() || !( p = yypsave ) ) - break; - - /* Run the parse tree. */ - - list_free( (*(p->func))( p, &l, &jmp ) ); - - parse_free( p ); - } -} - -void -parse_save( PARSE *p ) -{ - yypsave = p; -} - -PARSE * -parse_make( - LIST *(*func)( PARSE *p, LOL *args, int *jmp ), - PARSE *left, - PARSE *right, - PARSE *third, - const char *string, - const char *string1, - int num ) -{ - PARSE *p = (PARSE *)malloc( sizeof( PARSE ) ); - - p->func = func; - p->left = left; - p->right = right; - p->third = third; - p->string = string; - p->string1 = string1; - p->num = num; - p->refs = 1; - - return p; -} - -void -parse_refer( PARSE *p ) -{ - ++p->refs; -} - -void -parse_free( PARSE *p ) -{ - if( --p->refs ) - return; - - if( p->string ) - freestr( p->string ); - if( p->string1 ) - freestr( p->string1 ); - if( p->left ) - parse_free( p->left ); - if( p->right ) - parse_free( p->right ); - if( p->third ) - parse_free( p->third ); - - free( (char *)p ); -} diff --git a/jam-2.5/parse.h b/jam-2.5/parse.h deleted file mode 100644 index 137fa629f..000000000 --- a/jam-2.5/parse.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 1993, 2000 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * parse.h - make and destroy parse trees as driven by the parser - * - * 10/22/02 (seiwald) - working return/break/continue statements - * 11/04/02 (seiwald) - const-ing for string literals - */ - -/* - * parse tree node - */ - -typedef struct _PARSE PARSE; - -struct _PARSE { - LIST *(*func)( PARSE *p, LOL *args, int *jmp ); - PARSE *left; - PARSE *right; - PARSE *third; - const char *string; - const char *string1; - int num; - int refs; -} ; - -void parse_file( const char *f ); -void parse_save( PARSE *p ); - -PARSE * parse_make( - LIST *(*func)( PARSE *p, LOL *args, int *jmp ), - PARSE *left, - PARSE *right, - PARSE *third, - const char *string, - const char *string1, - int num ); - -void parse_refer( PARSE *p ); -void parse_free( PARSE *p ); diff --git a/jam-2.5/patchlevel.h b/jam-2.5/patchlevel.h deleted file mode 100644 index 92abc7598..000000000 --- a/jam-2.5/patchlevel.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Keep JAMVERSYM in sync with VERSION. */ -/* It can be accessed as $(JAMVERSION) in the Jamfile. */ - -#define VERSION "2.5" -#define JAMVERSYM "JAMVERSION=2.5" diff --git a/jam-2.5/pathmac.c b/jam-2.5/pathmac.c deleted file mode 100644 index 40a981f4e..000000000 --- a/jam-2.5/pathmac.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * pathunix.c - manipulate file names on UNIX, NT, OS2 - * - * External routines: - * - * path_parse() - split a file name into dir/base/suffix/member - * path_build() - build a filename given dir/base/suffix/member - * path_parent() - make a PATHNAME point to its parent dir - * - * File_parse() and path_build() just manipuate a string and a structure; - * they do not make system calls. - * - * 04/08/94 (seiwald) - Coherent/386 support added. - * 12/26/93 (seiwald) - handle dir/.suffix properly in path_build() - * 12/19/94 (mikem) - solaris string table insanity support - * 12/21/94 (wingerd) Use backslashes for pathnames - the NT way. - * 02/14/95 (seiwald) - parse and build /xxx properly - * 02/23/95 (wingerd) Compilers on NT can handle "/" in pathnames, so we - * should expect hdr searches to come up with strings - * like "thing/thing.h". So we need to test for "/" as - * well as "\" when parsing pathnames. - * 03/16/95 (seiwald) - fixed accursed typo on line 69. - * 05/03/96 (seiwald) - split from filent.c, fileunix.c - * 12/20/96 (seiwald) - when looking for the rightmost . in a file name, - * don't include the archive member name. - * 01/10/01 (seiwald) - path_parse now strips the trailing : from the - * directory name, unless the directory name is all - * :'s, so that $(d:P) works. - * 11/04/02 (seiwald) - const-ing for string literals - */ - -# include "jam.h" -# include "pathsys.h" - -# ifdef OS_MAC - -# define DELIM ':' - -/* - * path_parse() - split a file name into dir/base/suffix/member - */ - -void -path_parse( - const char *file, - PATHNAME *f ) -{ - const char *p, *q; - const char *end; - - memset( (char *)f, 0, sizeof( *f ) ); - - /* Look for */ - - if( file[0] == '<' && ( p = strchr( file, '>' ) ) ) - { - f->f_grist.ptr = file; - f->f_grist.len = p - file; - file = p + 1; - } - - /* Look for dir: */ - - if( p = strrchr( file, DELIM ) ) - { - f->f_dir.ptr = file; - f->f_dir.len = p - file; - file = p + 1; - - /* All :'s? Include last : as part of directory name */ - - while( p > f->f_dir.ptr && *--p == DELIM ) - ; - - if( p == f->f_dir.ptr ) - f->f_dir.len++; - } - - end = file + strlen( file ); - - /* Look for (member) */ - - if( ( p = strchr( file, '(' ) ) && end[-1] == ')' ) - { - f->f_member.ptr = p + 1; - f->f_member.len = end - p - 2; - end = p; - } - - /* Look for .suffix */ - /* This would be memrchr() */ - - p = 0; - q = file; - - while( q = memchr( q, '.', end - q ) ) - p = q++; - - if( p ) - { - f->f_suffix.ptr = p; - f->f_suffix.len = end - p; - end = p; - } - - /* Leaves base */ - - f->f_base.ptr = file; - f->f_base.len = end - file; -} - -/* - * path_build() - build a filename given dir/base/suffix/member - */ - -# define DIR_EMPTY 0 /* "" */ -# define DIR_DOT 1 /* : */ -# define DIR_DOTDOT 2 /* :: */ -# define DIR_ABS 3 /* dira:dirb: */ -# define DIR_REL 4 /* :dira:dirb: */ - -# define G_DIR 0 /* take dir */ -# define G_ROOT 1 /* take root */ -# define G_CAT 2 /* prepend root to dir */ -# define G_DTDR 3 /* :: of rel dir */ -# define G_DDDD 4 /* make it ::: (../..) */ -# define G_MT 5 /* leave it empty */ - -char grid[5][5] = { -/* EMPTY DOT DOTDOT ABS REL */ -/* EMPTY */ { G_MT, G_DIR, G_DIR, G_DIR, G_DIR }, -/* DOT */ { G_ROOT, G_DIR, G_DIR, G_DIR, G_DIR }, -/* DOTDOT */ { G_ROOT, G_ROOT, G_DDDD, G_DIR, G_DTDR }, -/* ABS */ { G_ROOT, G_ROOT, G_ROOT, G_DIR, G_CAT }, -/* REL */ { G_ROOT, G_ROOT, G_ROOT, G_DIR, G_CAT } -} ; - -static int -file_flags( - const char *ptr, - int len ) -{ - if( !len ) - return DIR_EMPTY; - if( len == 1 && ptr[0] == DELIM ) - return DIR_DOT; - if( len == 2 && ptr[0] == DELIM && ptr[1] == DELIM ) - return DIR_DOTDOT; - if( ptr[0] == DELIM ) - return DIR_REL; - return DIR_ABS; -} - -void -path_build( - PATHNAME *f, - char *file, - int binding ) -{ - char *ofile = file; - int dflag, rflag, act; - - if( DEBUG_SEARCH ) - { - printf("build file: "); - if( f->f_root.len ) - printf( "root = '%.*s' ", f->f_root.len, f->f_root.ptr ); - if( f->f_dir.len ) - printf( "dir = '%.*s' ", f->f_dir.len, f->f_dir.ptr ); - if( f->f_base.len ) - printf( "base = '%.*s' ", f->f_base.len, f->f_base.ptr ); - } - - /* Start with the grist. If the current grist isn't */ - /* surrounded by <>'s, add them. */ - - if( f->f_grist.len ) - { - if( f->f_grist.ptr[0] != '<' ) *file++ = '<'; - memcpy( file, f->f_grist.ptr, f->f_grist.len ); - file += f->f_grist.len; - if( file[-1] != '>' ) *file++ = '>'; - } - - /* Combine root & directory, according to the grid. */ - - dflag = file_flags( f->f_dir.ptr, f->f_dir.len ); - rflag = file_flags( f->f_root.ptr, f->f_root.len ); - - switch( act = grid[ rflag ][ dflag ] ) - { - case G_DTDR: - /* :: of rel dir */ - *file++ = DELIM; - /* fall through */ - - case G_DIR: - /* take dir */ - memcpy( file, f->f_dir.ptr, f->f_dir.len ); - file += f->f_dir.len; - break; - - case G_ROOT: - /* take root */ - memcpy( file, f->f_root.ptr, f->f_root.len ); - file += f->f_root.len; - break; - - case G_CAT: - /* prepend root to dir */ - memcpy( file, f->f_root.ptr, f->f_root.len ); - file += f->f_root.len; - if( file[-1] == DELIM ) --file; - memcpy( file, f->f_dir.ptr, f->f_dir.len ); - file += f->f_dir.len; - break; - - case G_DDDD: - /* make it ::: (../..) */ - strcpy( file, ":::" ); - file += 3; - break; - } - - /* Put : between dir and file (if none already) */ - - if( act != G_MT && - file[-1] != DELIM && - ( f->f_base.len || f->f_suffix.len ) ) - { - *file++ = DELIM; - } - - if( f->f_base.len ) - { - memcpy( file, f->f_base.ptr, f->f_base.len ); - file += f->f_base.len; - } - - if( f->f_suffix.len ) - { - memcpy( file, f->f_suffix.ptr, f->f_suffix.len ); - file += f->f_suffix.len; - } - - if( f->f_member.len ) - { - *file++ = '('; - memcpy( file, f->f_member.ptr, f->f_member.len ); - file += f->f_member.len; - *file++ = ')'; - } - *file = 0; - - if( DEBUG_SEARCH ) - printf(" -> '%s'\n", ofile); -} - -/* - * path_parent() - make a PATHNAME point to its parent dir - */ - -void -path_parent( PATHNAME *f ) -{ - /* just set everything else to nothing */ - - f->f_base.ptr = - f->f_suffix.ptr = - f->f_member.ptr = ""; - - f->f_base.len = - f->f_suffix.len = - f->f_member.len = 0; -} - -# endif /* OS_MAC */ diff --git a/jam-2.5/pathsys.h b/jam-2.5/pathsys.h deleted file mode 100644 index c8c94521a..000000000 --- a/jam-2.5/pathsys.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * pathsys.h - PATHNAME struct - * - * 11/04/02 (seiwald) - const-ing for string literals - */ - -/* - * PATHNAME - a name of a file, broken into dir/base/suffix(member) - * - * is salt to distinguish between targets that otherwise would - * have the same name: it never appears in the bound name of a target. - * (member) is an archive member name: the syntax is arbitrary, but must - * agree in path_parse(), path_build() and the Jambase. - * - * On VMS, we keep track of whether the original path was a directory - * (without a file), so that $(VAR:D) can climb to the parent. - */ - -typedef struct _pathname PATHNAME; -typedef struct _pathpart PATHPART; - -struct _pathpart { - const char *ptr; - int len; -}; - -struct _pathname { - PATHPART part[6]; -# ifdef OS_VMS - int parent; -# endif - -# define f_grist part[0] -# define f_root part[1] -# define f_dir part[2] -# define f_base part[3] -# define f_suffix part[4] -# define f_member part[5] - -} ; - -void path_build( PATHNAME *f, char *file, int binding ); -void path_parse( const char *file, PATHNAME *f ); -void path_parent( PATHNAME *f ); - diff --git a/jam-2.5/pathunix.c b/jam-2.5/pathunix.c deleted file mode 100644 index 5fa09418d..000000000 --- a/jam-2.5/pathunix.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * pathunix.c - manipulate file names on UNIX, NT, OS2, AmigaOS - * - * External routines: - * - * path_parse() - split a file name into dir/base/suffix/member - * path_build() - build a filename given dir/base/suffix/member - * path_parent() - make a PATHNAME point to its parent dir - * - * File_parse() and path_build() just manipuate a string and a structure; - * they do not make system calls. - * - * 04/08/94 (seiwald) - Coherent/386 support added. - * 12/26/93 (seiwald) - handle dir/.suffix properly in path_build() - * 12/19/94 (mikem) - solaris string table insanity support - * 12/21/94 (wingerd) Use backslashes for pathnames - the NT way. - * 02/14/95 (seiwald) - parse and build /xxx properly - * 02/23/95 (wingerd) Compilers on NT can handle "/" in pathnames, so we - * should expect hdr searches to come up with strings - * like "thing/thing.h". So we need to test for "/" as - * well as "\" when parsing pathnames. - * 03/16/95 (seiwald) - fixed accursed typo on line 69. - * 05/03/96 (seiwald) - split from filent.c, fileunix.c - * 12/20/96 (seiwald) - when looking for the rightmost . in a file name, - * don't include the archive member name. - * 01/13/01 (seiwald) - turn off \ handling on UNIX, on by accident - * 11/04/02 (seiwald) - const-ing for string literals - */ - -# include "jam.h" -# include "pathsys.h" - -# ifdef USE_PATHUNIX - -/* - * path_parse() - split a file name into dir/base/suffix/member - */ - -void -path_parse( - const char *file, - PATHNAME *f ) -{ - const char *p, *q; - const char *end; - - memset( (char *)f, 0, sizeof( *f ) ); - - /* Look for */ - - if( file[0] == '<' && ( p = strchr( file, '>' ) ) ) - { - f->f_grist.ptr = file; - f->f_grist.len = p - file; - file = p + 1; - } - - /* Look for dir/ */ - - p = strrchr( file, '/' ); - -# if PATH_DELIM == '\\' - /* On NT, look for dir\ as well */ - { - char *p1 = strrchr( file, '\\' ); - p = p1 > p ? p1 : p; - } -# endif - - if( p ) - { - f->f_dir.ptr = file; - f->f_dir.len = p - file; - - /* Special case for / - dirname is /, not "" */ - - if( !f->f_dir.len ) - f->f_dir.len = 1; - -# if PATH_DELIM == '\\' - /* Special case for D:/ - dirname is D:/, not "D:" */ - - if( f->f_dir.len == 2 && file[1] == ':' ) - f->f_dir.len = 3; -# endif - - file = p + 1; - } - - end = file + strlen( file ); - - /* Look for (member) */ - - if( ( p = strchr( file, '(' ) ) && end[-1] == ')' ) - { - f->f_member.ptr = p + 1; - f->f_member.len = end - p - 2; - end = p; - } - - /* Look for .suffix */ - /* This would be memrchr() */ - - p = 0; - q = file; - - while( q = (char *)memchr( q, '.', end - q ) ) - p = q++; - - if( p ) - { - f->f_suffix.ptr = p; - f->f_suffix.len = end - p; - end = p; - } - - /* Leaves base */ - - f->f_base.ptr = file; - f->f_base.len = end - file; -} - -/* - * path_build() - build a filename given dir/base/suffix/member - */ - -void -path_build( - PATHNAME *f, - char *file, - int binding ) -{ - /* Start with the grist. If the current grist isn't */ - /* surrounded by <>'s, add them. */ - - if( f->f_grist.len ) - { - if( f->f_grist.ptr[0] != '<' ) *file++ = '<'; - memcpy( file, f->f_grist.ptr, f->f_grist.len ); - file += f->f_grist.len; - if( file[-1] != '>' ) *file++ = '>'; - } - - /* Don't prepend root if it's . or directory is rooted */ - -# if PATH_DELIM == '/' - - if( f->f_root.len - && !( f->f_root.len == 1 && f->f_root.ptr[0] == '.' ) - && !( f->f_dir.len && f->f_dir.ptr[0] == '/' ) ) - -# else /* unix */ - - if( f->f_root.len - && !( f->f_root.len == 1 && f->f_root.ptr[0] == '.' ) - && !( f->f_dir.len && f->f_dir.ptr[0] == '/' ) - && !( f->f_dir.len && f->f_dir.ptr[0] == '\\' ) - && !( f->f_dir.len && f->f_dir.ptr[1] == ':' ) ) - -# endif /* unix */ - - { - memcpy( file, f->f_root.ptr, f->f_root.len ); - file += f->f_root.len; - *file++ = PATH_DELIM; - } - - if( f->f_dir.len ) - { - memcpy( file, f->f_dir.ptr, f->f_dir.len ); - file += f->f_dir.len; - } - - /* UNIX: Put / between dir and file */ - /* NT: Put \ between dir and file */ - - if( f->f_dir.len && ( f->f_base.len || f->f_suffix.len ) ) - { - /* UNIX: Special case for dir \ : don't add another \ */ - /* NT: Special case for dir / : don't add another / */ - -# if PATH_DELIM == '\\' - if( !( f->f_dir.len == 3 && f->f_dir.ptr[1] == ':' ) ) -# endif - if( !( f->f_dir.len == 1 && f->f_dir.ptr[0] == PATH_DELIM ) ) - *file++ = PATH_DELIM; - } - - if( f->f_base.len ) - { - memcpy( file, f->f_base.ptr, f->f_base.len ); - file += f->f_base.len; - } - - if( f->f_suffix.len ) - { - memcpy( file, f->f_suffix.ptr, f->f_suffix.len ); - file += f->f_suffix.len; - } - - if( f->f_member.len ) - { - *file++ = '('; - memcpy( file, f->f_member.ptr, f->f_member.len ); - file += f->f_member.len; - *file++ = ')'; - } - *file = 0; -} - -/* - * path_parent() - make a PATHNAME point to its parent dir - */ - -void -path_parent( PATHNAME *f ) -{ - /* just set everything else to nothing */ - - f->f_base.ptr = - f->f_suffix.ptr = - f->f_member.ptr = ""; - - f->f_base.len = - f->f_suffix.len = - f->f_member.len = 0; -} - -# endif /* unix, NT, OS/2, AmigaOS */ diff --git a/jam-2.5/pathvms.c b/jam-2.5/pathvms.c deleted file mode 100644 index 7edcd6a04..000000000 --- a/jam-2.5/pathvms.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * pathvms.c - manipulate file names on VMS - * - * External routines: - * - * path_parse() - split a file name into dir/base/suffix/member - * path_build() - build a filename given dir/base/suffix/member - * path_parent() - make a PATHNAME point to its parent dir - * - * File_parse() and path_build() just manipuate a string and a structure; - * they do not make system calls. - * - * WARNING! This file contains voodoo logic, as black magic is - * necessary for wrangling with VMS file name. Woe be to people - * who mess with this code. - * - * 02/09/95 (seiwald) - bungled R=[xxx] - was using directory length! - * 05/03/96 (seiwald) - split from filevms.c - * 11/04/02 (seiwald) - const-ing for string literals - */ - -# include "jam.h" -# include "pathsys.h" - -# ifdef OS_VMS - -# define DEBUG - -/* - * path_parse() - split a file name into dir/base/suffix/member - */ - -void -path_parse( - const char *file, - PATHNAME *f ) -{ - const char *p, *q; - const char *end; - - memset( (char *)f, 0, sizeof( *f ) ); - - /* Look for */ - - if( file[0] == '<' && ( p = strchr( file, '>' ) ) ) - { - f->f_grist.ptr = file; - f->f_grist.len = p - file; - file = p + 1; - } - - /* Look for dev:[dir] or dev: */ - - if( ( p = strchr( file, ']' ) ) || ( p = strchr( file, ':' ) ) ) - { - f->f_dir.ptr = file; - f->f_dir.len = p + 1 - file; - file = p + 1; - } - - end = file + strlen( file ); - - /* Look for (member) */ - - if( ( p = strchr( file, '(' ) ) && end[-1] == ')' ) - { - f->f_member.ptr = p + 1; - f->f_member.len = end - p - 2; - end = p; - } - - /* Look for .suffix */ - /* This would be memrchr() */ - - p = 0; - q = file; - - while( q = (char *)memchr( q, '.', end - q ) ) - p = q++; - - if( p ) - { - f->f_suffix.ptr = p; - f->f_suffix.len = end - p; - end = p; - } - - /* Leaves base */ - - f->f_base.ptr = file; - f->f_base.len = end - file; - - /* Is this a directory without a file spec? */ - - f->parent = 0; -} - -/* - * dir mods result - * --- --- ------ - * Rerooting: - * - * (none) :R=dev: dev: - * devd: :R=dev: devd: - * devd:[dir] :R=dev: devd:[dir] - * [.dir] :R=dev: dev:[dir] questionable - * [dir] :R=dev: dev:[dir] - * - * (none) :R=[rdir] [rdir] questionable - * devd: :R=[rdir] devd: - * devd:[dir] :R=[rdir] devd:[dir] - * [.dir] :R=[rdir] [rdir.dir] questionable - * [dir] :R=[rdir] [rdir] - * - * (none) :R=dev:[root] dev:[root] - * devd: :R=dev:[root] devd: - * devd:[dir] :R=dev:[root] devd:[dir] - * [.dir] :R=dev:[root] dev:[root.dir] - * [dir] :R=dev:[root] [dir] - * - * Climbing to parent: - * - */ - -# define DIR_EMPTY 0 /* empty string */ -# define DIR_DEV 1 /* dev: */ -# define DIR_DEVDIR 2 /* dev:[dir] */ -# define DIR_DOTDIR 3 /* [.dir] */ -# define DIR_DASHDIR 4 /* [-] or [-.dir] */ -# define DIR_ABSDIR 5 /* [dir] */ -# define DIR_ROOT 6 /* [000000] or dev:[000000] */ - -# define G_DIR 0 /* take just dir */ -# define G_ROOT 1 /* take just root */ -# define G_VAD 2 /* root's dev: + [abs] */ -# define G_DRD 3 /* root's dev:[dir] + [.rel] */ -# define G_VRD 4 /* root's dev: + [.rel] made [abs] */ -# define G_DDD 5 /* root's dev:[dir] + . + [dir] */ - -static int grid[7][7] = { - -/* root/dir EMPTY DEV DEVDIR DOTDIR DASH, ABSDIR ROOT */ -/* EMPTY */ G_DIR, G_DIR, G_DIR, G_DIR, G_DIR, G_DIR, G_DIR, -/* DEV */ G_ROOT, G_DIR, G_DIR, G_VRD, G_VAD, G_VAD, G_VAD, -/* DEVDIR */ G_ROOT, G_DIR, G_DIR, G_DRD, G_VAD, G_VAD, G_VAD, -/* DOTDIR */ G_ROOT, G_DIR, G_DIR, G_DRD, G_DIR, G_DIR, G_DIR, -/* DASHDIR */ G_ROOT, G_DIR, G_DIR, G_DRD, G_DDD, G_DIR, G_DIR, -/* ABSDIR */ G_ROOT, G_DIR, G_DIR, G_DRD, G_DIR, G_DIR, G_DIR, -/* ROOT */ G_ROOT, G_DIR, G_DIR, G_VRD, G_DIR, G_DIR, G_DIR, - -} ; - -struct dirinf { - int flags; - - struct { - char *ptr; - int len; - } dev, dir; -} ; - -static char * -strnchr( - char *buf, - int c, - int len ) -{ - while( len-- ) - if( *buf && *buf++ == c ) - return buf - 1; - - return 0; -} - -static void -dir_flags( - const char *buf, - int len, - struct dirinf *i ) -{ - const char *p; - - if( !buf || !len ) - { - i->flags = DIR_EMPTY; - i->dev.ptr = - i->dir.ptr = 0; - i->dev.len = - i->dir.len = 0; - } - else if( p = strnchr( (char *)buf, ':', len ) ) - { - i->dev.ptr = (char *)buf; - i->dev.len = p + 1 - buf; - i->dir.ptr = (char *)buf + i->dev.len; - i->dir.len = len - i->dev.len; - i->flags = i->dir.len && *i->dir.ptr == '[' ? DIR_DEVDIR : DIR_DEV; - } - else - { - i->dev.ptr = (char *)buf; - i->dev.len = 0; - i->dir.ptr = (char *)buf; - i->dir.len = len; - - if( *buf == '[' && buf[1] == ']' ) - i->flags = DIR_EMPTY; - else if( *buf == '[' && buf[1] == '.' ) - i->flags = DIR_DOTDIR; - else if( *buf == '[' && buf[1] == '-' ) - i->flags = DIR_DASHDIR; - else - i->flags = DIR_ABSDIR; - } - - /* But if its rooted in any way */ - - if( i->dir.len == 8 && !strncmp( i->dir.ptr, "[000000]", 8 ) ) - i->flags = DIR_ROOT; -} - -/* - * path_build() - build a filename given dir/base/suffix/member - */ - -void -path_build( - PATHNAME *f, - char *file, - int binding ) -{ - char *ofile = file; - struct dirinf root, dir; - int g; - - /* Start with the grist. If the current grist isn't */ - /* surrounded by <>'s, add them. */ - - if( f->f_grist.len ) - { - if( f->f_grist.ptr[0] != '<' ) *file++ = '<'; - memcpy( file, f->f_grist.ptr, f->f_grist.len ); - file += f->f_grist.len; - if( file[-1] != '>' ) *file++ = '>'; - } - - /* Get info on root and dir for combining. */ - - dir_flags( f->f_root.ptr, f->f_root.len, &root ); - dir_flags( f->f_dir.ptr, f->f_dir.len, &dir ); - - /* Combine */ - - switch( g = grid[ root.flags ][ dir.flags ] ) - { - case G_DIR: - /* take dir */ - memcpy( file, f->f_dir.ptr, f->f_dir.len ); - file += f->f_dir.len; - break; - - case G_ROOT: - /* take root */ - memcpy( file, f->f_root.ptr, f->f_root.len ); - file += f->f_root.len; - break; - - case G_VAD: - /* root's dev + abs directory */ - memcpy( file, root.dev.ptr, root.dev.len ); - file += root.dev.len; - memcpy( file, dir.dir.ptr, dir.dir.len ); - file += dir.dir.len; - break; - - case G_DRD: - case G_DDD: - /* root's dev:[dir] + rel directory */ - memcpy( file, f->f_root.ptr, f->f_root.len ); - file += f->f_root.len; - - /* sanity checks: root ends with ] */ - - if( file[-1] == ']' ) - --file; - - /* Add . if separating two -'s */ - - if( g == G_DDD ) - *file++ = '.'; - - /* skip [ of dir */ - memcpy( file, dir.dir.ptr + 1, dir.dir.len - 1 ); - file += dir.dir.len - 1; - break; - - case G_VRD: - /* root's dev + rel directory made abs */ - memcpy( file, root.dev.ptr, root.dev.len ); - file += root.dev.len; - *file++ = '['; - /* skip [. of rel dir */ - memcpy( file, dir.dir.ptr + 2, dir.dir.len - 2 ); - file += dir.dir.len - 2; - break; - } - -# ifdef DEBUG - if( DEBUG_SEARCH && ( root.flags || dir.flags ) ) - { - *file = 0; - printf( "%d x %d = %d (%s)\n", root.flags, dir.flags, - grid[ root.flags ][ dir.flags ], ofile ); - } -# endif - - /* - * Now do the special :P modifier when no file was present. - * (none) (none) - * [dir1.dir2] [dir1] - * [dir] [000000] - * [.dir] [] - * [] [] - */ - - if( file[-1] == ']' && f->parent ) - { - while( file-- > ofile ) - { - if( *file == '.' ) - { - *file++ = ']'; - break; - } - else if( *file == '-' ) - { - /* handle .- or - */ - if( file > ofile && file[-1] == '.' ) - --file; - *file++ = ']'; - break; - } - else if( *file == '[' ) - { - if( file[1] == ']' ) - { - file += 2; - } - else - { - strcpy( file, "[000000]" ); - file += 8; - } - break; - } - } - } - - /* Now copy the file pieces. */ - - if( f->f_base.len ) - { - memcpy( file, f->f_base.ptr, f->f_base.len ); - file += f->f_base.len; - } - - /* If there is no suffix, we append a "." onto all generated */ - /* names. This keeps VMS from appending its own (wrong) idea */ - /* of what the suffix should be. */ - - if( f->f_suffix.len ) - { - memcpy( file, f->f_suffix.ptr, f->f_suffix.len ); - file += f->f_suffix.len; - } - else if( binding && f->f_base.len ) - { - *file++ = '.'; - } - - if( f->f_member.len ) - { - *file++ = '('; - memcpy( file, f->f_member.ptr, f->f_member.len ); - file += f->f_member.len; - *file++ = ')'; - } - *file = 0; - -# ifdef DEBUG - if( DEBUG_SEARCH ) - printf("built %.*s + %.*s / %.*s suf %.*s mem %.*s -> %s\n", - f->f_root.len, f->f_root.ptr, - f->f_dir.len, f->f_dir.ptr, - f->f_base.len, f->f_base.ptr, - f->f_suffix.len, f->f_suffix.ptr, - f->f_member.len, f->f_member.ptr, - ofile ); -# endif -} - -/* - * path_parent() - make a PATHNAME point to its parent dir - */ - -void -path_parent( PATHNAME *f ) -{ - if( f->f_base.len ) - { - f->f_base.ptr = - f->f_suffix.ptr = - f->f_member.ptr = ""; - - f->f_base.len = - f->f_suffix.len = - f->f_member.len = 0; - } - else - { - f->parent = 1; - } -} - -# endif /* VMS */ diff --git a/jam-2.5/regexp.c b/jam-2.5/regexp.c deleted file mode 100644 index a1fcc181d..000000000 --- a/jam-2.5/regexp.c +++ /dev/null @@ -1,1325 +0,0 @@ -/* - * regcomp and regexec -- regsub and regerror are elsewhere - * - * Copyright (c) 1986 by University of Toronto. - * Written by Henry Spencer. Not derived from licensed software. - * - * Permission is granted to anyone to use this software for any - * purpose on any computer system, and to redistribute it freely, - * subject to the following restrictions: - * - * 1. The author is not responsible for the consequences of use of - * this software, no matter how awful, even if they arise - * from defects in it. - * - * 2. The origin of this software must not be misrepresented, either - * by explicit claim or by omission. - * - * 3. Altered versions must be plainly marked as such, and must not - * be misrepresented as being the original software. - *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore, - *** hoptoad!gnu, on 27 Dec 1986, to add \n as an alternative to | - *** to assist in implementing egrep. - *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore, - *** hoptoad!gnu, on 27 Dec 1986, to add \< and \> for word-matching - *** as in BSD grep and ex. - *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore, - *** hoptoad!gnu, on 28 Dec 1986, to optimize characters quoted with \. - *** THIS IS AN ALTERED VERSION. It was altered by James A. Woods, - *** ames!jaw, on 19 June 1987, to quash a regcomp() redundancy. - *** THIS IS AN ALTERED VERSION. It was altered by Christopher Seiwald - *** seiwald@vix.com, on 28 August 1993, for use in jam. Regmagic.h - *** was moved into regexp.h, and the include of regexp.h now uses "'s - *** to avoid conflicting with the system regexp.h. Const, bless its - *** soul, was removed so it can compile everywhere. The declaration - *** of strchr() was in conflict on AIX, so it was removed (as it is - *** happily defined in string.h). - *** THIS IS AN ALTERED VERSION. It was altered by Christopher Seiwald - *** seiwald@perforce.com, on 20 January 2000, to use function prototypes. - *** THIS IS AN ALTERED VERSION. It was altered by Christopher Seiwald - *** seiwald@perforce.com, on 05 November 2002, to const string literals. - * - * Beware that some of this code is subtly aware of the way operator - * precedence is structured in regular expressions. Serious changes in - * regular-expression syntax might require a total rethink. - */ -#include "regexp.h" -#include -#include -#ifndef ultrix -#include -#endif -#include - -/* - * The "internal use only" fields in regexp.h are present to pass info from - * compile to execute that permits the execute phase to run lots faster on - * simple cases. They are: - * - * regstart char that must begin a match; '\0' if none obvious - * reganch is the match anchored (at beginning-of-line only)? - * regmust string (pointer into program) that match must include, or NULL - * regmlen length of regmust string - * - * Regstart and reganch permit very fast decisions on suitable starting points - * for a match, cutting down the work a lot. Regmust permits fast rejection - * of lines that cannot possibly match. The regmust tests are costly enough - * that regcomp() supplies a regmust only if the r.e. contains something - * potentially expensive (at present, the only such thing detected is * or + - * at the start of the r.e., which can involve a lot of backup). Regmlen is - * supplied because the test in regexec() needs it and regcomp() is computing - * it anyway. - */ - -/* - * Structure for regexp "program". This is essentially a linear encoding - * of a nondeterministic finite-state machine (aka syntax charts or - * "railroad normal form" in parsing technology). Each node is an opcode - * plus a "next" pointer, possibly plus an operand. "Next" pointers of - * all nodes except BRANCH implement concatenation; a "next" pointer with - * a BRANCH on both ends of it is connecting two alternatives. (Here we - * have one of the subtle syntax dependencies: an individual BRANCH (as - * opposed to a collection of them) is never concatenated with anything - * because of operator precedence.) The operand of some types of node is - * a literal string; for others, it is a node leading into a sub-FSM. In - * particular, the operand of a BRANCH node is the first node of the branch. - * (NB this is *not* a tree structure: the tail of the branch connects - * to the thing following the set of BRANCHes.) The opcodes are: - */ - -/* definition number opnd? meaning */ -#define END 0 /* no End of program. */ -#define BOL 1 /* no Match "" at beginning of line. */ -#define EOL 2 /* no Match "" at end of line. */ -#define ANY 3 /* no Match any one character. */ -#define ANYOF 4 /* str Match any character in this string. */ -#define ANYBUT 5 /* str Match any character not in this string. */ -#define BRANCH 6 /* node Match this alternative, or the next... */ -#define BACK 7 /* no Match "", "next" ptr points backward. */ -#define EXACTLY 8 /* str Match this string. */ -#define NOTHING 9 /* no Match empty string. */ -#define STAR 10 /* node Match this (simple) thing 0 or more times. */ -#define PLUS 11 /* node Match this (simple) thing 1 or more times. */ -#define WORDA 12 /* no Match "" at wordchar, where prev is nonword */ -#define WORDZ 13 /* no Match "" at nonwordchar, where prev is word */ -#define OPEN 20 /* no Mark this point in input as start of #n. */ - /* OPEN+1 is number 1, etc. */ -#define CLOSE 30 /* no Analogous to OPEN. */ - -/* - * Opcode notes: - * - * BRANCH The set of branches constituting a single choice are hooked - * together with their "next" pointers, since precedence prevents - * anything being concatenated to any individual branch. The - * "next" pointer of the last BRANCH in a choice points to the - * thing following the whole choice. This is also where the - * final "next" pointer of each individual branch points; each - * branch starts with the operand node of a BRANCH node. - * - * BACK Normal "next" pointers all implicitly point forward; BACK - * exists to make loop structures possible. - * - * STAR,PLUS '?', and complex '*' and '+', are implemented as circular - * BRANCH structures using BACK. Simple cases (one character - * per match) are implemented with STAR and PLUS for speed - * and to minimize recursive plunges. - * - * OPEN,CLOSE ...are numbered at compile time. - */ - -/* - * A node is one char of opcode followed by two chars of "next" pointer. - * "Next" pointers are stored as two 8-bit pieces, high order first. The - * value is a positive offset from the opcode of the node containing it. - * An operand, if any, simply follows the node. (Note that much of the - * code generation knows about this implicit relationship.) - * - * Using two bytes for the "next" pointer is vast overkill for most things, - * but allows patterns to get big without disasters. - */ -#define OP(p) (*(p)) -#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377)) -#define OPERAND(p) ((p) + 3) - -/* - * See regmagic.h for one further detail of program structure. - */ - - -/* - * Utility definitions. - */ -#ifndef CHARBITS -#define UCHARAT(p) ((int)*(unsigned char *)(p)) -#else -#define UCHARAT(p) ((int)*(p)&CHARBITS) -#endif - -#define FAIL(m) { regerror(m); return(NULL); } -#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?') - -/* - * Flags to be passed up and down. - */ -#define HASWIDTH 01 /* Known never to match null string. */ -#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */ -#define SPSTART 04 /* Starts with * or +. */ -#define WORST 0 /* Worst case. */ - -/* - * Global work variables for regcomp(). - */ -static char *regparse; /* Input-scan pointer. */ -static int regnpar; /* () count. */ -static char regdummy; -static char *regcode; /* Code-emit pointer; ®dummy = don't. */ -static long regsize; /* Code size. */ - -/* - * Forward declarations for regcomp()'s friends. - */ -#ifndef STATIC -#define STATIC static -#endif -STATIC char *reg( int paren, int *flagp ); -STATIC char *regbranch( int *flagp ); -STATIC char *regpiece( int *flagp ); -STATIC char *regatom( int *flagp ); -STATIC char *regnode( int op ); -STATIC char *regnext( register char *p ); -STATIC void regc( int b ); -STATIC void reginsert( char op, char *opnd ); -STATIC void regtail( char *p, char *val ); -STATIC void regoptail( char *p, char *val ); -#ifdef STRCSPN -STATIC int strcspn(); -#endif - -/* - - regcomp - compile a regular expression into internal code - * - * We can't allocate space until we know how big the compiled form will be, - * but we can't compile it (and thus know how big it is) until we've got a - * place to put the code. So we cheat: we compile it twice, once with code - * generation turned off and size counting turned on, and once "for real". - * This also means that we don't allocate space until we are sure that the - * thing really will compile successfully, and we never have to move the - * code and thus invalidate pointers into it. (Note that it has to be in - * one piece because free() must be able to free it all.) - * - * Beware that the optimization-preparation code in here knows about some - * of the structure of the compiled regexp. - */ -regexp * -regcomp( const char *exp ) -{ - register regexp *r; - register char *scan; - register char *longest; - register unsigned len; - int flags; - - if (exp == NULL) - FAIL("NULL argument"); - - /* First pass: determine size, legality. */ -#ifdef notdef - if (exp[0] == '.' && exp[1] == '*') exp += 2; /* aid grep */ -#endif - regparse = (char *)exp; - regnpar = 1; - regsize = 0L; - regcode = ®dummy; - regc(MAGIC); - if (reg(0, &flags) == NULL) - return(NULL); - - /* Small enough for pointer-storage convention? */ - if (regsize >= 32767L) /* Probably could be 65535L. */ - FAIL("regexp too big"); - - /* Allocate space. */ - r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize); - if (r == NULL) - FAIL("out of space"); - - /* Second pass: emit code. */ - regparse = (char *)exp; - regnpar = 1; - regcode = r->program; - regc(MAGIC); - if (reg(0, &flags) == NULL) - return(NULL); - - /* Dig out information for optimizations. */ - r->regstart = '\0'; /* Worst-case defaults. */ - r->reganch = 0; - r->regmust = NULL; - r->regmlen = 0; - scan = r->program+1; /* First BRANCH. */ - if (OP(regnext(scan)) == END) { /* Only one top-level choice. */ - scan = OPERAND(scan); - - /* Starting-point info. */ - if (OP(scan) == EXACTLY) - r->regstart = *OPERAND(scan); - else if (OP(scan) == BOL) - r->reganch++; - - /* - * If there's something expensive in the r.e., find the - * longest literal string that must appear and make it the - * regmust. Resolve ties in favor of later strings, since - * the regstart check works with the beginning of the r.e. - * and avoiding duplication strengthens checking. Not a - * strong reason, but sufficient in the absence of others. - */ - if (flags&SPSTART) { - longest = NULL; - len = 0; - for (; scan != NULL; scan = regnext(scan)) - if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) { - longest = OPERAND(scan); - len = strlen(OPERAND(scan)); - } - r->regmust = longest; - r->regmlen = len; - } - } - - return(r); -} - -/* - - reg - regular expression, i.e. main body or parenthesized thing - * - * Caller must absorb opening parenthesis. - * - * Combining parenthesis handling with the base level of regular expression - * is a trifle forced, but the need to tie the tails of the branches to what - * follows makes it hard to avoid. - */ -static char * -reg( - int paren, /* Parenthesized? */ - int *flagp ) -{ - register char *ret; - register char *br; - register char *ender; - register int parno; - int flags; - - *flagp = HASWIDTH; /* Tentatively. */ - - /* Make an OPEN node, if parenthesized. */ - if (paren) { - if (regnpar >= NSUBEXP) - FAIL("too many ()"); - parno = regnpar; - regnpar++; - ret = regnode(OPEN+parno); - } else - ret = NULL; - - /* Pick up the branches, linking them together. */ - br = regbranch(&flags); - if (br == NULL) - return(NULL); - if (ret != NULL) - regtail(ret, br); /* OPEN -> first. */ - else - ret = br; - if (!(flags&HASWIDTH)) - *flagp &= ~HASWIDTH; - *flagp |= flags&SPSTART; - while (*regparse == '|' || *regparse == '\n') { - regparse++; - br = regbranch(&flags); - if (br == NULL) - return(NULL); - regtail(ret, br); /* BRANCH -> BRANCH. */ - if (!(flags&HASWIDTH)) - *flagp &= ~HASWIDTH; - *flagp |= flags&SPSTART; - } - - /* Make a closing node, and hook it on the end. */ - ender = regnode((paren) ? CLOSE+parno : END); - regtail(ret, ender); - - /* Hook the tails of the branches to the closing node. */ - for (br = ret; br != NULL; br = regnext(br)) - regoptail(br, ender); - - /* Check for proper termination. */ - if (paren && *regparse++ != ')') { - FAIL("unmatched ()"); - } else if (!paren && *regparse != '\0') { - if (*regparse == ')') { - FAIL("unmatched ()"); - } else - FAIL("junk on end"); /* "Can't happen". */ - /* NOTREACHED */ - } - - return(ret); -} - -/* - - regbranch - one alternative of an | operator - * - * Implements the concatenation operator. - */ -static char * -regbranch( int *flagp ) -{ - register char *ret; - register char *chain; - register char *latest; - int flags; - - *flagp = WORST; /* Tentatively. */ - - ret = regnode(BRANCH); - chain = NULL; - while (*regparse != '\0' && *regparse != ')' && - *regparse != '\n' && *regparse != '|') { - latest = regpiece(&flags); - if (latest == NULL) - return(NULL); - *flagp |= flags&HASWIDTH; - if (chain == NULL) /* First piece. */ - *flagp |= flags&SPSTART; - else - regtail(chain, latest); - chain = latest; - } - if (chain == NULL) /* Loop ran zero times. */ - (void) regnode(NOTHING); - - return(ret); -} - -/* - - regpiece - something followed by possible [*+?] - * - * Note that the branching code sequences used for ? and the general cases - * of * and + are somewhat optimized: they use the same NOTHING node as - * both the endmarker for their branch list and the body of the last branch. - * It might seem that this node could be dispensed with entirely, but the - * endmarker role is not redundant. - */ -static char * -regpiece( int *flagp ) -{ - register char *ret; - register char op; - register char *next; - int flags; - - ret = regatom(&flags); - if (ret == NULL) - return(NULL); - - op = *regparse; - if (!ISMULT(op)) { - *flagp = flags; - return(ret); - } - - if (!(flags&HASWIDTH) && op != '?') - FAIL("*+ operand could be empty"); - *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH); - - if (op == '*' && (flags&SIMPLE)) - reginsert(STAR, ret); - else if (op == '*') { - /* Emit x* as (x&|), where & means "self". */ - reginsert(BRANCH, ret); /* Either x */ - regoptail(ret, regnode(BACK)); /* and loop */ - regoptail(ret, ret); /* back */ - regtail(ret, regnode(BRANCH)); /* or */ - regtail(ret, regnode(NOTHING)); /* null. */ - } else if (op == '+' && (flags&SIMPLE)) - reginsert(PLUS, ret); - else if (op == '+') { - /* Emit x+ as x(&|), where & means "self". */ - next = regnode(BRANCH); /* Either */ - regtail(ret, next); - regtail(regnode(BACK), ret); /* loop back */ - regtail(next, regnode(BRANCH)); /* or */ - regtail(ret, regnode(NOTHING)); /* null. */ - } else if (op == '?') { - /* Emit x? as (x|) */ - reginsert(BRANCH, ret); /* Either x */ - regtail(ret, regnode(BRANCH)); /* or */ - next = regnode(NOTHING); /* null. */ - regtail(ret, next); - regoptail(ret, next); - } - regparse++; - if (ISMULT(*regparse)) - FAIL("nested *?+"); - - return(ret); -} - -/* - - regatom - the lowest level - * - * Optimization: gobbles an entire sequence of ordinary characters so that - * it can turn them into a single node, which is smaller to store and - * faster to run. Backslashed characters are exceptions, each becoming a - * separate node; the code is simpler that way and it's not worth fixing. - */ -static char * -regatom( int *flagp ) -{ - register char *ret; - int flags; - - *flagp = WORST; /* Tentatively. */ - - switch (*regparse++) { - /* FIXME: these chars only have meaning at beg/end of pat? */ - case '^': - ret = regnode(BOL); - break; - case '$': - ret = regnode(EOL); - break; - case '.': - ret = regnode(ANY); - *flagp |= HASWIDTH|SIMPLE; - break; - case '[': { - register int classr; - register int classend; - - if (*regparse == '^') { /* Complement of range. */ - ret = regnode(ANYBUT); - regparse++; - } else - ret = regnode(ANYOF); - if (*regparse == ']' || *regparse == '-') - regc(*regparse++); - while (*regparse != '\0' && *regparse != ']') { - if (*regparse == '-') { - regparse++; - if (*regparse == ']' || *regparse == '\0') - regc('-'); - else { - classr = UCHARAT(regparse-2)+1; - classend = UCHARAT(regparse); - if (classr > classend+1) - FAIL("invalid [] range"); - for (; classr <= classend; classr++) - regc(classr); - regparse++; - } - } else - regc(*regparse++); - } - regc('\0'); - if (*regparse != ']') - FAIL("unmatched []"); - regparse++; - *flagp |= HASWIDTH|SIMPLE; - } - break; - case '(': - ret = reg(1, &flags); - if (ret == NULL) - return(NULL); - *flagp |= flags&(HASWIDTH|SPSTART); - break; - case '\0': - case '|': - case '\n': - case ')': - FAIL("internal urp"); /* Supposed to be caught earlier. */ - break; - case '?': - case '+': - case '*': - FAIL("?+* follows nothing"); - break; - case '\\': - switch (*regparse++) { - case '\0': - FAIL("trailing \\"); - break; - case '<': - ret = regnode(WORDA); - break; - case '>': - ret = regnode(WORDZ); - break; - /* FIXME: Someday handle \1, \2, ... */ - default: - /* Handle general quoted chars in exact-match routine */ - goto de_fault; - } - break; - de_fault: - default: - /* - * Encode a string of characters to be matched exactly. - * - * This is a bit tricky due to quoted chars and due to - * '*', '+', and '?' taking the SINGLE char previous - * as their operand. - * - * On entry, the char at regparse[-1] is going to go - * into the string, no matter what it is. (It could be - * following a \ if we are entered from the '\' case.) - * - * Basic idea is to pick up a good char in ch and - * examine the next char. If it's *+? then we twiddle. - * If it's \ then we frozzle. If it's other magic char - * we push ch and terminate the string. If none of the - * above, we push ch on the string and go around again. - * - * regprev is used to remember where "the current char" - * starts in the string, if due to a *+? we need to back - * up and put the current char in a separate, 1-char, string. - * When regprev is NULL, ch is the only char in the - * string; this is used in *+? handling, and in setting - * flags |= SIMPLE at the end. - */ - { - char *regprev; - register char ch; - - regparse--; /* Look at cur char */ - ret = regnode(EXACTLY); - for ( regprev = 0 ; ; ) { - ch = *regparse++; /* Get current char */ - switch (*regparse) { /* look at next one */ - - default: - regc(ch); /* Add cur to string */ - break; - - case '.': case '[': case '(': - case ')': case '|': case '\n': - case '$': case '^': - case '\0': - /* FIXME, $ and ^ should not always be magic */ - magic: - regc(ch); /* dump cur char */ - goto done; /* and we are done */ - - case '?': case '+': case '*': - if (!regprev) /* If just ch in str, */ - goto magic; /* use it */ - /* End mult-char string one early */ - regparse = regprev; /* Back up parse */ - goto done; - - case '\\': - regc(ch); /* Cur char OK */ - switch (regparse[1]){ /* Look after \ */ - case '\0': - case '<': - case '>': - /* FIXME: Someday handle \1, \2, ... */ - goto done; /* Not quoted */ - default: - /* Backup point is \, scan * point is after it. */ - regprev = regparse; - regparse++; - continue; /* NOT break; */ - } - } - regprev = regparse; /* Set backup point */ - } - done: - regc('\0'); - *flagp |= HASWIDTH; - if (!regprev) /* One char? */ - *flagp |= SIMPLE; - } - break; - } - - return(ret); -} - -/* - - regnode - emit a node - */ -static char * /* Location. */ -regnode( int op ) -{ - register char *ret; - register char *ptr; - - ret = regcode; - if (ret == ®dummy) { - regsize += 3; - return(ret); - } - - ptr = ret; - *ptr++ = op; - *ptr++ = '\0'; /* Null "next" pointer. */ - *ptr++ = '\0'; - regcode = ptr; - - return(ret); -} - -/* - - regc - emit (if appropriate) a byte of code - */ -static void -regc( int b ) -{ - if (regcode != ®dummy) - *regcode++ = b; - else - regsize++; -} - -/* - - reginsert - insert an operator in front of already-emitted operand - * - * Means relocating the operand. - */ -static void -reginsert( - char op, - char *opnd ) -{ - register char *src; - register char *dst; - register char *place; - - if (regcode == ®dummy) { - regsize += 3; - return; - } - - src = regcode; - regcode += 3; - dst = regcode; - while (src > opnd) - *--dst = *--src; - - place = opnd; /* Op node, where operand used to be. */ - *place++ = op; - *place++ = '\0'; - *place++ = '\0'; -} - -/* - - regtail - set the next-pointer at the end of a node chain - */ -static void -regtail( - char *p, - char *val ) -{ - register char *scan; - register char *temp; - register int offset; - - if (p == ®dummy) - return; - - /* Find last node. */ - scan = p; - for (;;) { - temp = regnext(scan); - if (temp == NULL) - break; - scan = temp; - } - - if (OP(scan) == BACK) - offset = scan - val; - else - offset = val - scan; - *(scan+1) = (offset>>8)&0377; - *(scan+2) = offset&0377; -} - -/* - - regoptail - regtail on operand of first argument; nop if operandless - */ - -static void -regoptail( - char *p, - char *val ) -{ - /* "Operandless" and "op != BRANCH" are synonymous in practice. */ - if (p == NULL || p == ®dummy || OP(p) != BRANCH) - return; - regtail(OPERAND(p), val); -} - -/* - * regexec and friends - */ - -/* - * Global work variables for regexec(). - */ -static const char *reginput; /* String-input pointer. */ -static char *regbol; /* Beginning of input, for ^ check. */ -static const char **regstartp; /* Pointer to startp array. */ -static const char **regendp; /* Ditto for endp. */ - -/* - * Forwards. - */ -STATIC int regtry( regexp *prog, const char *string ); -STATIC int regmatch( char *prog ); -STATIC int regrepeat( char *p ); - -#ifdef DEBUG -int regnarrate = 0; -void regdump(); -STATIC char *regprop(); -#endif - -/* - - regexec - match a regexp against a string - */ -int -regexec( - register regexp *prog, - register const char *string ) -{ - register char *s; - - /* Be paranoid... */ - if (prog == NULL || string == NULL) { - regerror("NULL parameter"); - return(0); - } - - /* Check validity of program. */ - if (UCHARAT(prog->program) != MAGIC) { - regerror("corrupted program"); - return(0); - } - - /* If there is a "must appear" string, look for it. */ - if (prog->regmust != NULL) { - s = (char *)string; - while ((s = strchr(s, prog->regmust[0])) != NULL) { - if (strncmp(s, prog->regmust, prog->regmlen) == 0) - break; /* Found it. */ - s++; - } - if (s == NULL) /* Not present. */ - return(0); - } - - /* Mark beginning of line for ^ . */ - regbol = (char *)string; - - /* Simplest case: anchored match need be tried only once. */ - if (prog->reganch) - return(regtry(prog, string)); - - /* Messy cases: unanchored match. */ - s = (char *)string; - if (prog->regstart != '\0') - /* We know what char it must start with. */ - while ((s = strchr(s, prog->regstart)) != NULL) { - if (regtry(prog, s)) - return(1); - s++; - } - else - /* We don't -- general case. */ - do { - if (regtry(prog, s)) - return(1); - } while (*s++ != '\0'); - - /* Failure. */ - return(0); -} - -/* - - regtry - try match at specific point - */ -static int /* 0 failure, 1 success */ -regtry( - regexp *prog, - const char *string ) -{ - register int i; - register const char **sp; - register const char **ep; - - reginput = string; - regstartp = prog->startp; - regendp = prog->endp; - - sp = prog->startp; - ep = prog->endp; - for (i = NSUBEXP; i > 0; i--) { - *sp++ = NULL; - *ep++ = NULL; - } - if (regmatch(prog->program + 1)) { - prog->startp[0] = string; - prog->endp[0] = reginput; - return(1); - } else - return(0); -} - -/* - - regmatch - main matching routine - * - * Conceptually the strategy is simple: check to see whether the current - * node matches, call self recursively to see whether the rest matches, - * and then act accordingly. In practice we make some effort to avoid - * recursion, in particular by going through "ordinary" nodes (that don't - * need to know whether the rest of the match failed) by a loop instead of - * by recursion. - */ -static int /* 0 failure, 1 success */ -regmatch( char *prog ) -{ - register char *scan; /* Current node. */ - char *next; /* Next node. */ - - scan = prog; -#ifdef DEBUG - if (scan != NULL && regnarrate) - fprintf(stderr, "%s(\n", regprop(scan)); -#endif - while (scan != NULL) { -#ifdef DEBUG - if (regnarrate) - fprintf(stderr, "%s...\n", regprop(scan)); -#endif - next = regnext(scan); - - switch (OP(scan)) { - case BOL: - if (reginput != regbol) - return(0); - break; - case EOL: - if (*reginput != '\0') - return(0); - break; - case WORDA: - /* Must be looking at a letter, digit, or _ */ - if ((!isalnum(*reginput)) && *reginput != '_') - return(0); - /* Prev must be BOL or nonword */ - if (reginput > regbol && - (isalnum(reginput[-1]) || reginput[-1] == '_')) - return(0); - break; - case WORDZ: - /* Must be looking at non letter, digit, or _ */ - if (isalnum(*reginput) || *reginput == '_') - return(0); - /* We don't care what the previous char was */ - break; - case ANY: - if (*reginput == '\0') - return(0); - reginput++; - break; - case EXACTLY: { - register int len; - register char *opnd; - - opnd = OPERAND(scan); - /* Inline the first character, for speed. */ - if (*opnd != *reginput) - return(0); - len = strlen(opnd); - if (len > 1 && strncmp(opnd, reginput, len) != 0) - return(0); - reginput += len; - } - break; - case ANYOF: - if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL) - return(0); - reginput++; - break; - case ANYBUT: - if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL) - return(0); - reginput++; - break; - case NOTHING: - break; - case BACK: - break; - case OPEN+1: - case OPEN+2: - case OPEN+3: - case OPEN+4: - case OPEN+5: - case OPEN+6: - case OPEN+7: - case OPEN+8: - case OPEN+9: { - register int no; - register const char *save; - - no = OP(scan) - OPEN; - save = reginput; - - if (regmatch(next)) { - /* - * Don't set startp if some later - * invocation of the same parentheses - * already has. - */ - if (regstartp[no] == NULL) - regstartp[no] = save; - return(1); - } else - return(0); - } - break; - case CLOSE+1: - case CLOSE+2: - case CLOSE+3: - case CLOSE+4: - case CLOSE+5: - case CLOSE+6: - case CLOSE+7: - case CLOSE+8: - case CLOSE+9: { - register int no; - register const char *save; - - no = OP(scan) - CLOSE; - save = reginput; - - if (regmatch(next)) { - /* - * Don't set endp if some later - * invocation of the same parentheses - * already has. - */ - if (regendp[no] == NULL) - regendp[no] = save; - return(1); - } else - return(0); - } - break; - case BRANCH: { - register const char *save; - - if (OP(next) != BRANCH) /* No choice. */ - next = OPERAND(scan); /* Avoid recursion. */ - else { - do { - save = reginput; - if (regmatch(OPERAND(scan))) - return(1); - reginput = save; - scan = regnext(scan); - } while (scan != NULL && OP(scan) == BRANCH); - return(0); - /* NOTREACHED */ - } - } - break; - case STAR: - case PLUS: { - register char nextch; - register int no; - register const char *save; - register int min; - - /* - * Lookahead to avoid useless match attempts - * when we know what character comes next. - */ - nextch = '\0'; - if (OP(next) == EXACTLY) - nextch = *OPERAND(next); - min = (OP(scan) == STAR) ? 0 : 1; - save = reginput; - no = regrepeat(OPERAND(scan)); - while (no >= min) { - /* If it could work, try it. */ - if (nextch == '\0' || *reginput == nextch) - if (regmatch(next)) - return(1); - /* Couldn't or didn't -- back up. */ - no--; - reginput = save + no; - } - return(0); - } - break; - case END: - return(1); /* Success! */ - break; - default: - regerror("memory corruption"); - return(0); - break; - } - - scan = next; - } - - /* - * We get here only if there's trouble -- normally "case END" is - * the terminating point. - */ - regerror("corrupted pointers"); - return(0); -} - -/* - - regrepeat - repeatedly match something simple, report how many - */ -static int -regrepeat( char *p ) -{ - register int count = 0; - register const char *scan; - register char *opnd; - - scan = reginput; - opnd = OPERAND(p); - switch (OP(p)) { - case ANY: - count = strlen(scan); - scan += count; - break; - case EXACTLY: - while (*opnd == *scan) { - count++; - scan++; - } - break; - case ANYOF: - while (*scan != '\0' && strchr(opnd, *scan) != NULL) { - count++; - scan++; - } - break; - case ANYBUT: - while (*scan != '\0' && strchr(opnd, *scan) == NULL) { - count++; - scan++; - } - break; - default: /* Oh dear. Called inappropriately. */ - regerror("internal foulup"); - count = 0; /* Best compromise. */ - break; - } - reginput = scan; - - return(count); -} - -/* - - regnext - dig the "next" pointer out of a node - */ -static char * -regnext( register char *p ) -{ - register int offset; - - if (p == ®dummy) - return(NULL); - - offset = NEXT(p); - if (offset == 0) - return(NULL); - - if (OP(p) == BACK) - return(p-offset); - else - return(p+offset); -} - -#ifdef DEBUG - -STATIC char *regprop(); - -/* - - regdump - dump a regexp onto stdout in vaguely comprehensible form - */ -void -regdump( regexp *r ) -{ - register char *s; - register char op = EXACTLY; /* Arbitrary non-END op. */ - register char *next; - - - s = r->program + 1; - while (op != END) { /* While that wasn't END last time... */ - op = OP(s); - printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */ - next = regnext(s); - if (next == NULL) /* Next ptr. */ - printf("(0)"); - else - printf("(%d)", (s-r->program)+(next-s)); - s += 3; - if (op == ANYOF || op == ANYBUT || op == EXACTLY) { - /* Literal string, where present. */ - while (*s != '\0') { - putchar(*s); - s++; - } - s++; - } - putchar('\n'); - } - - /* Header fields of interest. */ - if (r->regstart != '\0') - printf("start `%c' ", r->regstart); - if (r->reganch) - printf("anchored "); - if (r->regmust != NULL) - printf("must have \"%s\"", r->regmust); - printf("\n"); -} - -/* - - regprop - printable representation of opcode - */ -static char * -regprop( char *op ) -{ - register char *p; - static char buf[50]; - - (void) strcpy(buf, ":"); - - switch (OP(op)) { - case BOL: - p = "BOL"; - break; - case EOL: - p = "EOL"; - break; - case ANY: - p = "ANY"; - break; - case ANYOF: - p = "ANYOF"; - break; - case ANYBUT: - p = "ANYBUT"; - break; - case BRANCH: - p = "BRANCH"; - break; - case EXACTLY: - p = "EXACTLY"; - break; - case NOTHING: - p = "NOTHING"; - break; - case BACK: - p = "BACK"; - break; - case END: - p = "END"; - break; - case OPEN+1: - case OPEN+2: - case OPEN+3: - case OPEN+4: - case OPEN+5: - case OPEN+6: - case OPEN+7: - case OPEN+8: - case OPEN+9: - sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN); - p = NULL; - break; - case CLOSE+1: - case CLOSE+2: - case CLOSE+3: - case CLOSE+4: - case CLOSE+5: - case CLOSE+6: - case CLOSE+7: - case CLOSE+8: - case CLOSE+9: - sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE); - p = NULL; - break; - case STAR: - p = "STAR"; - break; - case PLUS: - p = "PLUS"; - break; - case WORDA: - p = "WORDA"; - break; - case WORDZ: - p = "WORDZ"; - break; - default: - regerror("corrupted opcode"); - break; - } - if (p != NULL) - (void) strcat(buf, p); - return(buf); -} -#endif - -/* - * The following is provided for those people who do not have strcspn() in - * their C libraries. They should get off their butts and do something - * about it; at least one public-domain implementation of those (highly - * useful) string routines has been published on Usenet. - */ -#ifdef STRCSPN -/* - * strcspn - find length of initial segment of s1 consisting entirely - * of characters not from s2 - */ - -static int -strcspn( - char *s1, - char *s2 ) -{ - register char *scan1; - register char *scan2; - register int count; - - count = 0; - for (scan1 = s1; *scan1 != '\0'; scan1++) { - for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */ - if (*scan1 == *scan2++) - return(count); - count++; - } - return(count); -} -#endif - -void -regerror( const char *s ) -{ - printf( "re error %s\n", s ); -} diff --git a/jam-2.5/regexp.h b/jam-2.5/regexp.h deleted file mode 100644 index 87649c321..000000000 --- a/jam-2.5/regexp.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Definitions etc. for regexp(3) routines. - * - * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], - * not the System V one. - * - * 11/04/02 (seiwald) - const-ing for string literals - */ - -#define NSUBEXP 10 -typedef struct regexp { - const char *startp[NSUBEXP]; - const char *endp[NSUBEXP]; - char regstart; /* Internal use only. */ - char reganch; /* Internal use only. */ - char *regmust; /* Internal use only. */ - int regmlen; /* Internal use only. */ - char program[1]; /* Unwarranted chumminess with compiler. */ -} regexp; - -regexp *regcomp( const char *exp ); -int regexec( regexp *prog, const char *string ); -void regerror( const char *s ); - -/* - * The first byte of the regexp internal "program" is actually this magic - * number; the start node begins in the second byte. - */ -#define MAGIC 0234 diff --git a/jam-2.5/rules.c b/jam-2.5/rules.c deleted file mode 100644 index f1b436e39..000000000 --- a/jam-2.5/rules.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * rules.c - access to RULEs, TARGETs, and ACTIONs - * - * External routines: - * - * bindrule() - return pointer to RULE, creating it if necessary - * bindtarget() - return pointer to TARGET, creating it if necessary - * copytarget() - make a new target with the old target's name - * touchtarget() - mark a target to simulate being new - * targetlist() - turn list of target names into a TARGET chain - * targetentry() - add a TARGET to a chain of TARGETS - * targetchain() - append two TARGET chains - * actionlist() - append to an ACTION chain - * addsettings() - add a deferred "set" command to a target - * copysettings() - copy a settings list for temp use - * pushsettings() - set all target specific variables - * popsettings() - reset target specific variables to their pre-push values - * freesettings() - delete a settings list - * donerules() - free RULE and TARGET tables - * - * 04/12/94 (seiwald) - actionlist() now just appends a single action. - * 08/23/94 (seiwald) - Support for '+=' (append to variable) - * 06/21/02 (seiwald) - support for named parameters - * 11/04/02 (seiwald) - const-ing for string literals - * 12/03/02 (seiwald) - fix odd includes support by grafting them onto depends - * 12/17/02 (seiwald) - new copysettings() to protect target-specific vars - * 01/14/03 (seiwald) - fix includes fix with new internal includes TARGET - */ - -# include "jam.h" -# include "lists.h" -# include "parse.h" -# include "variable.h" -# include "rules.h" -# include "newstr.h" -# include "hash.h" - -static struct hash *rulehash = 0; -static struct hash *targethash = 0; - - -/* - * bindrule() - return pointer to RULE, creating it if necessary - */ - -RULE * -bindrule( const char *rulename ) -{ - RULE rule, *r = &rule; - - if( !rulehash ) - rulehash = hashinit( sizeof( RULE ), "rules" ); - - r->name = rulename; - - if( hashenter( rulehash, (HASHDATA **)&r ) ) - { - r->name = newstr( rulename ); /* never freed */ - r->procedure = (PARSE *)0; - r->actions = (char *)0; - r->bindlist = L0; - r->params = L0; - r->flags = 0; - } - - return r; -} - -/* - * bindtarget() - return pointer to TARGET, creating it if necessary - */ - -TARGET * -bindtarget( const char *targetname ) -{ - TARGET target, *t = ⌖ - - if( !targethash ) - targethash = hashinit( sizeof( TARGET ), "targets" ); - - t->name = targetname; - - if( hashenter( targethash, (HASHDATA **)&t ) ) - { - memset( (char *)t, '\0', sizeof( *t ) ); - t->name = newstr( targetname ); /* never freed */ - t->boundname = t->name; /* default for T_FLAG_NOTFILE */ - } - - return t; -} - -/* - * copytarget() - make a new target with the old target's name - * - * Not entered into hash table -- for internal nodes. - */ - -TARGET * -copytarget( const TARGET *ot ) -{ - TARGET *t; - - t = (TARGET *)malloc( sizeof( *t ) ); - memset( (char *)t, '\0', sizeof( *t ) ); - t->name = copystr( ot->name ); - t->boundname = t->name; - - t->flags |= T_FLAG_NOTFILE | T_FLAG_INTERNAL; - - return t; -} - -/* - * touchtarget() - mark a target to simulate being new - */ - -void -touchtarget( const char *t ) -{ - bindtarget( t )->flags |= T_FLAG_TOUCHED; -} - -/* - * targetlist() - turn list of target names into a TARGET chain - * - * Inputs: - * chain existing TARGETS to append to - * targets list of target names - */ - -TARGETS * -targetlist( - TARGETS *chain, - LIST *targets ) -{ - for( ; targets; targets = list_next( targets ) ) - chain = targetentry( chain, bindtarget( targets->string ) ); - - return chain; -} - -/* - * targetentry() - add a TARGET to a chain of TARGETS - * - * Inputs: - * chain exisitng TARGETS to append to - * target new target to append - */ - -TARGETS * -targetentry( - TARGETS *chain, - TARGET *target ) -{ - TARGETS *c; - - c = (TARGETS *)malloc( sizeof( TARGETS ) ); - c->target = target; - - if( !chain ) chain = c; - else chain->tail->next = c; - chain->tail = c; - c->next = 0; - - return chain; -} - -/* - * targetchain() - append two TARGET chains - * - * Inputs: - * chain exisitng TARGETS to append to - * target new target to append - */ - -TARGETS * -targetchain( - TARGETS *chain, - TARGETS *targets ) -{ - TARGETS *c; - - if( !targets ) - return chain; - else if( !chain ) - return targets; - - chain->tail->next = targets; - chain->tail = targets->tail; - - return chain; -} - -/* - * actionlist() - append to an ACTION chain - */ - -ACTIONS * -actionlist( - ACTIONS *chain, - ACTION *action ) -{ - ACTIONS *actions = (ACTIONS *)malloc( sizeof( ACTIONS ) ); - - actions->action = action; - - if( !chain ) chain = actions; - else chain->tail->next = actions; - chain->tail = actions; - actions->next = 0; - - return chain; -} - -/* - * addsettings() - add a deferred "set" command to a target - * - * Adds a variable setting (varname=list) onto a chain of settings - * for a particular target. Replaces the previous previous value, - * if any, unless 'append' says to append the new list onto the old. - * Returns the head of the chain of settings. - */ - -SETTINGS * -addsettings( - SETTINGS *head, - int setflag, - const char *symbol, - LIST *value ) -{ - SETTINGS *v; - - /* Look for previous setting */ - - for( v = head; v; v = v->next ) - if( !strcmp( v->symbol, symbol ) ) - break; - - /* If not previously set, alloc a new. */ - /* If appending, do so. */ - /* Else free old and set new. */ - - if( !v ) - { - v = (SETTINGS *)malloc( sizeof( *v ) ); - v->symbol = newstr( symbol ); - v->value = value; - v->next = head; - head = v; - } - else switch( setflag ) - { - case VAR_SET: - /* Toss old, set new */ - list_free( v->value ); - v->value = value; - break; - - case VAR_APPEND: - /* Append new to old */ - v->value = list_append( v->value, value ); - break; - - case VAR_DEFAULT: - /* Toss new, old already set */ - list_free( value ); - break; - } - - /* Return (new) head of list. */ - - return head; -} - -/* - * copysettings() - copy a settings list for temp use - * - * When target-specific variables are pushed into place with pushsettings(), - * any global variables with the same name are swapped onto the target's - * SETTINGS chain. If that chain gets modified (by using the "on target" - * syntax), popsettings() would wrongly swap those modified values back - * as the new global values. - * - * copysettings() protects the target's SETTINGS chain by providing a - * copy of the chain to pass to pushsettings() and popsettings(), so that - * the target's original SETTINGS chain can be modified using the usual - * "on target" syntax. - */ - -SETTINGS * -copysettings( SETTINGS *from ) -{ - SETTINGS *head = 0, *v; - - for( ; from; from = from->next ) - { - SETTINGS *v = (SETTINGS *)malloc( sizeof( *v ) ); - v->symbol = copystr( from->symbol ); - v->value = list_copy( 0, from->value ); - v->next = head; - head = v; - } - - return head; -} - -/* - * pushsettings() - set all target specific variables - */ - -void -pushsettings( SETTINGS *v ) -{ - for( ; v; v = v->next ) - v->value = var_swap( v->symbol, v->value ); -} - -/* - * popsettings() - reset target specific variables to their pre-push values - */ - -void -popsettings( SETTINGS *v ) -{ - pushsettings( v ); /* just swap again */ -} - -/* - * freesettings() - delete a settings list - */ - -void -freesettings( SETTINGS *v ) -{ - while( v ) - { - SETTINGS *n = v->next; - - freestr( v->symbol ); - list_free( v->value ); - free( (char *)v ); - - v = n; - } -} - -/* - * donerules() - free RULE and TARGET tables - */ - -void -donerules() -{ - hashdone( rulehash ); - hashdone( targethash ); -} diff --git a/jam-2.5/rules.h b/jam-2.5/rules.h deleted file mode 100644 index 532d2347b..000000000 --- a/jam-2.5/rules.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * rules.h - targets, rules, and related information - * - * This file describes the structures holding the targets, rules, and - * related information accumulated by interpreting the statements - * of the jam files. - * - * The following are defined: - * - * RULE - a generic jam rule, the product of RULE and ACTIONS - * ACTIONS - a chain of ACTIONs - * ACTION - a RULE instance with targets and sources - * SETTINGS - variables to set when executing a TARGET's ACTIONS - * TARGETS - a chain of TARGETs - * TARGET - a file or "thing" that can be built - * - * 04/11/94 (seiwald) - Combined deps & headers into deps[2] in TARGET. - * 04/12/94 (seiwald) - actionlist() now just appends a single action. - * 06/01/94 (seiwald) - new 'actions existing' does existing sources - * 12/20/94 (seiwald) - NOTIME renamed NOTFILE. - * 01/19/95 (seiwald) - split DONTKNOW into CANTFIND/CANTMAKE. - * 02/02/95 (seiwald) - new LEAVES modifier on targets. - * 02/14/95 (seiwald) - new NOUPDATE modifier on targets. - * 02/28/02 (seiwald) - merge EXEC_xxx flags in with RULE_xxx - * 06/21/02 (seiwald) - support for named parameters - * 07/17/02 (seiwald) - TEMPORARY sources for headers now get built - * 11/04/02 (seiwald) - const-ing for string literals - * 12/03/02 (seiwald) - fix odd includes support by grafting them onto depends - * 12/17/02 (seiwald) - new copysettings() to protect target-specific vars - * 01/14/03 (seiwald) - fix includes fix with new internal includes TARGET - */ - -typedef struct _rule RULE; -typedef struct _target TARGET; -typedef struct _targets TARGETS; -typedef struct _action ACTION; -typedef struct _actions ACTIONS; -typedef struct _settings SETTINGS ; - -/* RULE - a generic jam rule, the product of RULE and ACTIONS */ - -struct _rule { - const char *name; - PARSE *procedure; /* parse tree from RULE */ - const char *actions; /* command string from ACTIONS */ - LIST *bindlist; /* variable to bind for actions */ - LIST *params; /* bind args to local vars */ - int flags; /* modifiers on ACTIONS */ - -# define RULE_UPDATED 0x01 /* $(>) is updated sources only */ -# define RULE_TOGETHER 0x02 /* combine actions on single target */ -# define RULE_IGNORE 0x04 /* ignore return status of executes */ -# define RULE_QUIETLY 0x08 /* don't mention it unless verbose */ -# define RULE_PIECEMEAL 0x10 /* split exec so each $(>) is small */ -# define RULE_EXISTING 0x20 /* $(>) is pre-exisitng sources only */ -# define RULE_MAXLINE 0x40 /* cmd specific maxline (last) */ - -} ; - -/* ACTIONS - a chain of ACTIONs */ - -struct _actions { - ACTIONS *next; - ACTIONS *tail; /* valid only for head */ - ACTION *action; -} ; - -/* ACTION - a RULE instance with targets and sources */ - -struct _action { - RULE *rule; - TARGETS *targets; - TARGETS *sources; /* aka $(>) */ - char running; /* has been started */ - char status; /* see TARGET status */ -} ; - -/* SETTINGS - variables to set when executing a TARGET's ACTIONS */ - -struct _settings { - SETTINGS *next; - const char *symbol; /* symbol name for var_set() */ - LIST *value; /* symbol value for var_set() */ -} ; - -/* TARGETS - a chain of TARGETs */ - -struct _targets { - TARGETS *next; - TARGETS *tail; /* valid only for head */ - TARGET *target; -} ; - -/* TARGET - a file or "thing" that can be built */ - -struct _target { - const char *name; - const char *boundname; /* if search() relocates target */ - ACTIONS *actions; /* rules to execute, if any */ - SETTINGS *settings; /* variables to define */ - - char flags; /* status info */ - -# define T_FLAG_TEMP 0x01 /* TEMPORARY applied */ -# define T_FLAG_NOCARE 0x02 /* NOCARE applied */ -# define T_FLAG_NOTFILE 0x04 /* NOTFILE applied */ -# define T_FLAG_TOUCHED 0x08 /* ALWAYS applied or -t target */ -# define T_FLAG_LEAVES 0x10 /* LEAVES applied */ -# define T_FLAG_NOUPDATE 0x20 /* NOUPDATE applied */ -# define T_FLAG_INTERNAL 0x40 /* internal INCLUDES node */ - - char binding; /* how target relates to real file */ - -# define T_BIND_UNBOUND 0 /* a disembodied name */ -# define T_BIND_MISSING 1 /* couldn't find real file */ -# define T_BIND_PARENTS 2 /* using parent's timestamp */ -# define T_BIND_EXISTS 3 /* real file, timestamp valid */ - - TARGETS *depends; /* dependencies */ - TARGET *includes; /* includes */ - - time_t time; /* update time */ - time_t leaf; /* update time of leaf sources */ - char fate; /* make0()'s diagnosis */ - -# define T_FATE_INIT 0 /* nothing done to target */ -# define T_FATE_MAKING 1 /* make0(target) on stack */ - -# define T_FATE_STABLE 2 /* target didn't need updating */ -# define T_FATE_NEWER 3 /* target newer than parent */ - -# define T_FATE_SPOIL 4 /* >= SPOIL rebuilds parents */ -# define T_FATE_ISTMP 4 /* unneeded temp target oddly present */ - -# define T_FATE_BUILD 5 /* >= BUILD rebuilds target */ -# define T_FATE_TOUCHED 5 /* manually touched with -t */ -# define T_FATE_MISSING 6 /* is missing, needs updating */ -# define T_FATE_NEEDTMP 7 /* missing temp that must be rebuild */ -# define T_FATE_OUTDATED 8 /* is out of date, needs updating */ -# define T_FATE_UPDATE 9 /* deps updated, needs updating */ - -# define T_FATE_BROKEN 10 /* >= BROKEN ruins parents */ -# define T_FATE_CANTFIND 10 /* no rules to make missing target */ -# define T_FATE_CANTMAKE 11 /* can't find dependents */ - - char progress; /* tracks make1() progress */ - -# define T_MAKE_INIT 0 /* make1(target) not yet called */ -# define T_MAKE_ONSTACK 1 /* make1(target) on stack */ -# define T_MAKE_ACTIVE 2 /* make1(target) in make1b() */ -# define T_MAKE_RUNNING 3 /* make1(target) running commands */ -# define T_MAKE_DONE 4 /* make1(target) done */ - - char status; /* execcmd() result */ - - int asynccnt; /* child deps outstanding */ - TARGETS *parents; /* used by make1() for completion */ - char *cmds; /* type-punned command list */ -} ; - -RULE *bindrule( const char *rulename ); -TARGET *bindtarget( const char *targetname ); -TARGET *copytarget( const TARGET *t ); -void touchtarget( const char *t ); -TARGETS *targetlist( TARGETS *chain, LIST *targets ); -TARGETS *targetentry( TARGETS *chain, TARGET *target ); -TARGETS *targetchain( TARGETS *chain, TARGETS *targets ); -ACTIONS *actionlist( ACTIONS *chain, ACTION *action ); -SETTINGS *addsettings( SETTINGS *v, int setflag, const char *sym, LIST *val ); -SETTINGS *copysettings( SETTINGS *v ); -void pushsettings( SETTINGS *v ); -void popsettings( SETTINGS *v ); -void freesettings( SETTINGS *v ); -void donerules(); diff --git a/jam-2.5/scan.c b/jam-2.5/scan.c deleted file mode 100644 index 55879f4d7..000000000 --- a/jam-2.5/scan.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * scan.c - the jam yacc scanner - * - * 12/26/93 (seiwald) - bump buf in yylex to 10240 - yuk. - * 09/16/94 (seiwald) - check for overflows, unmatched {}'s, etc. - * Also handle tokens abutting EOF by remembering - * to return EOF now matter how many times yylex() - * reinvokes yyline(). - * 02/11/95 (seiwald) - honor only punctuation keywords if SCAN_PUNCT. - * 07/27/95 (seiwald) - Include jamgram.h after scan.h, so that YYSTYPE is - * defined before Linux's yacc tries to redefine it. - * 01/10/01 (seiwald) - \ can now escape any whitespace char - * 11/04/02 (seiwald) - const-ing for string literals - */ - -# include "jam.h" -# include "lists.h" -# include "parse.h" -# include "scan.h" -# include "jamgram.h" -# include "jambase.h" -# include "newstr.h" - -struct keyword { - const char *word; - int type; -} keywords[] = { -# include "jamgramtab.h" - { 0, 0 } -} ; - -struct include { - struct include *next; /* next serial include file */ - const char *string; /* pointer into current line */ - char **strings; /* for yyfparse() -- text to parse */ - FILE *file; /* for yyfparse() -- file being read */ - const char *fname; /* for yyfparse() -- file name */ - int line; /* line counter for error messages */ - char buf[ 512 ]; /* for yyfparse() -- line buffer */ -} ; - -static struct include *incp = 0; /* current file; head of chain */ - -static int scanmode = SCAN_NORMAL; -static int anyerrors = 0; -static char *symdump( YYSTYPE *s ); - -# define BIGGEST_TOKEN 10240 /* no single token can be larger */ - -/* - * Set parser mode: normal, string, or keyword - */ - -void -yymode( int n ) -{ - scanmode = n; -} - -void -yyerror( const char *s ) -{ - if( incp ) - printf( "%s: line %d: ", incp->fname, incp->line ); - - printf( "%s at %s\n", s, symdump( &yylval ) ); - - ++anyerrors; -} - -int -yyanyerrors() -{ - return anyerrors != 0; -} - -void -yyfparse( const char *s ) -{ - struct include *i = (struct include *)malloc( sizeof( *i ) ); - - /* Push this onto the incp chain. */ - - i->string = ""; - i->strings = 0; - i->file = 0; - i->fname = copystr( s ); - i->line = 0; - i->next = incp; - incp = i; - - /* If the filename is "+", it means use the internal jambase. */ - - if( !strcmp( s, "+" ) ) - i->strings = jambase; -} - -/* - * yyline() - read new line and return first character - * - * Fabricates a continuous stream of characters across include files, - * returning EOF at the bitter end. - */ - -int -yyline() -{ - struct include *i = incp; - - if( !incp ) - return EOF; - - /* Once we start reading from the input stream, we reset the */ - /* include insertion point so that the next include file becomes */ - /* the head of the list. */ - - /* If there is more data in this line, return it. */ - - if( *i->string ) - return *i->string++; - - /* If we're reading from an internal string list, go to the */ - /* next string. */ - - if( i->strings ) - { - if( !*i->strings ) - goto next; - - i->line++; - i->string = *(i->strings++); - return *i->string++; - } - - /* If necessary, open the file */ - - if( !i->file ) - { - FILE *f = stdin; - - if( strcmp( i->fname, "-" ) && !( f = fopen( i->fname, "r" ) ) ) - perror( i->fname ); - - i->file = f; - } - - /* If there's another line in this file, start it. */ - - if( i->file && fgets( i->buf, sizeof( i->buf ), i->file ) ) - { - i->line++; - i->string = i->buf; - return *i->string++; - } - - next: - /* This include is done. */ - /* Free it up and return EOF so yyparse() returns to parse_file(). */ - - incp = i->next; - - /* Close file, free name */ - - if( i->file && i->file != stdin ) - fclose( i->file ); - freestr( i->fname ); - free( (char *)i ); - - return EOF; -} - -/* - * yylex() - set yylval to current token; return its type - * - * Macros to move things along: - * - * yychar() - return and advance character; invalid after EOF - * yyprev() - back up one character; invalid before yychar() - * - * yychar() returns a continuous stream of characters, until it hits - * the EOF of the current include file. - */ - -# define yychar() ( *incp->string ? *incp->string++ : yyline() ) -# define yyprev() ( incp->string-- ) - -int -yylex() -{ - int c; - char buf[BIGGEST_TOKEN]; - char *b = buf; - - if( !incp ) - goto eof; - - /* Get first character (whitespace or of token) */ - - c = yychar(); - - if( scanmode == SCAN_STRING ) - { - /* If scanning for a string (action's {}'s), look for the */ - /* closing brace. We handle matching braces, if they match! */ - - int nest = 1; - - while( c != EOF && b < buf + sizeof( buf ) ) - { - if( c == '{' ) - nest++; - - if( c == '}' && !--nest ) - break; - - *b++ = c; - - c = yychar(); - } - - /* We ate the ending brace -- regurgitate it. */ - - if( c != EOF ) - yyprev(); - - /* Check obvious errors. */ - - if( b == buf + sizeof( buf ) ) - { - yyerror( "action block too big" ); - goto eof; - } - - if( nest ) - { - yyerror( "unmatched {} in action block" ); - goto eof; - } - - *b = 0; - yylval.type = STRING; - yylval.string = newstr( buf ); - - } - else - { - char *b = buf; - struct keyword *k; - int inquote = 0; - int notkeyword; - - /* Eat white space */ - - for( ;; ) - { - /* Skip past white space */ - - while( c != EOF && isspace( c ) ) - c = yychar(); - - /* Not a comment? Swallow up comment line. */ - - if( c != '#' ) - break; - while( ( c = yychar() ) != EOF && c != '\n' ) - ; - } - - /* c now points to the first character of a token. */ - - if( c == EOF ) - goto eof; - - /* While scanning the word, disqualify it for (expensive) */ - /* keyword lookup when we can: $anything, "anything", \anything */ - - notkeyword = c == '$'; - - /* look for white space to delimit word */ - /* "'s get stripped but preserve white space */ - /* \ protects next character */ - - while( - c != EOF && - b < buf + sizeof( buf ) && - ( inquote || !isspace( c ) ) ) - { - if( c == '"' ) - { - /* begin or end " */ - inquote = !inquote; - notkeyword = 1; - } - else if( c != '\\' ) - { - /* normal char */ - *b++ = c; - } - else if( ( c = yychar()) != EOF ) - { - /* \c */ - *b++ = c; - notkeyword = 1; - } - else - { - /* \EOF */ - break; - } - - c = yychar(); - } - - /* Check obvious errors. */ - - if( b == buf + sizeof( buf ) ) - { - yyerror( "string too big" ); - goto eof; - } - - if( inquote ) - { - yyerror( "unmatched \" in string" ); - goto eof; - } - - /* We looked ahead a character - back up. */ - - if( c != EOF ) - yyprev(); - - /* scan token table */ - /* don't scan if it's obviously not a keyword or if its */ - /* an alphabetic when were looking for punctuation */ - - *b = 0; - yylval.type = ARG; - - if( !notkeyword && !( isalpha( *buf ) && scanmode == SCAN_PUNCT ) ) - { - for( k = keywords; k->word; k++ ) - if( *buf == *k->word && !strcmp( k->word, buf ) ) - { - yylval.type = k->type; - yylval.string = k->word; /* used by symdump */ - break; - } - } - - if( yylval.type == ARG ) - yylval.string = newstr( buf ); - } - - if( DEBUG_SCAN ) - printf( "scan %s\n", symdump( &yylval ) ); - - return yylval.type; - -eof: - yylval.type = EOF; - return yylval.type; -} - -static char * -symdump( YYSTYPE *s ) -{ - static char buf[ BIGGEST_TOKEN + 20 ]; - - switch( s->type ) - { - case EOF: - sprintf( buf, "EOF" ); - break; - case 0: - sprintf( buf, "unknown symbol %s", s->string ); - break; - case ARG: - sprintf( buf, "argument %s", s->string ); - break; - case STRING: - sprintf( buf, "string \"%s\"", s->string ); - break; - default: - sprintf( buf, "keyword %s", s->string ); - break; - } - return buf; -} diff --git a/jam-2.5/scan.h b/jam-2.5/scan.h deleted file mode 100644 index 30be3888b..000000000 --- a/jam-2.5/scan.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * scan.h - the jam yacc scanner - * - * External functions: - * - * yyerror( char *s ) - print a parsing error message - * yyfparse( char *s ) - scan include file s - * yylex() - parse the next token, returning its type - * yymode() - adjust lexicon of scanner - * yyparse() - declaration for yacc parser - * yyanyerrors() - indicate if any parsing errors occured - * - * The yymode() function is for the parser to adjust the lexicon of the - * scanner. Aside from normal keyword scanning, there is a mode to - * handle action strings (look only for the closing }) and a mode to - * ignore most keywords when looking for a punctuation keyword. This - * allows non-punctuation keywords to be used in lists without quoting. - * - * 11/04/02 (seiwald) - const-ing for string literals - */ - -/* - * YYSTYPE - value of a lexical token - */ - -# define YYSTYPE YYSYMBOL - -typedef struct _YYSTYPE { - int type; - const char *string; - PARSE *parse; - LIST *list; - int number; -} YYSTYPE; - -extern YYSTYPE yylval; - -void yymode( int n ); -void yyerror( const char *s ); -int yyanyerrors(); -void yyfparse( const char *s ); -int yyline(); -int yylex(); -int yyparse(); - -# define SCAN_NORMAL 0 /* normal parsing */ -# define SCAN_STRING 1 /* look only for matching } */ -# define SCAN_PUNCT 2 /* only punctuation keywords */ diff --git a/jam-2.5/search.c b/jam-2.5/search.c deleted file mode 100644 index 52f3c99b5..000000000 --- a/jam-2.5/search.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * search.c - find a target along $(SEARCH) or $(LOCATE) - * - * 11/04/02 (seiwald) - const-ing for string literals - */ - -# include "jam.h" -# include "lists.h" -# include "search.h" -# include "timestamp.h" -# include "pathsys.h" -# include "variable.h" -# include "newstr.h" - -const char * -search( - const char *target, - time_t *time ) -{ - PATHNAME f[1]; - LIST *varlist; - char buf[ MAXJPATH ]; - - /* Parse the filename */ - - path_parse( target, f ); - - f->f_grist.ptr = 0; - f->f_grist.len = 0; - - if( varlist = var_get( "LOCATE" ) ) - { - f->f_root.ptr = varlist->string; - f->f_root.len = strlen( varlist->string ); - - path_build( f, buf, 1 ); - - if( DEBUG_SEARCH ) - printf( "locate %s: %s\n", target, buf ); - - timestamp( buf, time ); - - return newstr( buf ); - } - else if( varlist = var_get( "SEARCH" ) ) - { - while( varlist ) - { - f->f_root.ptr = varlist->string; - f->f_root.len = strlen( varlist->string ); - - path_build( f, buf, 1 ); - - if( DEBUG_SEARCH ) - printf( "search %s: %s\n", target, buf ); - - timestamp( buf, time ); - - if( *time ) - return newstr( buf ); - - varlist = list_next( varlist ); - } - } - - /* Look for the obvious */ - /* This is a questionable move. Should we look in the */ - /* obvious place if SEARCH is set? */ - - f->f_root.ptr = 0; - f->f_root.len = 0; - - path_build( f, buf, 1 ); - - if( DEBUG_SEARCH ) - printf( "search %s: %s\n", target, buf ); - - timestamp( buf, time ); - - return newstr( buf ); -} diff --git a/jam-2.5/search.h b/jam-2.5/search.h deleted file mode 100644 index fad146869..000000000 --- a/jam-2.5/search.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * search.h - find a target along $(SEARCH) or $(LOCATE) - * - * 11/04/02 (seiwald) - const-ing for string literals - */ - -const char *search( const char *target, time_t *time ); diff --git a/jam-2.5/timestamp.c b/jam-2.5/timestamp.c deleted file mode 100644 index 8b590a83c..000000000 --- a/jam-2.5/timestamp.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * timestamp.c - get the timestamp of a file or archive member - * - * 09/22/00 (seiwald) - downshift names on OS2, too - * 01/08/01 (seiwald) - closure param for file_dirscan/file_archscan - * 11/04/02 (seiwald) - const-ing for string literals - */ - -# include "jam.h" -# include "hash.h" -# include "filesys.h" -# include "pathsys.h" -# include "timestamp.h" -# include "newstr.h" - -/* - * BINDING - all known files - */ - -typedef struct _binding BINDING; - -struct _binding { - const char *name; - short flags; - -# define BIND_SCANNED 0x01 /* if directory or arch, has been scanned */ - - short progress; - -# define BIND_INIT 0 /* never seen */ -# define BIND_NOENTRY 1 /* timestamp requested but file never found */ -# define BIND_SPOTTED 2 /* file found but not timed yet */ -# define BIND_MISSING 3 /* file found but can't get timestamp */ -# define BIND_FOUND 4 /* file found and time stamped */ - - time_t time; /* update time - 0 if not exist */ -} ; - -static struct hash *bindhash = 0; -static void time_enter( void *, const char *, int , time_t ); - -static const char *time_progress[] = -{ - "INIT", - "NOENTRY", - "SPOTTED", - "MISSING", - "FOUND" -} ; - - -/* - * timestamp() - return timestamp on a file, if present - */ - -void -timestamp( - char *target, - time_t *time ) -{ - PATHNAME f1, f2; - BINDING binding, *b = &binding; - char buf[ MAXJPATH ]; - -# ifdef DOWNSHIFT_PATHS - char path[ MAXJPATH ]; - char *p = path; - - do *p++ = tolower( *target ); - while( *target++ ); - - target = path; -# endif - - if( !bindhash ) - bindhash = hashinit( sizeof( BINDING ), "bindings" ); - - /* Quick path - is it there? */ - - b->name = target; - b->time = b->flags = 0; - b->progress = BIND_INIT; - - if( hashenter( bindhash, (HASHDATA **)&b ) ) - b->name = newstr( target ); /* never freed */ - - if( b->progress != BIND_INIT ) - goto afterscanning; - - b->progress = BIND_NOENTRY; - - /* Not found - have to scan for it */ - - path_parse( target, &f1 ); - - /* Scan directory if not already done so */ - - { - BINDING binding, *b = &binding; - - f2 = f1; - f2.f_grist.len = 0; - path_parent( &f2 ); - path_build( &f2, buf, 0 ); - - b->name = buf; - b->time = b->flags = 0; - b->progress = BIND_INIT; - - if( hashenter( bindhash, (HASHDATA **)&b ) ) - b->name = newstr( buf ); /* never freed */ - - if( !( b->flags & BIND_SCANNED ) ) - { - file_dirscan( buf, time_enter, bindhash ); - b->flags |= BIND_SCANNED; - } - } - - /* Scan archive if not already done so */ - - if( f1.f_member.len ) - { - BINDING binding, *b = &binding; - - f2 = f1; - f2.f_grist.len = 0; - f2.f_member.len = 0; - path_build( &f2, buf, 0 ); - - b->name = buf; - b->time = b->flags = 0; - b->progress = BIND_INIT; - - if( hashenter( bindhash, (HASHDATA **)&b ) ) - b->name = newstr( buf ); /* never freed */ - - if( !( b->flags & BIND_SCANNED ) ) - { - file_archscan( buf, time_enter, bindhash ); - b->flags |= BIND_SCANNED; - } - } - - afterscanning: - - if( b->progress == BIND_SPOTTED ) - { - if( file_time( b->name, &b->time ) < 0 ) - b->progress = BIND_MISSING; - else - b->progress = BIND_FOUND; - } - - *time = b->progress == BIND_FOUND ? b->time : 0; -} - -static void -time_enter( - void *closure, - const char *target, - int found, - time_t time ) -{ - BINDING binding, *b = &binding; - struct hash *bindhash = (struct hash *)closure; - -# ifdef DOWNSHIFT_PATHS - char path[ MAXJPATH ]; - char *p = path; - - do *p++ = tolower( *target ); - while( *target++ ); - - target = path; -# endif - - b->name = target; - b->flags = 0; - - if( hashenter( bindhash, (HASHDATA **)&b ) ) - b->name = newstr( target ); /* never freed */ - - b->time = time; - b->progress = found ? BIND_FOUND : BIND_SPOTTED; - - if( DEBUG_BINDSCAN ) - printf( "time ( %s ) : %s\n", target, time_progress[b->progress] ); -} - -/* - * donestamps() - free timestamp tables - */ - -void -donestamps() -{ - hashdone( bindhash ); -} diff --git a/jam-2.5/timestamp.h b/jam-2.5/timestamp.h deleted file mode 100644 index f290f82cb..000000000 --- a/jam-2.5/timestamp.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright 1993, 1995 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * timestamp.h - get the timestamp of a file or archive member - */ - -void timestamp( char *target, time_t *time ); -void donestamps(); diff --git a/jam-2.5/variable.c b/jam-2.5/variable.c deleted file mode 100644 index 0a2d07c70..000000000 --- a/jam-2.5/variable.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * variable.c - handle jam multi-element variables - * - * External routines: - * - * var_defines() - load a bunch of variable=value settings - * var_string() - expand a string with variables in it - * var_get() - get value of a user defined symbol - * var_set() - set a variable in jam's user defined symbol table - * var_swap() - swap a variable's value with the given one - * var_done() - free variable tables - * - * Internal routines: - * - * var_enter() - make new var symbol table entry, returning var ptr - * var_dump() - dump a variable to stdout - * - * 04/13/94 (seiwald) - added shorthand L0 for null list pointer - * 08/23/94 (seiwald) - Support for '+=' (append to variable) - * 01/22/95 (seiwald) - split environment variables at blanks or :'s - * 05/10/95 (seiwald) - split path variables at SPLITPATH (not :) - * 09/11/00 (seiwald) - defunct var_list() removed - * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() - * 11/04/02 (seiwald) - const-ing for string literals - */ - -# include "jam.h" -# include "lists.h" -# include "parse.h" -# include "variable.h" -# include "expand.h" -# include "hash.h" -# include "newstr.h" - -static struct hash *varhash = 0; - -/* - * VARIABLE - a user defined multi-value variable - */ - -typedef struct _variable VARIABLE ; - -struct _variable { - const char *symbol; - LIST *value; -} ; - -static VARIABLE *var_enter( const char *symbol ); -static void var_dump( const char *symbol, LIST *value, const char *what ); - - - -/* - * var_defines() - load a bunch of variable=value settings - * - * If variable name ends in PATH, split value at :'s. - * Otherwise, split at blanks. - */ - -void -var_defines( const char **e ) -{ - for( ; *e; e++ ) - { - const char *val; - - /* Just say "no": windows defines this in the env, */ - /* but we don't want it to override our notion of OS. */ - - if( !strcmp( *e, "OS=Windows_NT" ) ) - continue; - -# ifdef OS_MAC - /* On the mac (MPW), the var=val is actually var\0val */ - /* Think different. */ - - if( ( val = strchr( *e, '=' ) ) || ( val = *e + strlen( *e ) ) ) -# else - if( val = strchr( *e, '=' ) ) -# endif - { - LIST *l = L0; - const char *pp, *p; -# ifdef OS_MAC - char split = ','; -# else - char split = ' '; -# endif - char buf[ MAXSYM ]; - - /* Split *PATH at :'s, not spaces */ - - if( val - 4 >= *e ) - { - if( !strncmp( val - 4, "PATH", 4 ) || - !strncmp( val - 4, "Path", 4 ) || - !strncmp( val - 4, "path", 4 ) ) - split = SPLITPATH; - } - - /* Do the split */ - - for( pp = val + 1; p = strchr( pp, split ); pp = p + 1 ) - { - strncpy( buf, pp, p - pp ); - buf[ p - pp ] = '\0'; - l = list_new( l, buf, 0 ); - } - - l = list_new( l, pp, 0 ); - - /* Get name */ - - strncpy( buf, *e, val - *e ); - buf[ val - *e ] = '\0'; - - var_set( buf, l, VAR_SET ); - } - } -} - -/* - * var_string() - expand a string with variables in it - * - * Copies in to out; doesn't modify targets & sources. - */ - -int -var_string( - const char *in, - char *out, - int outsize, - LOL *lol ) -{ - char *out0 = out; - char *oute = out + outsize - 1; - - while( *in ) - { - char *lastword; - int dollar = 0; - - /* Copy white space */ - - while( isspace( *in ) ) - { - if( out >= oute ) - return -1; - - *out++ = *in++; - } - - lastword = out; - - /* Copy non-white space, watching for variables */ - - while( *in && !isspace( *in ) ) - { - if( out >= oute ) - return -1; - - if( in[0] == '$' && in[1] == '(' ) - dollar++; - - *out++ = *in++; - } - - /* If a variable encountered, expand it and and embed the */ - /* space-separated members of the list in the output. */ - - if( dollar ) - { - LIST *l = var_expand( L0, lastword, out, lol, 0 ); - - out = lastword; - - while( l ) - { - int so = strlen( l->string ); - - if( out + so >= oute ) - return -1; - - strcpy( out, l->string ); - out += so; - - /* Separate with space */ - - if( l = list_next( l ) ) - *out++ = ' '; - } - - list_free( l ); - } - } - - if( out >= oute ) - return -1; - - *out++ = '\0'; - - return out - out0; -} - -/* - * var_get() - get value of a user defined symbol - * - * Returns NULL if symbol unset. - */ - -LIST * -var_get( const char *symbol ) -{ - VARIABLE var, *v = &var; - - v->symbol = symbol; - - if( varhash && hashcheck( varhash, (HASHDATA **)&v ) ) - { - if( DEBUG_VARGET ) - var_dump( v->symbol, v->value, "get" ); - return v->value; - } - - return 0; -} - -/* - * var_set() - set a variable in jam's user defined symbol table - * - * 'flag' controls the relationship between new and old values of - * the variable: SET replaces the old with the new; APPEND appends - * the new to the old; DEFAULT only uses the new if the variable - * was previously unset. - * - * Copies symbol. Takes ownership of value. - */ - -void -var_set( - const char *symbol, - LIST *value, - int flag ) -{ - VARIABLE *v = var_enter( symbol ); - - if( DEBUG_VARSET ) - var_dump( symbol, value, "set" ); - - switch( flag ) - { - case VAR_SET: - /* Replace value */ - list_free( v->value ); - v->value = value; - break; - - case VAR_APPEND: - /* Append value */ - v->value = list_append( v->value, value ); - break; - - case VAR_DEFAULT: - /* Set only if unset */ - if( !v->value ) - v->value = value; - else - list_free( value ); - break; - } -} - -/* - * var_swap() - swap a variable's value with the given one - */ - -LIST * -var_swap( - const char *symbol, - LIST *value ) -{ - VARIABLE *v = var_enter( symbol ); - LIST *oldvalue = v->value; - - if( DEBUG_VARSET ) - var_dump( symbol, value, "set" ); - - v->value = value; - - return oldvalue; -} - - - -/* - * var_enter() - make new var symbol table entry, returning var ptr - */ - -static VARIABLE * -var_enter( const char *symbol ) -{ - VARIABLE var, *v = &var; - - if( !varhash ) - varhash = hashinit( sizeof( VARIABLE ), "variables" ); - - v->symbol = symbol; - v->value = 0; - - if( hashenter( varhash, (HASHDATA **)&v ) ) - v->symbol = newstr( symbol ); /* never freed */ - - return v; -} - -/* - * var_dump() - dump a variable to stdout - */ - -static void -var_dump( - const char *symbol, - LIST *value, - const char *what ) -{ - printf( "%s %s = ", what, symbol ); - list_print( value ); - printf( "\n" ); -} - -/* - * var_done() - free variable tables - */ - -void -var_done() -{ - hashdone( varhash ); -} diff --git a/jam-2.5/variable.h b/jam-2.5/variable.h deleted file mode 100644 index e35020fb1..000000000 --- a/jam-2.5/variable.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 1993, 2000 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* - * variable.h - handle jam multi-element variables - * - * 11/04/02 (seiwald) - const-ing for string literals - */ - -void var_defines( const char **e ); -int var_string( const char *in, char *out, int outsize, LOL *lol ); -LIST * var_get( const char *symbol ); -void var_set( const char *symbol, LIST *value, int flag ); -LIST * var_swap( const char *symbol, LIST *value ); -void var_done(); - -/* - * Defines for var_set(). - */ - -# define VAR_SET 0 /* override previous value */ -# define VAR_APPEND 1 /* append to previous value */ -# define VAR_DEFAULT 2 /* set only if no previous value */ - diff --git a/jam-2.5/yyacc b/jam-2.5/yyacc deleted file mode 100644 index c4566ac7b..000000000 --- a/jam-2.5/yyacc +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/sh - -# yyacc - yacc wrapper -# -# Allows tokens to be written as `literal` and then automatically -# substituted with #defined tokens. -# -# Usage: -# yyacc file.y filetab.h file.yy -# -# inputs: -# file.yy yacc grammar with ` literals -# -# outputs: -# file.y yacc grammar -# filetab.h array of string <-> token mappings -# -# 03-13-93 - Documented and p moved in sed command (for some reason, -# s/x/y/p doesn't work). -# 10-12-93 - Take basename as second argument. -# 12-31-96 - reversed order of args to be compatible with GenFile rule -# 03/19/02 (seiwald) - suffix symbols with _t to avoid conflicts -# - -outy=${1?} -outh=${2?} -in=${3?} -out=`basename $in .yy` - -T=/tmp/yy$$ -trap 'rm -f $T.*' 0 - -sed ' - : 1 - /`/{ - h - s/[^`]*`\([^`]*\)`.*/\1/ - p - g - s/[^`]*`[^`]*`// - b 1 - } - d -' $in | sort -u | sed ' - h - y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/ - s/:/_COLON/ - s/!/_BANG/ - s/&&/_AMPERAMPER/ - s/&/_AMPER/ - s/+/_PLUS/ - s/||/_BARBAR/ - s/|/_BAR/ - s/;/_SEMIC/ - s/-/_MINUS/ - s//_RANGLE/ - s/\./_PERIOD/ - s/?/_QUESTION/ - s/=/_EQUALS/ - s/,/_COMMA/ - s/\[/_LBRACKET/ - s/]/_RBRACKET/ - s/{/_LBRACE/ - s/}/_RBRACE/ - s/(/_LPAREN/ - s/)/_RPAREN/ - s/.*/&_t/ - G - s/\n/ / -' > $T.1 - -sed ' - s:^\(.*\) \(.*\)$:s/`\2`/\1/g: - s:\.:\\.:g - s:\[:\\[:g -' $T.1 > $T.s - -rm -f $outy $outh - -( - sed 's:^\(.*\) \(.*\)$:%token \1:' $T.1 - sed -f $T.s $in -) > $outy - -( - sed 's:^\(.*\) \(.*\)$: { "\2", \1 },:' $T.1 -) > $outh