From 6a355c53aff11d990969d7a4f4897c2ff2102898 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 4 Feb 2004 21:44:27 +0000 Subject: [PATCH] This commit was generated by cvs2svn to compensate for changes in r6498, which included commits to RCS files with non-trunk default branches. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6499 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tools/jam/Jam.html | 1163 ++++++++++++++++++------------------ src/tools/jam/Jambase.html | 32 +- src/tools/jam/Jamfile.html | 10 +- src/tools/jam/README | 9 +- src/tools/jam/RELNOTES | 260 +++++++- src/tools/jam/builtins.c | 87 ++- src/tools/jam/builtins.h | 2 + src/tools/jam/command.c | 10 +- src/tools/jam/command.h | 3 +- src/tools/jam/execmac.c | 15 +- src/tools/jam/execunix.c | 87 +-- src/tools/jam/execvms.c | 31 +- src/tools/jam/expand.c | 53 +- src/tools/jam/expand.h | 9 +- src/tools/jam/filemac.c | 31 +- src/tools/jam/filent.c | 59 +- src/tools/jam/fileos2.c | 27 +- src/tools/jam/filesys.h | 10 +- src/tools/jam/fileunix.c | 193 ++++-- src/tools/jam/filevms.c | 27 +- src/tools/jam/glob.c | 14 +- src/tools/jam/hash.c | 20 +- src/tools/jam/hash.h | 4 +- src/tools/jam/lists.c | 60 +- src/tools/jam/lists.h | 12 +- src/tools/jam/make.h | 4 +- src/tools/jam/make1.c | 44 +- src/tools/jam/mkjambase.c | 3 +- src/tools/jam/newstr.c | 22 +- src/tools/jam/newstr.h | 8 +- src/tools/jam/option.c | 14 +- src/tools/jam/option.h | 10 +- src/tools/jam/patchlevel.h | 4 +- src/tools/jam/pathmac.c | 23 +- src/tools/jam/pathsys.h | 6 +- src/tools/jam/pathunix.c | 19 +- src/tools/jam/pathvms.c | 35 +- src/tools/jam/regexp.c | 36 +- src/tools/jam/regexp.h | 13 +- src/tools/jam/rules.c | 162 ++++- src/tools/jam/rules.h | 108 ++-- src/tools/jam/scan.h | 8 +- src/tools/jam/search.c | 14 +- src/tools/jam/search.h | 4 +- src/tools/jam/timestamp.c | 34 +- src/tools/jam/variable.c | 64 +- src/tools/jam/variable.h | 12 +- src/tools/jam/yyacc | 13 +- 48 files changed, 1741 insertions(+), 1147 deletions(-) diff --git a/src/tools/jam/Jam.html b/src/tools/jam/Jam.html index 91ffd3c78f..f750eee236 100644 --- a/src/tools/jam/Jam.html +++ b/src/tools/jam/Jam.html @@ -1,14 +1,14 @@ - Jam/MR - Make(1) Redux + Jam - Make(1) Redux
-

Jam/MR - Make(1) Redux

+

Jam - Make(1) Redux

-

The Jam/MR Executable +

The Jam Executable

@@ -17,7 +17,7 @@

USAGE

-jam [ -a ] [ -n ] [ -v ] [ -q ]
+jam [ -a ] [ -g ] [ -n ] [ -q ] [ -v ]
     [ -d debug ] 
     [ -f jambase ] 
     [ -j jobs ] 
@@ -60,21 +60,33 @@ jam [ -a ] [ -n ] [ -v ] [ -q ]
 
 	Jam may be invoked with the following options:
 
-	

+

-
-a +
-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 (the default) -
2
Show "quiet" actions and display all action text -
3
Show dependency analysis, and target/source - timestamps/paths -
4
Show shell arguments +
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 @@ -86,12 +98,15 @@ jam [ -a ] [ -n ] [ -v ] [ -q ]
Enable debugging level n.
-d 0 - Turn off all debugging levels. Only errors are not suppressed. + Turn off all debugging levels. Only errors are emitted.
-f jambase Read jambase instead of using the built-in Jambase. - Only one -f flag is permitted, but the jambase may - explicitly include other files. + 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 @@ -99,7 +114,7 @@ jam [ -a ] [ -n ] [ -v ] [ -q ]
-n Don't actually execute the updating actions, but do - everything else. This changes the debug level default to -d2. + everything else. This changes the debug level to -dax.
-o file Write the updating actions to the specified file instead @@ -107,7 +122,7 @@ jam [ -a ] [ -n ] [ -v ] [ -q ]
-q Quit quickly (as if an interrupt was received) - as soon as any target fails. + as soon as any target build fails.
-s var=value Set the variable var to value, overriding @@ -151,7 +166,7 @@ jam [ -a ] [ -n ] [ -v ] [ -q ]

- In the parsing phase, jam reads and parses the Jambase + 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) @@ -172,25 +187,45 @@ jam [ -a ] [ -n ] [ -v ] [ -q ]

Binding

-

-

Binding
After parsing, jam recursively descends the dependency graph and binds every file target with a location in the - filesystem. If jam detects a circular dependency in the - graph, it issues a warning. + 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.

- File target names are given as absolute or relative path names - in the filesystem. If the path name is absolute, it is bound - as is. If the path name is relative, it is normally bound as - is, and thus relative to the current directory. This can be - modified by the settings of the $(SEARCH) and $(LOCATE) variables, - which enable jam to find and build targets spread across - a directory tree. See SEARCH and LOCATE - Variables below. + 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
@@ -199,14 +234,11 @@ jam [ -a ] [ -n ] [ -v ] [ -q ] 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, ALWAYS, LEAVES, NOCARE, NOTFILE, - NOUPDATE, and TEMPORARY. See Modifying + 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 @@ -231,7 +263,9 @@ jam [ -a ] [ -n ] [ -v ] [ -q ] 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. + 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

@@ -239,238 +273,574 @@ jam [ -a ] [ -n ] [ -v ] [ -q ]

Overview

- Jam has an interpreted, procedural language. Statements - in jam are rule (procedure) definitions, rule invocations, - flow-of-control structures, variable assignments, and sundry - language support. + 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 rule action is treated + 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. + surround all tokens, including the colon (:) and semicolon + (;) tokens.

- Jam keywords (an mentioned in this document) are reserved + 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. -

Targets

+

Datatype

- The essential jam data entity is a target. Built targets - are files to be updated. Source targets are the files used in - updating built targets. Built targets and source targets are - collectively referred to as file targets, and frequently built - targets are source targets for other built 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). + 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 defined in two parts: the procedure and the actions. The - procedure is a body of jam statements to be run when the - rule is invoked; the actions are the OS shell commands to execute - when updating the built targets of the rule. + 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 can return values, which can be expanded into a list with - "[ rule args ... ]". 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' (value of the case - chosen), set (value of the resulting variable), and 'return' (value - of its arguments). Note that 'return' doesn't actually cause a - return, i.e., is a no-op unless it is the last statement - of the last block executed within rule body. + 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

- The jam statements for defining and invoking rules are - as follows: + 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:

- rule rulename { statements } + + rulename field1 : field2 : ... + : fieldN ; + -
Define a rule's procedure, replacing any previous - definition. +

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 } + + actions [ modifiers ] rulename { commands } + -
Define a rule's updating actions, replacing any - previous definition. +

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.

- rulename field1 : field2 : ... - : fieldN ; + + on target statement ; + -
Invoke a rule. +

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.

- on target rulename field1 : field2 : ... - : fieldN ; - - -
Invoke a rule under the influence of target's specific - variables.. - -

- [ rulename field1 : field2 : ... - : fieldN ]
- [ on target rulename field1 : field2 : ... - : fieldN ]
+ + rule rulename [ : vars ] { statements }
-
Used as an argument, expands to the return value of the rule invoked. +

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 ;

- A rule is invoked with values in field1 through - fieldN. They may be referenced in the procedure's - statements as $(1) through $(N) (9 max), and the - first two only may be referenced in the action's commands - as $(1) and $(2). $(<) and $(>) are synonymous with $(1) - and $(2). + 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 =".)

- Rules fall into two categories: updating rules (with actions), - and pure procedure rules (without actions). Updating rules - treat arguments $(1) and $(2) as built targets and sources, - respectively, while pure procedure rules can take arbitrary - arguments. + 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.

- When an updating rule is invoked, its updating 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, commands are passed to the OS command - shell, with $(1) and $(2) replaced by bound versions of the - target names. See Binding 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). -

- - Rule invokation may be indirected through a variable: - -

- -

- $(var) field1 : field2 : ... - : fieldN ; - - -

- on target $(var) field1 : field2 : ... - : fieldN ; - - -

- [ $(var) field1 : field2 : ... - - : fieldN ]
- [ on target $(var) field1 : field2 : ... - : fieldN ]
- -
- -
- - The variable's value names the rule (or rules) to be invoked. - A rule is invoked for each element in the list of - $(var)'s values. The fields - field1 : field2 : ... are passed as - arguments for each invokation. For the [ ... ] forms, - the return value is the concatenation of the return values for - all of the invokations. - - -

Action Modifiers

- + +

Variable Expansion

+

- The following action modifiers are understood: + 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. -

+

-

actions bind vars -
$(vars) will be replaced with bound values. + 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. -

actions existing -
$(>) includes only source targets currently existing. +

-

actions ignore -
The return status of the commands is ignored. + 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: -

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. +
$(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 -

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. +

-

+ 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 eleven built-in rules, all of which are pure + 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

@@ -597,441 +967,50 @@ jam [ -a ] [ -n ] [ -v ] [ -q ]

Utility Rules
-

- - The two rules ECHO and EXIT are utility rules, used only in - jam's parsing phase. + The remaining rules are utility rules.

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

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

- - "Echo", "echo", "Exit", and "exit" are accepted as aliases for ECHO - and EXIT, since it is hard to tell that these are built-in - rules and not part of the language, like "include". - -

- -

- - The GLOB rule does filename globbing. - -

-

- GLOB directories : patterns + GLOB directories : patterns ; -
Using the same wildcards as for the patterns in the switch statement). It is invoked by being - used as an argument to a rule invocation inside of `[ ]`. For - example: "FILES = [ GLOB dir1 dir2 : *.c *.h ]" sets - A to the list of C source and header files in dir1 or dir2. - The resulting filenames are the full pathnames, including the - directory, but the pattern is applied only to the file name - without the directory. - -
- -

- - The MATCH rule does pattern matching. - -

+
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 + 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 + each string in list, and for each regular expression in regexps. Only useful within the [ ] construct, to change the result into a list.
-

Flow-of-Control

- -

- - Jam has several simple flow-of-control statements: - -

- -

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

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

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

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. - -

- - 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. - -

- - return values ; - - - -

Within a rule body, the return statement sets the return - value for an invocation of the rule. It does not cause the - rule to return; a rule's value is actually the value of the - last statement executed, so a return should be the - last statement executed before the rule "naturally" returns. - -

- - - 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 - updating of the specific target. - -

- - A variable is defined with: - -

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

- - The first two forms set variable globally. The third - and forth 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 final two forms are - synonymous: they set variable globally, but only if it - was previously unset. - -

- - 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 - Assign value to the variable if it 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 Variables

@@ -1096,8 +1075,8 @@ jam [ -a ] [ -n ] [ -v ] [ -q ] 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. - This is the only place where jam invokes a rule through - a variable setting. + $(HDRRULE) is run under the influence of the scanned file's + target-specific variables.

@@ -1156,7 +1135,7 @@ jam [ -a ] [ -n ] [ -v ] [ -q ]

JAMDATETime and date at jam start-up.
JAMUNAMEOuput of uname(1) command (Unix only) -
JAMVERSIONjam version, currently "2.3" +
JAMVERSIONjam version, as reported by jam -v.
@@ -1341,9 +1320,9 @@ jam [ -a ] [ -n ] [ -v ] [ -q ]
Comments to info@perforce.com
- Last updated: April 1, 2002 + Last updated: May, 2002
- $Id: //public/jam/src/Jam.html#11 $ + $Id: //public/jam/src/Jam.html#19 $ diff --git a/src/tools/jam/Jambase.html b/src/tools/jam/Jambase.html index d1cb261365..6ef85e2481 100644 --- a/src/tools/jam/Jambase.html +++ b/src/tools/jam/Jambase.html @@ -5,7 +5,7 @@ Jambase Reference

-Jam/MR +Jam

@@ -14,9 +14,9 @@ Jambase Reference

- Jambase is a base set of Jam/MR rules which + Jambase is a base set of Jam rules which provide roughly make(1)-like functionality for - jam, the Jam/MR executable program. + jam, the Jam executable program. This document, which started out as the Jambase(5) man page, is a reference guide to the rules, @@ -29,10 +29,10 @@ Jambase Reference

  • Using Jamfiles and Jambase
  • - The Jam/MR Executable Program + The Jam Executable Program

    -Jam/MR documentation and source are available from the +Jam documentation and source are available from the Perforce Public Depot. For detailed information about any of the rules summarized below, see the @@ -267,19 +267,19 @@ Jambase Rules Makes target a symbolic link to source, if it isn't one already. (Unix only.) - SubDir VAR d1 ... dn ; + SubDir TOP d1 ... dn ;

    Sets up housekeeping for the source files located - in $(VAR)/d1/.../dn: + in $(TOP)/d1/.../dn:
      -
    • Reads in rules file associated with VAR, +
    • Reads in rules file associated with TOP, if it hasn't already been read.
    • Initializes variables for search paths, output directories, compiler flags, and grist, using d1 ... dn tokens.

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

    @@ -724,8 +724,16 @@ Jambase Variables MSVCNT
    - Selects Microsoft Visual C NT compile & link - actions on NT. + 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.
    @@ -926,6 +934,6 @@ Jambase Variables
    Last updated: Dec 31, 2000
    - $Id: //public/jam/src/Jambase.html#7 $ + $Id: //public/jam/src/Jambase.html#10 $ diff --git a/src/tools/jam/Jamfile.html b/src/tools/jam/Jamfile.html index 7cd9202084..cdfb8ef03a 100644 --- a/src/tools/jam/Jamfile.html +++ b/src/tools/jam/Jamfile.html @@ -5,7 +5,7 @@ Jamfiles and Jambase
    -Jam/MR +Jam

    @@ -14,12 +14,12 @@ Using Jamfiles and Jambase

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

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


    @@ -1445,6 +1445,6 @@ RmTemps Rule
    Last updated: Dec 31, 2000
    - $Id: //public/jam/src/Jamfile.html#5 $ + $Id: //public/jam/src/Jamfile.html#6 $ diff --git a/src/tools/jam/README b/src/tools/jam/README index 97777f09fd..977dff5745 100644 --- a/src/tools/jam/README +++ b/src/tools/jam/README @@ -1,10 +1,10 @@ -Jam/MR (aka "jam - make(1) redux") +Jam - make(1) redux /+\ +\ Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. \+/ - This is Release 2.4 of Jam/MR, a make-like program. + 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 @@ -110,10 +110,12 @@ INSTALLING 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 has really been tested and is known to work. + Only MSVCNT and MSVCDIR have really been tested and are known + to work. Macintosh @@ -142,6 +144,7 @@ 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 Christopher Seiwald diff --git a/src/tools/jam/RELNOTES b/src/tools/jam/RELNOTES index c5743caab8..6403cd578f 100644 --- a/src/tools/jam/RELNOTES +++ b/src/tools/jam/RELNOTES @@ -1,9 +1,259 @@ -Release notes for Jam/MR 2.4 +=============================================================================== +=============================================================================== + + +Release notes for Jam 2.5 +(aka Jam - make(1) redux) + +0. Changes between 2.5rc1 and 2.5rc2: + + Several uninitialized memory accesses have been corrected in + var_expand() and file_archscan(), thanks to Matt Armstrong. + + Fix 'actions updated' broken by change 2487. (See the + description to change 2612 for details). + + Fix "includes of includes not being considered", broken by 2499. + (See the description to change 2614 for details). + + Remove NT FQuote rule, as, \" is required to pass quotes on + the command line. + + Porting change: allow jam to build with BorlandC 5.5 + + Porting change: 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. + + Porting change: 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). + + Porting change: Minor Cray porting: make hashitem()'s key + value unsigned so we're guaranteed no integer overflows. + + SubDir's support for an externally set TOP variable was broken + in 2.5rc1. It now works as it did in 2.4. Further, using SubDir + to include a subpart of an SubDir tree now works. Previously, + you could only include the root of another SubDir tree. For example, + + SubDir ALL src builds ; + SubInclude ALL src server support ; + + Essentially includes the ../server/support/Jamfile, without getting + confused as to the current directory. + +0.1. Changes between 2.5rc2 and 2.5rc3: + + More SubDir work after rc2: if a Jamrules invoked SubDir to + establish other roots, and that Jamrules isn't in the current + directory, the roots it established were wrong. + + Fix mysterious rebuild problem: in an attempt to make 'jam -dc' + output report headers updates more accurately, internal (header + collection) targets were being bound as T_BIND_PARENTS so that + they could carry the timestamp of the actual source file. But + that caused the fate of the internal node to be marked as + T_FATE_NEEDTMP if anything they included was newer, and that + easily happens among header files (something is always newer + than something else). Now internal targets carry their parents + time, but with T_BIND_UNBOUND, like other NOTFILE targets. + + 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. + + 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. + +1. Release info: + + Jam 2.5 + January 20, 2002 + VERSION 2.5 + +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. + + $(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. + +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. + + +=============================================================================== +=============================================================================== + + +Release notes for Jam 2.4 (aka Jam - make(1) redux) 1. Release info: - Jam/MR 2.4 + Jam 2.4 March, 21, 2002 VERSION 2.4 @@ -196,7 +446,7 @@ Release notes for Jam/MR 2.4 =============================================================================== -Release notes for Jam/MR 2.3 +Release notes for Jam 2.3 (aka Jam - make(1) redux) 0. Bugs fixed since 2.3.1 @@ -211,7 +461,7 @@ Release notes for Jam/MR 2.3 1. Release info: - Jam/MR 2.3 + Jam 2.3 November 16, 2000 VERSION 2.3 PATCHLEVEL 1 @@ -258,7 +508,7 @@ Release notes for Jam/MR 2.3 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 [] synxtax. + 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 diff --git a/src/tools/jam/builtins.c b/src/tools/jam/builtins.c index b40e9ce753..a1b317c9d0 100644 --- a/src/tools/jam/builtins.c +++ b/src/tools/jam/builtins.c @@ -4,17 +4,6 @@ * This file is part of Jam - see jam.c for Copyright information. */ -# 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" - /* * builtins.c - builtin jam rules * @@ -32,8 +21,27 @@ * 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 */ @@ -41,14 +49,14 @@ # define P0 (PARSE *)0 # define C0 (char *)0 -LIST *builtin_depends( PARSE *parse, LOL *args ); -LIST *builtin_echo( PARSE *parse, LOL *args ); -LIST *builtin_exit( PARSE *parse, LOL *args ); -LIST *builtin_flags( PARSE *parse, LOL *args ); -LIST *builtin_glob( PARSE *parse, LOL *args ); -LIST *builtin_match( PARSE *parse, LOL *args ); +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( char *s, char *c ); +int glob( const char *s, const char *c ); void load_builtins() @@ -59,7 +67,7 @@ load_builtins() bindrule( "Depends" )->procedure = bindrule( "DEPENDS" )->procedure = - parse_make( builtin_depends, P0, P0, P0, C0, C0, T_DEPS_DEPENDS ); + parse_make( builtin_depends, P0, P0, P0, C0, C0, 0 ); bindrule( "echo" )->procedure = bindrule( "Echo" )->procedure = @@ -77,7 +85,7 @@ load_builtins() bindrule( "Includes" )->procedure = bindrule( "INCLUDES" )->procedure = - parse_make( builtin_depends, P0, P0, P0, C0, C0, T_DEPS_INCLUDES ); + parse_make( builtin_depends, P0, P0, P0, C0, C0, 1 ); bindrule( "Leaves" )->procedure = bindrule( "LEAVES" )->procedure = @@ -116,17 +124,29 @@ load_builtins() LIST * builtin_depends( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { LIST *targets = lol_get( args, 0 ); LIST *sources = lol_get( args, 1 ); - int which = parse->num; LIST *l; for( l = targets; l; l = list_next( l ) ) { TARGET *t = bindtarget( l->string ); - t->deps[ which ] = targetlist( t->deps[ which ], sources ); + + /* 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; @@ -142,7 +162,8 @@ builtin_depends( LIST * builtin_echo( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { list_print( lol_get( args, 0 ) ); printf( "\n" ); @@ -159,7 +180,8 @@ builtin_echo( LIST * builtin_exit( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { list_print( lol_get( args, 0 ) ); printf( "\n" ); @@ -177,7 +199,8 @@ builtin_exit( LIST * builtin_flags( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { LIST *l = lol_get( args, 0 ); @@ -199,7 +222,7 @@ struct globbing { static void builtin_glob_back( void *closure, - char *file, + const char *file, int status, time_t time ) { @@ -218,7 +241,7 @@ builtin_glob_back( for( l = globbing->patterns; l; l = l->next ) if( !glob( l->string, buf ) ) { - globbing->results = list_new( globbing->results, newstr( file ) ); + globbing->results = list_new( globbing->results, file, 0 ); break; } } @@ -226,7 +249,8 @@ builtin_glob_back( LIST * builtin_glob( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { LIST *l = lol_get( args, 0 ); LIST *r = lol_get( args, 1 ); @@ -249,7 +273,8 @@ builtin_glob( LIST * builtin_match( PARSE *parse, - LOL *args ) + LOL *args, + int *jmp ) { LIST *l, *r; LIST *result = 0; @@ -282,7 +307,7 @@ builtin_match( int l = re->endp[i] - re->startp[i]; memcpy( buf, re->startp[i], l ); buf[ l ] = 0; - result = list_new( result, newstr( buf ) ); + result = list_new( result, buf, 0 ); } } diff --git a/src/tools/jam/builtins.h b/src/tools/jam/builtins.h index e4320b7b18..beecb32e84 100644 --- a/src/tools/jam/builtins.h +++ b/src/tools/jam/builtins.h @@ -6,6 +6,8 @@ /* * builtins.h - compile parsed jam statements + * + * 01/10/01 (seiwald) - split from compile.h */ void load_builtins(); diff --git a/src/tools/jam/command.c b/src/tools/jam/command.c index 60c3eb20a2..931b4c83a2 100644 --- a/src/tools/jam/command.c +++ b/src/tools/jam/command.c @@ -6,6 +6,9 @@ /* * 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" @@ -26,7 +29,8 @@ cmd_new( RULE *rule, LIST *targets, LIST *sources, - LIST *shell ) + LIST *shell, + int maxline ) { CMD *cmd = (CMD *)malloc( sizeof( CMD ) ); @@ -38,10 +42,10 @@ cmd_new( lol_add( &cmd->args, targets ); lol_add( &cmd->args, sources ); - /* Bail if the result won't fit in MAXLINE */ + /* 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 ) + if( var_string( rule->actions, cmd->buf, maxline, &cmd->args ) < 0 ) { cmd_free( cmd ); return 0; diff --git a/src/tools/jam/command.h b/src/tools/jam/command.h index 9044cb4ea4..28ecd7a670 100644 --- a/src/tools/jam/command.h +++ b/src/tools/jam/command.h @@ -51,7 +51,8 @@ CMD *cmd_new( RULE *rule, /* rule (referenced) */ LIST *targets, /* $(<) (freed) */ LIST *sources, /* $(>) (freed) */ - LIST *shell ); /* $(SHELL) (freed) */ + LIST *shell, /* $(SHELL) (freed) */ + int maxline ); /* max line length */ void cmd_free( CMD *cmd ); diff --git a/src/tools/jam/execmac.c b/src/tools/jam/execmac.c index 20217dab19..d96358bf90 100644 --- a/src/tools/jam/execmac.c +++ b/src/tools/jam/execmac.c @@ -4,13 +4,6 @@ * This file is part of Jam - see jam.c for Copyright information. */ -# include "jam.h" -# include "lists.h" -# include "execcmd.h" -# include - -# ifdef OS_MAC - /* * execunix.c - execute a shell script on UNIX * @@ -38,8 +31,16 @@ * 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 */ diff --git a/src/tools/jam/execunix.c b/src/tools/jam/execunix.c index 0eb03ca3ae..6cde87a1b0 100644 --- a/src/tools/jam/execunix.c +++ b/src/tools/jam/execunix.c @@ -4,30 +4,6 @@ * This file is part of Jam - see jam.c for Copyright information. */ -# include "jam.h" -# include "lists.h" -# include "execcmd.h" -# include - -# ifdef USE_EXECUNIX - -# ifdef NO_VFORK -# define vfork() fork() -# endif - -# if defined( OS_NT ) || defined( OS_OS2 ) - -# define USE_EXECNT - -# include - -# if !defined( __BORLANDC__ ) && !defined( OS_OS2 ) -# define wait my_wait -static int my_wait( int *status ); -# endif - -# endif - /* * execunix.c - execute a shell script on UNIX/WinNT/OS2/AmigaOS * @@ -57,8 +33,35 @@ static int my_wait( int *status ); * 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 ); @@ -99,7 +102,7 @@ execcmd( { int pid; int slot; - char *argv[ MAXARGC + 1 ]; /* +1 for NULL */ + const char *argv[ MAXARGC + 1 ]; /* +1 for NULL */ # ifdef USE_EXECNT char *p; @@ -126,10 +129,12 @@ execcmd( !( tempdir = getenv( "TMP" ) ) ) tempdir = "\\temp"; - cmdtab[ slot ].tempfile = malloc( strlen( tempdir ) + 14 ); + /* +32 is room for \jamXXXXXtSS.bat (at least) */ - sprintf( cmdtab[ slot ].tempfile, "%s\\jamtmp%02d.bat", - tempdir, slot ); + cmdtab[ slot ].tempfile = malloc( strlen( tempdir ) + 32 ); + + sprintf( cmdtab[ slot ].tempfile, "%s\\jam%dt%d.bat", + tempdir, GetCurrentProcessId(), slot ); } /* Trim leading, ending white space */ @@ -216,12 +221,20 @@ execcmd( 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); + execvp( argv[0], argv ); + _exit(127); } +# endif if( pid == -1 ) { @@ -283,6 +296,12 @@ execwait() exit( EXITBAD ); } +# ifdef USE_EXECNT + /* Clear the temp file */ + + unlink( cmdtab[ i ].tempfile ); +# endif + /* Drive the completion */ if( !--cmdsrunning ) @@ -302,11 +321,7 @@ execwait() return 1; } -# if defined( OS_NT ) && !defined( __BORLANDC__ ) - -# define WIN32_LEAN_AND_MEAN - -# include /* do the ugly deed */ +# ifdef USE_MYWAIT static int my_wait( int *status ) @@ -365,6 +380,6 @@ FAILED: } -# endif /* NT && !__BORLANDC__ */ +# endif /* USE_MYWAIT */ # endif /* USE_EXECUNIX */ diff --git a/src/tools/jam/execvms.c b/src/tools/jam/execvms.c index 0bf5486f2f..f1db2309f6 100644 --- a/src/tools/jam/execvms.c +++ b/src/tools/jam/execvms.c @@ -4,21 +4,6 @@ * This file is part of Jam - see jam.c for Copyright information. */ -# include "jam.h" -# include "lists.h" -# include "execcmd.h" - -# ifdef OS_VMS - -#include -#include -#include -#include -#include -#include -#include -#include - /* * execvms.c - execute a shell script, ala VMS * @@ -36,8 +21,24 @@ * 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)) diff --git a/src/tools/jam/expand.c b/src/tools/jam/expand.c index 706c18379c..68f8826034 100644 --- a/src/tools/jam/expand.c +++ b/src/tools/jam/expand.c @@ -4,13 +4,6 @@ * This file is part of Jam - see jam.c for Copyright information. */ -# include "jam.h" -# include "lists.h" -# include "variable.h" -# include "expand.h" -# include "pathsys.h" -# include "newstr.h" - /* * expand.c - expand a buffer, given variable values * @@ -26,9 +19,23 @@ * * 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 */ @@ -39,8 +46,8 @@ typedef struct { PATHPART join; /* :J -- join list with char */ } VAR_EDITS ; -static void var_edit_parse( char *mods, VAR_EDITS *edits ); -static void var_edit_file( char *in, char *out, VAR_EDITS *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' @@ -61,15 +68,15 @@ static void var_edit_shift( char *out, VAR_EDITS *edits ); LIST * var_expand( - LIST *l, - char *in, - char *end, - LOL *lol, - int cancopyin ) + LIST *l, + const char *in, + const char *end, + LOL *lol, + int cancopyin ) { char out_buf[ MAXSYM ]; char *out = out_buf; - char *inp = in; + const char *inp = in; char *ov; /* for temp copy of variable in outbuf */ int depth; @@ -78,7 +85,7 @@ var_expand( /* This gets alot of cases: $(<) and $(>) */ - if( in[0] == '$' && in[1] == '(' && in[3] == ')' && !in[4] ) + if( end - in == 4 && in[0] == '$' && in[1] == '(' && in[3] == ')' ) { switch( in[2] ) { @@ -107,9 +114,9 @@ var_expand( *out = '\0'; if( cancopyin ) - return list_new( l, copystr( inp ) ); + return list_new( l, inp, 1 ); else - return list_new( l, newstr( out_buf ) ); + return list_new( l, out_buf, 0 ); expand: /* @@ -258,7 +265,7 @@ var_expand( /* Empty w/ :E=default? */ if( !value && colon && edits.empty.ptr ) - evalue = value = list_new( L0, newstr( edits.empty.ptr ) ); + evalue = value = list_new( L0, edits.empty.ptr, 0 ); /* For each variable value */ @@ -300,7 +307,7 @@ var_expand( if( in == end ) { - l = list_new( l, newstr( out_buf ) ); + l = list_new( l, out_buf, 0 ); continue; } @@ -314,7 +321,7 @@ var_expand( for( rem = remainder; rem; rem = list_next( rem ) ) { strcpy( out1, rem->string ); - l = list_new( l, newstr( out_buf ) ); + l = list_new( l, out_buf, 0 ); } } @@ -380,7 +387,7 @@ var_expand( static void var_edit_parse( - char *mods, + const char *mods, VAR_EDITS *edits ) { int havezeroed = 0; @@ -463,7 +470,7 @@ var_edit_parse( static void var_edit_file( - char *in, + const char *in, char *out, VAR_EDITS *edits ) { diff --git a/src/tools/jam/expand.h b/src/tools/jam/expand.h index c0644b150a..65f3b5f8e3 100644 --- a/src/tools/jam/expand.h +++ b/src/tools/jam/expand.h @@ -6,6 +6,13 @@ /* * expand.h - expand a buffer, given variable values + * + * 11/04/02 (seiwald) - const-ing for string literals */ -LIST *var_expand( LIST *l, char *in, char *end, LOL *lol, int cancopyin ); +LIST *var_expand( + LIST *l, + const char *in, + const char *end, + LOL *lol, + int cancopyin ); diff --git a/src/tools/jam/filemac.c b/src/tools/jam/filemac.c index fcfa93cf9d..5b3be5a2f8 100644 --- a/src/tools/jam/filemac.c +++ b/src/tools/jam/filemac.c @@ -3,17 +3,6 @@ * * This file is part of Jam - see jam.c for Copyright information. */ - -# include "jam.h" -# include "filesys.h" -# include "pathsys.h" - -# ifdef OS_MAC - -#include -#include - -# include <:sys:stat.h> /* * filemac.c - manipulate file names and scan directories on macintosh @@ -35,7 +24,21 @@ * 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) { @@ -53,7 +56,7 @@ void CopyC2PStr(const char * cstr, StringPtr pstr) void file_dirscan( - char *dir, + const char *dir, scanback func, void *closure ) { @@ -135,7 +138,7 @@ file_dirscan( int file_time( - char *filename, + const char *filename, time_t *time ) { struct stat statbuf; @@ -154,7 +157,7 @@ file_time( void file_archscan( - char *archive, + const char *archive, scanback func, void *closure ) { diff --git a/src/tools/jam/filent.c b/src/tools/jam/filent.c index d061d4b3a8..7a335818a8 100644 --- a/src/tools/jam/filent.c +++ b/src/tools/jam/filent.c @@ -4,6 +4,30 @@ * 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" @@ -22,39 +46,26 @@ # include # include -/* - * 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 - */ - /* * file_dirscan() - scan a directory for files */ +# ifdef _M_IA64 +# define FINDTYPE long long +# else +# define FINDTYPE long +# endif + void file_dirscan( - char *dir, + const char *dir, scanback func, void *closure ) { PATHNAME f; char filespec[ MAXJPATH ]; char filename[ MAXJPATH ]; - long handle; + FINDTYPE handle; int ret; struct _finddata_t finfo[1]; @@ -102,7 +113,7 @@ file_dirscan( # else handle = _findfirst( filespec, finfo ); - if( ret = ( handle < 0L ) ) + if( ret = ( handle == (FINDTYPE)(-1) ) ) return; while( !ret ) @@ -128,7 +139,7 @@ file_dirscan( int file_time( - char *filename, + const char *filename, time_t *time ) { /* On NT this is called only for C:/ */ @@ -169,7 +180,7 @@ struct ar_hdr { void file_archscan( - char *archive, + const char *archive, scanback func, void *closure ) { diff --git a/src/tools/jam/fileos2.c b/src/tools/jam/fileos2.c index bcf9fe6b58..18477574f6 100644 --- a/src/tools/jam/fileos2.c +++ b/src/tools/jam/fileos2.c @@ -4,15 +4,6 @@ * This file is part of Jam - see jam.c for Copyright information. */ -# include "jam.h" -# include "filesys.h" -# include "pathsys.h" - -# ifdef OS_OS2 - -# include -# include - /* * fileos2.c - scan directories and archives on NT * @@ -30,16 +21,28 @@ * * 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( - char *dir, + const char *dir, scanback func, void *closure ) { @@ -103,7 +106,7 @@ file_dirscan( int file_time( - char *filename, + const char *filename, time_t *time ) { /* This is called on OS2, not NT. */ @@ -121,7 +124,7 @@ file_time( void file_archscan( - char *archive, + const char *archive, scanback func, void *closure ) { diff --git a/src/tools/jam/filesys.h b/src/tools/jam/filesys.h index a99a0b5502..e424f29e09 100644 --- a/src/tools/jam/filesys.h +++ b/src/tools/jam/filesys.h @@ -6,11 +6,13 @@ /* * filesys.h - OS specific file routines + * + * 11/04/02 (seiwald) - const-ing for string literals */ -typedef void (*scanback)( void *closure, char *file, int found, time_t t ); +typedef void (*scanback)( void *closure, const char *file, int found, time_t t ); -void file_dirscan( char *dir, scanback func, void *closure ); -void file_archscan( char *arch, scanback func, void *closure ); +void file_dirscan( const char *dir, scanback func, void *closure ); +void file_archscan( const char *arch, scanback func, void *closure ); -int file_time( char *filename, time_t *time ); +int file_time( const char *filename, time_t *time ); diff --git a/src/tools/jam/fileunix.c b/src/tools/jam/fileunix.c index 406d31fecb..41127a293a 100644 --- a/src/tools/jam/fileunix.c +++ b/src/tools/jam/fileunix.c @@ -4,6 +4,35 @@ * 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" @@ -35,7 +64,7 @@ # endif # if defined( OS_MVS ) || \ - defined( OS_INTERIX ) || defined(OS_AIX) + defined( OS_INTERIX ) #define ARMAG "!\n" #define SARMAG 8 @@ -63,38 +92,20 @@ struct ar_hdr /* archive file member header - printable ascii */ # endif # ifndef HAVE_AR +# ifdef _AIX43 +/* AIX 43 ar SUPPORTs only __AR_BIG__ */ +# define __AR_BIG__ +# endif # include # endif -/* - * 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 - */ - /* * file_dirscan() - scan a directory for files */ void file_dirscan( - char *dir, + const char *dir, scanback func, void *closure ) { @@ -149,7 +160,7 @@ file_dirscan( int file_time( - char *filename, + const char *filename, time_t *time ) { struct stat statbuf; @@ -172,7 +183,7 @@ file_time( void file_archscan( - char *archive, + const char *archive, scanback func, void *closure ) { @@ -201,58 +212,92 @@ file_archscan( while( read( fd, &ar_hdr, SARHDR ) == SARHDR && !memcmp( ar_hdr.ar_fmag, ARFMAG, SARFMAG ) ) { - char lar_name[256]; long lar_date; long lar_size; - long lar_offset; - char *c; - char *src, *dest; + char lar_name[256]; + char *dst = lar_name; - strncpy( lar_name, ar_hdr.ar_name, sizeof(ar_hdr.ar_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 ); - if (ar_hdr.ar_name[0] == '/') - { - 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 - */ + /* Handle solaris string table. + ** The entry under the name // is the table, + ** and entries with the name /nnnn refer to the table. + */ - 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. - */ - dest = lar_name; - lar_offset = atoi(lar_name + 1); - src = &string_table[lar_offset]; - while (*src != '/') - *dest++ = *src++; - *dest = '/'; - } + 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++; } - c = lar_name - 1; - while( *++c != ' ' && *c != '/' ) - ; - *c = '\0'; + /* Terminate lar_name */ - if ( DEBUG_BINDSCAN ) - printf( "archive name %s found\n", lar_name ); + *dst = 0; - sprintf( buf, "%s(%s)", archive, lar_name ); + /* Modern (BSD4.4) long names: if the name is "#1/nnnn", + ** then the actual name is the nnnn bytes after the header. + */ - (*func)( closure, buf, 1 /* time valid */, (time_t)lar_date ); + 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 ); @@ -271,7 +316,7 @@ file_archscan( void file_archscan( - char *archive, + const char *archive, scanback func, void *closure ) { @@ -289,6 +334,20 @@ file_archscan( 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 ) ) { @@ -296,6 +355,8 @@ file_archscan( return; } +# endif + sscanf( fl_hdr.fl_fstmoff, "%ld", &offset ); if( DEBUG_BINDSCAN ) diff --git a/src/tools/jam/filevms.c b/src/tools/jam/filevms.c index dc2fe4c114..3699976c12 100644 --- a/src/tools/jam/filevms.c +++ b/src/tools/jam/filevms.c @@ -4,12 +4,6 @@ * This file is part of Jam - see jam.c for Copyright information. */ -# include "jam.h" -# include "filesys.h" -# include "pathsys.h" - -# ifdef OS_VMS - /* * filevms.c - scan directories and libaries on VMS * @@ -27,8 +21,17 @@ * * 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 @@ -99,7 +102,7 @@ file_cvttime( void file_dirscan( - char *dir, + const char *dir, scanback func, void *closure ) { @@ -135,7 +138,7 @@ file_dirscan( 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 = dir; /* address of file name */ + 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 */ @@ -224,7 +227,7 @@ file_dirscan( int file_time( - char *filename, + const char *filename, time_t *time ) { /* This should never be called, as all files are */ @@ -281,7 +284,7 @@ file_archmember( void file_archscan( - char *archive, + const char *archive, scanback func, void *closure ) { @@ -294,7 +297,7 @@ file_archscan( register int status; - VMS_archive = archive; + VMS_archive = (char *)archive; VMS_func = func; VMS_closure = closure; @@ -302,7 +305,7 @@ file_archscan( if ( !( status & 1 ) ) return; - library.dsc$a_pointer = archive; + library.dsc$a_pointer = (char *)archive; library.dsc$w_length = strlen( archive ); status = lbr$open( &context, &library, NULL, NULL, NULL, NULL, NULL ); diff --git a/src/tools/jam/glob.c b/src/tools/jam/glob.c index abb56eb1be..74d6e7e0fd 100644 --- a/src/tools/jam/glob.c +++ b/src/tools/jam/glob.c @@ -22,6 +22,8 @@ * Internal functions: * * globchars() - build a bitlist to check for character group match + * + * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" @@ -29,7 +31,7 @@ # define CHECK_BIT( tab, bit ) ( tab[ (bit)/8 ] & (1<<( (bit)%8 )) ) # define BITLISTSIZE 16 /* bytes used for [chars] in compiled expr */ -static void globchars( char *s, char *e, char *b ); +static void globchars( const char *s, const char *e, char *b ); /* * glob() - match a string against a simple pattern @@ -37,11 +39,11 @@ static void globchars( char *s, char *e, char *b ); int glob( - register char *c, - register char *s ) + const char *c, + const char *s ) { char bitlist[ BITLISTSIZE ]; - char *here; + const char *here; for( ;; ) switch( *c++ ) @@ -118,8 +120,8 @@ glob( static void globchars( - char *s, - char *e, + const char *s, + const char *e, char *b ) { int neg = 0; diff --git a/src/tools/jam/hash.c b/src/tools/jam/hash.c index 1d11efa22b..015181c0e1 100644 --- a/src/tools/jam/hash.c +++ b/src/tools/jam/hash.c @@ -4,9 +4,6 @@ * This file is part of Jam - see jam.c for Copyright information. */ -# include "jam.h" -# include "hash.h" - /* * hash.c - simple in-memory hashing routines * @@ -21,15 +18,18 @@ * 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) */ -char *hashsccssid="@(#)hash.c 1.14 () 6/20/88"; +# include "jam.h" +# include "hash.h" /* Header attached to all data items entered into a hash table. */ struct hashhdr { struct item *next; - int keyval; /* for quick comparisons */ + unsigned int keyval; /* for quick comparisons */ } ; /* This structure overlays the one handed to hashenter(). */ @@ -78,7 +78,7 @@ struct hash } lists[ MAX_LISTS ]; } items; - char *name; /* just for hashstats() */ + const char *name; /* just for hashstats() */ } ; static void hashrehash( struct hash *hp ); @@ -96,8 +96,8 @@ hashitem( { ITEM **base; register ITEM *i; - char *b = (*data)->key; - int keyval; + unsigned char *b = (unsigned char *)(*data)->key; + unsigned int keyval; if( enter && !hp->items.more ) hashrehash( hp ); @@ -110,8 +110,6 @@ hashitem( while( *b ) keyval = keyval * 2147059363 + *b++; - keyval &= 0x7FFFFFFF; - base = hp->tab.base + ( keyval % hp->tab.nel ); for( i = *base; i; i = i->hdr.next ) @@ -187,7 +185,7 @@ static void hashrehash( register struct hash *hp ) struct hash * hashinit( int datalen, - char *name ) + const char *name ) { struct hash *hp = (struct hash *)malloc( sizeof( *hp ) ); diff --git a/src/tools/jam/hash.h b/src/tools/jam/hash.h index 65af38c323..28149e2be4 100644 --- a/src/tools/jam/hash.h +++ b/src/tools/jam/hash.h @@ -6,11 +6,13 @@ /* * 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, char *name ); +struct hash * hashinit( int datalen, const char *name ); int hashitem( struct hash *hp, HASHDATA **data, int enter ); void hashdone( struct hash *hp ); diff --git a/src/tools/jam/lists.c b/src/tools/jam/lists.c index e205e0ff39..92f3f9f16a 100644 --- a/src/tools/jam/lists.c +++ b/src/tools/jam/lists.c @@ -4,10 +4,6 @@ * This file is part of Jam - see jam.c for Copyright information. */ -# include "jam.h" -# include "newstr.h" -# include "lists.h" - /* * lists.c - maintain lists of strings * @@ -23,8 +19,15 @@ * * 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() */ /* @@ -61,13 +64,18 @@ list_append( LIST * list_new( LIST *head, - char *string ) + 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 */ @@ -107,7 +115,7 @@ list_copy( LIST *nl ) { for( ; nl; nl = list_next( nl ) ) - l = list_new( l, copystr( nl->string ) ); + l = list_new( l, nl->string, 1 ); return l; } @@ -128,7 +136,7 @@ list_sublist( ; for( ; l && count--; l = list_next( l ) ) - nl = list_new( nl, copystr( l->string ) ); + nl = list_new( nl, l->string, 1 ); return nl; } @@ -160,6 +168,44 @@ list_print( LIST *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 */ diff --git a/src/tools/jam/lists.h b/src/tools/jam/lists.h index 33afc58860..0b02d74265 100644 --- a/src/tools/jam/lists.h +++ b/src/tools/jam/lists.h @@ -24,6 +24,7 @@ * 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) @@ -34,6 +35,9 @@ * * 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 */ /* @@ -43,9 +47,9 @@ typedef struct _list LIST; struct _list { - LIST *next; - LIST *tail; /* only valid in head node */ - char *string; /* private copy */ + LIST *next; + LIST *tail; /* only valid in head node */ + const char *string; /* private copy */ } ; /* @@ -64,7 +68,7 @@ struct _lol { LIST * list_append( LIST *l, LIST *nl ); LIST * list_copy( LIST *l, LIST *nl ); void list_free( LIST *head ); -LIST * list_new( LIST *head, char *string ); +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 ); diff --git a/src/tools/jam/make.h b/src/tools/jam/make.h index 87ca862093..9fa0b73d06 100644 --- a/src/tools/jam/make.h +++ b/src/tools/jam/make.h @@ -6,7 +6,9 @@ /* * 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, char **targets, int anyhow ); +int make( int n_targets, const char **targets, int anyhow ); int make1( TARGET *t ); diff --git a/src/tools/jam/make1.c b/src/tools/jam/make1.c index f2e62459f2..b12ca3cef9 100644 --- a/src/tools/jam/make1.c +++ b/src/tools/jam/make1.c @@ -26,7 +26,7 @@ * * 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 values, build up replacement lists + * 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. @@ -38,6 +38,15 @@ * 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" @@ -116,7 +125,6 @@ make1a( TARGET *parent ) { TARGETS *c; - int i; /* If the parent is the first to try to build this target */ /* or this target is in the make1c() quagmire, arrange for the */ @@ -148,9 +156,8 @@ make1a( t->progress = T_MAKE_ONSTACK; - for( i = T_DEPS_DEPENDS; i <= T_DEPS_INCLUDES; i++ ) - for( c = t->deps[i]; c && !intr; c = c->next ) - make1a( c->target, t ); + for( c = t->depends; c && !intr; c = c->next ) + make1a( c->target, t ); t->progress = T_MAKE_ACTIVE; @@ -168,8 +175,7 @@ static void make1b( TARGET *t ) { TARGETS *c; - int i; - char *failed = "dependents"; + const char *failed = "dependents"; /* If any dependents are still outstanding, wait until they */ /* call make1b() to signal their completion. */ @@ -181,9 +187,8 @@ make1b( TARGET *t ) /* Collect status from dependents */ - for( i = T_DEPS_DEPENDS; i <= T_DEPS_INCLUDES; i++ ) - for( c = t->deps[i]; c; c = c->next ) - if( c->target->status > t->status ) + for( c = t->depends; c; c = c->next ) + if( c->target->status > t->status ) { failed = c->target->name; t->status = c->target->status; @@ -215,12 +220,13 @@ make1b( TARGET *t ) break; case T_FATE_ISTMP: - if( DEBUG_MAKE ) + 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 */ @@ -421,7 +427,7 @@ make1cmds( ACTIONS *a0 ) LIST *nt, *ns; ACTIONS *a1; CMD *cmd; - int start, chunk, length; + int start, chunk, length, maxline; /* Only do rules with commands to execute. */ /* If this action has already been executed, use saved status */ @@ -475,10 +481,15 @@ make1cmds( ACTIONS *a0 ) * 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 { @@ -487,7 +498,8 @@ make1cmds( ACTIONS *a0 ) CMD *cmd = cmd_new( rule, list_copy( L0, nt ), list_sublist( ns, start, chunk ), - list_copy( L0, shell ) ); + list_copy( L0, shell ), + maxline ); if( cmd ) { @@ -509,7 +521,7 @@ make1cmds( ACTIONS *a0 ) /* Too long and not splittable. */ printf( "%s actions too long (max %d)!\n", - rule->name, MAXLINE ); + rule->name, maxline ); exit( EXITBAD ); } } @@ -574,7 +586,7 @@ make1list( /* Build new list */ - l = list_new( l, copystr( t->boundname ) ); + l = list_new( l, t->boundname, 1 ); } return l; @@ -606,7 +618,7 @@ make1settings( LIST *vars ) /* Build new list */ - nl = list_new( nl, copystr( t->boundname ) ); + nl = list_new( nl, t->boundname, 1 ); } /* Add to settings chain */ diff --git a/src/tools/jam/mkjambase.c b/src/tools/jam/mkjambase.c index 2a67db7ea5..26224c977d 100644 --- a/src/tools/jam/mkjambase.c +++ b/src/tools/jam/mkjambase.c @@ -18,6 +18,7 @@ * * Handles \'s and "'s specially; knows to delete blank and comment lines. * + * 11/04/02 (seiwald) - const-ing for string literals */ # include @@ -55,7 +56,7 @@ main( int argc, char **argv, char **envp ) if( doDotC ) { fprintf( fout, "/* Generated by mkjambase from Jambase */\n" ); - fprintf( fout, "char *jambase[] = {\n" ); + fprintf( fout, "const char *jambase[] = {\n" ); } for( ; argc--; argv++ ) diff --git a/src/tools/jam/newstr.c b/src/tools/jam/newstr.c index 08336480ee..c3c2d3bdb0 100644 --- a/src/tools/jam/newstr.c +++ b/src/tools/jam/newstr.c @@ -4,10 +4,6 @@ * This file is part of Jam - see jam.c for Copyright information. */ -# include "jam.h" -# include "newstr.h" -# include "hash.h" - /* * newstr.c - string manipulation routines * @@ -26,9 +22,15 @@ * 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 */ -typedef char *STRING; +# include "jam.h" +# include "newstr.h" +# include "hash.h" + +typedef const char *STRING; static struct hash *strhash = 0; static int strtotal = 0; @@ -37,8 +39,8 @@ static int strtotal = 0; * newstr() - return a malloc'ed copy of a string */ -char * -newstr( char *string ) +const char * +newstr( const char *string ) { STRING str, *s = &str; @@ -67,8 +69,8 @@ newstr( char *string ) * copystr() - return a copy of a string previously returned by newstr() */ -char * -copystr( char *s ) +const char * +copystr( const char *s ) { return s; } @@ -78,7 +80,7 @@ copystr( char *s ) */ void -freestr( char *s ) +freestr( const char *s ) { } diff --git a/src/tools/jam/newstr.h b/src/tools/jam/newstr.h index cf2dd34b7e..87d59a85c4 100644 --- a/src/tools/jam/newstr.h +++ b/src/tools/jam/newstr.h @@ -6,9 +6,11 @@ /* * newstr.h - string manipulation routines + * + * 11/04/02 (seiwald) - const-ing for string literals */ -char *newstr( char *string ); -char *copystr( char *s ); -void freestr( char *s ); +const char *newstr( const char *string ); +const char *copystr( const char *s ); +void freestr( const char *s ); void donestr(); diff --git a/src/tools/jam/option.c b/src/tools/jam/option.c index e4491523cb..ad3825f191 100644 --- a/src/tools/jam/option.c +++ b/src/tools/jam/option.c @@ -4,9 +4,6 @@ * This file is part of Jam - see jam.c for Copyright information. */ -# include "jam.h" -# include "option.h" - /* * option.c - command line option processing * @@ -15,13 +12,18 @@ * 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, - char *opts, + const char *opts, option *optv ) { int i; @@ -44,7 +46,7 @@ getoptions( for( arg = &argv[i][1]; *arg; arg++ ) { - char *f; + const char *f; for( f = opts; *f; f++ ) if( *f == *arg ) @@ -87,7 +89,7 @@ getoptions( * Name: getoptval() - find an option given its character */ -char * +const char * getoptval( option *optv, char opt, diff --git a/src/tools/jam/option.h b/src/tools/jam/option.h index 657a763a08..beb461f9e6 100644 --- a/src/tools/jam/option.h +++ b/src/tools/jam/option.h @@ -9,15 +9,17 @@ * * {o >o * \ -) "Command line option." + * + * 11/04/02 (seiwald) - const-ing for string literals */ typedef struct option { - char flag; /* filled in by getoption() */ - char *val; /* set to random address if true */ + 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, char *opts, option *optv ); -char * getoptval( option *optv, char opt, int subopt ); +int getoptions( int argc, char **argv, const char *opts, option *optv ); +const char * getoptval( option *optv, char opt, int subopt ); diff --git a/src/tools/jam/patchlevel.h b/src/tools/jam/patchlevel.h index ae63fd4eba..205eb66506 100644 --- a/src/tools/jam/patchlevel.h +++ b/src/tools/jam/patchlevel.h @@ -1,5 +1,5 @@ /* Keep JAMVERSYM in sync with VERSION. */ /* It can be accessed as $(JAMVERSION) in the Jamfile. */ -#define VERSION "2.4" -#define JAMVERSYM "JAMVERSION=2.4" +#define VERSION "2.5rc3" +#define JAMVERSYM "JAMVERSION=2.5" diff --git a/src/tools/jam/pathmac.c b/src/tools/jam/pathmac.c index 541729bb43..40a981f4eb 100644 --- a/src/tools/jam/pathmac.c +++ b/src/tools/jam/pathmac.c @@ -4,13 +4,6 @@ * This file is part of Jam - see jam.c for Copyright information. */ -# include "jam.h" -# include "pathsys.h" - -# ifdef OS_MAC - -# define DELIM ':' - /* * pathunix.c - manipulate file names on UNIX, NT, OS2 * @@ -39,19 +32,27 @@ * 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( - char *file, + const char *file, PATHNAME *f ) { - char *p, *q; - char *end; + const char *p, *q; + const char *end; memset( (char *)f, 0, sizeof( *f ) ); @@ -142,7 +143,7 @@ char grid[5][5] = { static int file_flags( - char *ptr, + const char *ptr, int len ) { if( !len ) diff --git a/src/tools/jam/pathsys.h b/src/tools/jam/pathsys.h index c16442bbc4..c8c94521a1 100644 --- a/src/tools/jam/pathsys.h +++ b/src/tools/jam/pathsys.h @@ -6,6 +6,8 @@ /* * pathsys.h - PATHNAME struct + * + * 11/04/02 (seiwald) - const-ing for string literals */ /* @@ -24,7 +26,7 @@ typedef struct _pathname PATHNAME; typedef struct _pathpart PATHPART; struct _pathpart { - char *ptr; + const char *ptr; int len; }; @@ -44,6 +46,6 @@ struct _pathname { } ; void path_build( PATHNAME *f, char *file, int binding ); -void path_parse( char *file, PATHNAME *f ); +void path_parse( const char *file, PATHNAME *f ); void path_parent( PATHNAME *f ); diff --git a/src/tools/jam/pathunix.c b/src/tools/jam/pathunix.c index ae0bd01a44..5fa09418d1 100644 --- a/src/tools/jam/pathunix.c +++ b/src/tools/jam/pathunix.c @@ -4,11 +4,6 @@ * This file is part of Jam - see jam.c for Copyright information. */ -# include "jam.h" -# include "pathsys.h" - -# ifdef USE_PATHUNIX - /* * pathunix.c - manipulate file names on UNIX, NT, OS2, AmigaOS * @@ -34,20 +29,26 @@ * 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 on \ handling on UNIX, on by accident + * 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( - char *file, + const char *file, PATHNAME *f ) { - char *p, *q; - char *end; + const char *p, *q; + const char *end; memset( (char *)f, 0, sizeof( *f ) ); diff --git a/src/tools/jam/pathvms.c b/src/tools/jam/pathvms.c index c0140cca79..7edcd6a040 100644 --- a/src/tools/jam/pathvms.c +++ b/src/tools/jam/pathvms.c @@ -4,13 +4,6 @@ * This file is part of Jam - see jam.c for Copyright information. */ -# include "jam.h" -# include "pathsys.h" - -# ifdef OS_VMS - -# define DEBUG - /* * pathvms.c - manipulate file names on VMS * @@ -29,19 +22,27 @@ * * 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( - char *file, + const char *file, PATHNAME *f ) { - char *p, *q; - char *end; + const char *p, *q; + const char *end; memset( (char *)f, 0, sizeof( *f ) ); @@ -179,11 +180,11 @@ strnchr( static void dir_flags( - char *buf, + const char *buf, int len, struct dirinf *i ) { - char *p; + const char *p; if( !buf || !len ) { @@ -193,19 +194,19 @@ dir_flags( i->dev.len = i->dir.len = 0; } - else if( p = strnchr( buf, ':', len ) ) + else if( p = strnchr( (char *)buf, ':', len ) ) { - i->dev.ptr = buf; + i->dev.ptr = (char *)buf; i->dev.len = p + 1 - buf; - i->dir.ptr = buf + i->dev.len; + 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 = buf; + i->dev.ptr = (char *)buf; i->dev.len = 0; - i->dir.ptr = buf; + i->dir.ptr = (char *)buf; i->dir.len = len; if( *buf == '[' && buf[1] == ']' ) diff --git a/src/tools/jam/regexp.c b/src/tools/jam/regexp.c index 92ee8efd8a..a1fcc181d6 100644 --- a/src/tools/jam/regexp.c +++ b/src/tools/jam/regexp.c @@ -36,6 +36,8 @@ *** 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 @@ -210,7 +212,7 @@ STATIC int strcspn(); * of the structure of the compiled regexp. */ regexp * -regcomp( char *exp ) +regcomp( const char *exp ) { register regexp *r; register char *scan; @@ -767,15 +769,15 @@ regoptail( /* * Global work variables for regexec(). */ -static char *reginput; /* String-input pointer. */ +static const char *reginput; /* String-input pointer. */ static char *regbol; /* Beginning of input, for ^ check. */ -static char **regstartp; /* Pointer to startp array. */ -static char **regendp; /* Ditto for endp. */ +static const char **regstartp; /* Pointer to startp array. */ +static const char **regendp; /* Ditto for endp. */ /* * Forwards. */ -STATIC int regtry( regexp *prog, char *string ); +STATIC int regtry( regexp *prog, const char *string ); STATIC int regmatch( char *prog ); STATIC int regrepeat( char *p ); @@ -791,7 +793,7 @@ STATIC char *regprop(); int regexec( register regexp *prog, - register char *string ) + register const char *string ) { register char *s; @@ -852,11 +854,11 @@ regexec( static int /* 0 failure, 1 success */ regtry( regexp *prog, - char *string ) + const char *string ) { register int i; - register char **sp; - register char **ep; + register const char **sp; + register const char **ep; reginput = string; regstartp = prog->startp; @@ -971,7 +973,7 @@ regmatch( char *prog ) case OPEN+8: case OPEN+9: { register int no; - register char *save; + register const char *save; no = OP(scan) - OPEN; save = reginput; @@ -999,7 +1001,7 @@ regmatch( char *prog ) case CLOSE+8: case CLOSE+9: { register int no; - register char *save; + register const char *save; no = OP(scan) - CLOSE; save = reginput; @@ -1018,7 +1020,7 @@ regmatch( char *prog ) } break; case BRANCH: { - register char *save; + register const char *save; if (OP(next) != BRANCH) /* No choice. */ next = OPERAND(scan); /* Avoid recursion. */ @@ -1039,7 +1041,7 @@ regmatch( char *prog ) case PLUS: { register char nextch; register int no; - register char *save; + register const char *save; register int min; /* @@ -1091,7 +1093,7 @@ static int regrepeat( char *p ) { register int count = 0; - register char *scan; + register const char *scan; register char *opnd; scan = reginput; @@ -1315,3 +1317,9 @@ strcspn( return(count); } #endif + +void +regerror( const char *s ) +{ + printf( "re error %s\n", s ); +} diff --git a/src/tools/jam/regexp.h b/src/tools/jam/regexp.h index 40b7538a07..87649c321a 100644 --- a/src/tools/jam/regexp.h +++ b/src/tools/jam/regexp.h @@ -3,11 +3,14 @@ * * 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 { - char *startp[NSUBEXP]; - char *endp[NSUBEXP]; + const char *startp[NSUBEXP]; + const char *endp[NSUBEXP]; char regstart; /* Internal use only. */ char reganch; /* Internal use only. */ char *regmust; /* Internal use only. */ @@ -15,9 +18,9 @@ typedef struct regexp { char program[1]; /* Unwarranted chumminess with compiler. */ } regexp; -regexp *regcomp( char *exp ); -int regexec( regexp *prog, char *string ); -void regerror( char *s ); +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 diff --git a/src/tools/jam/rules.c b/src/tools/jam/rules.c index dc3f8dbc56..f1b436e393 100644 --- a/src/tools/jam/rules.c +++ b/src/tools/jam/rules.c @@ -4,6 +4,35 @@ * 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" @@ -12,28 +41,6 @@ # include "newstr.h" # include "hash.h" -/* - * 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 - * 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 - * actionlist() - append to an ACTION chain - * addsettings() - add a deferred "set" command to a target - * usesettings() - set all target specific variables - * 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) - */ - static struct hash *rulehash = 0; static struct hash *targethash = 0; @@ -43,7 +50,7 @@ static struct hash *targethash = 0; */ RULE * -bindrule( char *rulename ) +bindrule( const char *rulename ) { RULE rule, *r = &rule; @@ -58,6 +65,7 @@ bindrule( char *rulename ) r->procedure = (PARSE *)0; r->actions = (char *)0; r->bindlist = L0; + r->params = L0; r->flags = 0; } @@ -69,7 +77,7 @@ bindrule( char *rulename ) */ TARGET * -bindtarget( char *targetname ) +bindtarget( const char *targetname ) { TARGET target, *t = ⌖ @@ -88,12 +96,33 @@ bindtarget( char *targetname ) 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( char *t ) +touchtarget( const char *t ) { bindtarget( t )->flags |= T_FLAG_TOUCHED; } @@ -143,6 +172,32 @@ targetentry( 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 */ @@ -176,8 +231,8 @@ actionlist( SETTINGS * addsettings( SETTINGS *head, - int append, - char *symbol, + int setflag, + const char *symbol, LIST *value ) { SETTINGS *v; @@ -200,21 +255,62 @@ addsettings( v->next = head; head = v; } - else if( append ) - { - v->value = list_append( v->value, value ); - } - else + 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 */ diff --git a/src/tools/jam/rules.h b/src/tools/jam/rules.h index 40503d97a2..532d2347b4 100644 --- a/src/tools/jam/rules.h +++ b/src/tools/jam/rules.h @@ -27,6 +27,13 @@ * 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; @@ -39,11 +46,12 @@ typedef struct _settings SETTINGS ; /* RULE - a generic jam rule, the product of RULE and ACTIONS */ struct _rule { - char *name; - PARSE *procedure; /* parse tree from RULE */ - char *actions; /* command string from ACTIONS */ - LIST *bindlist; /* variable to bind for actions */ - int flags; /* modifiers on ACTIONS */ + 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 */ @@ -51,52 +59,53 @@ struct _rule { # 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; + 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 */ + 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; - char *symbol; /* symbol name for var_set() */ - LIST *value; /* symbol value for var_set() */ + 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; + TARGETS *next; + TARGETS *tail; /* valid only for head */ + TARGET *target; } ; /* TARGET - a file or "thing" that can be built */ struct _target { - char *name; - char *boundname; /* if search() relocates target */ - ACTIONS *actions; /* rules to execute, if any */ - SETTINGS *settings; /* variables to define */ + 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 */ + char flags; /* status info */ # define T_FLAG_TEMP 0x01 /* TEMPORARY applied */ # define T_FLAG_NOCARE 0x02 /* NOCARE applied */ @@ -104,26 +113,21 @@ struct _target { # 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 */ + 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 *deps[2]; /* dependencies */ + TARGETS *depends; /* dependencies */ + TARGET *includes; /* includes */ -# define T_DEPS_DEPENDS 0 /* due to DEPENDS */ -# define T_DEPS_INCLUDES 1 /* due to INCLUDES */ - - time_t time; /* update time */ - time_t leaf; /* update time of leaf sources */ - time_t htime; /* header's time */ - time_t hleaf; /* update time of leaf headers */ - - char fate; /* make0()'s diagnosis */ - char hfate; /* collected fate for headers */ + 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 */ @@ -137,14 +141,15 @@ struct _target { # 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_OUTDATED 7 /* is out of date, needs updating */ -# define T_FATE_UPDATE 8 /* deps updated, 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 9 /* >= BROKEN ruins parents */ -# define T_FATE_CANTFIND 9 /* no rules to make missing target */ -# define T_FATE_CANTMAKE 10 /* can't find dependents */ +# 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 */ + char progress; /* tracks make1() progress */ # define T_MAKE_INIT 0 /* make1(target) not yet called */ # define T_MAKE_ONSTACK 1 /* make1(target) on stack */ @@ -152,20 +157,23 @@ struct _target { # define T_MAKE_RUNNING 3 /* make1(target) running commands */ # define T_MAKE_DONE 4 /* make1(target) done */ - char status; /* execcmd() result */ + char status; /* execcmd() result */ - int asynccnt; /* child deps outstanding */ - TARGETS *parents; /* used by make1() for completion */ - char *cmds; /* type-punned command list */ + int asynccnt; /* child deps outstanding */ + TARGETS *parents; /* used by make1() for completion */ + char *cmds; /* type-punned command list */ } ; -RULE *bindrule( char *rulename ); -TARGET *bindtarget( char *targetname ); -void touchtarget( char *t ); +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 *head, int append, char *symbol, LIST *value ); +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 ); diff --git a/src/tools/jam/scan.h b/src/tools/jam/scan.h index 37b026f1f8..30be3888b5 100644 --- a/src/tools/jam/scan.h +++ b/src/tools/jam/scan.h @@ -21,6 +21,8 @@ * 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 */ /* @@ -31,7 +33,7 @@ typedef struct _YYSTYPE { int type; - char *string; + const char *string; PARSE *parse; LIST *list; int number; @@ -40,9 +42,9 @@ typedef struct _YYSTYPE { extern YYSTYPE yylval; void yymode( int n ); -void yyerror( char *s ); +void yyerror( const char *s ); int yyanyerrors(); -void yyfparse( char *s ); +void yyfparse( const char *s ); int yyline(); int yylex(); int yyparse(); diff --git a/src/tools/jam/search.c b/src/tools/jam/search.c index c260c2a01f..52f3c99b50 100644 --- a/src/tools/jam/search.c +++ b/src/tools/jam/search.c @@ -4,6 +4,12 @@ * 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" @@ -12,13 +18,9 @@ # include "variable.h" # include "newstr.h" -/* - * search.c - find a target along $(SEARCH) or $(LOCATE) - */ - -char * +const char * search( - char *target, + const char *target, time_t *time ) { PATHNAME f[1]; diff --git a/src/tools/jam/search.h b/src/tools/jam/search.h index bb8035723c..fad1468692 100644 --- a/src/tools/jam/search.h +++ b/src/tools/jam/search.h @@ -6,6 +6,8 @@ /* * search.h - find a target along $(SEARCH) or $(LOCATE) + * + * 11/04/02 (seiwald) - const-ing for string literals */ -char *search( char *target, time_t *time ); +const char *search( const char *target, time_t *time ); diff --git a/src/tools/jam/timestamp.c b/src/tools/jam/timestamp.c index a5bbcc8c40..8b590a83c1 100644 --- a/src/tools/jam/timestamp.c +++ b/src/tools/jam/timestamp.c @@ -4,6 +4,14 @@ * 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" @@ -11,12 +19,6 @@ # include "timestamp.h" # include "newstr.h" -/* - * timestamp.c - get the timestamp of a file or archive member - * - * 09/22/00 (seiwald) - downshift names on OS2, too - */ - /* * BINDING - all known files */ @@ -24,12 +26,12 @@ typedef struct _binding BINDING; struct _binding { - char *name; - short flags; + const char *name; + short flags; # define BIND_SCANNED 0x01 /* if directory or arch, has been scanned */ - short progress; + short progress; # define BIND_INIT 0 /* never seen */ # define BIND_NOENTRY 1 /* timestamp requested but file never found */ @@ -37,13 +39,13 @@ struct _binding { # 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 */ + time_t time; /* update time - 0 if not exist */ } ; static struct hash *bindhash = 0; -static void time_enter( void *, char *, int , time_t ); +static void time_enter( void *, const char *, int , time_t ); -static char *time_progress[] = +static const char *time_progress[] = { "INIT", "NOENTRY", @@ -161,10 +163,10 @@ timestamp( static void time_enter( - void *closure, - char *target, - int found, - time_t time ) + void *closure, + const char *target, + int found, + time_t time ) { BINDING binding, *b = &binding; struct hash *bindhash = (struct hash *)closure; diff --git a/src/tools/jam/variable.c b/src/tools/jam/variable.c index d62e4c19cf..0a2d07c70e 100644 --- a/src/tools/jam/variable.c +++ b/src/tools/jam/variable.c @@ -4,14 +4,6 @@ * This file is part of Jam - see jam.c for Copyright information. */ -# include "jam.h" -# include "lists.h" -# include "parse.h" -# include "variable.h" -# include "expand.h" -# include "hash.h" -# include "newstr.h" - /* * variable.c - handle jam multi-element variables * @@ -34,8 +26,18 @@ * 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; /* @@ -45,12 +47,12 @@ static struct hash *varhash = 0; typedef struct _variable VARIABLE ; struct _variable { - char *symbol; - LIST *value; + const char *symbol; + LIST *value; } ; -static VARIABLE *var_enter( char *symbol ); -static void var_dump( char *symbol, LIST *value, char *what ); +static VARIABLE *var_enter( const char *symbol ); +static void var_dump( const char *symbol, LIST *value, const char *what ); @@ -62,11 +64,11 @@ static void var_dump( char *symbol, LIST *value, char *what ); */ void -var_defines( char **e ) +var_defines( const char **e ) { for( ; *e; e++ ) { - char *val; + const char *val; /* Just say "no": windows defines this in the env, */ /* but we don't want it to override our notion of OS. */ @@ -84,7 +86,7 @@ var_defines( char **e ) # endif { LIST *l = L0; - char *pp, *p; + const char *pp, *p; # ifdef OS_MAC char split = ','; # else @@ -108,10 +110,10 @@ var_defines( char **e ) { strncpy( buf, pp, p - pp ); buf[ p - pp ] = '\0'; - l = list_new( l, newstr( buf ) ); + l = list_new( l, buf, 0 ); } - l = list_new( l, newstr( pp ) ); + l = list_new( l, pp, 0 ); /* Get name */ @@ -131,7 +133,7 @@ var_defines( char **e ) int var_string( - char *in, + const char *in, char *out, int outsize, LOL *lol ) @@ -174,13 +176,11 @@ var_string( if( dollar ) { - LIST *l; - - l = var_expand( L0, lastword, out, lol, 0 ); + LIST *l = var_expand( L0, lastword, out, lol, 0 ); out = lastword; - for( ; l; l = list_next( l ) ) + while( l ) { int so = strlen( l->string ); @@ -189,7 +189,11 @@ var_string( strcpy( out, l->string ); out += so; - *out++ = ' '; + + /* Separate with space */ + + if( l = list_next( l ) ) + *out++ = ' '; } list_free( l ); @@ -211,7 +215,7 @@ var_string( */ LIST * -var_get( char *symbol ) +var_get( const char *symbol ) { VARIABLE var, *v = &var; @@ -240,7 +244,7 @@ var_get( char *symbol ) void var_set( - char *symbol, + const char *symbol, LIST *value, int flag ) { @@ -278,7 +282,7 @@ var_set( LIST * var_swap( - char *symbol, + const char *symbol, LIST *value ) { VARIABLE *v = var_enter( symbol ); @@ -299,7 +303,7 @@ var_swap( */ static VARIABLE * -var_enter( char *symbol ) +var_enter( const char *symbol ) { VARIABLE var, *v = &var; @@ -321,9 +325,9 @@ var_enter( char *symbol ) static void var_dump( - char *symbol, - LIST *value, - char *what ) + const char *symbol, + LIST *value, + const char *what ) { printf( "%s %s = ", what, symbol ); list_print( value ); diff --git a/src/tools/jam/variable.h b/src/tools/jam/variable.h index 77b89f1eaa..e35020fb17 100644 --- a/src/tools/jam/variable.h +++ b/src/tools/jam/variable.h @@ -6,13 +6,15 @@ /* * variable.h - handle jam multi-element variables + * + * 11/04/02 (seiwald) - const-ing for string literals */ -void var_defines( char **e ); -int var_string( char *in, char *out, int outsize, LOL *lol ); -LIST * var_get( char *symbol ); -void var_set( char *symbol, LIST *value, int flag ); -LIST * var_swap( char *symbol, LIST *value ); +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(); /* diff --git a/src/tools/jam/yyacc b/src/tools/jam/yyacc index f566868dda..c4566ac7b8 100755 --- a/src/tools/jam/yyacc +++ b/src/tools/jam/yyacc @@ -15,13 +15,12 @@ # file.y yacc grammar # filetab.h array of string <-> token mappings # -# 3-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-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?}