diff options
author | joerg <joerg> | 2008-03-09 19:39:31 +0000 |
---|---|---|
committer | joerg <joerg> | 2008-03-09 19:39:31 +0000 |
commit | 76e4024418d6a18142400ac95c7cd980bc920728 (patch) | |
tree | f6147401a0ff7061a4e0e838277a74e0a62d4274 /devel/bmake | |
parent | 4529d719240d40bc49aa24f5d0aac4c4dd7a2461 (diff) | |
download | pkgsrc-76e4024418d6a18142400ac95c7cd980bc920728.tar.gz |
Import bmake-20080215
Diffstat (limited to 'devel/bmake')
55 files changed, 2686 insertions, 1902 deletions
diff --git a/devel/bmake/files/FILES b/devel/bmake/files/FILES index a2ceb926dc1..2558b1710c3 100644 --- a/devel/bmake/files/FILES +++ b/devel/bmake/files/FILES @@ -56,6 +56,7 @@ lst.lib/lstLast.c lst.lib/lstMember.c lst.lib/lstNext.c lst.lib/lstOpen.c +lst.lib/lstPrev.c lst.lib/lstRemove.c lst.lib/lstReplace.c lst.lib/lstSucc.c @@ -84,6 +85,9 @@ wait.h unit-tests/Makefile.in unit-tests/cond1 unit-tests/comment +unit-tests/export +unit-tests/export-all +unit-tests/moderrs unit-tests/modmatch unit-tests/modorder unit-tests/modts @@ -92,3 +96,5 @@ unit-tests/posix unit-tests/ternary unit-tests/test.exp unit-tests/varcmd +unit-tests/modmisc +unit-tests/dotwait diff --git a/devel/bmake/files/arch.c b/devel/bmake/files/arch.c index 3119a51b627..98be9f25c20 100644 --- a/devel/bmake/files/arch.c +++ b/devel/bmake/files/arch.c @@ -1,4 +1,4 @@ -/* $NetBSD: arch.c,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $ */ +/* $NetBSD: arch.c,v 1.1.1.2 2008/03/09 19:39:32 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: arch.c,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $"; +static char rcsid[] = "$NetBSD: arch.c,v 1.1.1.2 2008/03/09 19:39:32 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)arch.c 8.2 (Berkeley) 1/2/94"; #else -__RCSID("$NetBSD: arch.c,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $"); +__RCSID("$NetBSD: arch.c,v 1.1.1.2 2008/03/09 19:39:32 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -288,19 +288,18 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt) * so we can safely advance beyond it... */ int length; - Boolean freeIt; + void *freeIt; char *result; - result=Var_Parse(cp, ctxt, TRUE, &length, &freeIt); + result = Var_Parse(cp, ctxt, TRUE, &length, &freeIt); + if (freeIt) + free(freeIt); if (result == var_Error) { return(FAILURE); } else { subLibName = TRUE; } - if (freeIt) { - free(result); - } cp += length-1; } } @@ -330,19 +329,18 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt) * so we can safely advance beyond it... */ int length; - Boolean freeIt; + void *freeIt; char *result; - result=Var_Parse(cp, ctxt, TRUE, &length, &freeIt); + result = Var_Parse(cp, ctxt, TRUE, &length, &freeIt); + if (freeIt) + free(freeIt); if (result == var_Error) { return(FAILURE); } else { doSubst = TRUE; } - if (freeIt) { - free(result); - } cp += length; } else { cp++; @@ -412,7 +410,7 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt) return(FAILURE); } else { gn->type |= OP_ARCHV; - (void)Lst_AtEnd(nodeLst, (ClientData)gn); + (void)Lst_AtEnd(nodeLst, gn); } } else if (Arch_ParseArchive(&sacrifice, nodeLst, ctxt)!=SUCCESS) { /* @@ -454,7 +452,7 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt) * end of the provided list. */ gn->type |= OP_ARCHV; - (void)Lst_AtEnd(nodeLst, (ClientData)gn); + (void)Lst_AtEnd(nodeLst, gn); } } Lst_Destroy(members, NOFREE); @@ -476,7 +474,7 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt) * provided list. */ gn->type |= OP_ARCHV; - (void)Lst_AtEnd(nodeLst, (ClientData)gn); + (void)Lst_AtEnd(nodeLst, gn); } } if (doSubst) { @@ -578,7 +576,7 @@ ArchStatMember(char *archive, char *member, Boolean hash) member = cp + 1; } - ln = Lst_Find(archives, (ClientData) archive, ArchFindArchive); + ln = Lst_Find(archives, archive, ArchFindArchive); if (ln != NILLNODE) { ar = (Arch *)Lst_Datum(ln); @@ -589,7 +587,7 @@ ArchStatMember(char *archive, char *member, Boolean hash) } else { /* Try truncated name */ char copy[AR_MAX_NAME_LEN+1]; - int len = strlen(member); + size_t len = strlen(member); if (len > AR_MAX_NAME_LEN) { len = AR_MAX_NAME_LEN; @@ -711,7 +709,7 @@ ArchStatMember(char *archive, char *member, Boolean hash) memName[elen] = '\0'; fseek(arch, -elen, SEEK_CUR); if (DEBUG(ARCH) || DEBUG(MAKE)) { - printf("ArchStat: Extended format entry for %s\n", memName); + fprintf(debug_file, "ArchStat: Extended format entry for %s\n", memName); } } #endif @@ -725,7 +723,7 @@ ArchStatMember(char *archive, char *member, Boolean hash) fclose(arch); - (void)Lst_AtEnd(archives, (ClientData) ar); + (void)Lst_AtEnd(archives, ar); /* * Now that the archive has been read and cached, we can look into @@ -782,7 +780,7 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch) if (ar->fnametab != NULL) { if (DEBUG(ARCH)) { - printf("Attempted to redefine an SVR4 name table\n"); + fprintf(debug_file, "Attempted to redefine an SVR4 name table\n"); } return -1; } @@ -796,7 +794,7 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch) if (fread(ar->fnametab, size, 1, arch) != 1) { if (DEBUG(ARCH)) { - printf("Reading an SVR4 name table failed\n"); + fprintf(debug_file, "Reading an SVR4 name table failed\n"); } return -1; } @@ -815,7 +813,7 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch) break; } if (DEBUG(ARCH)) { - printf("Found svr4 archive name table with %lu entries\n", + fprintf(debug_file, "Found svr4 archive name table with %lu entries\n", (u_long)entry); } return 0; @@ -827,20 +825,20 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch) entry = (size_t)strtol(&name[1], &eptr, 0); if ((*eptr != ' ' && *eptr != '\0') || eptr == &name[1]) { if (DEBUG(ARCH)) { - printf("Could not parse SVR4 name %s\n", name); + fprintf(debug_file, "Could not parse SVR4 name %s\n", name); } return 2; } if (entry >= ar->fnamesize) { if (DEBUG(ARCH)) { - printf("SVR4 entry offset %s is greater than %lu\n", + fprintf(debug_file, "SVR4 entry offset %s is greater than %lu\n", name, (u_long)ar->fnamesize); } return 2; } if (DEBUG(ARCH)) { - printf("Replaced %s with %s\n", name, &ar->fnametab[entry]); + fprintf(debug_file, "Replaced %s with %s\n", name, &ar->fnametab[entry]); } (void)strncpy(name, &ar->fnametab[entry], MAXPATHLEN); @@ -882,7 +880,7 @@ ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr, int size; /* Size of archive member */ char *cp; /* Useful character pointer */ char magic[SARMAG]; - int len, tlen; + size_t len, tlen; arch = fopen(archive, mode); if (arch == NULL) { @@ -954,7 +952,7 @@ ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr, isdigit((unsigned char)arhPtr->AR_NAME[sizeof(AR_EFMT1) - 1])) { unsigned int elen = atoi(&arhPtr->AR_NAME[sizeof(AR_EFMT1)-1]); - char ename[MAXPATHLEN]; + char ename[MAXPATHLEN + 1]; if (elen > MAXPATHLEN) { fclose(arch); @@ -966,7 +964,7 @@ ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr, } ename[elen] = '\0'; if (DEBUG(ARCH) || DEBUG(MAKE)) { - printf("ArchFind: Extended format entry for %s\n", ename); + fprintf(debug_file, "ArchFind: Extended format entry for %s\n", ename); } if (strncmp(ename, member, len) == 0) { /* Found as extended name */ @@ -1290,7 +1288,7 @@ Arch_LibOODate(GNode *gn) modTimeTOC = (int)strtol(arhPtr->AR_DATE, NULL, 10); if (DEBUG(ARCH) || DEBUG(MAKE)) { - printf("%s modified %s...", RANLIBMAG, Targ_FmtTime(modTimeTOC)); + fprintf(debug_file, "%s modified %s...", RANLIBMAG, Targ_FmtTime(modTimeTOC)); } oodate = (gn->cmtime > modTimeTOC); } else { @@ -1298,7 +1296,7 @@ Arch_LibOODate(GNode *gn) * A library w/o a table of contents is out-of-date */ if (DEBUG(ARCH) || DEBUG(MAKE)) { - printf("No t.o.c...."); + fprintf(debug_file, "No t.o.c...."); } oodate = TRUE; } diff --git a/devel/bmake/files/bmake.cat1 b/devel/bmake/files/bmake.cat1 index a1c12d8d22f..ab7cddc458f 100644 --- a/devel/bmake/files/bmake.cat1 +++ b/devel/bmake/files/bmake.cat1 @@ -1,7 +1,7 @@ -MAKE(1) NetBSD General Commands Manual MAKE(1) +MAKE(1) BSD General Commands Manual MAKE(1) NNAAMMEE - bbmmaakkee - maintain program dependencies + bbmmaakkee -- maintain program dependencies SSYYNNOOPPSSIISS bbmmaakkee [--BBeeiikkNNnnqqrrssttWWXX] [--DD _v_a_r_i_a_b_l_e] [--dd _f_l_a_g_s] [--ff _m_a_k_e_f_i_l_e] @@ -11,15 +11,18 @@ SSYYNNOOPPSSIISS DDEESSCCRRIIPPTTIIOONN bbmmaakkee is a program designed to simplify the maintenance of other pro- grams. Its input is a list of specifications as to the files upon which - programs and other files depend. If the file `_m_a_k_e_f_i_l_e' exists, it is - read for this list of specifications. If it does not exist, the file - `_M_a_k_e_f_i_l_e' is read. If the file `_._d_e_p_e_n_d' exists, it is read (see + programs and other files depend. If no --ff _m_a_k_e_f_i_l_e makefile option is + given, bbmmaakkee will try to open `_m_a_k_e_f_i_l_e' then `_M_a_k_e_f_i_l_e' in order to find + the specifications. If the file `_._d_e_p_e_n_d' exists, it is read (see mkdep(1)). This manual page is intended as a reference document only. For a more thorough description of bbmmaakkee and makefiles, please refer to _M_a_k_e _- _A _T_u_t_o_r_i_a_l. + bbmmaakkee will prepend the contents of the _M_A_K_E_F_L_A_G_S environment variable to + the command line arguments before parsing them. + The options are as follows: --BB Try to be backwards compatible by executing a single shell per @@ -29,10 +32,12 @@ DDEESSCCRRIIPPTTIIOONN --DD _v_a_r_i_a_b_l_e Define _v_a_r_i_a_b_l_e to be 1, in the global context. - --dd _f_l_a_g_s + --dd _[_-_]_f_l_a_g_s Turn on debugging, and specify which portions of bbmmaakkee are to - print debugging information. _F_l_a_g_s is one or more of the follow- - ing: + print debugging information. Unless the flags are preceded by + `-' they are added to the _M_A_K_E_F_L_A_G_S environment variable and will + be processed by any child make processes. _F_l_a_g_s is one or more + of the following: _A Print all possible debugging information; equivalent to specifying all of the debugging flags. @@ -48,6 +53,10 @@ DDEESSCCRRIIPPTTIIOONN _e Print debugging information about failed commands and targets. + _F Use the rest of `flags' as the name of the file to which + the debug output is written. If the filename ends `.%d' + then the `%d' is replaced by the pid. + _f Print debugging information about loop evaluation. _g_1 Print the input graph before making anything. @@ -60,9 +69,20 @@ DDEESSCCRRIIPPTTIIOONN _j Print debugging information about running multiple shells. + _l Print commands in Makefiles regardless of whether or not + they are prefixed by `@' or other "quiet" flags. Also + known as "loud" behavior. + _m Print debugging information about making targets, includ- ing modification dates. + _n Don't delete the temporary command scripts created in + _/_t_m_p when running commands. These are created via + mkstemp(3) and have names of the form _/_t_m_p_/_m_a_k_e_X_X_X_X_X. + _N_O_T_E: This can create many file in _/_t_m_p so use with care. + + _p Print debugging information about makefile parsing. + _s Print debugging information about suffix-transformation rules. @@ -243,7 +263,9 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS ::== Assign with expansion, i.e. expand the value before assigning it to the variable. Normally, expansion is not done until the vari- - able is referenced. + able is referenced. _N_O_T_E: References to undefined variables are + _n_o_t expanded. This can cause problems when variable modifiers + are used. !!== Expand the value and pass it to the shell for execution and assign the result to the variable. Any newlines in the result @@ -322,15 +344,37 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS evaluated during Makefile parsing, lists only those tar- gets encountered thus far. - _._C_U_R_D_I_R A path to the directory where bbmmaakkee was executed. + _._C_U_R_D_I_R A path to the directory where bbmmaakkee was executed. Refer + to the description of `PWD' for more details. MAKE The name that bbmmaakkee was executed with (_a_r_g_v_[_0_]). For - compatibily bbmmaakkee also sets _._M_A_K_E with the same value. + compatibility bbmmaakkee also sets _._M_A_K_E with the same value. The preferred variable to use is the environment variable MAKE because it is more compatible with other versions of bbmmaakkee and cannot be confused with the special target with the same name. + _._M_A_K_E_._E_X_P_O_R_T_E_D The list of variables exported by bbmmaakkee. + + _._M_A_K_E_._M_A_K_E_F_I_L_E_S + The list of makefiles read by bbmmaakkee, which is useful for + tracking dependencies. Each makefile is recorded only + once, regardless of the number of times read. + + _._M_A_K_E_._P_I_D The process-id of bbmmaakkee. + + _._M_A_K_E_._P_P_I_D The parent process-id of bbmmaakkee. + + _._M_A_K_E_._J_O_B_._P_R_E_F_I_X + If bbmmaakkee is run with _j then output for each target is + prefixed with a token `--- target ---' the first part of + which can be controlled via _._M_A_K_E_._J_O_B_._P_R_E_F_I_X. + For example: + .MAKE.JOB.PREFIX=${.newline}---${.MAKE:T}[${.MAKE.PID}] + would produce tokens like `---make[1234] target ---' mak- + ing it easier to track the degree of parallelism being + achieved. + MAKEFLAGS The environment variable `MAKEFLAGS' may contain anything that may be specified on bbmmaakkee's command line. Anything specified on bbmmaakkee's command line is appended to the @@ -358,7 +402,37 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS `_M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R' could be done as ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}. - _._O_B_J_D_I_R A path to the directory where the targets are built. + _._O_B_J_D_I_R A path to the directory where the targets are built. Its + value is determined by trying to chdir(2) to the follow- + ing directories in order and using the first match: + + 1. ${MAKEOBJDIRPREFIX}${.CURDIR} + + (Only if `MAKEOBJDIRPREFIX' is set in the environ- + ment or on the command line.) + + 2. ${MAKEOBJDIR} + + (Only if `MAKEOBJDIR' is set in the environment or + on the command line.) + + 3. ${.CURDIR}_/_o_b_j_.${MACHINE} + + 4. ${.CURDIR}_/_o_b_j + + 5. _/_u_s_r_/_o_b_j_/${.CURDIR} + + 6. ${.CURDIR} + + Variable expansion is performed on the value before it's + used, so expressions such as + ${.CURDIR:C,^/usr/src,/var/obj,} + may be used. + + `_._O_B_J_D_I_R' may be modified in the makefile as a global + variable. In all cases, bbmmaakkee will chdir(2) to `_._O_B_J_D_I_R' + and set `PWD' to that directory before executing any tar- + gets. _._P_A_R_S_E_D_I_R A path to the directory of the current `_M_a_k_e_f_i_l_e' being parsed. @@ -377,19 +451,31 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS However, if the environment variable `PWD' is set and gives a path to the current directory, then bbmmaakkee sets `_._C_U_R_D_I_R' to the value of `PWD' instead. This behaviour - is disabled if `MAKEOBJDIRPREFIX' is set. `PWD' is set - to the value of `_._O_B_J_D_I_R' for all programs which bbmmaakkee - executes. + is disabled if `MAKEOBJDIRPREFIX' is set or `MAKEOBJDIR' + contains a variable transform. `PWD' is set to the value + of `_._O_B_J_D_I_R' for all programs which bbmmaakkee executes. VVaarriiaabbllee mmooddiiffiieerrss Variable expansion may be modified to select or modify each word of the variable (where a ``word'' is white-space delimited sequence of charac- ters). The general format of a variable expansion is as follows: - {variable[:modifier[:...]]} + ${variable[:modifier[:...]]} Each modifier begins with a colon, which may be escaped with a backslash - (`\'). The supported modifiers are: + (`\'). + + A set of modifiers can be specified via a variable, as follows: + + modifier_variable=modifier[:...] + ${variable:${modifier_variable}[:...]} + + In this case the first modifier in the modifier_variable does not start + with a colon, since that must appear in the referencing variable. If any + of the modifiers in the modifier_variable contain a dollar sign (`$'), + these must be doubled to avoid early expansion. + + The supported modifiers are: ::EE Replaces each word in the variable with its suffix. @@ -620,6 +706,13 @@ IINNCCLLUUDDEE SSTTAATTEEMMEENNTTSS,, CCOONNDDIITTIIOO Conditional expressions are also preceded by a single dot as the first character of a line. The possible conditionals are as follows: + ..eexxppoorrtt _v_a_r_i_a_b_l_e + Export the specified global variable. If no variable is pro- + vided, all globals are exported except for internal variables + (those that start with `.' ). This is not affected by the --XX + flag, so should be used with caution. Appending a variable name + to _._M_A_K_E_._E_X_P_O_R_T_E_D is equivalent to exporting a variable. + ..uunnddeeff _v_a_r_i_a_b_l_e Un-define the specified global variable. Only global variables may be un-defined. @@ -733,7 +826,7 @@ IINNCCLLUUDDEE SSTTAATTEEMMEENNTTSS,, CCOONNDDIITTIIOO CCOOMMMMEENNTTSS Comments begin with a hash (`#') character, anywhere but in a shell com- - mand line, and continue to the end of the line. + mand line, and continue to the end of an unescaped new line. SSPPEECCIIAALL SSOOUURRCCEESS ((AATTTTRRIIBBUUTTEESS)) ..EEXXEECC Target is never out of date, but always execute commands any- @@ -765,8 +858,9 @@ SSPPEECCIIAALL SSOOUURRCCEESS ((AATTTTRRIIBBUUTTEESS)) --tt option. ..PPRREECCIIOOUUSS - When bbmmaakkee is interrupted, it removes any partially made tar- - gets. This source prevents the target from being removed. + When bbmmaakkee is interrupted, it normally removes any partially + made targets. This source prevents the target from being + removed. ..RREECCUURRSSIIVVEE Synonym for ..MMAAKKEE. @@ -786,8 +880,23 @@ SSPPEECCIIAALL SSOOUURRCCEESS ((AATTTTRRIIBBUUTTEESS)) ..WWAAIITT If ..WWAAIITT appears in a dependency line, the sources that precede it are made before the sources that succeed it in the line. - Loops are not detected and targets that form loops will be - silently ignored. + Since the dependents of files are not made until the file + itself could be made, this also stops the dependents being + built unless they are needed for another branch of the depen- + dency tree. So given: + + x: a .WAIT b + echo x + a: + echo a + b: b1 + echo b + b1: + echo b1 + + the output is always `b1', `b', `a', `x'. + The ordering imposed by ..WWAAIITT is only relevant for parallel + makes. SSPPEECCIIAALL TTAARRGGEETTSS Special targets may not be included with other targets, i.e. they must be @@ -831,7 +940,17 @@ SSPPEECCIIAALL TTAARRGGEETTSS Synonym for ..NNOOTTPPAARRAALLLLEELL, for compatibility with other pmake variants. - ..OORRDDEERR The named targets are made in sequence. + ..OORRDDEERR The named targets are made in sequence. This ordering does not + add targets to the list of targets to be made. Since the depen- + dents of a target do not get built until the target itself could + be built, unless `a' is built by another part of the dependency + graph, the following is a dependency loop: + + .ORDER a b + b: a + + The ordering imposed by ..OORRDDEERR is only relevant for parallel + makes. ..PPAATTHH The sources are directories which are to be searched for files not found in the current directory. If no sources are speci- @@ -872,12 +991,16 @@ SSPPEECCIIAALL TTAARRGGEETTSS _e_c_h_o_F_l_a_g The flag to pass the shell to enable command echo- ing. + + _n_e_w_l_i_n_e The string literal to pass the shell that results in + a single newline character when used outside of any + quoting characters. Example: .SHELL: name=ksh path=/bin/ksh hasErrCtl=true \ check="set -e" ignore="set +e" \ echo="set -v" quiet="set +v" filter="set +v" \ - echoFlag=v errFlag=e + echoFlag=v errFlag=e newline="'\n'" ..SSIILLEENNTT Apply the ..SSIILLEENNTT attribute to any specified sources. If no sources are specified, the ..SSIILLEENNTT attribute is applied to every @@ -892,11 +1015,9 @@ EENNVVIIRROONNMMEENNTT MACHINE_ARCH, MAKE, MAKEFLAGS, MAKEOBJDIR, MAKEOBJDIRPREFIX, MAKESYSPATH, and PWD. - If MAKEOBJDIRPREFIX is set, then bbmmaakkee will chdir(2) to ${MAKEOBJDIRPRE- - FIX}${.CURDIR} if it exists. Otherwise if MAKEOBJDIR and the named - directory exists bbmmaakkee will chdir(2) to it. These actions are taken - before any makefiles are read which is why they need to be set in the - environment. + MAKEOBJDIRPREFIX and MAKEOBJDIR may only be set in the environment or on + the command line to bbmmaakkee and not as makefile variables; see the descrip- + tion of `_._O_B_J_D_I_R' for more details. FFIILLEESS .depend list of dependencies @@ -905,6 +1026,15 @@ FFIILLEESS sys.mk system makefile /usr/share/mk system makefile directory +CCOOMMPPAATTIIBBIILLIITTYY + The basic make syntax is compatible between different versions of make, + however the special variables, variable modifiers and conditionals are + not. + + The way that parallel makes are scheduled changed in NetBSD 4.0 so that + .ORDER and .WAIT apply recursively to the dependant nodes. The algo- + rithms used may change again in the future. + SSEEEE AALLSSOO mkdep(1) @@ -912,4 +1042,4 @@ HHIISSTTOORRYY bbmmaakkee is derived from NetBSD's make(1). It uses autoconf to facilitate portability to other platforms. -NetBSD 2.0 June 1, 2005 NetBSD 2.0 +BSD November 19, 2006 BSD diff --git a/devel/bmake/files/buf.c b/devel/bmake/files/buf.c index 88892914bb2..91d810426b3 100644 --- a/devel/bmake/files/buf.c +++ b/devel/bmake/files/buf.c @@ -1,4 +1,4 @@ -/* $NetBSD: buf.c,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $ */ +/* $NetBSD: buf.c,v 1.1.1.2 2008/03/09 19:39:32 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -70,14 +70,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: buf.c,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $"; +static char rcsid[] = "$NetBSD: buf.c,v 1.1.1.2 2008/03/09 19:39:32 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)buf.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: buf.c,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $"); +__RCSID("$NetBSD: buf.c,v 1.1.1.2 2008/03/09 19:39:32 joerg Exp $"); #endif #endif /* not lint */ #endif diff --git a/devel/bmake/files/buf.h b/devel/bmake/files/buf.h index 9d2077fd485..2712571339c 100644 --- a/devel/bmake/files/buf.h +++ b/devel/bmake/files/buf.h @@ -1,4 +1,4 @@ -/* $NetBSD: buf.h,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $ */ +/* $NetBSD: buf.h,v 1.1.1.2 2008/03/09 19:39:32 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. diff --git a/devel/bmake/files/dir.c b/devel/bmake/files/dir.c index 7cc5dd07001..530d70c7b64 100644 --- a/devel/bmake/files/dir.c +++ b/devel/bmake/files/dir.c @@ -1,4 +1,4 @@ -/* $NetBSD: dir.c,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $ */ +/* $NetBSD: dir.c,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -70,14 +70,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: dir.c,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $"; +static char rcsid[] = "$NetBSD: dir.c,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94"; #else -__RCSID("$NetBSD: dir.c,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $"); +__RCSID("$NetBSD: dir.c,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -303,7 +303,7 @@ Dir_InitCur(const char *cdname) * We've been here before, cleanup. */ cur->refCount -= 1; - Dir_Destroy((ClientData) cur); + Dir_Destroy(cur); } cur = p; } @@ -329,7 +329,7 @@ Dir_InitDot(void) LstNode ln; /* Remove old entry from openDirectories, but do not destroy. */ - ln = Lst_Member(openDirectories, (ClientData)dot); + ln = Lst_Member(openDirectories, dot); (void)Lst_Remove(openDirectories, ln); } @@ -366,12 +366,12 @@ Dir_End(void) #ifdef CLEANUP if (cur) { cur->refCount -= 1; - Dir_Destroy((ClientData) cur); + Dir_Destroy(cur); } dot->refCount -= 1; dotLast->refCount -= 1; - Dir_Destroy((ClientData) dotLast); - Dir_Destroy((ClientData) dot); + Dir_Destroy(dotLast); + Dir_Destroy(dot); Dir_ClearPath(dirSearchPath); Lst_Destroy(dirSearchPath, NOFREE); Dir_ClearPath(openDirectories); @@ -726,7 +726,7 @@ DirExpandInt(const char *word, Lst path, Lst expansions) static int DirPrintWord(ClientData word, ClientData dummy) { - printf("%s ", (char *)word); + fprintf(debug_file, "%s ", (char *)word); return(dummy ? 0 : 0); } @@ -757,7 +757,7 @@ Dir_Expand(const char *word, Lst path, Lst expansions) const char *cp; if (DEBUG(DIR)) { - printf("Expanding \"%s\"... ", word); + fprintf(debug_file, "Expanding \"%s\"... ", word); } cp = strchr(word, '{'); @@ -841,8 +841,8 @@ Dir_Expand(const char *word, Lst path, Lst expansions) } } if (DEBUG(DIR)) { - Lst_ForEach(expansions, DirPrintWord, (ClientData) 0); - fputc('\n', stdout); + Lst_ForEach(expansions, DirPrintWord, NULL); + fprintf(debug_file, "\n"); } } @@ -866,7 +866,7 @@ DirLookup(Path *p, const char *name __unused, const char *cp, char *file; /* the current filename to check */ if (DEBUG(DIR)) { - printf(" %s ...\n", p->name); + fprintf(debug_file, " %s ...\n", p->name); } if (Hash_FindEntry(&p->files, cp) == NULL) @@ -874,7 +874,7 @@ DirLookup(Path *p, const char *name __unused, const char *cp, file = str_concat(p->name, cp, STR_ADDSLASH); if (DEBUG(DIR)) { - printf(" returning %s\n", file); + fprintf(debug_file, " returning %s\n", file); } p->hits += 1; hits += 1; @@ -913,7 +913,7 @@ DirLookupSubdir(Path *p, const char *name) } if (DEBUG(DIR)) { - printf("checking %s ...\n", file); + fprintf(debug_file, "checking %s ...\n", file); } if (stat(file, &stb) == 0) { @@ -922,7 +922,7 @@ DirLookupSubdir(Path *p, const char *name) * to fetch it again. */ if (DEBUG(DIR)) { - printf(" Caching %s for %s\n", Targ_FmtTime(stb.st_mtime), + fprintf(debug_file, " Caching %s for %s\n", Targ_FmtTime(stb.st_mtime), file); } entry = Hash_CreateEntry(&mtimes, (char *)file, NULL); @@ -956,7 +956,7 @@ DirLookupAbs(Path *p, const char *name, const char *cp) const char *p2; /* pointer into name */ if (DEBUG(DIR)) { - printf(" %s ...\n", p->name); + fprintf(debug_file, " %s ...\n", p->name); } /* @@ -974,7 +974,7 @@ DirLookupAbs(Path *p, const char *name, const char *cp) if (Hash_FindEntry(&p->files, cp) == NULL) { if (DEBUG(DIR)) { - printf(" must be here but isn't -- returning\n"); + fprintf(debug_file, " must be here but isn't -- returning\n"); } /* Return empty string: terminates search */ return estrdup(""); @@ -983,7 +983,7 @@ DirLookupAbs(Path *p, const char *name, const char *cp) p->hits += 1; hits += 1; if (DEBUG(DIR)) { - printf(" returning %s\n", name); + fprintf(debug_file, " returning %s\n", name); } return (estrdup(name)); } @@ -1007,7 +1007,7 @@ DirFindDot(Boolean hasSlash __unused, const char *name, const char *cp) if (Hash_FindEntry(&dot->files, cp) != NULL) { if (DEBUG(DIR)) { - printf(" in '.'\n"); + fprintf(debug_file, " in '.'\n"); } hits += 1; dot->hits += 1; @@ -1016,7 +1016,7 @@ DirFindDot(Boolean hasSlash __unused, const char *name, const char *cp) if (cur && Hash_FindEntry(&cur->files, cp) != NULL) { if (DEBUG(DIR)) { - printf(" in ${.CURDIR} = %s\n", cur->name); + fprintf(debug_file, " in ${.CURDIR} = %s\n", cur->name); } hits += 1; cur->hits += 1; @@ -1054,7 +1054,7 @@ Dir_FindFile(const char *name, Lst path) LstNode ln; /* a list element */ char *file; /* the current filename to check */ Path *p; /* current path member */ - const char *cp; /* index of first slash, if any */ + const char *cp; /* Terminal name of file */ Boolean hasLastDot = FALSE; /* true we should search dot last */ Boolean hasSlash; /* true if 'name' contains a / */ struct stat stb; /* Buffer for stat, if necessary */ @@ -1074,12 +1074,12 @@ Dir_FindFile(const char *name, Lst path) } if (DEBUG(DIR)) { - printf("Searching for %s ...", name); + fprintf(debug_file, "Searching for %s ...", name); } if (Lst_Open(path) == FAILURE) { if (DEBUG(DIR)) { - printf("couldn't open path, file not found\n"); + fprintf(debug_file, "couldn't open path, file not found\n"); } misses += 1; return (NULL); @@ -1090,11 +1090,11 @@ Dir_FindFile(const char *name, Lst path) if (p == dotLast) { hasLastDot = TRUE; if (DEBUG(DIR)) - printf("[dot last]..."); + fprintf(debug_file, "[dot last]..."); } } if (DEBUG(DIR)) { - printf("\n"); + fprintf(debug_file, "\n"); } /* @@ -1102,7 +1102,7 @@ Dir_FindFile(const char *name, Lst path) * directory component is exactly `./', consult the cached contents * of each of the directories on the search path. */ - if ((!hasSlash || (cp - name == 2 && *name == '.'))) { + if (!hasSlash || (cp - name == 2 && *name == '.')) { /* * We look through all the directories on the path seeking one which * contains the final component of the given name. If such a beast @@ -1129,7 +1129,7 @@ Dir_FindFile(const char *name, Lst path) continue; if ((file = DirLookup(p, name, cp, hasSlash)) != NULL) { Lst_Close(path); - return file; + return file; } } @@ -1157,7 +1157,7 @@ Dir_FindFile(const char *name, Lst path) */ if (!hasSlash) { if (DEBUG(DIR)) { - printf(" failed.\n"); + fprintf(debug_file, " failed.\n"); } misses += 1; return (NULL); @@ -1167,7 +1167,7 @@ Dir_FindFile(const char *name, Lst path) Boolean checkedDot = FALSE; if (DEBUG(DIR)) { - printf(" Trying subdirectories...\n"); + fprintf(debug_file, " Trying subdirectories...\n"); } if (!hasLastDot) { @@ -1213,7 +1213,7 @@ Dir_FindFile(const char *name, Lst path) * so no point in proceeding... */ if (DEBUG(DIR)) { - printf(" Checked . already, returning NULL\n"); + fprintf(debug_file, " Checked . already, returning NULL\n"); } return(NULL); } @@ -1230,7 +1230,7 @@ Dir_FindFile(const char *name, Lst path) * returning an empty string. */ if (DEBUG(DIR)) { - printf(" Trying exact path matches...\n"); + fprintf(debug_file, " Trying exact path matches...\n"); } if (!hasLastDot && cur && (file = DirLookupAbs(cur, name, cp)) != NULL) @@ -1289,27 +1289,27 @@ Dir_FindFile(const char *name, Lst path) } #else /* !notdef */ if (DEBUG(DIR)) { - printf(" Looking for \"%s\" ...\n", name); + fprintf(debug_file, " Looking for \"%s\" ...\n", name); } bigmisses += 1; entry = Hash_FindEntry(&mtimes, name); if (entry != NULL) { if (DEBUG(DIR)) { - printf(" got it (in mtime cache)\n"); + fprintf(debug_file, " got it (in mtime cache)\n"); } return(estrdup(name)); } else if (stat(name, &stb) == 0) { entry = Hash_CreateEntry(&mtimes, name, NULL); if (DEBUG(DIR)) { - printf(" Caching %s for %s\n", Targ_FmtTime(stb.st_mtime), + fprintf(debug_file, " Caching %s for %s\n", Targ_FmtTime(stb.st_mtime), name); } Hash_SetValue(entry, (long)stb.st_mtime); return (estrdup(name)); } else { if (DEBUG(DIR)) { - printf(" failed. Returning NULL\n"); + fprintf(debug_file, " failed. Returning NULL\n"); } return (NULL); } @@ -1428,8 +1428,12 @@ Dir_MTime(GNode *gn) } else if (gn->path == NULL) { if (gn->type & OP_NOPATH) fullName = NULL; - else + else { fullName = Dir_FindFile(gn->name, Suff_FindPath(gn)); + if (DEBUG(DIR)) + fprintf(debug_file, "Found '%s' as '%s'\n", + gn->name, fullName ? fullName : "(not found)" ); + } } else { fullName = gn->path; } @@ -1446,7 +1450,7 @@ Dir_MTime(GNode *gn) * to the file system. */ if (DEBUG(DIR)) { - printf("Using cached time %s for %s\n", + fprintf(debug_file, "Using cached time %s for %s\n", Targ_FmtTime((time_t)(long)Hash_GetValue(entry)), fullName); } stb.st_mtime = (time_t)(long)Hash_GetValue(entry); @@ -1497,27 +1501,26 @@ Dir_AddDir(Lst path, const char *name) struct dirent *dp; /* entry in directory */ if (strcmp(name, ".DOTLAST") == 0) { - ln = Lst_Find(path, (ClientData)UNCONST(name), DirFindName); + ln = Lst_Find(path, UNCONST(name), DirFindName); if (ln != NILLNODE) return (Path *)Lst_Datum(ln); else { dotLast->refCount += 1; - (void)Lst_AtFront(path, (ClientData)dotLast); + (void)Lst_AtFront(path, dotLast); } } if (path) - ln = Lst_Find(openDirectories, (ClientData)UNCONST(name), DirFindName); + ln = Lst_Find(openDirectories, UNCONST(name), DirFindName); if (ln != NILLNODE) { p = (Path *)Lst_Datum(ln); - if (Lst_Member(path, (ClientData)p) == NILLNODE) { + if (path && Lst_Member(path, p) == NILLNODE) { p->refCount += 1; - (void)Lst_AtEnd(path, (ClientData)p); + (void)Lst_AtEnd(path, p); } } else { if (DEBUG(DIR)) { - printf("Caching %s ...", name); - fflush(stdout); + fprintf(debug_file, "Caching %s ...", name); } if ((d = opendir(name)) != NULL) { @@ -1541,12 +1544,12 @@ Dir_AddDir(Lst path, const char *name) (void)Hash_CreateEntry(&p->files, dp->d_name, NULL); } (void)closedir(d); - (void)Lst_AtEnd(openDirectories, (ClientData)p); + (void)Lst_AtEnd(openDirectories, p); if (path != NULL) - (void)Lst_AtEnd(path, (ClientData)p); + (void)Lst_AtEnd(path, p); } if (DEBUG(DIR)) { - printf("done\n"); + fprintf(debug_file, "done\n"); } } return p; @@ -1571,7 +1574,7 @@ Dir_CopyDir(ClientData p) { ((Path *)p)->refCount += 1; - return ((ClientData)p); + return (p); } /*- @@ -1646,7 +1649,7 @@ Dir_Destroy(ClientData pp) if (p->refCount == 0) { LstNode ln; - ln = Lst_Member(openDirectories, (ClientData)p); + ln = Lst_Member(openDirectories, p); (void)Lst_Remove(openDirectories, ln); Hash_DeleteTable(&p->files); @@ -1678,7 +1681,7 @@ Dir_ClearPath(Lst path) Path *p; while (!Lst_IsEmpty(path)) { p = (Path *)Lst_DeQueue(path); - Dir_Destroy((ClientData) p); + Dir_Destroy(p); } } @@ -1709,9 +1712,9 @@ Dir_Concat(Lst path1, Lst path2) for (ln = Lst_First(path2); ln != NILLNODE; ln = Lst_Succ(ln)) { p = (Path *)Lst_Datum(ln); - if (Lst_Member(path1, (ClientData)p) == NILLNODE) { + if (Lst_Member(path1, p) == NILLNODE) { p->refCount += 1; - (void)Lst_AtEnd(path1, (ClientData)p); + (void)Lst_AtEnd(path1, p); } } } @@ -1723,16 +1726,16 @@ Dir_PrintDirectories(void) LstNode ln; Path *p; - printf("#*** Directory Cache:\n"); - printf("# Stats: %d hits %d misses %d near misses %d losers (%d%%)\n", + fprintf(debug_file, "#*** Directory Cache:\n"); + fprintf(debug_file, "# Stats: %d hits %d misses %d near misses %d losers (%d%%)\n", hits, misses, nearmisses, bigmisses, (hits+bigmisses+nearmisses ? hits * 100 / (hits + bigmisses + nearmisses) : 0)); - printf("# %-20s referenced\thits\n", "directory"); + fprintf(debug_file, "# %-20s referenced\thits\n", "directory"); if (Lst_Open(openDirectories) == SUCCESS) { while ((ln = Lst_Next(openDirectories)) != NILLNODE) { p = (Path *)Lst_Datum(ln); - printf("# %-20s %10d\t%4d\n", p->name, p->refCount, p->hits); + fprintf(debug_file, "# %-20s %10d\t%4d\n", p->name, p->refCount, p->hits); } Lst_Close(openDirectories); } @@ -1741,12 +1744,12 @@ Dir_PrintDirectories(void) static int DirPrintDir(ClientData p, ClientData dummy) { - printf("%s ", ((Path *)p)->name); + fprintf(debug_file, "%s ", ((Path *)p)->name); return (dummy ? 0 : 0); } void Dir_PrintPath(Lst path) { - Lst_ForEach(path, DirPrintDir, (ClientData)0); + Lst_ForEach(path, DirPrintDir, NULL); } diff --git a/devel/bmake/files/dir.h b/devel/bmake/files/dir.h index 852e32da017..48c9e221ff3 100644 --- a/devel/bmake/files/dir.h +++ b/devel/bmake/files/dir.h @@ -1,4 +1,4 @@ -/* $NetBSD: dir.h,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $ */ +/* $NetBSD: dir.h,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. diff --git a/devel/bmake/files/for.c b/devel/bmake/files/for.c index a47fb77bceb..085c49cf012 100644 --- a/devel/bmake/files/for.c +++ b/devel/bmake/files/for.c @@ -1,4 +1,4 @@ -/* $NetBSD: for.c,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $ */ +/* $NetBSD: for.c,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $ */ /* * Copyright (c) 1992, The Regents of the University of California. @@ -30,14 +30,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: for.c,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $"; +static char rcsid[] = "$NetBSD: for.c,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)for.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: for.c,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $"); +__RCSID("$NetBSD: for.c,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -164,7 +164,7 @@ For_Eval(char *line) * a for. */ if (ptr[0] != 'f' || ptr[1] != 'o' || ptr[2] != 'r' || - !isspace((unsigned char) ptr[3])) + !isspace((unsigned char) ptr[3])) return FALSE; ptr += 3; @@ -228,7 +228,7 @@ For_Eval(char *line) #define ADDWORD() \ Buf_AddBytes(buf, ptr - wrd, (Byte *)wrd), \ Buf_AddByte(buf, (Byte)'\0'), \ - Lst_AtFront(accumFor.lst, (ClientData)Buf_GetAll(buf, &varlen)), \ + Lst_AtFront(accumFor.lst, Buf_GetAll(buf, &varlen)), \ Buf_Destroy(buf, FALSE) for (ptr = sub; *ptr && isspace((unsigned char) *ptr); ptr++) @@ -245,9 +245,9 @@ For_Eval(char *line) if (DEBUG(FOR)) { int i; for (i = 0; i < accumFor.nvars; i++) { - (void)fprintf(stderr, "For: variable %s\n", accumFor.vars[i]); + (void)fprintf(debug_file, "For: variable %s\n", accumFor.vars[i]); } - (void)fprintf(stderr, "For: list %s\n", sub); + (void)fprintf(debug_file, "For: list %s\n", sub); } if (ptr - wrd > 0) ADDWORD(); @@ -259,25 +259,25 @@ For_Eval(char *line) forLevel++; return 1; } - else if (*ptr == '.') { + + if (*ptr == '.') { for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++) continue; if (strncmp(ptr, "endfor", 6) == 0 && - (isspace((unsigned char) ptr[6]) || !ptr[6])) { + (isspace((unsigned char) ptr[6]) || !ptr[6])) { if (DEBUG(FOR)) - (void)fprintf(stderr, "For: end for %d\n", forLevel); + (void)fprintf(debug_file, "For: end for %d\n", forLevel); if (--forLevel < 0) { Parse_Error(level, "for-less endfor"); return 0; } - } - else if (strncmp(ptr, "for", 3) == 0 && + } else if (strncmp(ptr, "for", 3) == 0 && isspace((unsigned char) ptr[3])) { forLevel++; if (DEBUG(FOR)) - (void)fprintf(stderr, "For: new loop %d\n", forLevel); + (void)fprintf(debug_file, "For: new loop %d\n", forLevel); } } @@ -286,9 +286,8 @@ For_Eval(char *line) Buf_AddByte(accumFor.buf, (Byte)'\n'); return 1; } - else { - return 0; - } + + return 0; } @@ -351,7 +350,7 @@ For_Run(int lineno) for (i = 0; i < arg.nvars; i++) { Var_Set(arg.vars[i], values[i], VAR_GLOBAL, 0); if (DEBUG(FOR)) - (void)fprintf(stderr, "--- %s = %s\n", arg.vars[i], + (void)fprintf(debug_file, "--- %s = %s\n", arg.vars[i], values[i]); } @@ -372,7 +371,7 @@ For_Run(int lineno) if (old_guy != orig_guy) free(old_guy); } - Parse_FromString(guy, lineno); + Parse_SetInput(NULL, lineno, -1, guy); for (i = 0; i < arg.nvars; i++) Var_Delete(arg.vars[i], VAR_GLOBAL); diff --git a/devel/bmake/files/lst.h b/devel/bmake/files/lst.h index 223d159703e..5205294a542 100644 --- a/devel/bmake/files/lst.h +++ b/devel/bmake/files/lst.h @@ -1,4 +1,4 @@ -/* $NetBSD: lst.h,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lst.h,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -89,8 +89,8 @@ * basic typedef. This is what the Lst_ functions handle */ -typedef struct Lst *Lst; -typedef struct LstNode *LstNode; +typedef struct List *Lst; +typedef struct ListNode *LstNode; typedef ClientData DuplicateProc(ClientData); typedef void FreeProc(ClientData); @@ -125,9 +125,9 @@ Boolean Lst_IsEmpty(Lst); * Functions to modify a list */ /* Insert an element before another */ -ReturnStatus Lst_Insert(Lst, LstNode, ClientData); +ReturnStatus Lst_InsertBefore(Lst, LstNode, ClientData); /* Insert an element after another */ -ReturnStatus Lst_Append(Lst, LstNode, ClientData); +ReturnStatus Lst_InsertAfter(Lst, LstNode, ClientData); /* Place an element at the front of a lst. */ ReturnStatus Lst_AtFront(Lst, ClientData); /* Place an element at the end of a lst. */ @@ -148,6 +148,8 @@ LstNode Lst_First(Lst); LstNode Lst_Last(Lst); /* Return successor to given element */ LstNode Lst_Succ(LstNode); +/* Return predecessor to given element */ +LstNode Lst_Prev(LstNode); /* Get datum from LstNode */ ClientData Lst_Datum(LstNode); @@ -165,13 +167,13 @@ LstNode Lst_FindFrom(Lst, LstNode, ClientData, */ LstNode Lst_Member(Lst, ClientData); /* Apply a function to all elements of a lst */ -void Lst_ForEach(Lst, int (*)(ClientData, ClientData), ClientData); +int Lst_ForEach(Lst, int (*)(ClientData, ClientData), ClientData); /* * Apply a function to all elements of a lst starting from a certain point. * If the list is circular, the application will wrap around to the * beginning of the list again. */ -void Lst_ForEachFrom(Lst, LstNode, int (*)(ClientData, ClientData), +int Lst_ForEachFrom(Lst, LstNode, int (*)(ClientData, ClientData), ClientData); /* * these functions are for dealing with a list as a table, of sorts. diff --git a/devel/bmake/files/lst.lib/Makefile b/devel/bmake/files/lst.lib/Makefile index eec86e6665b..1f49ba4fd53 100644 --- a/devel/bmake/files/lst.lib/Makefile +++ b/devel/bmake/files/lst.lib/Makefile @@ -1,10 +1,10 @@ -# $NetBSD: Makefile,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ +# $NetBSD: Makefile,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ OBJ=lstAppend.o lstDupl.o lstInit.o lstOpen.o lstAtEnd.o lstEnQueue.o \ lstInsert.o lstAtFront.o lstIsAtEnd.o lstClose.o lstFind.o lstIsEmpty.o \ lstRemove.o lstConcat.o lstFindFrom.o lstLast.o lstReplace.o lstFirst.o \ lstDatum.o lstForEach.o lstMember.o lstSucc.o lstDeQueue.o \ - lstForEachFrom.o lstDestroy.o lstNext.o + lstForEachFrom.o lstDestroy.o lstNext.o lstPrev.o CPPFLAGS=-I${.CURDIR}/.. all: ${OBJ} diff --git a/devel/bmake/files/lst.lib/lstAppend.c b/devel/bmake/files/lst.lib/lstAppend.c index f033c14a79a..97b1bbae1b0 100644 --- a/devel/bmake/files/lst.lib/lstAppend.c +++ b/devel/bmake/files/lst.lib/lstAppend.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstAppend.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstAppend.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstAppend.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstAppend.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstAppend.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstAppend.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstAppend.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -54,7 +54,7 @@ __RCSID("$NetBSD: lstAppend.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); /*- *----------------------------------------------------------------------- - * Lst_Append -- + * Lst_InsertAfter -- * Create a new node and add it to the given list after the given node. * * Input: @@ -74,7 +74,7 @@ __RCSID("$NetBSD: lstAppend.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); *----------------------------------------------------------------------- */ ReturnStatus -Lst_Append(Lst l, LstNode ln, ClientData d) +Lst_InsertAfter(Lst l, LstNode ln, ClientData d) { List list; ListNode lNode; @@ -89,8 +89,8 @@ Lst_Append(Lst l, LstNode ln, ClientData d) } ok: - list = (List)l; - lNode = (ListNode)ln; + list = l; + lNode = ln; PAlloc (nLNode, ListNode); nLNode->datum = d; diff --git a/devel/bmake/files/lst.lib/lstAtEnd.c b/devel/bmake/files/lst.lib/lstAtEnd.c index 8f870caa64d..cbc926fb01a 100644 --- a/devel/bmake/files/lst.lib/lstAtEnd.c +++ b/devel/bmake/files/lst.lib/lstAtEnd.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstAtEnd.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstAtEnd.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstAtEnd.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstAtEnd.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstAtEnd.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstAtEnd.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstAtEnd.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -75,5 +75,5 @@ Lst_AtEnd(Lst l, ClientData d) LstNode end; end = Lst_Last(l); - return (Lst_Append(l, end, d)); + return (Lst_InsertAfter(l, end, d)); } diff --git a/devel/bmake/files/lst.lib/lstAtFront.c b/devel/bmake/files/lst.lib/lstAtFront.c index 58abff7ad40..3bf37a9c07f 100644 --- a/devel/bmake/files/lst.lib/lstAtFront.c +++ b/devel/bmake/files/lst.lib/lstAtFront.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstAtFront.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstAtFront.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstAtFront.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstAtFront.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstAtFront.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstAtFront.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstAtFront.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -72,5 +72,5 @@ Lst_AtFront(Lst l, ClientData d) LstNode front; front = Lst_First(l); - return (Lst_Insert(l, front, d)); + return (Lst_InsertBefore(l, front, d)); } diff --git a/devel/bmake/files/lst.lib/lstClose.c b/devel/bmake/files/lst.lib/lstClose.c index 2e58dfa234d..42f852612b5 100644 --- a/devel/bmake/files/lst.lib/lstClose.c +++ b/devel/bmake/files/lst.lib/lstClose.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstClose.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstClose.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstClose.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstClose.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstClose.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstClose.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstClose.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -76,7 +76,7 @@ __RCSID("$NetBSD: lstClose.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); void Lst_Close(Lst l) { - List list = (List) l; + List list = l; if (LstValid(l) == TRUE) { list->isOpen = FALSE; diff --git a/devel/bmake/files/lst.lib/lstConcat.c b/devel/bmake/files/lst.lib/lstConcat.c index 1561148f64c..6c15e4704c5 100644 --- a/devel/bmake/files/lst.lib/lstConcat.c +++ b/devel/bmake/files/lst.lib/lstConcat.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstConcat.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstConcat.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstConcat.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstConcat.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstConcat.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstConcat.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstConcat.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -82,8 +82,8 @@ Lst_Concat(Lst l1, Lst l2, int flags) ListNode nln; /* new LstNode */ ListNode last; /* the last element in the list. Keeps * bookkeeping until the end */ - List list1 = (List)l1; - List list2 = (List)l2; + List list1 = l1; + List list2 = l2; if (!LstValid (l1) || !LstValid (l2)) { return (FAILURE); diff --git a/devel/bmake/files/lst.lib/lstDatum.c b/devel/bmake/files/lst.lib/lstDatum.c index 697766788f5..06d841a11ca 100644 --- a/devel/bmake/files/lst.lib/lstDatum.c +++ b/devel/bmake/files/lst.lib/lstDatum.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstDatum.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstDatum.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstDatum.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstDatum.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstDatum.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstDatum.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstDatum.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -69,7 +69,7 @@ ClientData Lst_Datum(LstNode ln) { if (ln != NILLNODE) { - return (((ListNode)ln)->datum); + return ((ln)->datum); } else { return ((ClientData) NIL); } diff --git a/devel/bmake/files/lst.lib/lstDeQueue.c b/devel/bmake/files/lst.lib/lstDeQueue.c index e506806ef21..92bb4149cbe 100644 --- a/devel/bmake/files/lst.lib/lstDeQueue.c +++ b/devel/bmake/files/lst.lib/lstDeQueue.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstDeQueue.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstDeQueue.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstDeQueue.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstDeQueue.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstDeQueue.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstDeQueue.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstDeQueue.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -72,13 +72,13 @@ Lst_DeQueue(Lst l) ClientData rd; ListNode tln; - tln = (ListNode) Lst_First(l); + tln = Lst_First(l); if (tln == NilListNode) { return ((ClientData) NIL); } rd = tln->datum; - if (Lst_Remove(l, (LstNode)tln) == FAILURE) { + if (Lst_Remove(l, tln) == FAILURE) { return ((ClientData) NIL); } else { return (rd); diff --git a/devel/bmake/files/lst.lib/lstDestroy.c b/devel/bmake/files/lst.lib/lstDestroy.c index 1152a9fcc83..67d6563e06f 100644 --- a/devel/bmake/files/lst.lib/lstDestroy.c +++ b/devel/bmake/files/lst.lib/lstDestroy.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstDestroy.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstDestroy.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstDestroy.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstDestroy.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstDestroy.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstDestroy.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstDestroy.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -72,7 +72,7 @@ Lst_Destroy(Lst l, FreeProc *freeProc) { ListNode ln; ListNode tln = NilListNode; - List list = (List)l; + List list = l; if (l == NILLST || ! l) { /* diff --git a/devel/bmake/files/lst.lib/lstDupl.c b/devel/bmake/files/lst.lib/lstDupl.c index 14a5dd85097..a4a65f34924 100644 --- a/devel/bmake/files/lst.lib/lstDupl.c +++ b/devel/bmake/files/lst.lib/lstDupl.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstDupl.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstDupl.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstDupl.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstDupl.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstDupl.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstDupl.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstDupl.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -75,7 +75,7 @@ Lst_Duplicate(Lst l, DuplicateProc *copyProc) { Lst nl; ListNode ln; - List list = (List)l; + List list = l; if (!LstValid (l)) { return (NILLST); diff --git a/devel/bmake/files/lst.lib/lstEnQueue.c b/devel/bmake/files/lst.lib/lstEnQueue.c index 0ecf5b368f0..6832b79ac20 100644 --- a/devel/bmake/files/lst.lib/lstEnQueue.c +++ b/devel/bmake/files/lst.lib/lstEnQueue.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstEnQueue.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstEnQueue.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstEnQueue.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstEnQueue.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstEnQueue.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstEnQueue.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstEnQueue.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -58,7 +58,7 @@ __RCSID("$NetBSD: lstEnQueue.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); * Add the datum to the tail of the given list. * * Results: - * SUCCESS or FAILURE as returned by Lst_Append. + * SUCCESS or FAILURE as returned by Lst_InsertAfter. * * Side Effects: * the lastPtr field is altered all the time and the firstPtr field @@ -73,6 +73,6 @@ Lst_EnQueue(Lst l, ClientData d) return (FAILURE); } - return (Lst_Append(l, Lst_Last(l), d)); + return (Lst_InsertAfter(l, Lst_Last(l), d)); } diff --git a/devel/bmake/files/lst.lib/lstFindFrom.c b/devel/bmake/files/lst.lib/lstFindFrom.c index c0fe531e98e..271f310ca67 100644 --- a/devel/bmake/files/lst.lib/lstFindFrom.c +++ b/devel/bmake/files/lst.lib/lstFindFrom.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstFindFrom.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstFindFrom.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstFindFrom.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstFindFrom.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstFindFrom.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstFindFrom.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstFindFrom.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -78,7 +78,7 @@ Lst_FindFrom(Lst l, LstNode ln, ClientData d, return (NILLNODE); } - tln = (ListNode)ln; + tln = ln; do { if ((*cProc) (tln->datum, d) == 0) { @@ -87,10 +87,10 @@ Lst_FindFrom(Lst l, LstNode ln, ClientData d, } else { tln = tln->nextPtr; } - } while (tln != (ListNode)ln && tln != NilListNode); + } while (tln != ln && tln != NilListNode); if (found) { - return ((LstNode)tln); + return (tln); } else { return (NILLNODE); } diff --git a/devel/bmake/files/lst.lib/lstFirst.c b/devel/bmake/files/lst.lib/lstFirst.c index 14d1a59e535..4539f8b22f8 100644 --- a/devel/bmake/files/lst.lib/lstFirst.c +++ b/devel/bmake/files/lst.lib/lstFirst.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstFirst.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstFirst.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstFirst.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstFirst.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstFirst.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstFirst.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstFirst.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -71,7 +71,7 @@ Lst_First(Lst l) if (!LstValid (l) || LstIsEmpty (l)) { return (NILLNODE); } else { - return ((LstNode)((List)l)->firstPtr); + return (l->firstPtr); } } diff --git a/devel/bmake/files/lst.lib/lstForEach.c b/devel/bmake/files/lst.lib/lstForEach.c index 92be4a7388c..cca3dd80f5d 100644 --- a/devel/bmake/files/lst.lib/lstForEach.c +++ b/devel/bmake/files/lst.lib/lstForEach.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstForEach.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstForEach.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstForEach.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstForEach.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstForEach.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstForEach.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstForEach.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -68,9 +68,9 @@ __RCSID("$NetBSD: lstForEach.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); *----------------------------------------------------------------------- */ /*VARARGS2*/ -void +int Lst_ForEach(Lst l, int (*proc)(ClientData, ClientData), ClientData d) { - Lst_ForEachFrom(l, Lst_First(l), proc, d); + return Lst_ForEachFrom(l, Lst_First(l), proc, d); } diff --git a/devel/bmake/files/lst.lib/lstForEachFrom.c b/devel/bmake/files/lst.lib/lstForEachFrom.c index 59fba8b53ca..c65a60043a3 100644 --- a/devel/bmake/files/lst.lib/lstForEachFrom.c +++ b/devel/bmake/files/lst.lib/lstForEachFrom.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstForEachFrom.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstForEachFrom.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstForEachFrom.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstForEachFrom.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstForEachFrom.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstForEachFrom.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstForEachFrom.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -69,18 +69,18 @@ __RCSID("$NetBSD: lstForEachFrom.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); *----------------------------------------------------------------------- */ /*VARARGS2*/ -void +int Lst_ForEachFrom(Lst l, LstNode ln, int (*proc)(ClientData, ClientData), ClientData d) { - ListNode tln = (ListNode)ln; - List list = (List)l; + ListNode tln = ln; + List list = l; ListNode next; Boolean done; int result; if (!LstValid (list) || LstIsEmpty (list)) { - return; + return 0; } do { @@ -120,5 +120,6 @@ Lst_ForEachFrom(Lst l, LstNode ln, int (*proc)(ClientData, ClientData), tln = next; } while (!result && !LstIsEmpty(list) && !done); + return result; } diff --git a/devel/bmake/files/lst.lib/lstInit.c b/devel/bmake/files/lst.lib/lstInit.c index d63642a35b4..a82d127cca8 100644 --- a/devel/bmake/files/lst.lib/lstInit.c +++ b/devel/bmake/files/lst.lib/lstInit.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstInit.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstInit.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstInit.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstInit.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstInit.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstInit.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstInit.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -81,5 +81,5 @@ Lst_Init(Boolean circ) nList->isCirc = circ; nList->atEnd = Unknown; - return ((Lst)nList); + return (nList); } diff --git a/devel/bmake/files/lst.lib/lstInsert.c b/devel/bmake/files/lst.lib/lstInsert.c index a63bbb4de70..c60022efdfa 100644 --- a/devel/bmake/files/lst.lib/lstInsert.c +++ b/devel/bmake/files/lst.lib/lstInsert.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstInsert.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstInsert.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstInsert.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstInsert.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstInsert.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstInsert.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstInsert.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -54,7 +54,7 @@ __RCSID("$NetBSD: lstInsert.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); /*- *----------------------------------------------------------------------- - * Lst_Insert -- + * Lst_InsertBefore -- * Insert a new node with the given piece of data before the given * node in the given list. * @@ -73,11 +73,11 @@ __RCSID("$NetBSD: lstInsert.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); *----------------------------------------------------------------------- */ ReturnStatus -Lst_Insert(Lst l, LstNode ln, ClientData d) +Lst_InsertBefore(Lst l, LstNode ln, ClientData d) { ListNode nLNode; /* new lnode for d */ - ListNode lNode = (ListNode)ln; - List list = (List)l; + ListNode lNode = ln; + List list = l; /* diff --git a/devel/bmake/files/lst.lib/lstIsAtEnd.c b/devel/bmake/files/lst.lib/lstIsAtEnd.c index 385fd82f152..fb09223c3ce 100644 --- a/devel/bmake/files/lst.lib/lstIsAtEnd.c +++ b/devel/bmake/files/lst.lib/lstIsAtEnd.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstIsAtEnd.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstIsAtEnd.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstIsAtEnd.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstIsAtEnd.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstIsAtEnd.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstIsAtEnd.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstIsAtEnd.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -79,7 +79,7 @@ __RCSID("$NetBSD: lstIsAtEnd.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); Boolean Lst_IsAtEnd(Lst l) { - List list = (List) l; + List list = l; return (!LstValid (l) || !list->isOpen || (list->atEnd == Head) || (list->atEnd == Tail)); diff --git a/devel/bmake/files/lst.lib/lstLast.c b/devel/bmake/files/lst.lib/lstLast.c index fc88aa52851..47cc372cebb 100644 --- a/devel/bmake/files/lst.lib/lstLast.c +++ b/devel/bmake/files/lst.lib/lstLast.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstLast.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstLast.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstLast.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstLast.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstLast.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstLast.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstLast.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -71,7 +71,7 @@ Lst_Last(Lst l) if (!LstValid(l) || LstIsEmpty (l)) { return (NILLNODE); } else { - return ((LstNode)((List)l)->lastPtr); + return (l->lastPtr); } } diff --git a/devel/bmake/files/lst.lib/lstMember.c b/devel/bmake/files/lst.lib/lstMember.c index 8356e3b4c21..a023ac97248 100644 --- a/devel/bmake/files/lst.lib/lstMember.c +++ b/devel/bmake/files/lst.lib/lstMember.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstMember.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstMember.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstMember.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstMember.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstMember.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstMember.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstMember.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -55,7 +55,7 @@ __RCSID("$NetBSD: lstMember.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); LstNode Lst_Member(Lst l, ClientData d) { - List list = (List) l; + List list = l; ListNode lNode; lNode = list->firstPtr; @@ -65,7 +65,7 @@ Lst_Member(Lst l, ClientData d) do { if (lNode->datum == d) { - return (LstNode)lNode; + return lNode; } lNode = lNode->nextPtr; } while (lNode != NilListNode && lNode != list->firstPtr); diff --git a/devel/bmake/files/lst.lib/lstNext.c b/devel/bmake/files/lst.lib/lstNext.c index e20ade15ab4..f28e467c0c1 100644 --- a/devel/bmake/files/lst.lib/lstNext.c +++ b/devel/bmake/files/lst.lib/lstNext.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstNext.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstNext.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstNext.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstNext.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstNext.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstNext.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstNext.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -76,7 +76,7 @@ LstNode Lst_Next(Lst l) { ListNode tln; - List list = (List)l; + List list = l; if ((LstValid (l) == FALSE) || (list->isOpen == FALSE)) { @@ -115,6 +115,6 @@ Lst_Next(Lst l) } } - return ((LstNode)tln); + return (tln); } diff --git a/devel/bmake/files/lst.lib/lstOpen.c b/devel/bmake/files/lst.lib/lstOpen.c index ee0b3e390e8..9208b35ac3b 100644 --- a/devel/bmake/files/lst.lib/lstOpen.c +++ b/devel/bmake/files/lst.lib/lstOpen.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstOpen.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstOpen.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstOpen.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstOpen.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstOpen.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstOpen.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstOpen.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -78,9 +78,9 @@ Lst_Open(Lst l) if (LstValid (l) == FALSE) { return (FAILURE); } - ((List) l)->isOpen = TRUE; - ((List) l)->atEnd = LstIsEmpty (l) ? Head : Unknown; - ((List) l)->curPtr = NilListNode; + (l)->isOpen = TRUE; + (l)->atEnd = LstIsEmpty (l) ? Head : Unknown; + (l)->curPtr = NilListNode; return (SUCCESS); } diff --git a/devel/bmake/files/lst.lib/lstPrev.c b/devel/bmake/files/lst.lib/lstPrev.c new file mode 100644 index 00000000000..7ea030338ec --- /dev/null +++ b/devel/bmake/files/lst.lib/lstPrev.c @@ -0,0 +1,79 @@ +/* $NetBSD: lstPrev.c,v 1.1.1.1 2008/03/09 19:39:35 joerg Exp $ */ + +/* + * Copyright (c) 1988, 1989, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Adam de Boor. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef MAKE_NATIVE +static char rcsid[] = "$NetBSD: lstPrev.c,v 1.1.1.1 2008/03/09 19:39:35 joerg Exp $"; +#else +#include <sys/cdefs.h> +#ifndef lint +#if 0 +static char sccsid[] = "@(#)lstSucc.c 8.1 (Berkeley) 6/6/93"; +#else +__RCSID("$NetBSD: lstPrev.c,v 1.1.1.1 2008/03/09 19:39:35 joerg Exp $"); +#endif +#endif /* not lint */ +#endif + +/*- + * LstPrev.c -- + * return the predecessor to a given node + */ + +#include "lstInt.h" + +/*- + *----------------------------------------------------------------------- + * Lst_Prev -- + * Return the predecessor to the given node on its list. + * + * Results: + * The predecessor of the node, if it exists (note that on a circular + * list, if the node is the only one in the list, it is its own + * predecessor). + * + * Side Effects: + * None. + * + *----------------------------------------------------------------------- + */ +LstNode +Lst_Prev(LstNode ln) +{ + if (ln == NILLNODE) { + return (NILLNODE); + } else { + return (ln->prevPtr); + } +} + diff --git a/devel/bmake/files/lst.lib/lstRemove.c b/devel/bmake/files/lst.lib/lstRemove.c index 8a0a14cb811..37c949a627a 100644 --- a/devel/bmake/files/lst.lib/lstRemove.c +++ b/devel/bmake/files/lst.lib/lstRemove.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstRemove.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstRemove.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstRemove.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstRemove.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstRemove.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstRemove.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstRemove.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -70,8 +70,8 @@ __RCSID("$NetBSD: lstRemove.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); ReturnStatus Lst_Remove(Lst l, LstNode ln) { - List list = (List) l; - ListNode lNode = (ListNode) ln; + List list = l; + ListNode lNode = ln; if (!LstValid (l) || !LstNodeValid (ln, l)) { diff --git a/devel/bmake/files/lst.lib/lstReplace.c b/devel/bmake/files/lst.lib/lstReplace.c index a728145d03f..c7aa48aad5c 100644 --- a/devel/bmake/files/lst.lib/lstReplace.c +++ b/devel/bmake/files/lst.lib/lstReplace.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstReplace.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstReplace.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstReplace.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstReplace.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstReplace.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstReplace.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstReplace.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -71,7 +71,7 @@ Lst_Replace(LstNode ln, ClientData d) if (ln == NILLNODE) { return (FAILURE); } else { - ((ListNode) ln)->datum = d; + (ln)->datum = d; return (SUCCESS); } } diff --git a/devel/bmake/files/lst.lib/lstSucc.c b/devel/bmake/files/lst.lib/lstSucc.c index 6d668a0f42b..497bac25967 100644 --- a/devel/bmake/files/lst.lib/lstSucc.c +++ b/devel/bmake/files/lst.lib/lstSucc.c @@ -1,4 +1,4 @@ -/* $NetBSD: lstSucc.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: lstSucc.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -33,14 +33,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: lstSucc.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: lstSucc.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)lstSucc.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: lstSucc.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: lstSucc.c,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -73,7 +73,7 @@ Lst_Succ(LstNode ln) if (ln == NILLNODE) { return (NILLNODE); } else { - return ((LstNode) ((ListNode) ln)->nextPtr); + return (ln->nextPtr); } } diff --git a/devel/bmake/files/make-conf.h b/devel/bmake/files/make-conf.h index 5fbb4f15594..6dc0164c376 100644 --- a/devel/bmake/files/make-conf.h +++ b/devel/bmake/files/make-conf.h @@ -1,4 +1,4 @@ -/* $NetBSD: make-conf.h,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $ */ +/* $NetBSD: make-conf.h,v 1.1.1.2 2008/03/09 19:39:32 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -72,10 +72,6 @@ * from: @(#)config.h 8.1 (Berkeley) 6/6/93 */ -#ifndef DEFSHELL -#define DEFSHELL 1 /* Bourne shell */ -#endif - /* * DEFMAXJOBS * DEFMAXLOCAL @@ -146,13 +142,6 @@ #define SUNSHCMD /* - * USE_PGRP - * Kill the process group of the job so that all the progeny of the - * current job dies, instead of just the one forked. - */ -#define USE_PGRP - -/* * USE_IOVEC * We have writev(2) */ diff --git a/devel/bmake/files/make.1 b/devel/bmake/files/make.1 index f0ef8bedc0b..b861a916508 100644 --- a/devel/bmake/files/make.1 +++ b/devel/bmake/files/make.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: make.1,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ +.\" $NetBSD: make.1,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $ .\" .\" Copyright (c) 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -29,7 +29,7 @@ .\" .\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 .\" -.Dd June 27, 2005 +.Dd November 19, 2006 .Dt MAKE 1 .Os .Sh NAME @@ -74,12 +74,15 @@ is a program designed to simplify the maintenance of other programs. Its input is a list of specifications as to the files upon which programs and other files depend. -If the file +If no +.Fl f Ar makefile +makefile option is given, +.Nm +will try to open .Ql Pa makefile -exists, it is read for this list of specifications. -If it does not exist, the file +then .Ql Pa Makefile -is read. +in order to find the specifications. If the file .Ql Pa .depend exists, it is read (see @@ -91,6 +94,11 @@ For a more thorough description of and makefiles, please refer to .%T "Make \- A Tutorial" . .Pp +.Nm +will prepend the contents of the +.Va MAKEFLAGS +environment variable to the command line arguments before parsing them. +.Pp The options are as follows: .Bl -tag -width Ds .It Fl B @@ -100,10 +108,15 @@ by executing the commands to make the sources of a dependency line in sequence. Define .Ar variable to be 1, in the global context. -.It Fl d Ar flags +.It Fl d Ar [-]flags Turn on debugging, and specify which portions of .Nm are to print debugging information. +Unless the flags are preceded by +.Ql - +they are added to the +.Va MAKEFLAGS +environment variable and will be processed by any child make processes. .Ar Flags is one or more of the following: .Bl -tag -width Ds @@ -118,6 +131,15 @@ Print debugging information about conditional evaluation. Print debugging information about directory searching and caching. .It Ar e Print debugging information about failed commands and targets. +.It Ar F +Use the rest of +.Ql flags +as the name of the file to which the debug output is written. +If the filename ends +.Ql .%d +then the +.Ql %d +is replaced by the pid. .It Ar f Print debugging information about loop evaluation. .It Ar "g1" @@ -129,6 +151,11 @@ on error. Print the input graph before exiting on error. .It Ar j Print debugging information about running multiple shells. +.It Ar l +Print commands in Makefiles regardless of whether or not they are prefixed by +.Ql @ +or other "quiet" flags. +Also known as "loud" behavior. .It Ar m Print debugging information about making targets, including modification dates. @@ -140,8 +167,12 @@ These are created via .Xr mkstemp 3 and have names of the form .Pa /tmp/makeXXXXX . -.Em NOTE: -This can create many file in /tmp so use with care. +.Em NOTE : +This can create many file in +.Pa /tmp +so use with care. +.It Ar p +Print debugging information about makefile parsing. .It Ar s Print debugging information about suffix-transformation rules. .It Ar t @@ -413,6 +444,11 @@ Assign the value to the variable if it is not already defined. Assign with expansion, i.e. expand the value before assigning it to the variable. Normally, expansion is not done until the variable is referenced. +.Em NOTE : +References to undefined variables are +.Em not +expanded. +This can cause problems when variable modifiers are used. .It Ic \&!= Expand the value and pass it to the shell for execution and assign the result to the variable. @@ -539,7 +575,7 @@ The name that .Nm was executed with .Pq Va argv[0] . -For compatibily +For compatibility .Nm also sets .Va .MAKE @@ -549,6 +585,35 @@ The preferred variable to use is the environment variable because it is more compatible with other versions of .Nm and cannot be confused with the special target with the same name. +.It Va .MAKE.EXPORTED +The list of variables exported by +.Nm . +.It Va .MAKE.MAKEFILES +The list of makefiles read by +.Nm , +which is useful for tracking dependencies. +Each makefile is recorded only once, regardless of the number of times read. +.It Va .MAKE.PID +The process-id of +.Nm . +.It Va .MAKE.PPID +The parent process-id of +.Nm . +.It Va .MAKE.JOB.PREFIX +If +.Nm +is run with +.Ar j +then output for each target is prefixed with a token +.Ql --- target --- +the first part of which can be controlled via +.Va .MAKE.JOB.PREFIX . +.br +For example: +.Li .MAKE.JOB.PREFIX=${.newline}---${.MAKE:T}[${.MAKE.PID}] +would produce tokens like +.Ql ---make[1234] target --- +making it easier to track the degree of parallelism being achieved. .It Ev MAKEFLAGS The environment variable .Ql Ev MAKEFLAGS @@ -692,11 +757,24 @@ Variable expansion may be modified to select or modify each word of the variable (where a ``word'' is white-space delimited sequence of characters). The general format of a variable expansion is as follows: .Pp -.Dl {variable[:modifier[:...]]} +.Dl ${variable[:modifier[:...]]} .Pp Each modifier begins with a colon, which may be escaped with a backslash .Pq Ql \e . +.Pp +A set of modifiers can be specified via a variable, as follows: +.Pp +.Dl modifier_variable=modifier[:...] +.Dl ${variable:${modifier_variable}[:...]} +.Pp +In this case the first modifier in the modifier_variable does not +start with a colon, since that must appear in the referencing +variable. +If any of the modifiers in the modifier_variable contain a dollar sign +.Pq Ql $ , +these must be doubled to avoid early expansion. +.Pp The supported modifiers are: .Bl -tag -width EEE .It Cm \&:E @@ -1117,6 +1195,18 @@ Conditional expressions are also preceded by a single dot as the first character of a line. The possible conditionals are as follows: .Bl -tag -width Ds +.It Ic .export Ar variable +Export the specified global variable. +If no variable is provided, all globals are exported +except for internal variables (those that start with +.Ql \&. +). +This is not affected by the +.Fl X +flag, so should be used with caution. +Appending a variable name to +.Va .MAKE.EXPORTED +is equivalent to exporting a variable. .It Ic .undef Ar variable Un-define the specified global variable. Only global variables may be un-defined. @@ -1380,7 +1470,7 @@ option. .It Ic .PRECIOUS When .Nm -is interrupted, it removes any partially made targets. +is interrupted, it normally removes any partially made targets. This source prevents the target from being removed. .It Ic .RECURSIVE Synonym for @@ -1413,8 +1503,30 @@ If .Ic .WAIT appears in a dependency line, the sources that precede it are made before the sources that succeed it in the line. -Loops are not -detected and targets that form loops will be silently ignored. +Since the dependents of files are not made until the file itself +could be made, this also stops the dependents being built unless they +are needed for another branch of the dependency tree. +So given: +.Bd -literal +x: a .WAIT b + echo x +a: + echo a +b: b1 + echo b +b1: + echo b1 + +.Ed +the output is always +.Ql b1 , +.Ql b , +.Ql a , +.Ql x . +.br +The ordering imposed by +.Ic .WAIT +is only relevant for parallel makes. .El .Sh SPECIAL TARGETS Special targets may not be included with other targets, i.e. they must be @@ -1480,6 +1592,20 @@ Synonym for for compatibility with other pmake variants. .It Ic .ORDER The named targets are made in sequence. +This ordering does not add targets to the list of targets to be made. +Since the dependents of a target do not get built until the target itself +could be built, unless +.Ql a +is built by another part of the dependency graph, +the following is a dependency loop: +.Bd -literal +\&.ORDER a b +b: a +.Ed +.Pp +The ordering imposed by +.Ic .ORDER +is only relevant for parallel makes. .\" XXX: NOT YET!!!! .\" .It Ic .PARALLEL .\" The named targets are executed in parallel mode. @@ -1543,13 +1669,16 @@ It is typically identical to The flag to pass the shell to enable error checking. .It Ar echoFlag The flag to pass the shell to enable command echoing. +.It Ar newline +The string literal to pass the shell that results in a single newline +character when used outside of any quoting characters. .El Example: .Bd -literal \&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \\ check="set -e" ignore="set +e" \\ echo="set -v" quiet="set +v" filter="set +v" \\ - echoFlag=v errFlag=e + echoFlag=v errFlag=e newline="'\\n'" .Ed .It Ic .SILENT Apply the @@ -1599,6 +1728,14 @@ system makefile .It /usr/share/mk system makefile directory .El +.Sh COMPATIBILITY +The basic make syntax is compatible between different versions of make, +however the special variables, variable modifiers and conditionals are not. +.Pp +The way that parallel makes are scheduled changed in +.Nx 4.0 +so that .ORDER and .WAIT apply recursively to the dependant nodes. +The algorithms used may change again in the future. .Sh SEE ALSO .Xr mkdep 1 .Sh HISTORY diff --git a/devel/bmake/files/make.c b/devel/bmake/files/make.c index 1661b7d0de6..d313208b2e2 100644 --- a/devel/bmake/files/make.c +++ b/devel/bmake/files/make.c @@ -1,4 +1,4 @@ -/* $NetBSD: make.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: make.c,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: make.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: make.c,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: make.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: make.c,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -112,8 +112,7 @@ __RCSID("$NetBSD: make.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); * Make_HandleUse See if a child is a .USE node for a parent * and perform the .USE actions if so. * - * Make_ExpandUse Expand .USE nodes and return the new list of - * targets. + * Make_ExpandUse Expand .USE nodes */ #include "make.h" @@ -121,14 +120,12 @@ __RCSID("$NetBSD: make.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); #include "dir.h" #include "job.h" +static unsigned int checked = 1;/* Sequence # to detect recursion */ static Lst toBeMade; /* The current fringe of the graph. These * are nodes which await examination by * MakeOODate. It is added to by * Make_Update and subtracted from by * MakeStartJobs */ -static int numNodes; /* Number of nodes to be processed. If this - * is non-zero when Job_Empty() returns - * TRUE, there's a cycle in the graph */ static int MakeAddChild(ClientData, ClientData); static int MakeFindChild(ClientData, ClientData); @@ -138,6 +135,22 @@ static int MakeTimeStamp(ClientData, ClientData); static int MakeHandleUse(ClientData, ClientData); static Boolean MakeStartJobs(void); static int MakePrintStatus(ClientData, ClientData); +static int MakeCheckOrder(ClientData, ClientData); +static int MakeBuildChild(ClientData, ClientData); +static int MakeBuildParent(ClientData, ClientData); + +static void +make_abort(GNode *gn, int line) +{ + static int two = 2; + + fprintf(debug_file, "make_abort from line %d\n", line); + Targ_PrintNode(gn, &two); + Lst_ForEach(toBeMade, Targ_PrintNode, &two); + Targ_PrintGraph(3); + abort(); +} + /*- *----------------------------------------------------------------------- * Make_TimeStamp -- @@ -211,9 +224,9 @@ Make_OODate(GNode *gn) (void)Dir_MTime(gn); if (DEBUG(MAKE)) { if (gn->mtime != 0) { - printf("modified %s...", Targ_FmtTime(gn->mtime)); + fprintf(debug_file, "modified %s...", Targ_FmtTime(gn->mtime)); } else { - printf("non-existent..."); + fprintf(debug_file, "non-existent..."); } } } @@ -238,13 +251,13 @@ Make_OODate(GNode *gn) * no matter *what*. */ if (DEBUG(MAKE)) { - printf(".USE node..."); + fprintf(debug_file, ".USE node..."); } oodate = FALSE; } else if ((gn->type & OP_LIB) && ((gn->mtime==0) || Arch_IsLib(gn))) { if (DEBUG(MAKE)) { - printf("library..."); + fprintf(debug_file, "library..."); } /* @@ -259,10 +272,10 @@ Make_OODate(GNode *gn) * out-of-date if any of its children was out-of-date. */ if (DEBUG(MAKE)) { - printf(".JOIN node..."); + fprintf(debug_file, ".JOIN node..."); } if (DEBUG(MAKE)) { - printf("source %smade...", gn->flags & CHILDMADE ? "" : "not "); + fprintf(debug_file, "source %smade...", gn->flags & CHILDMADE ? "" : "not "); } oodate = (gn->flags & CHILDMADE) ? TRUE : FALSE; } else if (gn->type & (OP_FORCE|OP_EXEC|OP_PHONY)) { @@ -272,11 +285,11 @@ Make_OODate(GNode *gn) */ if (DEBUG(MAKE)) { if (gn->type & OP_FORCE) { - printf("! operator..."); + fprintf(debug_file, "! operator..."); } else if (gn->type & OP_PHONY) { - printf(".PHONY node..."); + fprintf(debug_file, ".PHONY node..."); } else { - printf(".EXEC node..."); + fprintf(debug_file, ".EXEC node..."); } } oodate = TRUE; @@ -294,11 +307,11 @@ Make_OODate(GNode *gn) */ if (DEBUG(MAKE)) { if (gn->mtime < gn->cmtime) { - printf("modified before source..."); + fprintf(debug_file, "modified before source..."); } else if (gn->mtime == 0) { - printf("non-existent and no sources..."); + fprintf(debug_file, "non-existent and no sources..."); } else { - printf(":: operator and no sources..."); + fprintf(debug_file, ":: operator and no sources..."); } } oodate = TRUE; @@ -312,7 +325,7 @@ Make_OODate(GNode *gn) */ if (DEBUG(MAKE)) { if (gn->flags & FORCE) - printf("non existing child..."); + fprintf(debug_file, "non existing child..."); } oodate = (gn->flags & FORCE) ? TRUE : FALSE; } @@ -325,7 +338,7 @@ Make_OODate(GNode *gn) * thinking they're out-of-date. */ if (!oodate) { - Lst_ForEach(gn->parents, MakeTimeStamp, (ClientData)gn); + Lst_ForEach(gn->parents, MakeTimeStamp, gn); } return (oodate); @@ -355,7 +368,10 @@ MakeAddChild(ClientData gnp, ClientData lp) Lst l = (Lst) lp; if ((gn->flags & REMAKE) == 0 && !(gn->type & (OP_USE|OP_USEBEFORE))) { - (void)Lst_EnQueue(l, (ClientData)gn); + if (DEBUG(MAKE)) + fprintf(debug_file, "MakeAddChild: need to examine %s%s\n", + gn->name, gn->cohort_num); + (void)Lst_EnQueue(l, gn); } return (0); } @@ -422,7 +438,7 @@ Make_HandleUse(GNode *cgn, GNode *pgn) #ifdef DEBUG_SRC if ((cgn->type & (OP_USE|OP_USEBEFORE|OP_TRANSFORM)) == 0) { - printf("Make_HandleUse: called for plain node %s\n", cgn->name); + fprintf(debug_file, "Make_HandleUse: called for plain node %s\n", cgn->name); return; } #endif @@ -525,7 +541,7 @@ MakeHandleUse(ClientData cgnp, ClientData pgnp) * children the parent has. This is used by Make_Run to decide * whether to queue the parent or examine its children... */ - if ((ln = Lst_Member(pgn->children, (ClientData) cgn)) != NILLNODE) { + if ((ln = Lst_Member(pgn->children, cgn)) != NILLNODE) { Lst_Remove(pgn->children, ln); pgn->unmade--; } @@ -605,17 +621,17 @@ Make_Recheck(GNode *gn) * the target is made now. Otherwise archives with ... rules * don't work! */ - if (NoExecute(gn) || - (gn->type & OP_SAVE_CMDS) || mtime == 0) { + if (NoExecute(gn) || (gn->type & OP_SAVE_CMDS) || + (mtime == 0 && !(gn->type & OP_WAIT))) { if (DEBUG(MAKE)) { - printf(" recheck(%s): update time to now: %s\n", + fprintf(debug_file, " recheck(%s): update time from %s to now\n", gn->name, Targ_FmtTime(gn->mtime)); } gn->mtime = now; } else { if (DEBUG(MAKE)) { - printf(" recheck(%s): current update time: %s\n", + fprintf(debug_file, " recheck(%s): current update time: %s\n", gn->name, Targ_FmtTime(gn->mtime)); } } @@ -665,10 +681,16 @@ Make_Update(GNode *cgn) Lst parents; GNode *centurion; + /* It is save to re-examine any nodes again */ + checked++; + cname = Var_Value(TARGET, cgn, &p1); if (p1) free(p1); + if (DEBUG(MAKE)) + fprintf(debug_file, "Make_Update: %s%s\n", cgn->name, cgn->cohort_num); + /* * If the child was actually made, see what its modification time is * now -- some rules won't actually update the file. If the file still @@ -684,27 +706,50 @@ Make_Update(GNode *cgn) */ if ((centurion = cgn->centurion) != NULL) { if (!Lst_IsEmpty(cgn->parents)) - Punt("%s: cohort has parents", cgn->name); + Punt("%s%s: cohort has parents", cgn->name, cgn->cohort_num); centurion->unmade_cohorts -= 1; if (centurion->unmade_cohorts < 0) Error("Graph cycles through centurion %s", centurion->name); - parents = centurion->parents; } else { centurion = cgn; - parents = cgn->parents; } + parents = centurion->parents; + + /* If this was a .ORDER node, schedule the RHS */ + Lst_ForEach(centurion->order_succ, MakeBuildParent, Lst_First(toBeMade)); + + /* Now mark all the parents as having one less unmade child */ if (Lst_Open(parents) == SUCCESS) { while ((ln = Lst_Next(parents)) != NILLNODE) { pgn = (GNode *)Lst_Datum(ln); - if (mtime == 0) + if (DEBUG(MAKE)) + fprintf(debug_file, "inspect parent %s%s: flags %x, " + "type %x, made %d, unmade %d ", + pgn->name, pgn->cohort_num, pgn->flags, + pgn->type, pgn->made, pgn->unmade-1); + + if (!(pgn->flags & REMAKE)) { + /* This parent isn't needed */ + if (DEBUG(MAKE)) + fprintf(debug_file, "- not needed\n"); + continue; + } + if (mtime == 0 && !(cgn->type & OP_WAIT)) pgn->flags |= FORCE; + /* - * If the parent has the .MADE attribute, it has already - * been queued on the `toBeMade' list in Make_ExpandUse() - * and its unmade children counter is zero. + * If the parent has the .MADE attribute, its timestamp got + * updated to that of its newest child, and its unmake + * child count got set to zero in Make_ExpandUse(). + * However other things might cause us to build one of its + * children - and so we mustn't do any processing here when + * the child build finishes. */ - if ((pgn->flags & REMAKE) == 0 || (pgn->type & OP_MADE) != 0) + if (pgn->type & OP_MADE) { + if (DEBUG(MAKE)) + fprintf(debug_file, "- .MADE\n"); continue; + } if ( ! (cgn->type & (OP_EXEC|OP_USE|OP_USEBEFORE))) { if (cgn->made == MADE) @@ -716,40 +761,60 @@ Make_Update(GNode *cgn) * A parent must wait for the completion of all instances * of a `::' dependency. */ - if (centurion->unmade_cohorts != 0 || centurion->made == UNMADE) + if (centurion->unmade_cohorts != 0 || centurion->made < MADE) { + if (DEBUG(MAKE)) + fprintf(debug_file, + "- centurion made %d, %d unmade cohorts\n", + centurion->made, centurion->unmade_cohorts); continue; + } /* One more child of this parent is now made */ pgn->unmade -= 1; - if (pgn->unmade == 0) { + if (pgn->unmade < 0) { + if (DEBUG(MAKE)) { + fprintf(debug_file, "Graph cycles through %s%s\n", + pgn->name, pgn->cohort_num); + Targ_PrintGraph(2); + } + Error("Graph cycles through %s%s", pgn->name, pgn->cohort_num); + } + + /* We must always rescan the parents of .WAIT and .ORDER nodes. */ + if (pgn->unmade != 0 && !(centurion->type & OP_WAIT) + && !(centurion->flags & DONE_ORDER)) { + if (DEBUG(MAKE)) + fprintf(debug_file, "- unmade children\n"); + continue; + } + if (pgn->made != DEFERRED) { /* - * Queue the node up -- any unmade predecessors will - * be dealt with in MakeStartJobs. + * Either this parent is on a different branch of the tree, + * or it on the RHS of a .WAIT directive + * or it is already on the toBeMade list. */ - (void)Lst_EnQueue(toBeMade, (ClientData)pgn); - } else if (pgn->unmade < 0) { - Error("Graph cycles through %s", pgn->name); + if (DEBUG(MAKE)) + fprintf(debug_file, "- not deferred\n"); + continue; } + if (pgn->order_pred + && Lst_ForEach(pgn->order_pred, MakeCheckOrder, 0)) { + /* A .ORDER rule stops us building this */ + continue; + } + if (DEBUG(MAKE)) { + static int two = 2; + fprintf(debug_file, "- %s%s made, schedule %s%s (made %d)\n", + cgn->name, cgn->cohort_num, + pgn->name, pgn->cohort_num, pgn->made); + Targ_PrintNode(pgn, &two); + } + /* Ok, we can schedule the parent again */ + pgn->made = REQUESTED; + (void)Lst_EnQueue(toBeMade, pgn); } Lst_Close(parents); } - /* - * Deal with successor nodes. If any is marked for making and has an unmade - * count of 0, has not been made and isn't in the examination queue, - * it means we need to place it in the queue as it restrained itself - * before. - */ - for (ln = Lst_First(centurion->successors); ln != NILLNODE; - ln = Lst_Succ(ln)) { - GNode *succ = (GNode *)Lst_Datum(ln); - - if ((succ->flags & REMAKE) != 0 && succ->unmade == 0 && - succ->made == UNMADE && - Lst_Member(toBeMade, (ClientData)succ) == NILLNODE) - { - (void)Lst_EnQueue(toBeMade, (ClientData)succ); - } - } /* * Set the .PREFIX and .IMPSRC variables for all the implied parents @@ -893,8 +958,8 @@ MakeAddAllSrc(ClientData cgnp, ClientData pgnp) void Make_DoAllVar(GNode *gn) { - Lst_ForEach(gn->children, MakeUnmark, (ClientData) gn); - Lst_ForEach(gn->children, MakeAddAllSrc, (ClientData) gn); + Lst_ForEach(gn->children, MakeUnmark, gn); + Lst_ForEach(gn->children, MakeAddAllSrc, gn); if (!Var_Exists (OODATE, gn)) { Var_Set(OODATE, "", gn, 0); @@ -927,63 +992,136 @@ Make_DoAllVar(GNode *gn) * *----------------------------------------------------------------------- */ + +static int +MakeCheckOrder(ClientData v_bn, ClientData ignore __unused) +{ + GNode *bn = v_bn; + + if (bn->made >= MADE || !(bn->flags & REMAKE)) + return 0; + if (DEBUG(MAKE)) + fprintf(debug_file, "MakeCheckOrder: Waiting for .ORDER node %s%s\n", + bn->name, bn->cohort_num); + return 1; +} + +static int +MakeBuildChild(ClientData v_cn, ClientData toBeMade_next) +{ + GNode *cn = v_cn; + + if (DEBUG(MAKE)) + fprintf(debug_file, "MakeBuildChild: inspect %s%s, made %d, type %x\n", + cn->name, cn->cohort_num, cn->made, cn->type); + if (cn->made > DEFERRED) + return 0; + + /* If this node is on the RHS of a .ORDER, check LHSs. */ + if (cn->order_pred && Lst_ForEach(cn->order_pred, MakeCheckOrder, 0)) { + /* Can't build this (or anything else in this child list) yet */ + cn->made = DEFERRED; + return 1; + } + + if (DEBUG(MAKE)) + fprintf(debug_file, "MakeBuildChild: schedule %s%s\n", + cn->name, cn->cohort_num); + + cn->made = REQUESTED; + if (toBeMade_next == NILLNODE) + Lst_AtEnd(toBeMade, cn); + else + Lst_InsertBefore(toBeMade, toBeMade_next, cn); + + if (cn->unmade_cohorts != 0) + Lst_ForEach(cn->cohorts, MakeBuildChild, toBeMade_next); + + /* + * If this node is a .WAIT node with unmade chlidren + * then don't add the next sibling. + */ + return cn->type & OP_WAIT && cn->unmade > 0; +} + +/* When a .ORDER RHS node completes we do this on each LHS */ +static int +MakeBuildParent(ClientData v_pn, ClientData toBeMade_next) +{ + GNode *pn = v_pn; + + if (pn->made != DEFERRED) + return 0; + + if (MakeBuildChild(pn, toBeMade_next) == 0) { + /* Mark so that when this node is built we reschedule its parents */ + pn->flags |= DONE_ORDER; + } + + return 0; +} + static Boolean MakeStartJobs(void) { GNode *gn; + int have_token = 0; while (!Lst_IsEmpty (toBeMade)) { + /* Get token now to avoid cycling job-list when we only have 1 token */ + if (!have_token && !Job_TokenWithdraw()) + break; + have_token = 1; + gn = (GNode *)Lst_DeQueue(toBeMade); - if (DEBUG(MAKE)) { - printf("Examining %s...", gn->name); + if (DEBUG(MAKE)) + fprintf(debug_file, "Examining %s%s...\n", + gn->name, gn->cohort_num); + + if (gn->made != REQUESTED) { + if (DEBUG(MAKE)) + fprintf(debug_file, "state %d\n", gn->made); + + make_abort(gn, __LINE__); } - /* - * Make sure any and all predecessors that are going to be made, - * have been. - */ - if (!Lst_IsEmpty(gn->preds)) { - LstNode ln; - - for (ln = Lst_First(gn->preds); ln != NILLNODE; ln = Lst_Succ(ln)){ - GNode *pgn = (GNode *)Lst_Datum(ln); - - if ((pgn->flags & REMAKE) && - (pgn->made == UNMADE || pgn->unmade_cohorts != 0)) { - if (DEBUG(MAKE)) { - printf("predecessor %s not made yet.\n", pgn->name); - } - break; - } - } - /* - * If ln isn't nil, there's a predecessor as yet unmade, so we - * just drop this node on the floor. When the node in question - * has been made, it will notice this node as being ready to - * make but as yet unmade and will place the node on the queue. - */ - if (ln != NILLNODE) { - continue; - } + + if (gn->checked == checked) { + /* We've already looked at this node since a job finished... */ + if (DEBUG(MAKE)) + fprintf(debug_file, "already checked %s%s\n", + gn->name, gn->cohort_num); + gn->made = DEFERRED; + continue; } + gn->checked = checked; - if (!Job_TokenWithdraw()) { - Lst_AtFront(toBeMade, gn); - break; + if (gn->unmade != 0) { + /* + * We can't build this yet, add all unmade children to toBeMade, + * just before the current first element. + */ + gn->made = DEFERRED; + Lst_ForEach(gn->children, MakeBuildChild, Lst_First(toBeMade)); + /* and drop this node on the floor */ + if (DEBUG(MAKE)) + fprintf(debug_file, "dropped %s%s\n", gn->name, gn->cohort_num); + continue; } - numNodes--; + gn->made = BEINGMADE; if (Make_OODate(gn)) { if (DEBUG(MAKE)) { - printf("out-of-date\n"); + fprintf(debug_file, "out-of-date\n"); } if (queryFlag) { return (TRUE); } Make_DoAllVar(gn); Job_Make(gn); + have_token = 0; } else { if (DEBUG(MAKE)) { - printf("up-to-date\n"); + fprintf(debug_file, "up-to-date\n"); } gn->made = UPTODATE; if (gn->type & OP_JOIN) { @@ -995,10 +1133,13 @@ MakeStartJobs(void) */ Make_DoAllVar(gn); } - Job_TokenReturn(); Make_Update(gn); } } + + if (have_token) + Job_TokenReturn(); + return (FALSE); } @@ -1024,39 +1165,97 @@ MakeStartJobs(void) *----------------------------------------------------------------------- */ static int -MakePrintStatus(ClientData gnp, ClientData cyclep) +MakePrintStatusOrder(ClientData ognp, ClientData gnp) +{ + GNode *ogn = ognp; + GNode *gn = gnp; + + if (!(ogn->flags & REMAKE) || ogn->made > REQUESTED) + /* not waiting for this one */ + return 0; + + printf(" `%s%s' has .ORDER dependency against %s%s " + "(made %d, flags %x, type %x)\n", + gn->name, gn->cohort_num, + ogn->name, ogn->cohort_num, ogn->made, ogn->flags, ogn->type); + if (DEBUG(MAKE) && debug_file != stdout) + fprintf(debug_file, " `%s%s' has .ORDER dependency against %s%s " + "(made %d, flags %x, type %x)\n", + gn->name, gn->cohort_num, + ogn->name, ogn->cohort_num, ogn->made, ogn->flags, ogn->type); + return 0; +} + +static int +MakePrintStatus(ClientData gnp, ClientData v_errors) { GNode *gn = (GNode *)gnp; - Boolean cycle = *(Boolean *)cyclep; - if (gn->made == UPTODATE) { - printf("`%s' is up to date.\n", gn->name); - } else if (gn->unmade != 0) { - if (cycle) { - Boolean t = TRUE; - /* - * If printing cycles and came to one that has unmade children, - * print out the cycle by recursing on its children. Note a - * cycle like: - * a : b - * b : c - * c : b - * will cause this to erroneously complain about a being in - * the cycle, but this is a good approximation. - */ - if (gn->made == CYCLE) { - Error("Graph cycles through `%s'", gn->name); - gn->made = ENDCYCLE; - Lst_ForEach(gn->children, MakePrintStatus, (ClientData) &t); - gn->made = UNMADE; - } else if (gn->made != ENDCYCLE) { - gn->made = CYCLE; - Lst_ForEach(gn->children, MakePrintStatus, (ClientData) &t); - } - } else { - printf("`%s' not remade because of errors.\n", gn->name); + int *errors = v_errors; + + if (gn->flags & DONECYCLE) + /* We've completely processed this node before, don't do it again. */ + return 0; + + if (gn->unmade == 0) { + gn->flags |= DONECYCLE; + switch (gn->made) { + case UPTODATE: + printf("`%s%s' is up to date.\n", gn->name, gn->cohort_num); + break; + case MADE: + break; + case UNMADE: + case DEFERRED: + case REQUESTED: + case BEINGMADE: + (*errors)++; + printf("`%s%s' was not built (made %d, flags %x, type %x)!\n", + gn->name, gn->cohort_num, gn->made, gn->flags, gn->type); + if (DEBUG(MAKE) && debug_file != stdout) + fprintf(debug_file, + "`%s%s' was not built (made %d, flags %x, type %x)!\n", + gn->name, gn->cohort_num, gn->made, gn->flags, gn->type); + /* Most likely problem is actually caused by .ORDER */ + Lst_ForEach(gn->order_pred, MakePrintStatusOrder, gn); + break; + default: + /* Errors - already counted */ + printf("`%s%s' not remade because of errors.\n", + gn->name, gn->cohort_num); + if (DEBUG(MAKE) && debug_file != stdout) + fprintf(debug_file, "`%s%s' not remade because of errors.\n", + gn->name, gn->cohort_num); + break; } + return 0; } - return (0); + + if (DEBUG(MAKE)) + fprintf(debug_file, "MakePrintStatus: %s%s has %d unmade children\n", + gn->name, gn->cohort_num, gn->unmade); + /* + * If printing cycles and came to one that has unmade children, + * print out the cycle by recursing on its children. + */ + if (!(gn->flags & CYCLE)) { + /* Fist time we've seen this node, check all children */ + gn->flags |= CYCLE; + Lst_ForEach(gn->children, MakePrintStatus, errors); + /* Mark that this node needn't be processed again */ + gn->flags |= DONECYCLE; + return 0; + } + + /* Only output the error once per node */ + gn->flags |= DONECYCLE; + Error("Graph cycles through `%s%s'", gn->name, gn->cohort_num); + if ((*errors)++ > 100) + /* Abandon the whole error report */ + return 1; + + /* Reporting for our children will give the rest of the loop */ + Lst_ForEach(gn->children, MakePrintStatus, errors); + return 0; } @@ -1068,24 +1267,16 @@ MakePrintStatus(ClientData gnp, ClientData cyclep) * Input: * targs the initial list of targets * - * Results: - * The new list of targets. - * * Side Effects: - * numNodes is set to the number of elements in the list of targets. *----------------------------------------------------------------------- */ -Lst +void Make_ExpandUse(Lst targs) { GNode *gn; /* a temporary pointer */ Lst examine; /* List of targets to examine */ - Lst ntargs; /* List of new targets to be made */ - - ntargs = Lst_Init(FALSE); examine = Lst_Duplicate(targs, NOCOPY); - numNodes = 0; /* * Make an initial downward pass over the graph, marking nodes to be made @@ -1097,63 +1288,174 @@ Make_ExpandUse(Lst targs) */ while (!Lst_IsEmpty (examine)) { gn = (GNode *)Lst_DeQueue(examine); + + if (gn->flags & REMAKE) + /* We've looked at this one already */ + continue; + gn->flags |= REMAKE; + if (DEBUG(MAKE)) + fprintf(debug_file, "Make_ExpandUse: examine %s%s\n", + gn->name, gn->cohort_num); if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts)) { + /* Append all the 'cohorts' to the list of things to examine */ Lst new; new = Lst_Duplicate(gn->cohorts, NOCOPY); Lst_Concat(new, examine, LST_CONCLINK); examine = new; } - - if ((gn->flags & REMAKE) == 0) { - gn->flags |= REMAKE; - numNodes++; - /* - * Apply any .USE rules before looking for implicit dependencies - * to make sure everything has commands that should... - * Make sure that the TARGET is set, so that we can make - * expansions. - */ - if (gn->type & OP_ARCHV) { - char *eoa, *eon; - eoa = strchr(gn->name, '('); - eon = strchr(gn->name, ')'); - if (eoa == NULL || eon == NULL) - continue; - *eoa = '\0'; - *eon = '\0'; - Var_Set(MEMBER, eoa + 1, gn, 0); - Var_Set(ARCHIVE, gn->name, gn, 0); - *eoa = '('; - *eon = ')'; - } + /* + * Apply any .USE rules before looking for implicit dependencies + * to make sure everything has commands that should... + * Make sure that the TARGET is set, so that we can make + * expansions. + */ + if (gn->type & OP_ARCHV) { + char *eoa, *eon; + eoa = strchr(gn->name, '('); + eon = strchr(gn->name, ')'); + if (eoa == NULL || eon == NULL) + continue; + *eoa = '\0'; + *eon = '\0'; + Var_Set(MEMBER, eoa + 1, gn, 0); + Var_Set(ARCHIVE, gn->name, gn, 0); + *eoa = '('; + *eon = ')'; + } - (void)Dir_MTime(gn); - Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0); - Lst_ForEach(gn->children, MakeUnmark, (ClientData)gn); - Lst_ForEach(gn->children, MakeHandleUse, (ClientData)gn); - - if ((gn->type & OP_MADE) == 0) - Suff_FindDeps(gn); - else { - /* Pretend we made all this node's children */ - Lst_ForEach(gn->children, MakeFindChild, (ClientData)gn); - if (gn->unmade != 0) - printf("Warning: %s still has %d unmade children\n", - gn->name, gn->unmade); - } + (void)Dir_MTime(gn); + Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0); + Lst_ForEach(gn->children, MakeUnmark, gn); + Lst_ForEach(gn->children, MakeHandleUse, gn); + + if ((gn->type & OP_MADE) == 0) + Suff_FindDeps(gn); + else { + /* Pretend we made all this node's children */ + Lst_ForEach(gn->children, MakeFindChild, gn); + if (gn->unmade != 0) + printf("Warning: %s%s still has %d unmade children\n", + gn->name, gn->cohort_num, gn->unmade); + } + + if (gn->unmade != 0) + Lst_ForEach(gn->children, MakeAddChild, examine); + } + + Lst_Destroy(examine, NOFREE); +} - if (gn->unmade != 0) { - Lst_ForEach(gn->children, MakeAddChild, (ClientData)examine); +/*- + *----------------------------------------------------------------------- + * Make_ProcessWait -- + * Convert .WAIT nodes into dependencies + * + * Input: + * targs the initial list of targets + * + *----------------------------------------------------------------------- + */ + +static int +link_parent(ClientData cnp, ClientData pnp) +{ + GNode *cn = cnp; + GNode *pn = pnp; + + Lst_AtEnd(pn->children, cn); + Lst_AtEnd(cn->parents, pn); + pn->unmade++; + return 0; +} + +static int +add_wait_dep(void *v_cn, void *v_wn) +{ + GNode *cn = v_cn; + GNode *wn = v_wn; + + if (cn == wn) + return 1; + + if (cn == NULL || wn == NULL) { + printf("bad wait dep %p %p\n", cn, wn); + exit(4); + } + if (DEBUG(MAKE)) + fprintf(debug_file, ".WAIT: add dependency %s%s -> %s\n", + cn->name, cn->cohort_num, wn->name); + + Lst_AtEnd(wn->children, cn); + wn->unmade++; + Lst_AtEnd(cn->parents, wn); + return 0; +} + +static void +Make_ProcessWait(Lst targs) +{ + GNode *pgn; /* 'parent' node we are examining */ + GNode *cgn; /* Each child in turn */ + LstNode owln; /* Previous .WAIT node */ + Lst examine; /* List of targets to examine */ + LstNode ln; + + /* + * We need all the nodes to have a common parent in order for the + * .WAIT and .ORDER scheduling to work. + * Perhaps this should be done earlier... + */ + + pgn = Targ_NewGN(".MAIN"); + pgn->flags = REMAKE; + pgn->type = OP_PHONY | OP_DEPENDS; + /* Get it displayed in the diag dumps */ + Lst_AtFront(Targ_List(), pgn); + + Lst_ForEach(targs, link_parent, pgn); + + /* Start building with the 'dummy' .MAIN' node */ + MakeBuildChild(pgn, NILLNODE); + + examine = Lst_Init(FALSE); + Lst_AtEnd(examine, pgn); + + while (!Lst_IsEmpty (examine)) { + pgn = Lst_DeQueue(examine); + + /* We only want to process each child-list once */ + if (pgn->flags & DONE_WAIT) + continue; + pgn->flags |= DONE_WAIT; + if (DEBUG(MAKE)) + fprintf(debug_file, "Make_ProcessWait: examine %s\n", pgn->name); + + if ((pgn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (pgn->cohorts)) { + /* Append all the 'cohorts' to the list of things to examine */ + Lst new; + new = Lst_Duplicate(pgn->cohorts, NOCOPY); + Lst_Concat(new, examine, LST_CONCLINK); + examine = new; + } + + owln = Lst_First(pgn->children); + Lst_Open(pgn->children); + for (; (ln = Lst_Next(pgn->children)) != NILLNODE; ) { + cgn = Lst_Datum(ln); + if (cgn->type & OP_WAIT) { + /* Make the .WAIT node depend on the previous children */ + Lst_ForEachFrom(pgn->children, owln, add_wait_dep, cgn); + owln = ln; } else { - (void)Lst_EnQueue(ntargs, (ClientData)gn); + Lst_AtEnd(examine, cgn); } } + Lst_Close(pgn->children); } Lst_Destroy(examine, NOFREE); - return ntargs; } /*- @@ -1185,7 +1487,16 @@ Make_Run(Lst targs) { int errors; /* Number of errors the Job module reports */ - toBeMade = Make_ExpandUse(targs); + /* Start trying to make the current targets... */ + toBeMade = Lst_Init(FALSE); + + Make_ExpandUse(targs); + Make_ProcessWait(targs); + + if (DEBUG(MAKE)) { + fprintf(debug_file, "#***# full graph\n"); + Targ_PrintGraph(1); + } if (queryFlag) { /* @@ -1194,16 +1505,15 @@ Make_Run(Lst targs) * to see if any of the targets was out of date) */ return (MakeStartJobs()); - } else { - /* - * Initialization. At the moment, no jobs are running and until some - * get started, nothing will happen since the remaining upward - * traversal of the graph is performed by the routines in job.c upon - * the finishing of a job. So we fill the Job table as much as we can - * before going into our loop. - */ - (void)MakeStartJobs(); } + /* + * Initialization. At the moment, no jobs are running and until some + * get started, nothing will happen since the remaining upward + * traversal of the graph is performed by the routines in job.c upon + * the finishing of a job. So we fill the Job table as much as we can + * before going into our loop. + */ + (void)MakeStartJobs(); /* * Main Loop: The idea here is that the ending of jobs will take @@ -1215,9 +1525,8 @@ Make_Run(Lst targs) * Note that the Job module will exit if there were any errors unless the * keepgoing flag was given. */ - while (!Lst_IsEmpty(toBeMade) || !Job_Empty ()) { + while (!Lst_IsEmpty(toBeMade) || jobTokensRunning > 0) { Job_CatchOutput(); - Job_CatchChildren(!usePipes); (void)MakeStartJobs(); } @@ -1227,8 +1536,15 @@ Make_Run(Lst targs) * Print the final status of each target. E.g. if it wasn't made * because some inferior reported an error. */ - errors = ((errors == 0) && (numNodes != 0)); - Lst_ForEach(targs, MakePrintStatus, (ClientData) &errors); - - return (TRUE); + if (DEBUG(MAKE)) + fprintf(debug_file, "done: errors %d\n", errors); + if (errors == 0) { + Lst_ForEach(targs, MakePrintStatus, &errors); + if (DEBUG(MAKE)) { + fprintf(debug_file, "done: errors %d\n", errors); + if (errors) + Targ_PrintGraph(4); + } + } + return errors != 0; } diff --git a/devel/bmake/files/make.h b/devel/bmake/files/make.h index aeff250e283..46e752fe9b7 100644 --- a/devel/bmake/files/make.h +++ b/devel/bmake/files/make.h @@ -1,4 +1,4 @@ -/* $NetBSd: make.h,v 1.53 2005/05/01 01:25:36 christos Exp $ */ +/* $NetBSD: make.h,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -145,20 +145,25 @@ * 7) the number of its children that are, as yet, unmade * 8) its modification time * 9) the modification time of its youngest child (qv. make.c) - * 10) a list of nodes for which this is a source - * 11) a list of nodes on which this depends + * 10) a list of nodes for which this is a source (parents) + * 11) a list of nodes on which this depends (children) * 12) a list of nodes that depend on this, as gleaned from the - * transformation rules. - * 13) a list of nodes of the same name created by the :: operator - * 14) a list of nodes that must be made (if they're made) before - * this node can be, but that do no enter into the datedness of + * transformation rules (iParents) + * 13) a list of ancestor nodes, which includes parents, iParents, + * and recursive parents of parents + * 14) a list of nodes of the same name created by the :: operator + * 15) a list of nodes that must be made (if they're made) before + * this node can be, but that do not enter into the datedness of * this node. - * 15) a list of nodes that must be made (if they're made) after + * 16) a list of nodes that must be made (if they're made) before + * this node or any child of this node can be, but that do not + * enter into the datedness of this node. + * 17) a list of nodes that must be made (if they're made) after * this node is, but that do not depend on this node, in the * normal sense. - * 16) a Lst of ``local'' variables that are specific to this target + * 18) a Lst of ``local'' variables that are specific to this target * and this target only (qv. var.c [$@ $< $?, etc.]) - * 17) a Lst of strings that are commands to be given to a shell + * 19) a Lst of strings that are commands to be given to a shell * to create this target. */ typedef struct GNode { @@ -166,34 +171,32 @@ typedef struct GNode { char *uname; /* The unexpanded name of a .USE node */ char *path; /* The full pathname of the file */ int type; /* Its type (see the OP flags, below) */ - int order; /* Its wait weight */ int flags; -#define REMAKE 0x1 /* this target needs to be remade */ +#define REMAKE 0x1 /* this target needs to be (re)made */ #define CHILDMADE 0x2 /* children of this target were made */ #define FORCE 0x4 /* children don't exist, and we pretend made */ - enum { - UNMADE, BEINGMADE, MADE, UPTODATE, ERROR, ABORTED, - CYCLE, ENDCYCLE +#define DONE_WAIT 0x8 /* Set by Make_ProcessWait() */ +#define DONE_ORDER 0x10 /* Build requested by .ORDER processing */ +#define FROM_DEPEND 0x20 /* Node created from .depend */ +#define CYCLE 0x1000 /* Used by MakePrintStatus */ +#define DONECYCLE 0x2000 /* Used by MakePrintStatus */ + enum enum_made { + UNMADE, DEFERRED, REQUESTED, BEINGMADE, + MADE, UPTODATE, ERROR, ABORTED } made; /* Set to reflect the state of processing * on this node: * UNMADE - Not examined yet + * DEFERRED - Examined once (building child) + * REQUESTED - on toBeMade list * BEINGMADE - Target is already being made. - * Indicates a cycle in the graph. (compat - * mode only) + * Indicates a cycle in the graph. * MADE - Was out-of-date and has been made * UPTODATE - Was already up-to-date * ERROR - An error occurred while it was being * made (used only in compat mode) * ABORTED - The target was aborted due to * an error making an inferior (compat). - * CYCLE - Marked as potentially being part of - * a graph cycle. If we come back to a - * node marked this way, it is printed - * and 'made' is changed to ENDCYCLE. - * ENDCYCLE - the cycle has been completely - * printed. Go back and unmark all its - * members. */ int unmade; /* The number of unmade children */ @@ -206,12 +209,15 @@ typedef struct GNode { Lst cohorts; /* Other nodes for the :: operator */ Lst parents; /* Nodes that depend on this one */ Lst children; /* Nodes on which this one depends */ - Lst successors; /* Nodes that must be made after this one */ - Lst preds; /* Nodes that must be made before this one */ + Lst order_pred; /* .ORDER nodes we need made */ + Lst order_succ; /* .ORDER nodes who need us */ + + char cohort_num[8]; /* #n for this cohort */ int unmade_cohorts;/* # of unmade instances on the cohorts list */ struct GNode *centurion; /* Pointer to the first instance of a :: node; only set when on a cohorts list */ + unsigned int checked; /* Last time we tried to makle this node */ Hash_Table context; /* The local variables */ Lst commands; /* Creation commands */ @@ -219,7 +225,7 @@ typedef struct GNode { struct _Suff *suffix; /* Suffix for the node (determined by * Suff_FindDeps and opaque to everyone * but the Suff module) */ - char *fname; /* filename where the GNode got defined */ + const char *fname; /* filename where the GNode got defined */ int lineno; /* line number where the GNode got defined */ } GNode; @@ -272,6 +278,7 @@ typedef struct GNode { * target' processing in parse.c */ #define OP_PHONY 0x00010000 /* Not a file target; run always */ #define OP_NOPATH 0x00020000 /* Don't search for file in the path */ +#define OP_WAIT 0x00040000 /* .WAIT phony node */ /* Attributes applied by PMake */ #define OP_TRANSFORM 0x80000000 /* The node is a transformation rule */ #define OP_MEMBER 0x40000000 /* Target is a member of an archive */ @@ -301,19 +308,9 @@ typedef struct GNode { * table of all targets and its address returned. If TARG_NOCREATE is given, * a NIL pointer will be returned. */ -#define TARG_CREATE 0x01 /* create node if not found */ #define TARG_NOCREATE 0x00 /* don't create it */ - -/* - * There are several places where expandable buffers are used (parse.c and - * var.c). This constant is merely the starting point for those buffers. If - * lines tend to be much shorter than this, it would be best to reduce BSIZE. - * If longer, it should be increased. Reducing it will cause more copying to - * be done for longer lines, but will save space for shorter ones. In any - * case, it ought to be a power of two simply because most storage allocation - * schemes allocate in powers of two. - */ -#define MAKE_BSIZE 256 /* starting size for expandable buffers */ +#define TARG_CREATE 0x01 /* create node if not found */ +#define TARG_NOHASH 0x02 /* don't look in/add to hash table */ /* * These constants are all used by the Str_Concat function to decide how the @@ -380,13 +377,10 @@ extern Boolean keepgoing; /* True if should continue on unaffected * in one portion */ extern Boolean touchFlag; /* TRUE if targets should just be 'touched' * if out of date. Set by the -t flag */ -extern Boolean usePipes; /* TRUE if should capture the output of - * subshells by means of pipes. Otherwise it - * is routed to temporary files from which it - * is retrieved when the shell exits */ extern Boolean queryFlag; /* TRUE if we aren't supposed to really make * anything, just see if the targets are out- * of-date */ +extern Boolean doing_depend; /* TRUE if processing .depend */ extern Boolean checkEnvFirst; /* TRUE if environment should be searched for * variables before the global context */ @@ -421,12 +415,16 @@ extern char *progname; /* The program name */ #define MAKEFLAGS ".MAKEFLAGS" #define MAKEOVERRIDES ".MAKEOVERRIDES" +#define MAKE_JOB_PREFIX ".MAKE.JOB.PREFIX" /* prefix for job target output */ +#define MAKE_EXPORTED ".MAKE.EXPORTED" /* variables we export */ +#define MAKE_MAKEFILES ".MAKE.MAKEFILES" /* all the makefiles we read */ /* * debug control: * There is one bit per module. It is up to the module what debug * information to print. */ +FILE *debug_file; /* Output written here - default stdout */ extern int debug; #define DEBUG_ARCH 0x0001 #define DEBUG_COND 0x0002 @@ -441,8 +439,10 @@ extern int debug; #define DEBUG_FOR 0x0400 #define DEBUG_SHELL 0x0800 #define DEBUG_ERROR 0x1000 -#define DEBUG_GRAPH3 0x10000 +#define DEBUG_LOUD 0x2000 +#define DEBUG_GRAPH3 0x10000 #define DEBUG_SCRIPT 0x20000 +#define DEBUG_PARSE 0x40000 #define CONCAT(a,b) a##b @@ -456,7 +456,7 @@ extern int debug; int Make_TimeStamp(GNode *, GNode *); Boolean Make_OODate(GNode *); -Lst Make_ExpandUse(Lst); +void Make_ExpandUse(Lst); time_t Make_Recheck(GNode *); void Make_HandleUse(GNode *, GNode *); void Make_Update(GNode *); diff --git a/devel/bmake/files/nonints.h b/devel/bmake/files/nonints.h index 812b5015406..c6468fb65c6 100644 --- a/devel/bmake/files/nonints.h +++ b/devel/bmake/files/nonints.h @@ -1,4 +1,4 @@ -/* $NetBSD: nonints.h,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: nonints.h,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $ */ /*- * Copyright (c) 1988, 1989, 1990, 1993 @@ -97,7 +97,8 @@ int Compat_Make(ClientData, ClientData); /* cond.c */ int Cond_EvalExpression(int, char *, Boolean *, int); int Cond_Eval(char *); -void Cond_End(void); +void Cond_restore_depth(unsigned int); +unsigned int Cond_save_depth(void); /* for.c */ int For_Eval(char *); @@ -115,10 +116,16 @@ void Punt(const char *, ...) void DieHorribly(void) __attribute__((__noreturn__)); int PrintAddr(ClientData, ClientData); void Finish(int); +#ifndef HAVE_EMALLOC char *estrdup(const char *); +char *strndup(const char *, size_t); +char *estrndup(const char *, size_t); void *emalloc(size_t); void *erealloc(void *, size_t); void enomem(void); +#else +#include <util.h> +#endif int eunlink(const char *); void execError(const char *, const char *); @@ -129,10 +136,10 @@ Boolean Parse_AnyExport(void); Boolean Parse_IsVar(char *); void Parse_DoVar(char *, GNode *); void Parse_AddIncludeDir(char *); -void Parse_File(const char *, FILE *); +void Parse_File(const char *, int); void Parse_Init(void); void Parse_End(void); -void Parse_FromString(char *, int); +void Parse_SetInput(const char *, int, int, char *); Lst Parse_MainName(void); /* str.c */ @@ -172,10 +179,12 @@ Boolean Targ_Silent(GNode *); Boolean Targ_Precious(GNode *); void Targ_SetMain(GNode *); int Targ_PrintCmd(ClientData, ClientData); +int Targ_PrintNode(ClientData, ClientData); char *Targ_FmtTime(time_t); void Targ_PrintType(int); void Targ_PrintGraph(int); void Targ_Propagate(void); +void Targ_Propagate_Wait(void); /* var.c */ void Var_Delete(const char *, GNode *); @@ -183,10 +192,12 @@ void Var_Set(const char *, const char *, GNode *, int); void Var_Append(const char *, const char *, GNode *); Boolean Var_Exists(const char *, GNode *); char *Var_Value(const char *, GNode *, char **); -char *Var_Parse(const char *, GNode *, Boolean, int *, Boolean *); +char *Var_Parse(const char *, GNode *, Boolean, int *, void **); char *Var_Subst(const char *, const char *, GNode *, Boolean); char *Var_GetTail(const char *); char *Var_GetHead(const char *); void Var_Init(void); void Var_End(void); void Var_Dump(GNode *); +void Var_ExportVars(void); +void Var_Export(char *, int); diff --git a/devel/bmake/files/parse.c b/devel/bmake/files/parse.c index 0b6a0edec7e..2a41b85f5c7 100644 --- a/devel/bmake/files/parse.c +++ b/devel/bmake/files/parse.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: parse.c,v 1.1.1.2 2008/03/09 19:39:34 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: parse.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: parse.c,v 1.1.1.2 2008/03/09 19:39:34 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: parse.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: parse.c,v 1.1.1.2 2008/03/09 19:39:34 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -91,8 +91,8 @@ __RCSID("$NetBSD: parse.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); * module. * * Most important structures are kept in Lsts. Directories for - * the #include "..." function are kept in the 'parseIncPath' Lst, while - * those for the #include <...> are kept in the 'sysIncPath' Lst. The + * the .include "..." function are kept in the 'parseIncPath' Lst, while + * those for the .include <...> are kept in the 'sysIncPath' Lst. The * targets currently being defined are kept in the 'targets' Lst. * * The variables 'fname' and 'lineno' are used to track the name @@ -125,6 +125,7 @@ __RCSID("$NetBSD: parse.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); #include <ctype.h> #include <errno.h> +#include <fcntl.h> #include <stdarg.h> #include <stdio.h> @@ -148,32 +149,31 @@ static Lst targCmds; /* command lines for targets */ #endif static Boolean inLine; /* true if currently in a dependency * line or its commands */ -typedef struct { - char *str; - char *ptr; -} PTR; - static int fatals = 0; static GNode *mainNode; /* The main target to create. This is the * first target on the first dependency * line in the first makefile */ typedef struct IFile { - char *fname; /* name of previous file */ - int lineno; /* saved line number */ - FILE * F; /* the open stream */ - PTR * P; /* the char pointer */ + const char *fname; /* name of file */ + int lineno; /* line number in file */ + int fd; /* the open file */ + int cond_depth; /* 'if' nesting when file opened */ + char *P_str; /* point to base of string buffer */ + char *P_ptr; /* point to next char of string buffer */ + char *P_end; /* point to the end of string buffer */ + int P_buflen; /* current size of file buffer */ } IFile; -static IFile curFile; +#define IFILE_BUFLEN 0x8000 +static IFile *curFile; /* * Definitions for handling #include specifications */ -static Lst includes; /* stack of IFiles generated by - * #includes */ +static Lst includes; /* stack of IFiles generated by .includes */ Lst parseIncPath; /* list of directories for "..." includes */ Lst sysIncPath; /* list of directories for <...> includes */ Lst defIncPath; /* default directories for <...> includes */ @@ -218,7 +218,6 @@ typedef enum { } ParseSpecial; static ParseSpecial specType; -static int waiting; #define LPAREN '(' #define RPAREN ')' @@ -280,42 +279,28 @@ static struct { { ".WAIT", Wait, 0 }, }; -/* - * Used by ParseDoSpecialSrc() - */ -typedef struct { - int op; - char *src; - Lst allsrc; -} SpecialSrc; - static int ParseIsEscaped(const char *, const char *); -static void ParseErrorInternal(char *, size_t, int, const char *, ...) +static void ParseErrorInternal(const char *, size_t, int, const char *, ...) __attribute__((__format__(__printf__, 4, 5))); -static void ParseVErrorInternal(char *, size_t, int, const char *, va_list) - __attribute__((__format__(__printf__, 4, 0))); -static int ParseFindKeyword(char *); +static void ParseVErrorInternal(FILE *, const char *, size_t, int, const char *, va_list) + __attribute__((__format__(__printf__, 5, 0))); +static int ParseFindKeyword(const char *); static int ParseLinkSrc(ClientData, ClientData); static int ParseDoOp(ClientData, ClientData); -static int ParseAddDep(ClientData, ClientData); -static int ParseDoSpecialSrc(ClientData, ClientData); -static void ParseDoSrc(int, char *, Lst, Boolean); +static void ParseDoSrc(int, const char *); static int ParseFindMain(ClientData, ClientData); static int ParseAddDir(ClientData, ClientData); static int ParseClearPath(ClientData, ClientData); static void ParseDoDependency(char *); static int ParseAddCmd(ClientData, ClientData); -static __inline int ParseReadc(void); -static void ParseUnreadc(int); static void ParseHasCommands(ClientData); static void ParseDoInclude(char *); -static void ParseSetParseFile(char *); +static void ParseSetParseFile(const char *); #ifdef SYSVINCLUDE static void ParseTraditionalInclude(char *); #endif -static int ParseEOF(int); +static int ParseEOF(void); static char *ParseReadLine(void); -static char *ParseSkipLine(int, int); static void ParseFinishLine(void); static void ParseMark(GNode *); @@ -363,7 +348,7 @@ ParseIsEscaped(const char *line, const char *c) *---------------------------------------------------------------------- */ static int -ParseFindKeyword(char *str) +ParseFindKeyword(const char *str) { int start, end, cur; int diff; @@ -400,14 +385,14 @@ ParseFindKeyword(char *str) */ /* VARARGS */ static void -ParseVErrorInternal(char *cfname, size_t clineno, int type, const char *fmt, - va_list ap) +ParseVErrorInternal(FILE *f, const char *cfname, size_t clineno, int type, + const char *fmt, va_list ap) { static Boolean fatal_warning_error_printed = FALSE; - (void)fprintf(stderr, "%s: \"", progname); + (void)fprintf(f, "%s: \"", progname); - if (*cfname != '/') { + if (*cfname != '/' && strcmp(cfname, "(stdin)") != 0) { char *cp; const char *dir; @@ -422,16 +407,16 @@ ParseVErrorInternal(char *cfname, size_t clineno, int type, const char *fmt, if (dir == NULL) dir = "."; - (void)fprintf(stderr, "%s/%s", dir, cfname); + (void)fprintf(f, "%s/%s", dir, cfname); } else - (void)fprintf(stderr, "%s", cfname); + (void)fprintf(f, "%s", cfname); - (void)fprintf(stderr, "\" line %d: ", (int)clineno); + (void)fprintf(f, "\" line %d: ", (int)clineno); if (type == PARSE_WARNING) - (void)fprintf(stderr, "warning: "); - (void)vfprintf(stderr, fmt, ap); - (void)fprintf(stderr, "\n"); - (void)fflush(stderr); + (void)fprintf(f, "warning: "); + (void)vfprintf(f, fmt, ap); + (void)fprintf(f, "\n"); + (void)fflush(f); if (type == PARSE_FATAL || parseWarnFatal) fatals += 1; if (parseWarnFatal && !fatal_warning_error_printed) { @@ -452,13 +437,20 @@ ParseVErrorInternal(char *cfname, size_t clineno, int type, const char *fmt, */ /* VARARGS */ static void -ParseErrorInternal(char *cfname, size_t clineno, int type, const char *fmt, ...) +ParseErrorInternal(const char *cfname, size_t clineno, int type, + const char *fmt, ...) { va_list ap; va_start(ap, fmt); - ParseVErrorInternal(cfname, clineno, type, fmt, ap); + ParseVErrorInternal(stderr, cfname, clineno, type, fmt, ap); va_end(ap); + + if (debug_file != stderr && debug_file != stdout) { + va_start(ap, fmt); + ParseVErrorInternal(debug_file, cfname, clineno, type, fmt, ap); + va_end(ap); + } } /*- @@ -479,8 +471,16 @@ Parse_Error(int type, const char *fmt, ...) va_list ap; va_start(ap, fmt); - ParseVErrorInternal(curFile.fname, curFile.lineno, type, fmt, ap); + ParseVErrorInternal(stderr, curFile->fname, curFile->lineno, + type, fmt, ap); va_end(ap); + + if (debug_file != stderr && debug_file != stdout) { + va_start(ap, fmt); + ParseVErrorInternal(debug_file, curFile->fname, curFile->lineno, + type, fmt, ap); + va_end(ap); + } } /*- @@ -511,10 +511,15 @@ ParseLinkSrc(ClientData pgnp, ClientData cgnp) if ((pgn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (pgn->cohorts)) pgn = (GNode *)Lst_Datum(Lst_Last(pgn->cohorts)); - (void)Lst_AtEnd(pgn->children, (ClientData)cgn); + (void)Lst_AtEnd(pgn->children, cgn); if (specType == Not) - (void)Lst_AtEnd(cgn->parents, (ClientData)pgn); + (void)Lst_AtEnd(cgn->parents, pgn); pgn->unmade += 1; + if (DEBUG(PARSE)) { + fprintf(debug_file, "# ParseLinkSrc: added child %s - %s\n", pgn->name, cgn->name); + Targ_PrintNode(pgn, 0); + Targ_PrintNode(cgn, 0); + } return (0); } @@ -572,7 +577,7 @@ ParseDoOp(ClientData gnp, ClientData opp) */ gn->type |= op & ~OP_OPMASK; - cohort = Targ_NewGN(gn->name); + cohort = Targ_FindNode(gn->name, TARG_NOHASH); /* * Make the cohort invisible as well to avoid duplicating it into * other variables. True, parents of this target won't tend to do @@ -581,9 +586,11 @@ ParseDoOp(ClientData gnp, ClientData opp) * traversals will no longer see this node anyway. -mycroft) */ cohort->type = op | OP_INVISIBLE; - (void)Lst_AtEnd(gn->cohorts, (ClientData)cohort); + (void)Lst_AtEnd(gn->cohorts, cohort); cohort->centurion = gn; gn->unmade_cohorts += 1; + snprintf(cohort->cohort_num, sizeof cohort->cohort_num, "#%d", + gn->unmade_cohorts); } else { /* * We don't want to nuke any previous flags (whatever they were) so we @@ -597,117 +604,6 @@ ParseDoOp(ClientData gnp, ClientData opp) /*- *--------------------------------------------------------------------- - * ParseAddDep -- - * Check if the pair of GNodes given needs to be synchronized. - * This has to be when two nodes are on different sides of a - * .WAIT directive. - * - * Results: - * Returns 1 if the two targets need to be ordered, 0 otherwise. - * If it returns 1, the search can stop - * - * Side Effects: - * A dependency can be added between the two nodes. - * - *--------------------------------------------------------------------- - */ -static int -ParseAddDep(ClientData pp, ClientData sp) -{ - GNode *p = (GNode *)pp; - GNode *s = (GNode *)sp; - - if (p->order < s->order) { - /* - * XXX: This can cause loops, and loops can cause unmade targets, - * but checking is tedious, and the debugging output can show the - * problem - */ - (void)Lst_AtEnd(p->successors, (ClientData)s); - (void)Lst_AtEnd(s->preds, (ClientData)p); - return 0; - } - else - return 1; -} - -/* - - *--------------------------------------------------------------------- - * ParseDoSpecialSrc -- - * ParseDoSrc struck an unexpanded variable in a src. - * The most likely reason is a src that refers to .TARGET or - * .PREFIX so we get called to set those for each target - * and then call ParseDoSrc again to do the real work. - * - * Input: - * tp A target GNode * - * sp A SpecialSrc * which contains the args we need - * for ParseDoSrc. - * - * Results: - * Goodness - * - * Side Effects: - * The target GNode will have .TARGET and .PREFIX set, this seems - * harmless. - */ -static int -ParseDoSpecialSrc(ClientData tp, ClientData sp) -{ - GNode *tn = (GNode *)tp; - GNode *gn; - SpecialSrc *ss = (SpecialSrc *)sp; - char *cp; - char *cp2; - char *pref; - - /* - * If the target is a suffix rule, leave it alone. - */ - if (Suff_IsTransform(tn->name)) { - ParseDoSrc(ss->op, ss->src, ss->allsrc, FALSE); /* don't come back */ - return 0; - } - Var_Set(TARGET, tn->name, tn, 0); - if ((pref = strrchr(tn->name, '/'))) - pref++; - else - pref = tn->name; - if ((cp2 = strchr(pref, '.')) > pref) { - cp = estrdup(pref); - cp[cp2 - pref] = '\0'; - Var_Set(PREFIX, cp, tn, 0); - free(cp); - } else - Var_Set(PREFIX, pref, tn, 0); - cp = Var_Subst(NULL, ss->src, tn, FALSE); - if (strchr(cp, '$')) { - Parse_Error(PARSE_WARNING, "Cannot resolve '%s' here", ss->src); - ParseDoSrc(ss->op, ss->src, ss->allsrc, FALSE); /* don't come back */ - return 1; /* stop list traversal */ - } - /* - * We don't want to make every target dependent on sources for - * other targets. This is the bit of ParseDoSrc which is relevant. - * The main difference is we don't link the resolved src to all targets. - */ - gn = Targ_FindNode(cp, TARG_CREATE); - if (ss->op) { - gn->type |= ss->op; - } else { - ParseLinkSrc((ClientData)tn, (ClientData)gn); - } - gn->order = waiting; - (void)Lst_AtEnd(ss->allsrc, (ClientData)gn); - if (waiting) { - Lst_ForEach(ss->allsrc, ParseAddDep, (ClientData)gn); - } - return 0; -} - - -/*- - *--------------------------------------------------------------------- * ParseDoSrc -- * Given the name of a source, figure out if it is an attribute * and apply it to the targets if it is. Else decide if there is @@ -718,8 +614,6 @@ ParseDoSpecialSrc(ClientData tp, ClientData sp) * Input: * tOp operator (if any) from special targets * src name of the source to handle - * allsrc List of all sources to wait for - * resolve boolean - should we try and resolve .TARGET refs. * * Results: * None @@ -730,20 +624,34 @@ ParseDoSpecialSrc(ClientData tp, ClientData sp) *--------------------------------------------------------------------- */ static void -ParseDoSrc(int tOp, char *src, Lst allsrc, Boolean resolve) +ParseDoSrc(int tOp, const char *src) { GNode *gn = NULL; + static int wait_number = 0; + char wait_src[16]; if (*src == '.' && isupper ((unsigned char)src[1])) { int keywd = ParseFindKeyword(src); if (keywd != -1) { int op = parseKeywords[keywd].op; if (op != 0) { - Lst_ForEach(targets, ParseDoOp, (ClientData)&op); + Lst_ForEach(targets, ParseDoOp, &op); return; } if (parseKeywords[keywd].spec == Wait) { - waiting++; + /* + * We add a .WAIT node in the dependency list. + * After any dynamic dependencies (and filename globbing) + * have happened, it is given a dependency on the each + * previous child back to and previous .WAIT node. + * The next child won't be scheduled until the .WAIT node + * is built. + * We give each .WAIT node a unique name (mainly for diag). + */ + snprintf(wait_src, sizeof wait_src, ".WAIT_%u", ++wait_number); + gn = Targ_FindNode(wait_src, TARG_NOHASH); + gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN; + Lst_ForEach(targets, ParseLinkSrc, gn); return; } } @@ -759,9 +667,9 @@ ParseDoSrc(int tOp, char *src, Lst allsrc, Boolean resolve) * invoked if the user didn't specify a target on the command * line. This is to allow #ifmake's to succeed, or something... */ - (void)Lst_AtEnd(create, (ClientData)estrdup(src)); + (void)Lst_AtEnd(create, estrdup(src)); /* - * Add the name to the .TARGETS variable as well, so the user cna + * Add the name to the .TARGETS variable as well, so the user can * employ that, if desired. */ Var_Append(".TARGETS", src, VAR_GLOBAL); @@ -774,8 +682,14 @@ ParseDoSrc(int tOp, char *src, Lst allsrc, Boolean resolve) */ gn = Targ_FindNode(src, TARG_CREATE); if (predecessor != NILGNODE) { - (void)Lst_AtEnd(predecessor->successors, (ClientData)gn); - (void)Lst_AtEnd(gn->preds, (ClientData)predecessor); + (void)Lst_AtEnd(predecessor->order_succ, gn); + (void)Lst_AtEnd(gn->order_pred, predecessor); + if (DEBUG(PARSE)) { + fprintf(debug_file, "# ParseDoSrc: added Order dependency %s - %s\n", + predecessor->name, gn->name); + Targ_PrintNode(predecessor, 0); + Targ_PrintNode(gn, 0); + } } /* * The current source now becomes the predecessor for the next one. @@ -795,34 +709,16 @@ ParseDoSrc(int tOp, char *src, Lst allsrc, Boolean resolve) * the 'cohorts' list of the node) or all the cohorts are linked * to all the targets. */ - if (resolve && strchr(src, '$')) { - SpecialSrc ss; - ss.op = tOp; - ss.src = src; - ss.allsrc = allsrc; - - /* - * If src cannot be fully resolved, we'll be called again - * with resolve==FALSE. - */ - Lst_ForEach(targets, ParseDoSpecialSrc, (ClientData)&ss); - return; - } + /* Find/create the 'src' node and attach to all targets */ gn = Targ_FindNode(src, TARG_CREATE); if (tOp) { gn->type |= tOp; } else { - Lst_ForEach(targets, ParseLinkSrc, (ClientData)gn); + Lst_ForEach(targets, ParseLinkSrc, gn); } break; } - - gn->order = waiting; - (void)Lst_AtEnd(allsrc, (ClientData)gn); - if (waiting) { - Lst_ForEach(allsrc, ParseAddDep, (ClientData)gn); - } } /*- @@ -947,26 +843,22 @@ ParseDoDependency(char *line) * expansion */ Lst curTargs; /* list of target names to be found and added * to the targets list */ - Lst curSrcs; /* list of sources in order */ char *lstart = line; - Boolean hasWait; /* is .WAIT present in srcs */ + if (DEBUG(PARSE)) + fprintf(debug_file, "ParseDoDependency(%s)\n", line); tOp = 0; specType = Not; - waiting = 0; paths = (Lst)NULL; curTargs = Lst_Init(FALSE); - curSrcs = Lst_Init(FALSE); do { - for (cp = line; - *cp && (ParseIsEscaped(lstart, cp) || - (!isspace ((unsigned char)*cp) && - (*cp != '!') && (*cp != ':') && (*cp != LPAREN))); - cp++) - { + for (cp = line; *cp && (ParseIsEscaped(lstart, cp) || + !(isspace((unsigned char)*cp) || + *cp == '!' || *cp == ':' || *cp == LPAREN)); + cp++) { if (*cp == '$') { /* * Must be a dynamic source (would have been expanded @@ -976,18 +868,16 @@ ParseDoDependency(char *line) * in the initial Var_Subst and we wouldn't be here. */ int length; - Boolean freeIt; + void *freeIt; char *result; - result=Var_Parse(cp, VAR_CMD, TRUE, &length, &freeIt); - - if (freeIt) { - free(result); - } + result = Var_Parse(cp, VAR_CMD, TRUE, &length, &freeIt); + if (freeIt) + free(freeIt); cp += length-1; } - continue; } + if (!ParseIsEscaped(lstart, cp) && *cp == LPAREN) { /* * Archives must be handled specially to make sure the OP_ARCHV @@ -1002,7 +892,7 @@ ParseDoDependency(char *line) if (Arch_ParseArchive(&line, targets, VAR_CMD) != SUCCESS) { Parse_Error(PARSE_FATAL, "Error in archive specification: \"%s\"", line); - return; + goto out; } else { continue; } @@ -1022,9 +912,10 @@ ParseDoDependency(char *line) "Makefile appears to contain unresolved cvs/rcs/??? merge conflicts"); else Parse_Error(PARSE_FATAL, "Need an operator"); - return; + goto out; } *cp = '\0'; + /* * Have a word in line. See if it's a special target and set * specType to match it. @@ -1038,7 +929,7 @@ ParseDoDependency(char *line) if (keywd != -1) { if (specType == ExPath && parseKeywords[keywd].spec != ExPath) { Parse_Error(PARSE_FATAL, "Mismatched special targets"); - return; + goto out; } specType = parseKeywords[keywd].spec; @@ -1078,7 +969,7 @@ ParseDoDependency(char *line) if (paths == NULL) { paths = Lst_Init(FALSE); } - (void)Lst_AtEnd(paths, (ClientData)dirSearchPath); + (void)Lst_AtEnd(paths, dirSearchPath); break; case Main: if (!Lst_IsEmpty(create)) { @@ -1090,19 +981,17 @@ ParseDoDependency(char *line) case Interrupt: gn = Targ_FindNode(line, TARG_CREATE); gn->type |= OP_NOTMAIN|OP_SPECIAL; - (void)Lst_AtEnd(targets, (ClientData)gn); + (void)Lst_AtEnd(targets, gn); break; case Default: gn = Targ_NewGN(".DEFAULT"); gn->type |= (OP_NOTMAIN|OP_TRANSFORM); - (void)Lst_AtEnd(targets, (ClientData)gn); + (void)Lst_AtEnd(targets, gn); DEFAULT = gn; break; case NotParallel: - { maxJobs = 1; break; - } case SingleShell: compatMake = TRUE; break; @@ -1126,12 +1015,12 @@ ParseDoDependency(char *line) Parse_Error(PARSE_FATAL, "Suffix '%s' not defined (yet)", &line[5]); - return; + goto out; } else { if (paths == (Lst)NULL) { paths = Lst_Init(FALSE); } - (void)Lst_AtEnd(paths, (ClientData)path); + (void)Lst_AtEnd(paths, path); } } } @@ -1158,7 +1047,7 @@ ParseDoDependency(char *line) * No wildcards, but we want to avoid code duplication, * so create a list with the word on it. */ - (void)Lst_AtEnd(curTargs, (ClientData)line); + (void)Lst_AtEnd(curTargs, line); } while(!Lst_IsEmpty(curTargs)) { @@ -1170,7 +1059,7 @@ ParseDoDependency(char *line) gn = Suff_AddTransform(targName); } - (void)Lst_AtEnd(targets, (ClientData)gn); + (void)Lst_AtEnd(targets, gn); } } else if (specType == ExPath && *line != '.' && *line != '\0') { Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", line); @@ -1182,17 +1071,17 @@ ParseDoDependency(char *line) * allow on this line... */ if (specType != Not && specType != ExPath) { - Boolean warn = FALSE; + Boolean warning = FALSE; while (*cp && (ParseIsEscaped(lstart, cp) || ((*cp != '!') && (*cp != ':')))) { if (ParseIsEscaped(lstart, cp) || (*cp != ' ' && *cp != '\t')) { - warn = TRUE; + warning = TRUE; } cp++; } - if (warn) { + if (warning) { Parse_Error(PARSE_WARNING, "Extra target ignored"); } } else { @@ -1208,6 +1097,7 @@ ParseDoDependency(char *line) * Don't need the list of target names anymore... */ Lst_Destroy(curTargs, NOFREE); + curTargs = NULL; if (!Lst_IsEmpty(targets)) { switch(specType) { @@ -1245,12 +1135,12 @@ ParseDoDependency(char *line) } } else { Parse_Error(PARSE_FATAL, "Missing dependency operator"); - return; + goto out; } cp++; /* Advance beyond operator */ - Lst_ForEach(targets, ParseDoOp, (ClientData)&op); + Lst_ForEach(targets, ParseDoOp, &op); /* * Get to the first source @@ -1284,7 +1174,7 @@ ParseDoDependency(char *line) beSilent = TRUE; break; case ExPath: - Lst_ForEach(paths, ParseClearPath, (ClientData)NULL); + Lst_ForEach(paths, ParseClearPath, NULL); Dir_SetPATH(); break; #ifdef POSIX @@ -1306,7 +1196,7 @@ ParseDoDependency(char *line) } else if (specType == ExShell) { if (Job_ParseShell(line) != SUCCESS) { Parse_Error(PARSE_FATAL, "improper shell specification"); - return; + goto out; } *line = '\0'; } else if ((specType == NotParallel) || (specType == SingleShell)) { @@ -1358,7 +1248,7 @@ ParseDoDependency(char *line) Suff_AddSuffix(line, &mainNode); break; case ExPath: - Lst_ForEach(paths, ParseAddDir, (ClientData)line); + Lst_ForEach(paths, ParseAddDir, line); break; case Includes: Suff_AddInclude(line); @@ -1390,18 +1280,13 @@ ParseDoDependency(char *line) if (specType == ExPath) Dir_SetPATH(); } else { - /* - * We don't need ParseDoSpecialSrc unless .WAIT is present. - */ - hasWait = (strstr(line, ".WAIT") != NULL); - while (*line) { /* * The targets take real sources, so we must beware of archive * specifications (i.e. things with left parentheses in them) * and handle them accordingly. */ - while (*cp && !isspace ((unsigned char)*cp)) { + for (; *cp && !isspace ((unsigned char)*cp); cp++) { if ((*cp == LPAREN) && (cp > line) && (cp[-1] != '$')) { /* * Only stop for a left parenthesis if it isn't at the @@ -1410,8 +1295,6 @@ ParseDoDependency(char *line) * source). */ break; - } else { - cp++; } } @@ -1420,12 +1303,12 @@ ParseDoDependency(char *line) if (Arch_ParseArchive(&line, sources, VAR_CMD) != SUCCESS) { Parse_Error(PARSE_FATAL, "Error in source archive spec \"%s\"", line); - return; + goto out; } while (!Lst_IsEmpty (sources)) { gn = (GNode *)Lst_DeQueue(sources); - ParseDoSrc(tOp, gn->name, curSrcs, hasWait); + ParseDoSrc(tOp, gn->name); } Lst_Destroy(sources, NOFREE); cp = line; @@ -1435,7 +1318,7 @@ ParseDoDependency(char *line) cp += 1; } - ParseDoSrc(tOp, line, curSrcs, hasWait); + ParseDoSrc(tOp, line); } while (*cp && isspace ((unsigned char)*cp)) { cp++; @@ -1451,13 +1334,12 @@ ParseDoDependency(char *line) * the first dependency line that is actually a real target * (i.e. isn't a .USE or .EXEC rule) to be made. */ - Lst_ForEach(targets, ParseFindMain, (ClientData)0); + Lst_ForEach(targets, ParseFindMain, NULL); } - /* - * Finally, destroy the list of sources - */ - Lst_Destroy(curSrcs, NOFREE); +out: + if (curTargs) + Lst_Destroy(curTargs, NOFREE); } /*- @@ -1597,14 +1479,6 @@ Parse_DoVar(char *line, GNode *ctxt) Boolean freeCp = FALSE; /* TRUE if cp needs to be freed, * i.e. if any variable expansion was * performed */ - /* - * Avoid clobbered variable warnings by forcing the compiler - * to ``unregister'' variables - */ -#if __GNUC__ - (void) &cp; - (void) &line; -#endif /* * Skip to variable name @@ -1706,7 +1580,7 @@ Parse_DoVar(char *line, GNode *ctxt) Var_Set(line, cp, ctxt, 0); } else if (type == VAR_SHELL) { char *res; - const char *err; + const char *error; if (strchr(cp, '$') != NULL) { /* @@ -1718,12 +1592,12 @@ Parse_DoVar(char *line, GNode *ctxt) freeCp = TRUE; } - res = Cmd_Exec(cp, &err); + res = Cmd_Exec(cp, &error); Var_Set(line, res, ctxt, 0); free(res); - if (err) - Parse_Error(PARSE_WARNING, err, cp); + if (error) + Parse_Error(PARSE_WARNING, error, cp); } else { /* * Normal assignment -- just do it. @@ -1740,6 +1614,10 @@ Parse_DoVar(char *line, GNode *ctxt) */ Dir_InitCur(cp); Dir_SetPATH(); + } else if (strcmp(line, MAKE_JOB_PREFIX) == 0) { + Job_SetPrefix(); + } else if (strcmp(line, MAKE_EXPORTED) == 0) { + Var_Export(cp, 0); } if (freeCp) free(cp); @@ -1764,9 +1642,12 @@ static int ParseAddCmd(ClientData gnp, ClientData cmd) { GNode *gn = (GNode *)gnp; - /* if target already supplied, ignore commands */ + + /* Add to last (ie current) cohort for :: targets */ if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts)) gn = (GNode *)Lst_Datum(Lst_Last(gn->cohorts)); + + /* if target already supplied, ignore commands */ if (!(gn->type & OP_HAS_COMMANDS)) { (void)Lst_AtEnd(gn->commands, cmd); ParseMark(gn); @@ -1859,72 +1740,24 @@ Parse_AddIncludeDir(char *dir) * fname and curFILE are altered for the new file *--------------------------------------------------------------------- */ + static void -ParseDoInclude(char *line) +Parse_include_file(char *file, Boolean isSystem, int silent) { char *fullname; /* full pathname of file */ - IFile *oldFile; /* state associated with current file */ - char endc; /* the character which ends the file spec */ - char *cp; /* current position in file spec */ - Boolean isSystem; /* TRUE if makefile is a system makefile */ - int silent = (*line != 'i') ? 1 : 0; - char *file = &line[7 + silent]; - - /* - * Skip to delimiter character so we know where to look - */ - while ((*file == ' ') || (*file == '\t')) { - file++; - } - - if ((*file != '"') && (*file != '<')) { - Parse_Error(PARSE_FATAL, - ".include filename must be delimited by '\"' or '<'"); - return; - } - - /* - * Set the search path on which to find the include file based on the - * characters which bracket its name. Angle-brackets imply it's - * a system Makefile while double-quotes imply it's a user makefile - */ - if (*file == '<') { - isSystem = TRUE; - endc = '>'; - } else { - isSystem = FALSE; - endc = '"'; - } - - /* - * Skip to matching delimiter - */ - for (cp = ++file; *cp && *cp != endc; cp++) { - continue; - } - - if (*cp != endc) { - Parse_Error(PARSE_FATAL, - "Unclosed %cinclude filename. '%c' expected", - '.', endc); - return; - } - *cp = '\0'; - - /* - * Substitute for any variables in the file name before trying to - * find the thing. - */ - file = Var_Subst(NULL, file, VAR_CMD, FALSE); + char *newName; + char *prefEnd, *incdir; + int fd; + int i; /* * Now we know the file's name and its search path, we attempt to * find the durn thing. A return of NULL indicates the file don't * exist. */ - fullname = NULL; + fullname = file[0] == '/' ? estrdup(file) : NULL; - if (!isSystem) { + if (fullname == NULL && !isSystem) { /* * Include files contained in double-quotes are first searched for * relative to the including file's location. We don't want to @@ -1932,42 +1765,49 @@ ParseDoInclude(char *line) * leading path components and call Dir_FindFile to see if * we can locate the beast. */ - char *prefEnd, *Fname; - - /* Make a temporary copy of this, to be safe. */ - Fname = estrdup(curFile.fname); - prefEnd = strrchr(Fname, '/'); + incdir = estrdup(curFile->fname); + prefEnd = strrchr(incdir, '/'); if (prefEnd != NULL) { - char *newName; - *prefEnd = '\0'; - if (file[0] == '/') - newName = estrdup(file); - else - newName = str_concat(Fname, file, STR_ADDSLASH); + /* Now do lexical processing of leading "../" on the filename */ + for (i = 0; strncmp(file + i, "../", 3) == 0; i += 3) { + prefEnd = strrchr(incdir + 1, '/'); + if (prefEnd == NULL || strcmp(prefEnd, "/..") == 0) + break; + *prefEnd = '\0'; + } + newName = str_concat(incdir, file + i, STR_ADDSLASH); fullname = Dir_FindFile(newName, parseIncPath); - if (fullname == NULL) { + if (fullname == NULL) fullname = Dir_FindFile(newName, dirSearchPath); - } free(newName); - *prefEnd = '/'; - } else { - fullname = NULL; } - free(Fname); - if (fullname == NULL) { + free(incdir); + + if (fullname == NULL) { /* * Makefile wasn't found in same directory as included makefile. * Search for it first on the -I search path, * then on the .PATH search path, if not found in a -I directory. - * XXX: Suffix specific? + * If we have a suffix specific path we should use that. */ - fullname = Dir_FindFile(file, parseIncPath); + char *suff; + Lst suffPath = NILLST; + + if ((suff = strrchr(file, '.'))) { + suffPath = Suff_GetPath(suff); + if (suffPath != NILLST) { + fullname = Dir_FindFile(file, suffPath); + } + } if (fullname == NULL) { - fullname = Dir_FindFile(file, dirSearchPath); + fullname = Dir_FindFile(file, parseIncPath); + if (fullname == NULL) { + fullname = Dir_FindFile(file, dirSearchPath); + } } - } + } } /* Looking for a system file or file still not found */ @@ -1975,53 +1815,78 @@ ParseDoInclude(char *line) /* * Look for it on the system path */ - fullname = Dir_FindFile(file, Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath); + fullname = Dir_FindFile(file, + Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath); } if (fullname == NULL) { - *cp = endc; if (!silent) Parse_Error(PARSE_FATAL, "Could not find %s", file); return; } - free(file); + /* Actually open the file... */ + fd = open(fullname, O_RDONLY); + if (fd == -1) { + if (!silent) + Parse_Error(PARSE_FATAL, "Cannot open %s", fullname); + free(fullname); + return; + } - /* - * Once we find the absolute path to the file, we get to save all the - * state from the current file before we can start reading this - * include file. The state is stored in an IFile structure which - * is placed on a list with other IFile structures. The list makes - * a very nice stack to track how we got here... - */ - oldFile = emalloc(sizeof(IFile)); + /* Start reading from this file next */ + Parse_SetInput(fullname, 0, fd, NULL); +} - memcpy(oldFile, &curFile, sizeof(IFile)); +static void +ParseDoInclude(char *line) +{ + char endc; /* the character which ends the file spec */ + char *cp; /* current position in file spec */ + int silent = (*line != 'i') ? 1 : 0; + char *file = &line[7 + silent]; - (void)Lst_AtFront(includes, (ClientData)oldFile); + /* Skip to delimiter character so we know where to look */ + while (*file == ' ' || *file == '\t') + file++; + + if (*file != '"' && *file != '<') { + Parse_Error(PARSE_FATAL, + ".include filename must be delimited by '\"' or '<'"); + return; + } /* - * Once the previous state has been saved, we can get down to reading - * the new file. We set up the name of the file to be the absolute - * name of the include file so error messages refer to the right - * place. Naturally enough, we start reading at line number 0. + * Set the search path on which to find the include file based on the + * characters which bracket its name. Angle-brackets imply it's + * a system Makefile while double-quotes imply it's a user makefile */ - curFile.fname = fullname; - curFile.lineno = 0; - - ParseSetParseFile(curFile.fname); + if (*file == '<') { + endc = '>'; + } else { + endc = '"'; + } - curFile.F = fopen(fullname, "r"); - curFile.P = NULL; + /* Skip to matching delimiter */ + for (cp = ++file; *cp && *cp != endc; cp++) + continue; - if (curFile.F == (FILE * ) NULL) { - if (!silent) - Parse_Error(PARSE_FATAL, "Cannot open %s", fullname); - /* - * Pop to previous file - */ - (void)ParseEOF(0); + if (*cp != endc) { + Parse_Error(PARSE_FATAL, + "Unclosed %cinclude filename. '%c' expected", + '.', endc); + return; } + *cp = '\0'; + + /* + * Substitute for any variables in the file name before trying to + * find the thing. + */ + file = Var_Subst(NULL, file, VAR_CMD, FALSE); + + Parse_include_file(file, endc == '>', silent); + free(file); } @@ -2040,56 +1905,127 @@ ParseDoInclude(char *line) *--------------------------------------------------------------------- */ static void -ParseSetParseFile(char *filename) +ParseSetParseFile(const char *filename) { char *slash; + char *dirname; + int len; slash = strrchr(filename, '/'); - if (slash == 0) { + if (slash == NULL) { Var_Set(".PARSEDIR", ".", VAR_GLOBAL, 0); Var_Set(".PARSEFILE", filename, VAR_GLOBAL, 0); } else { - *slash = '\0'; - Var_Set(".PARSEDIR", filename, VAR_GLOBAL, 0); + len = slash - filename; + dirname = emalloc(len + 1); + memcpy(dirname, filename, len); + dirname[len] = 0; + Var_Set(".PARSEDIR", dirname, VAR_GLOBAL, 0); Var_Set(".PARSEFILE", slash+1, VAR_GLOBAL, 0); - *slash = '/'; + free(dirname); + } +} + +/* + * Track the makefiles we read - so makefiles can + * set dependencies on them. + * Avoid adding anything more than once. + */ + +static void +ParseTrackInput(const char *name) +{ + char *old; + char *fp = NULL; + size_t name_len = strlen(name); + + old = Var_Value(MAKE_MAKEFILES, VAR_GLOBAL, &fp); + if (old) { + /* does it contain name? */ + for (; old != NULL; old = strchr(old, ' ')) { + if (*old == ' ') + old++; + if (memcmp(old, name, name_len) == 0 + && (old[name_len] == 0 || old[name_len] == ' ')) + goto cleanup; + } + } + Var_Append (MAKE_MAKEFILES, name, VAR_GLOBAL); + cleanup: + if (fp) { + free(fp); } } /*- *--------------------------------------------------------------------- - * Parse_FromString -- - * Start Parsing from the given string + * Parse_setInput -- + * Start Parsing from the given source * * Results: * None * * Side Effects: * A structure is added to the includes Lst and readProc, lineno, - * fname and curFILE are altered for the new file + * fname and curFile are altered for the new file *--------------------------------------------------------------------- */ void -Parse_FromString(char *str, int lineno) +Parse_SetInput(const char *name, int line, int fd, char *buf) { - IFile *oldFile; /* state associated with this file */ + if (name == NULL) + name = curFile->fname; + else + ParseTrackInput(name); - if (DEBUG(FOR)) - (void)fprintf(stderr, "%s\n---- at line %d\n", str, lineno); + if (DEBUG(PARSE)) + fprintf(debug_file, "Parse_SetInput: file %s, line %d, fd %d, buf %p\n", + name, line, fd, buf); - oldFile = emalloc(sizeof(IFile)); - memcpy(oldFile, &curFile, sizeof(IFile)); + if (fd == -1 && buf == NULL) + /* sanity */ + return; - (void)Lst_AtFront(includes, (ClientData)oldFile); + if (curFile != NULL) + /* Save exiting file info */ + Lst_AtFront(includes, curFile); - curFile.F = NULL; - curFile.P = emalloc(sizeof(PTR)); - curFile.P->str = curFile.P->ptr = str; - curFile.lineno = lineno; - curFile.fname = estrdup(curFile.fname); -} + /* Allocate and fill in new structure */ + curFile = emalloc(sizeof *curFile); + + /* + * Once the previous state has been saved, we can get down to reading + * the new file. We set up the name of the file to be the absolute + * name of the include file so error messages refer to the right + * place. + */ + curFile->fname = name; + curFile->lineno = line; + curFile->fd = fd; + curFile->cond_depth = Cond_save_depth(); + ParseSetParseFile(name); + + if (buf == NULL) { + /* + * Allocate a 32k data buffer (as stdio seems to). + * Set pointers so that first ParseReadc has to do a file read. + */ + buf = emalloc(IFILE_BUFLEN); + buf[0] = 0; + curFile->P_str = buf; + curFile->P_ptr = buf; + curFile->P_end = buf; + curFile->P_buflen = IFILE_BUFLEN; + } else { + /* Start reading from the start of the buffer */ + curFile->P_str = buf; + curFile->P_ptr = buf; + curFile->P_end = NULL; + } + +} #ifdef SYSVINCLUDE /*- @@ -2111,18 +2047,15 @@ Parse_FromString(char *str, int lineno) static void ParseTraditionalInclude(char *line) { - char *fullname; /* full pathname of file */ - IFile *oldFile; /* state associated with current file */ char *cp; /* current position in file spec */ - char *prefEnd; int done = 0; int silent = (line[0] != 'i') ? 1 : 0; char *file = &line[silent + 7]; - char *cfname; - size_t clineno; + char *all_files; - cfname = curFile.fname; - clineno = curFile.lineno; + if (DEBUG(PARSE)) { + fprintf(debug_file, "ParseTraditionalInclude: %s\n", file); + } /* * Skip over whitespace @@ -2130,16 +2063,20 @@ ParseTraditionalInclude(char *line) while (isspace((unsigned char)*file)) file++; + /* + * Substitute for any variables in the file name before trying to + * find the thing. + */ + all_files = Var_Subst(NULL, file, VAR_CMD, FALSE); + if (*file == '\0') { Parse_Error(PARSE_FATAL, "Filename missing from \"include\""); return; } - for (; !done; file = cp + 1) { - /* - * Skip to end of line or next whitespace - */ + for (file = all_files; !done; file = cp + 1) { + /* Skip to end of line or next whitespace */ for (cp = file; *cp && !isspace((unsigned char) *cp); cp++) continue; @@ -2148,105 +2085,9 @@ ParseTraditionalInclude(char *line) else done = 1; - /* - * Substitute for any variables in the file name before trying to - * find the thing. - */ - file = Var_Subst(NULL, file, VAR_CMD, FALSE); - - /* - * Now we know the file's name, we attempt to find the durn thing. - * A return of NULL indicates the file don't exist. - * - * Include files are first searched for relative to the including - * file's location. We don't want to cd there, of course, so we - * just tack on the old file's leading path components and call - * Dir_FindFile to see if we can locate the beast. - * XXX - this *does* search in the current directory, right? - */ - - prefEnd = strrchr(cfname, '/'); - if (prefEnd != NULL) { - char *newName; - - *prefEnd = '\0'; - newName = str_concat(cfname, file, STR_ADDSLASH); - fullname = Dir_FindFile(newName, parseIncPath); - if (fullname == NULL) { - fullname = Dir_FindFile(newName, dirSearchPath); - } - free(newName); - *prefEnd = '/'; - } else { - fullname = NULL; - } - - if (fullname == NULL) { - /* - * System makefile or makefile wasn't found in same directory as - * included makefile. Search for it first on the -I search path, - * then on the .PATH search path, if not found in a - * -I directory. XXX: Suffix specific? - */ - fullname = Dir_FindFile(file, parseIncPath); - if (fullname == NULL) { - fullname = Dir_FindFile(file, dirSearchPath); - } - } - - if (fullname == NULL) { - /* - * Still haven't found the makefile. Look for it on the system - * path as a last resort. - */ - fullname = Dir_FindFile(file, - Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath); - } - - if (fullname == NULL) { - if (!silent) - ParseErrorInternal(cfname, clineno, PARSE_FATAL, - "Could not find %s", file); - free(file); - continue; - } - - free(file); - - /* - * Once we find the absolute path to the file, we get to save all - * the state from the current file before we can start reading this - * include file. The state is stored in an IFile structure which - * is placed on a list with other IFile structures. The list makes - * a very nice stack to track how we got here... - */ - oldFile = emalloc(sizeof(IFile)); - memcpy(oldFile, &curFile, sizeof(IFile)); - - (void)Lst_AtFront(includes, (ClientData)oldFile); - - /* - * Once the previous state has been saved, we can get down to - * reading the new file. We set up the name of the file to be the - * absolute name of the include file so error messages refer to the - * right place. Naturally enough, we start reading at line number 0. - */ - curFile.fname = fullname; - curFile.lineno = 0; - - curFile.F = fopen(fullname, "r"); - curFile.P = NULL; - - if (curFile.F == NULL) { - if (!silent) - ParseErrorInternal(cfname, clineno, PARSE_FATAL, - "Cannot open %s", fullname); - /* - * Pop to previous file - */ - (void)ParseEOF(1); - } + Parse_include_file(file, FALSE, silent); } + free(all_files); } #endif @@ -2266,149 +2107,236 @@ ParseTraditionalInclude(char *line) *--------------------------------------------------------------------- */ static int -ParseEOF(int opened) +ParseEOF(void) { - IFile *ifile; /* the state on the top of the includes stack */ + /* Ensure the makefile (or loop) didn't have mismatched conditionals */ + Cond_restore_depth(curFile->cond_depth); - if (Lst_IsEmpty(includes)) { - Var_Delete(".PARSEDIR", VAR_GLOBAL); - Var_Delete(".PARSEFILE", VAR_GLOBAL); - return (DONE); - } + /* Dispose of curFile info */ + /* Leak curFile->fname because all the gnodes have pointers to it */ + if (curFile->fd != -1) + close(curFile->fd); + free(curFile->P_str); + free(curFile); - ifile = (IFile *)Lst_DeQueue(includes); + curFile = Lst_DeQueue(includes); - /* XXX dispose of curFile info */ - free( curFile.fname); - if (opened && curFile.F) - (void)fclose(curFile.F); - if (curFile.P) { - free(curFile.P->str); - free(curFile.P); + if (curFile == (IFile *)NIL) { + /* We've run out of input */ + Var_Delete(".PARSEDIR", VAR_GLOBAL); + Var_Delete(".PARSEFILE", VAR_GLOBAL); + return DONE; } - memcpy(&curFile, ifile, sizeof(IFile)); + if (DEBUG(PARSE)) + fprintf(debug_file, "ParseEOF: returning to file %s, line %d, fd %d\n", + curFile->fname, curFile->lineno, curFile->fd); - free(ifile); - - /* pop the PARSEDIR/PARSEFILE variables */ - ParseSetParseFile(curFile.fname); + /* Restore the PARSEDIR/PARSEFILE variables */ + ParseSetParseFile(curFile->fname); return (CONTINUE); } -/*- - *--------------------------------------------------------------------- - * ParseReadc -- - * Read a character from the current file - * - * Results: - * The character that was read - * - * Side Effects: - *--------------------------------------------------------------------- - */ -static __inline int -ParseReadc(void) +#define PARSE_RAW 1 +#define PARSE_SKIP 2 + +static char * +ParseGetLine(int flags, int *length) { - if (curFile.F) - return fgetc(curFile.F); + IFile *cf = curFile; + char *ptr; + char ch; + char *line; + char *line_end; + char *escaped; + char *comment; + char *tp; + int len, dist; - if (curFile.P && *curFile.P->ptr) - return *curFile.P->ptr++; - return EOF; -} + /* Loop through blank lines and comment lines */ + for (;;) { + cf->lineno++; + line = cf->P_ptr; + ptr = line; + line_end = line; + escaped = NULL; + comment = NULL; + for (;;) { + ch = *ptr; + if (ch == 0 || (ch == '\\' && ptr[1] == 0)) { + if (cf->P_end == NULL) + /* End of string (aka for loop) data */ + break; + /* End of data read from file, read more data */ + if (ptr != cf->P_end && (ch != '\\' || ptr + 1 != cf->P_end)) { + Parse_Error(PARSE_FATAL, "Zero byte read from file"); + return NULL; + } + /* Move existing data to (near) start of file buffer */ + len = cf->P_end - cf->P_ptr; + tp = cf->P_str + 32; + memmove(tp, cf->P_ptr, len); + dist = cf->P_ptr - tp; + /* Update all pointers to reflect moved data */ + ptr -= dist; + line -= dist; + line_end -= dist; + if (escaped) + escaped -= dist; + if (comment) + comment -= dist; + cf->P_ptr = tp; + tp += len; + cf->P_end = tp; + /* Try to read more data from file into buffer space */ + len = cf->P_str + cf->P_buflen - tp - 32; + if (len <= 0) { + /* We need a bigger buffer to hold this line */ + tp = erealloc(cf->P_str, cf->P_buflen + IFILE_BUFLEN); + cf->P_end = cf->P_end - cf->P_str + tp; + ptr = ptr - cf->P_str + tp; + line = line - cf->P_str + tp; + line_end = line_end - cf->P_str + tp; + if (escaped) + escaped = escaped - cf->P_str + tp; + if (comment) + comment = comment - cf->P_str + tp; + cf->P_str = tp; + tp = cf->P_end; + len += IFILE_BUFLEN; + cf->P_buflen += IFILE_BUFLEN; + } + len = read(cf->fd, tp, len); + if (len <= 0) { + if (len < 0) { + Parse_Error(PARSE_FATAL, "Makefile read error: %s", + strerror(errno)); + return NULL; + } + /* End of file */ + break; + } + /* 0 terminate the data, and update end pointer */ + tp += len; + cf->P_end = tp; + *tp = 0; + /* Process newly read characters */ + continue; + } + if (ch == '\\') { + /* Don't treat next character as special, remember first one */ + if (escaped == NULL) + escaped = ptr; + if (ptr[1] == '\n') + cf->lineno++; + ptr += 2; + line_end = ptr; + continue; + } + if (ch == '#' && comment == NULL) { + /* Remember first '#' for comment stripping */ + comment = line_end; + } + ptr++; + if (ch == '\n') + break; + if (!isspace((unsigned char)ch)) + /* We are not interested in trailing whitespace */ + line_end = ptr; + } -/*- - *--------------------------------------------------------------------- - * ParseUnreadc -- - * Put back a character to the current file - * - * Results: - * None. - * - * Side Effects: - *--------------------------------------------------------------------- - */ -static void -ParseUnreadc(int c) -{ - if (curFile.F) { - ungetc(c, curFile.F); - return; + /* Save next 'to be processed' location */ + cf->P_ptr = ptr; + + /* Check we have a non-comment, non-blank line */ + if (line_end == line || comment == line) { + if (ch == 0) + /* At end of file */ + return NULL; + /* Parse another line */ + continue; + } + + /* We now have a line of data */ + *line_end = 0; + + if (flags & PARSE_RAW) { + /* Leave '\' (etc) in line buffer (eg 'for' lines) */ + *length = line_end - line; + return line; + } + + if (flags & PARSE_SKIP) { + /* Completely ignore non-directives */ + if (line[0] != '.') + continue; + /* We could do more of the .else/.elif/.endif checks here */ + } + break; } - if (curFile.P) { - *--(curFile.P->ptr) = c; - return; + + /* Brutally ignore anything after a non-escaped '#' in non-commands */ + if (comment != NULL && line[0] != '\t') { + line_end = comment; + *line_end = 0; + } + + /* If we didn't see a '\\' then the in-situ data is fine */ + if (escaped == NULL) { + *length = line_end - line; + return line; } -} + /* Remove escapes from '\n' and '#' */ + tp = ptr = escaped; + escaped = line; + for (; ; *tp++ = ch) { + ch = *ptr++; + if (ch != '\\') { + if (ch == 0) + break; + continue; + } -/* ParseSkipLine(): - * Grab the next line - * - * Input: - * skip Skip lines that don't start with . - * keep_newline Keep newline character as is. - * - */ -static char * -ParseSkipLine(int skip, int keep_newline) -{ - char *line; - int c, lastc, lineLength = 0; - Buffer buf; + ch = *ptr++; + if (ch == 0) { + /* Delete '\\' at end of buffer */ + tp--; + break; + } - buf = Buf_Init(MAKE_BSIZE); + if (ch == '#' && line[0] != '\t') + /* Delete '\\' from before '#' on non-command lines */ + continue; - do { - Buf_Discard(buf, lineLength); - lastc = '\0'; - - while (((c = ParseReadc()) != '\n' || lastc == '\\') - && c != EOF) { - if (c == '\n') { - if (keep_newline) - Buf_AddByte(buf, (Byte)c); - else - Buf_ReplaceLastByte(buf, (Byte)' '); - curFile.lineno++; - - while ((c = ParseReadc()) == ' ' || c == '\t'); - - if (c == EOF) - break; - } - - Buf_AddByte(buf, (Byte)c); - lastc = c; - } - - if (c == EOF) { - Parse_Error(PARSE_FATAL, "Unclosed conditional/for loop"); - Buf_Destroy(buf, TRUE); - return(NULL); - } - - curFile.lineno++; - Buf_AddByte(buf, (Byte)'\0'); - line = (char *)Buf_GetAll(buf, &lineLength); - } while (skip == 1 && line[0] != '.'); - - Buf_Destroy(buf, FALSE); + if (ch != '\n') { + /* Leave '\\' in buffer for later */ + *tp++ = '\\'; + /* Make sure we don't delete an escaped ' ' from the line end */ + escaped = tp + 1; + continue; + } + + /* Escaped '\n' replace following whitespace with a single ' ' */ + while (ptr[0] == ' ' || ptr[0] == '\t') + ptr++; + ch = ' '; + } + + /* Delete any trailing spaces - eg from empty continuations */ + while (tp > escaped && isspace((unsigned char)tp[-1])) + tp--; + + *tp = 0; + *length = tp - line; return line; } - /*- *--------------------------------------------------------------------- * ParseReadLine -- * Read an entire line from the input file. Called only by Parse_File. - * To facilitate escaped newlines and what have you, a character is - * buffered in 'lastc', which is '\0' when no characters have been - * read. When we break out of the loop, c holds the terminating - * character and lastc holds a character that should be added to - * the line (unless we don't read anything but a terminator). * * Results: * A line w/o its newline @@ -2420,255 +2348,52 @@ ParseSkipLine(int skip, int keep_newline) static char * ParseReadLine(void) { - Buffer buf; /* Buffer for current line */ - int c; /* the current character */ - int lastc; /* The most-recent character */ - Boolean semiNL; /* treat semi-colons as newlines */ - Boolean ignDepOp; /* TRUE if should ignore dependency operators - * for the purposes of setting semiNL */ - Boolean ignComment; /* TRUE if should ignore comments (in a - * shell command */ char *line; /* Result */ - char *ep; /* to strip trailing blanks */ int lineLength; /* Length of result */ int lineno; /* Saved line # */ - semiNL = FALSE; - ignDepOp = FALSE; - ignComment = FALSE; - - /* - * Handle special-characters at the beginning of the line. Either a - * leading tab (shell command) or pound-sign (possible conditional) - * forces us to ignore comments and dependency operators and treat - * semi-colons as semi-colons (by leaving semiNL FALSE). This also - * discards completely blank lines. - */ for (;;) { - c = ParseReadc(); - - if (c == '\t') { - ignComment = ignDepOp = TRUE; - break; - } else if (c == '\n') { - curFile.lineno++; - } else if (c == '#') { - ParseUnreadc(c); - break; - } else { - /* - * Anything else breaks out without doing anything - */ - break; - } - } + line = ParseGetLine(0, &lineLength); + if (line == NULL) + return NULL; - if (c != EOF) { - lastc = c; - buf = Buf_Init(MAKE_BSIZE); - - while (((c = ParseReadc()) != '\n' || (lastc == '\\')) && - (c != EOF)) - { -test_char: - switch(c) { - case '\n': - /* - * Escaped newline: read characters until a non-space or an - * unescaped newline and replace them all by a single space. - * This is done by storing the space over the backslash and - * dropping through with the next nonspace. If it is a - * semi-colon and semiNL is TRUE, it will be recognized as a - * newline in the code below this... - */ - curFile.lineno++; - lastc = ' '; - while ((c = ParseReadc()) == ' ' || c == '\t') { - continue; - } - if (c == EOF || c == '\n') { - goto line_read; - } else { - /* - * Check for comments, semiNL's, etc. -- easier than - * ParseUnreadc(c); continue; - */ - goto test_char; - } - /*NOTREACHED*/ - break; - - case ';': - /* - * Semi-colon: Need to see if it should be interpreted as a - * newline - */ - if (semiNL) { - /* - * To make sure the command that may be following this - * semi-colon begins with a tab, we push one back into the - * input stream. This will overwrite the semi-colon in the - * buffer. If there is no command following, this does no - * harm, since the newline remains in the buffer and the - * whole line is ignored. - */ - ParseUnreadc('\t'); - goto line_read; - } - break; - case '=': - if (!semiNL) { - /* - * Haven't seen a dependency operator before this, so this - * must be a variable assignment -- don't pay attention to - * dependency operators after this. - */ - ignDepOp = TRUE; - } else if (lastc == ':' || lastc == '!') { - /* - * Well, we've seen a dependency operator already, but it - * was the previous character, so this is really just an - * expanded variable assignment. Revert semi-colons to - * being just semi-colons again and ignore any more - * dependency operators. - * - * XXX: Note that a line like "foo : a:=b" will blow up, - * but who'd write a line like that anyway? - */ - ignDepOp = TRUE; semiNL = FALSE; - } - break; - case '#': - if (!ignComment) { - if ( -#if 0 - compatMake && -#endif - (lastc != '\\')) { - /* - * If the character is a hash mark and it isn't escaped - * (or we're being compatible), the thing is a comment. - * Skip to the end of the line. - */ - do { - c = ParseReadc(); - /* - * If we found a backslash not escaped - * itself it means that the comment is - * going to continue in the next line. - */ - if (c == '\\') - ParseReadc(); - } while ((c != '\n') && (c != EOF)); - goto line_read; - } else { - /* - * Don't add the backslash. Just let the # get copied - * over. - */ - lastc = c; - continue; - } - } - break; - case ':': - case '!': - if (!ignDepOp && (c == ':' || c == '!')) { - /* - * A semi-colon is recognized as a newline only on - * dependency lines. Dependency lines are lines with a - * colon or an exclamation point. Ergo... - */ - semiNL = TRUE; - } - break; - } - /* - * Copy in the previous character and save this one in lastc. - */ - Buf_AddByte(buf, (Byte)lastc); - lastc = c; - - } - line_read: - curFile.lineno++; - - if (lastc != '\0') { - Buf_AddByte(buf, (Byte)lastc); - } - Buf_AddByte(buf, (Byte)'\0'); - line = (char *)Buf_GetAll(buf, &lineLength); - Buf_Destroy(buf, FALSE); + if (line[0] != '.') + return line; /* - * Strip trailing blanks and tabs from the line. - * Do not strip a blank or tab that is preceded by - * a '\' + * The line might be a conditional. Ask the conditional module + * about it and act accordingly */ - ep = line; - while (*ep) - ++ep; - while (ep > line + 1 && (ep[-1] == ' ' || ep[-1] == '\t')) { - if (ep > line + 1 && ep[-2] == '\\') + switch (Cond_Eval(line)) { + case COND_SKIP: + /* Skip to next conditional that evaluates to COND_PARSE. */ + do { + line = ParseGetLine(PARSE_SKIP, &lineLength); + } while (line && Cond_Eval(line) != COND_PARSE); + if (line == NULL) break; - --ep; - } - *ep = 0; - - if (line[0] == '.') { - /* - * The line might be a conditional. Ask the conditional module - * about it and act accordingly - */ - switch (Cond_Eval(line)) { - case COND_SKIP: - /* - * Skip to next conditional that evaluates to COND_PARSE. - */ - do { - free(line); - line = ParseSkipLine(1, 0); - } while (line && Cond_Eval(line) != COND_PARSE); - if (line == NULL) - break; - /*FALLTHRU*/ - case COND_PARSE: - free(line); - line = ParseReadLine(); + continue; + case COND_PARSE: + continue; + case COND_INVALID: /* Not a conditional line */ + if (!For_Eval(line)) break; - case COND_INVALID: - lineno = curFile.lineno; - if (For_Eval(line)) { - int ok; - free(line); - do { - /* - * Skip after the matching end - */ - line = ParseSkipLine(0, 1); - if (line == NULL) { - Parse_Error(PARSE_FATAL, - "Unexpected end of file in for loop.\n"); - break; - } - ok = For_Eval(line); - free(line); - } - while (ok); - if (line != NULL) - For_Run(lineno); - line = ParseReadLine(); + lineno = curFile->lineno; + /* Skip after the matching end */ + do { + line = ParseGetLine(PARSE_RAW, &lineLength); + if (line == NULL) { + Parse_Error(PARSE_FATAL, + "Unexpected end of file in for loop.\n"); + break; } - break; - } + } while (For_Eval(line)); + /* Stash each iteration as a new 'input file' */ + For_Run(lineno); + /* Read next line from for-loop buffer */ + continue; } return (line); - - } else { - /* - * Hit end-of-file, so return a NULL line to indicate this. - */ - return(NULL); } } @@ -2689,7 +2414,7 @@ static void ParseFinishLine(void) { if (inLine) { - Lst_ForEach(targets, Suff_EndTransform, (ClientData)NULL); + Lst_ForEach(targets, Suff_EndTransform, NULL); Lst_Destroy(targets, ParseHasCommands); targets = NULL; inLine = FALSE; @@ -2706,190 +2431,190 @@ ParseFinishLine(void) * * Input: * name the name of the file being read - * stream Stream open to makefile to parse + * fd Open file to makefile to parse * * Results: * None * * Side Effects: + * closes fd. * Loads. Nodes are added to the list of all targets, nodes and links * are added to the dependency graph. etc. etc. etc. *--------------------------------------------------------------------- */ void -Parse_File(const char *name, FILE *stream) +Parse_File(const char *name, int fd) { - char *cp, /* pointer into the line */ - *line; /* the line we're working on */ + char *cp; /* pointer into the line */ + char *line; /* the line we're working on */ inLine = FALSE; fatals = 0; - curFile.fname = UNCONST(name); - curFile.F = stream; - curFile.lineno = 0; - - ParseSetParseFile(curFile.fname); + Parse_SetInput(name, 0, fd, NULL); do { - while ((line = ParseReadLine()) != NULL) { + for (; (line = ParseReadLine()) != NULL; ) { + if (DEBUG(PARSE)) + fprintf(debug_file, "ParseReadLine (%d): '%s'\n", + curFile->lineno, line); if (*line == '.') { /* * Lines that begin with the special character are either * include or undef directives. */ - for (cp = line + 1; isspace ((unsigned char)*cp); cp++) { + for (cp = line + 1; isspace((unsigned char)*cp); cp++) { continue; } if (strncmp(cp, "include", 7) == 0 || - ((cp[0] == 's' || cp[0] == '-') && - strncmp(&cp[1], "include", 7) == 0)) { + ((cp[0] == 's' || cp[0] == '-') && + strncmp(&cp[1], "include", 7) == 0)) { ParseDoInclude(cp); - goto nextLine; - } else if (strncmp(cp, "undef", 5) == 0) { + continue; + } + if (strncmp(cp, "undef", 5) == 0) { char *cp2; - for (cp += 5; isspace((unsigned char) *cp); cp++) { + for (cp += 5; isspace((unsigned char) *cp); cp++) continue; - } - for (cp2 = cp; !isspace((unsigned char) *cp2) && - (*cp2 != '\0'); cp2++) { + (*cp2 != '\0'); cp2++) continue; - } - *cp2 = '\0'; - Var_Delete(cp, VAR_GLOBAL); - goto nextLine; + continue; + } else if (strncmp(cp, "export", 6) == 0) { + for (cp += 6; isspace((unsigned char) *cp); cp++) + continue; + Var_Export(cp, 1); + continue; } } - if (*line == '#') { - /* If we're this far, the line must be a comment. */ - goto nextLine; - } if (*line == '\t') { /* * If a line starts with a tab, it can only hope to be * a creation command. */ -#ifndef POSIX - shellCommand: -#endif - for (cp = line + 1; isspace ((unsigned char)*cp); cp++) { + cp = line + 1; + shellCommand: + for (; isspace ((unsigned char)*cp); cp++) { continue; } if (*cp) { - if (inLine) { - /* - * So long as it's not a blank line and we're actually - * in a dependency spec, add the command to the list of - * commands of all targets in the dependency spec - */ - Lst_ForEach(targets, ParseAddCmd, cp); -#ifdef CLEANUP - Lst_AtEnd(targCmds, (ClientData) line); -#endif - continue; - } else { + if (!inLine) Parse_Error(PARSE_FATAL, "Unassociated shell command \"%s\"", cp); + /* + * So long as it's not a blank line and we're actually + * in a dependency spec, add the command to the list of + * commands of all targets in the dependency spec + */ + if (targets) { + cp = estrdup(cp); + Lst_ForEach(targets, ParseAddCmd, cp); +#ifdef CLEANUP + Lst_AtEnd(targCmds, cp); +#endif } } + continue; + } + #ifdef SYSVINCLUDE - } else if (((strncmp(line, "include", 7) == 0 && - isspace((unsigned char) line[7])) || - ((line[0] == 's' || line[0] == '-') && - strncmp(&line[1], "include", 7) == 0 && - isspace((unsigned char) line[8]))) && - strchr(line, ':') == NULL) { + if (((strncmp(line, "include", 7) == 0 && + isspace((unsigned char) line[7])) || + ((line[0] == 's' || line[0] == '-') && + strncmp(&line[1], "include", 7) == 0 && + isspace((unsigned char) line[8]))) && + strchr(line, ':') == NULL) { /* * It's an S3/S5-style "include". */ ParseTraditionalInclude(line); - goto nextLine; + continue; + } #endif - } else if (Parse_IsVar(line)) { + if (Parse_IsVar(line)) { ParseFinishLine(); Parse_DoVar(line, VAR_GLOBAL); - } else { - /* - * We now know it's a dependency line so it needs to have all - * variables expanded before being parsed. Tell the variable - * module to complain if some variable is undefined... - * To make life easier on novices, if the line is indented we - * first make sure the line has a dependency operator in it. - * If it doesn't have an operator and we're in a dependency - * line's script, we assume it's actually a shell command - * and add it to the current list of targets. - */ -#ifndef POSIX - Boolean nonSpace = FALSE; -#endif + continue; + } - cp = line; - if (isspace((unsigned char) line[0])) { - while ((*cp != '\0') && isspace((unsigned char) *cp)) { - cp++; - } - if (*cp == '\0') { - goto nextLine; - } #ifndef POSIX - while (*cp && (ParseIsEscaped(line, cp) || + /* + * To make life easier on novices, if the line is indented we + * first make sure the line has a dependency operator in it. + * If it doesn't have an operator and we're in a dependency + * line's script, we assume it's actually a shell command + * and add it to the current list of targets. + */ + cp = line; + if (isspace((unsigned char) line[0])) { + while ((*cp != '\0') && isspace((unsigned char) *cp)) + cp++; + while (*cp && (ParseIsEscaped(line, cp) || (*cp != ':') && (*cp != '!'))) { - nonSpace = TRUE; - cp++; - } -#endif + cp++; } - -#ifndef POSIX if (*cp == '\0') { if (inLine) { Parse_Error(PARSE_WARNING, "Shell command needs a leading tab"); goto shellCommand; - } else if (nonSpace) { - Parse_Error(PARSE_FATAL, "Missing operator"); } - } else { + } + } #endif - ParseFinishLine(); + ParseFinishLine(); - cp = Var_Subst(NULL, line, VAR_CMD, TRUE); - free(line); - line = cp; - - /* - * Need a non-circular list for the target nodes - */ - if (targets) - Lst_Destroy(targets, NOFREE); - - targets = Lst_Init(FALSE); - inLine = TRUE; - - ParseDoDependency(line); -#ifndef POSIX + /* + * For some reason - probably to make the parser impossible - + * a ';' can be used to separate commands from dependencies. + * No attempt is made to avoid ';' inside substitution patterns. + */ + for (cp = line; *cp != 0; cp++) { + if (*cp == '\\' && cp[1] != 0) { + cp++; + continue; } -#endif + if (*cp == ';') + break; } + if (*cp != 0) + /* Terminate the dependency list at the ';' */ + *cp++ = 0; + else + cp = NULL; + + /* + * We now know it's a dependency line so it needs to have all + * variables expanded before being parsed. Tell the variable + * module to complain if some variable is undefined... + */ + line = Var_Subst(NULL, line, VAR_CMD, TRUE); - nextLine: + /* + * Need a non-circular list for the target nodes + */ + if (targets) + Lst_Destroy(targets, NOFREE); + targets = Lst_Init(FALSE); + inLine = TRUE; + + ParseDoDependency(line); free(line); + + /* If there were commands after a ';', add them now */ + if (cp != NULL) { + goto shellCommand; + } } /* * Reached EOF, but it may be just EOF of an include file... */ - } while (ParseEOF(1) == CONTINUE); - - /* - * Make sure conditionals are clean - */ - Cond_End(); + } while (ParseEOF() == CONTINUE); if (fatals) { (void)fprintf(stderr, @@ -2965,11 +2690,11 @@ Parse_MainName(void) Punt("no target to make."); /*NOTREACHED*/ } else if (mainNode->type & OP_DOUBLEDEP) { - (void)Lst_AtEnd(mainList, (ClientData)mainNode); + (void)Lst_AtEnd(mainList, mainNode); Lst_Concat(mainList, mainNode->cohorts, LST_CONCNEW); } else - (void)Lst_AtEnd(mainList, (ClientData)mainNode); + (void)Lst_AtEnd(mainList, mainNode); Var_Append(".TARGETS", mainNode->name, VAR_GLOBAL); return (mainList); } @@ -2988,6 +2713,6 @@ Parse_MainName(void) static void ParseMark(GNode *gn) { - gn->fname = strdup(curFile.fname); - gn->lineno = curFile.lineno; + gn->fname = curFile->fname; + gn->lineno = curFile->lineno; } diff --git a/devel/bmake/files/str.c b/devel/bmake/files/str.c index 217f5efb48f..04f27863bfe 100644 --- a/devel/bmake/files/str.c +++ b/devel/bmake/files/str.c @@ -1,4 +1,4 @@ -/* $NetBSD: str.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: str.c,v 1.1.1.2 2008/03/09 19:39:34 joerg Exp $ */ /*- * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: str.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: str.c,v 1.1.1.2 2008/03/09 19:39:34 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90"; #else -__RCSID("$NetBSD: str.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: str.c,v 1.1.1.2 2008/03/09 19:39:34 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -128,8 +128,14 @@ str_concat(const char *s1, const char *s2, int flags) * spaces) taking quotation marks into account. Leading tabs/spaces * are ignored. * + * If expand is TRUE, quotes are removed and escape sequences + * such as \r, \t, etc... are expanded. + * * returns -- * Pointer to the array of pointers to the words. + * Memory containing the actual words in *buffer. + * Both of these must be free'd by the caller. + * Number of words in *store_argc. */ char ** brk_string(const char *str, int *store_argc, Boolean expand, char **buffer) @@ -170,6 +176,8 @@ brk_string(const char *str, int *store_argc, Boolean expand, char **buffer) /* Don't miss "" or '' */ if (start == NULL && p[1] == inquote) { start = t + 1; + p++; + inquote = '\0'; break; } } @@ -211,6 +219,8 @@ brk_string(const char *str, int *store_argc, Boolean expand, char **buffer) if (!start) start = t; *t++ = '\\'; + if (*(p+1) == '\0') // catch '\' at end of line + continue; ch = *++p; break; } diff --git a/devel/bmake/files/suff.c b/devel/bmake/files/suff.c index 79dd0b005e2..acfd62214e6 100644 --- a/devel/bmake/files/suff.c +++ b/devel/bmake/files/suff.c @@ -1,4 +1,4 @@ -/* $NetBSD: suff.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: suff.c,v 1.1.1.2 2008/03/09 19:39:34 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: suff.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: suff.c,v 1.1.1.2 2008/03/09 19:39:34 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)suff.c 8.4 (Berkeley) 3/21/94"; #else -__RCSID("$NetBSD: suff.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: suff.c,v 1.1.1.2 2008/03/09 19:39:34 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -230,7 +230,8 @@ static int SuffRemoveSrc(Lst); static void SuffAddLevel(Lst, Src *); static Src *SuffFindThem(Lst, Lst); static Src *SuffFindCmds(Src *, Lst); -static int SuffExpandChildren(LstNode, GNode *); +static void SuffExpandChildren(LstNode, GNode *); +static void SuffExpandWildcards(LstNode, GNode *); static Boolean SuffApplyTransform(GNode *, GNode *, Suff *, Suff *); static void SuffFindDeps(GNode *, Lst); static void SuffFindArchiveDeps(GNode *, Lst); @@ -464,10 +465,10 @@ SuffFree(ClientData sp) static void SuffRemove(Lst l, Suff *s) { - SuffUnRef((ClientData) l, (ClientData) s); + SuffUnRef(l, s); if (s->refCount == 0) { - SuffUnRef((ClientData) sufflist, (ClientData) s); - SuffFree((ClientData) s); + SuffUnRef(sufflist, s); + SuffFree(s); } } @@ -506,24 +507,24 @@ SuffInsert(Lst l, Suff *s) Lst_Close(l); if (DEBUG(SUFF)) { - printf("inserting %s(%d)...", s->name, s->sNum); + fprintf(debug_file, "inserting %s(%d)...", s->name, s->sNum); } if (ln == NILLNODE) { if (DEBUG(SUFF)) { - printf("at end of list\n"); + fprintf(debug_file, "at end of list\n"); } - (void)Lst_AtEnd(l, (ClientData)s); + (void)Lst_AtEnd(l, s); s->refCount++; - (void)Lst_AtEnd(s->ref, (ClientData) l); + (void)Lst_AtEnd(s->ref, l); } else if (s2->sNum != s->sNum) { if (DEBUG(SUFF)) { - printf("before %s(%d)\n", s2->name, s2->sNum); + fprintf(debug_file, "before %s(%d)\n", s2->name, s2->sNum); } - (void)Lst_Insert(l, ln, (ClientData)s); + (void)Lst_InsertBefore(l, ln, s); s->refCount++; - (void)Lst_AtEnd(s->ref, (ClientData) l); + (void)Lst_AtEnd(s->ref, l); } else if (DEBUG(SUFF)) { - printf("already there\n"); + fprintf(debug_file, "already there\n"); } } @@ -596,9 +597,9 @@ SuffParseTransform(char *str, Suff **srcPtr, Suff **targPtr) */ for (;;) { if (srcLn == NILLNODE) { - srcLn = Lst_Find(sufflist, (ClientData)str, SuffSuffIsPrefix); + srcLn = Lst_Find(sufflist, str, SuffSuffIsPrefix); } else { - srcLn = Lst_FindFrom(sufflist, Lst_Succ(srcLn), (ClientData)str, + srcLn = Lst_FindFrom(sufflist, Lst_Succ(srcLn), str, SuffSuffIsPrefix); } if (srcLn == NILLNODE) { @@ -627,7 +628,7 @@ SuffParseTransform(char *str, Suff **srcPtr, Suff **targPtr) single = src; singleLn = srcLn; } else { - targLn = Lst_Find(sufflist, (ClientData)str2, SuffSuffHasNameP); + targLn = Lst_Find(sufflist, str2, SuffSuffHasNameP); if (targLn != NILLNODE) { *srcPtr = src; *targPtr = (Suff *)Lst_Datum(targLn); @@ -687,14 +688,14 @@ Suff_AddTransform(char *line) *t; /* target suffix */ LstNode ln; /* Node for existing transformation */ - ln = Lst_Find(transforms, (ClientData)line, SuffGNHasNameP); + ln = Lst_Find(transforms, line, SuffGNHasNameP); if (ln == NILLNODE) { /* * Make a new graph node for the transformation. It will be filled in * by the Parse module. */ gn = Targ_NewGN(line); - (void)Lst_AtEnd(transforms, (ClientData)gn); + (void)Lst_AtEnd(transforms, gn); } else { /* * New specification for transformation rule. Just nuke the old list @@ -717,7 +718,7 @@ Suff_AddTransform(char *line) * link the two together in the proper relationship and order */ if (DEBUG(SUFF)) { - printf("defining transformation from `%s' to `%s'\n", + fprintf(debug_file, "defining transformation from `%s' to `%s'\n", s->name, t->name); } SuffInsert(t->children, s); @@ -767,7 +768,7 @@ Suff_EndTransform(ClientData gnp, ClientData dummy) Lst p; if (DEBUG(SUFF)) { - printf("deleting transformation from `%s' to `%s'\n", + fprintf(debug_file, "deleting transformation from `%s' to `%s'\n", s->name, t->name); } @@ -792,7 +793,7 @@ Suff_EndTransform(ClientData gnp, ClientData dummy) SuffRemove(p, t); } } else if ((gn->type & OP_TRANSFORM) && DEBUG(SUFF)) { - printf("transformation %s complete\n", gn->name); + fprintf(debug_file, "transformation %s complete\n", gn->name); } return(dummy ? 0 : 0); @@ -836,7 +837,7 @@ SuffRebuildGraph(ClientData transformp, ClientData sp) */ cp = SuffStrIsPrefix(s->name, transform->name); if (cp != NULL) { - ln = Lst_Find(sufflist, (ClientData)cp, SuffSuffHasNameP); + ln = Lst_Find(sufflist, cp, SuffSuffHasNameP); if (ln != NILLNODE) { /* * Found target. Link in and return, since it can't be anything @@ -860,7 +861,7 @@ SuffRebuildGraph(ClientData transformp, ClientData sp) * Null-terminate the source suffix in order to find it. */ cp[1] = '\0'; - ln = Lst_Find(sufflist, (ClientData)transform->name, SuffSuffHasNameP); + ln = Lst_Find(sufflist, transform->name, SuffSuffHasNameP); /* * Replace the start of the target suffix */ @@ -908,7 +909,7 @@ SuffScanTargets(ClientData targetp, ClientData gsp) return 1; } - if (target->type == OP_TRANSFORM) + if ((unsigned int)target->type == OP_TRANSFORM) return 0; if ((ptr = strstr(target->name, gs->s->name)) == NULL || @@ -928,7 +929,7 @@ SuffScanTargets(ClientData targetp, ClientData gsp) * link the two together in the proper relationship and order */ if (DEBUG(SUFF)) { - printf("defining transformation from `%s' to `%s'\n", + fprintf(debug_file, "defining transformation from `%s' to `%s'\n", s->name, t->name); } SuffInsert(t->children, s); @@ -963,7 +964,7 @@ Suff_AddSuffix(char *str, GNode **gn) LstNode ln; GNodeSuff gs; - ln = Lst_Find(sufflist, (ClientData)str, SuffSuffHasNameP); + ln = Lst_Find(sufflist, str, SuffSuffHasNameP); if (ln == NILLNODE) { s = emalloc(sizeof(Suff)); @@ -977,7 +978,7 @@ Suff_AddSuffix(char *str, GNode **gn) s->flags = 0; s->refCount = 1; - (void)Lst_AtEnd(sufflist, (ClientData)s); + (void)Lst_AtEnd(sufflist, s); /* * We also look at our existing targets list to see if adding * this suffix will make one of our current targets mutate into @@ -987,12 +988,12 @@ Suff_AddSuffix(char *str, GNode **gn) gs.gn = gn; gs.s = s; gs.r = FALSE; - Lst_ForEach(Targ_List(), SuffScanTargets, (ClientData) &gs); + Lst_ForEach(Targ_List(), SuffScanTargets, &gs); /* * Look for any existing transformations from or to this suffix. * XXX: Only do this after a Suff_ClearSuffixes? */ - Lst_ForEach(transforms, SuffRebuildGraph, (ClientData) s); + Lst_ForEach(transforms, SuffRebuildGraph, s); } } @@ -1015,7 +1016,7 @@ Suff_GetPath(char *sname) LstNode ln; Suff *s; - ln = Lst_Find(sufflist, (ClientData)sname, SuffSuffHasNameP); + ln = Lst_Find(sufflist, sname, SuffSuffHasNameP); if (ln == NILLNODE) { return (NILLST); } else { @@ -1113,7 +1114,7 @@ Suff_AddInclude(char *sname) LstNode ln; Suff *s; - ln = Lst_Find(sufflist, (ClientData)sname, SuffSuffHasNameP); + ln = Lst_Find(sufflist, sname, SuffSuffHasNameP); if (ln != NILLNODE) { s = (Suff *)Lst_Datum(ln); s->flags |= SUFF_INCLUDE; @@ -1145,7 +1146,7 @@ Suff_AddLib(char *sname) LstNode ln; Suff *s; - ln = Lst_Find(sufflist, (ClientData)sname, SuffSuffHasNameP); + ln = Lst_Find(sufflist, sname, SuffSuffHasNameP); if (ln != NILLNODE) { s = (Suff *)Lst_Datum(ln); s->flags |= SUFF_LIBRARY; @@ -1197,13 +1198,13 @@ SuffAddSrc(ClientData sp, ClientData lsp) s->refCount++; s2->children = 0; targ->children += 1; - (void)Lst_AtEnd(ls->l, (ClientData)s2); + (void)Lst_AtEnd(ls->l, s2); #ifdef DEBUG_SRC s2->cp = Lst_Init(FALSE); - Lst_AtEnd(targ->cp, (ClientData) s2); - printf("1 add %x %x to %x:", targ, s2, ls->l); - Lst_ForEach(ls->l, PrintAddr, (ClientData) 0); - printf("\n"); + Lst_AtEnd(targ->cp, s2); + fprintf(debug_file, "1 add %x %x to %x:", targ, s2, ls->l); + Lst_ForEach(ls->l, PrintAddr, NULL); + fprintf(debug_file, "\n"); #endif } s2 = emalloc(sizeof(Src)); @@ -1215,13 +1216,13 @@ SuffAddSrc(ClientData sp, ClientData lsp) s->refCount++; s2->children = 0; targ->children += 1; - (void)Lst_AtEnd(ls->l, (ClientData)s2); + (void)Lst_AtEnd(ls->l, s2); #ifdef DEBUG_SRC s2->cp = Lst_Init(FALSE); - Lst_AtEnd(targ->cp, (ClientData) s2); - printf("2 add %x %x to %x:", targ, s2, ls->l); - Lst_ForEach(ls->l, PrintAddr, (ClientData) 0); - printf("\n"); + Lst_AtEnd(targ->cp, s2); + fprintf(debug_file, "2 add %x %x to %x:", targ, s2, ls->l); + Lst_ForEach(ls->l, PrintAddr, NULL); + fprintf(debug_file, "\n"); #endif return(0); @@ -1251,7 +1252,7 @@ SuffAddLevel(Lst l, Src *targ) ls.s = targ; ls.l = l; - Lst_ForEach(targ->suff->children, SuffAddSrc, (ClientData)&ls); + Lst_ForEach(targ->suff->children, SuffAddSrc, &ls); } /*- @@ -1277,9 +1278,9 @@ SuffRemoveSrc(Lst l) return 0; } #ifdef DEBUG_SRC - printf("cleaning %lx: ", (unsigned long) l); - Lst_ForEach(l, PrintAddr, (ClientData) 0); - printf("\n"); + fprintf(debug_file, "cleaning %lx: ", (unsigned long) l); + Lst_ForEach(l, PrintAddr, NULL); + fprintf(debug_file, "\n"); #endif @@ -1291,14 +1292,14 @@ SuffRemoveSrc(Lst l) free(s->pref); else { #ifdef DEBUG_SRC - LstNode ln = Lst_Member(s->parent->cp, (ClientData)s); + LstNode ln = Lst_Member(s->parent->cp, s); if (ln != NILLNODE) Lst_Remove(s->parent->cp, ln); #endif --s->parent->children; } #ifdef DEBUG_SRC - printf("free: [l=%x] p=%x %d\n", l, s, s->children); + fprintf(debug_file, "free: [l=%x] p=%x %d\n", l, s, s->children); Lst_Destroy(s->cp, NOFREE); #endif Lst_Remove(l, ln); @@ -1309,9 +1310,9 @@ SuffRemoveSrc(Lst l) } #ifdef DEBUG_SRC else { - printf("keep: [l=%x] p=%x %d: ", l, s, s->children); - Lst_ForEach(s->cp, PrintAddr, (ClientData) 0); - printf("\n"); + fprintf(debug_file, "keep: [l=%x] p=%x %d: ", l, s, s->children); + Lst_ForEach(s->cp, PrintAddr, NULL); + fprintf(debug_file, "\n"); } #endif } @@ -1349,7 +1350,7 @@ SuffFindThem(Lst srcs, Lst slst) s = (Src *)Lst_DeQueue(srcs); if (DEBUG(SUFF)) { - printf("\ttrying %s...", s->file); + fprintf(debug_file, "\ttrying %s...", s->file); } /* @@ -1358,7 +1359,7 @@ SuffFindThem(Lst srcs, Lst slst) */ if (Targ_FindNode(s->file, TARG_NOCREATE) != NILGNODE) { #ifdef DEBUG_SRC - printf("remove %x from %x\n", s, srcs); + fprintf(debug_file, "remove %x from %x\n", s, srcs); #endif rs = s; break; @@ -1367,22 +1368,22 @@ SuffFindThem(Lst srcs, Lst slst) if ((ptr = Dir_FindFile(s->file, s->suff->searchPath)) != NULL) { rs = s; #ifdef DEBUG_SRC - printf("remove %x from %x\n", s, srcs); + fprintf(debug_file, "remove %x from %x\n", s, srcs); #endif free(ptr); break; } if (DEBUG(SUFF)) { - printf("not there\n"); + fprintf(debug_file, "not there\n"); } SuffAddLevel(srcs, s); - Lst_AtEnd(slst, (ClientData) s); + Lst_AtEnd(slst, s); } if (DEBUG(SUFF) && rs) { - printf("got it\n"); + fprintf(debug_file, "got it\n"); } return (rs); } @@ -1428,6 +1429,17 @@ SuffFindCmds(Src *targ, Lst slst) } s = (GNode *)Lst_Datum(ln); + if (s->type & OP_OPTIONAL && Lst_IsEmpty(t->commands)) { + /* + * We haven't looked to see if .OPTIONAL files exist yet, so + * don't use one as the implicit source. + * This allows us to use .OPTIONAL in .depend files so make won't + * complain "don't know how to make xxx.h' when a dependant file + * has been moved/deleted. + */ + continue; + } + cp = strrchr(s->name, '/'); if (cp == NULL) { cp = s->name; @@ -1440,7 +1452,7 @@ SuffFindCmds(Src *targ, Lst slst) * The node matches the prefix ok, see if it has a known * suffix. */ - ln = Lst_Find(sufflist, (ClientData)&cp[prefLen], + ln = Lst_Find(sufflist, &cp[prefLen], SuffSuffHasNameP); if (ln == NILLNODE) continue; @@ -1452,7 +1464,7 @@ SuffFindCmds(Src *targ, Lst slst) */ suff = (Suff *)Lst_Datum(ln); - if (Lst_Member(suff->parents, (ClientData)targ->suff) != NILLNODE) + if (Lst_Member(suff->parents, targ->suff) != NILLNODE) break; } @@ -1473,12 +1485,12 @@ SuffFindCmds(Src *targ, Lst slst) targ->children += 1; #ifdef DEBUG_SRC ret->cp = Lst_Init(FALSE); - printf("3 add %x %x\n", targ, ret); - Lst_AtEnd(targ->cp, (ClientData) ret); + fprintf(debug_file, "3 add %x %x\n", targ, ret); + Lst_AtEnd(targ->cp, ret); #endif - Lst_AtEnd(slst, (ClientData) ret); + Lst_AtEnd(slst, ret); if (DEBUG(SUFF)) { - printf("\tusing existing source %s\n", s->name); + fprintf(debug_file, "\tusing existing source %s\n", s->name); } return (ret); } @@ -1490,7 +1502,7 @@ SuffFindCmds(Src *targ, Lst slst) * variable invocations or file wildcards into actual targets. * * Input: - * prevLN Child to examine + * cln Child to examine * pgn Parent node being processed * * Results: @@ -1503,183 +1515,203 @@ SuffFindCmds(Src *targ, Lst slst) * *----------------------------------------------------------------------- */ -static int -SuffExpandChildren(LstNode prevLN, GNode *pgn) +static void +SuffExpandChildren(LstNode cln, GNode *pgn) { - GNode *cgn = (GNode *)Lst_Datum(prevLN); + GNode *cgn = (GNode *)Lst_Datum(cln); GNode *gn; /* New source 8) */ char *cp; /* Expanded value */ + if (!Lst_IsEmpty(cgn->order_pred) || !Lst_IsEmpty(cgn->order_succ)) + /* It is all too hard to process the result of .ORDER */ + return; + + if (cgn->type & OP_WAIT) + /* Ignore these (& OP_PHONY ?) */ + return; + /* * First do variable expansion -- this takes precedence over * wildcard expansion. If the result contains wildcards, they'll be gotten * to later since the resulting words are tacked on to the end of * the children list. */ - if (strchr(cgn->name, '$') != NULL) { - if (DEBUG(SUFF)) { - printf("Expanding \"%s\"...", cgn->name); - } - cp = Var_Subst(NULL, cgn->name, pgn, TRUE); + if (strchr(cgn->name, '$') == NULL) { + SuffExpandWildcards(cln, pgn); + return; + } - if (cp != NULL) { - Lst members = Lst_Init(FALSE); + if (DEBUG(SUFF)) { + fprintf(debug_file, "Expanding \"%s\"...", cgn->name); + } + cp = Var_Subst(NULL, cgn->name, pgn, TRUE); - if (cgn->type & OP_ARCHV) { - /* - * Node was an archive(member) target, so we want to call - * on the Arch module to find the nodes for us, expanding - * variables in the parent's context. - */ - char *sacrifice = cp; + if (cp != NULL) { + Lst members = Lst_Init(FALSE); - (void)Arch_ParseArchive(&sacrifice, members, pgn); - } else { - /* - * Break the result into a vector of strings whose nodes - * we can find, then add those nodes to the members list. - * Unfortunately, we can't use brk_string b/c it - * doesn't understand about variable specifications with - * spaces in them... - */ - char *start; - char *initcp = cp; /* For freeing... */ - - for (start = cp; *start == ' ' || *start == '\t'; start++) - continue; - for (cp = start; *cp != '\0'; cp++) { - if (*cp == ' ' || *cp == '\t') { - /* - * White-space -- terminate element, find the node, - * add it, skip any further spaces. - */ - *cp++ = '\0'; - gn = Targ_FindNode(start, TARG_CREATE); - (void)Lst_AtEnd(members, (ClientData)gn); - while (*cp == ' ' || *cp == '\t') { - cp++; - } - /* - * Adjust cp for increment at start of loop, but - * set start to first non-space. - */ - start = cp--; - } else if (*cp == '$') { - /* - * Start of a variable spec -- contact variable module - * to find the end so we can skip over it. - */ - char *junk; - int len; - Boolean doFree; - - junk = Var_Parse(cp, pgn, TRUE, &len, &doFree); - if (junk != var_Error) { - cp += len - 1; - } - - if (doFree) { - free(junk); - } - } else if (*cp == '\\' && *cp != '\0') { - /* - * Escaped something -- skip over it - */ + if (cgn->type & OP_ARCHV) { + /* + * Node was an archive(member) target, so we want to call + * on the Arch module to find the nodes for us, expanding + * variables in the parent's context. + */ + char *sacrifice = cp; + + (void)Arch_ParseArchive(&sacrifice, members, pgn); + } else { + /* + * Break the result into a vector of strings whose nodes + * we can find, then add those nodes to the members list. + * Unfortunately, we can't use brk_string b/c it + * doesn't understand about variable specifications with + * spaces in them... + */ + char *start; + char *initcp = cp; /* For freeing... */ + + for (start = cp; *start == ' ' || *start == '\t'; start++) + continue; + for (cp = start; *cp != '\0'; cp++) { + if (*cp == ' ' || *cp == '\t') { + /* + * White-space -- terminate element, find the node, + * add it, skip any further spaces. + */ + *cp++ = '\0'; + gn = Targ_FindNode(start, TARG_CREATE); + (void)Lst_AtEnd(members, gn); + while (*cp == ' ' || *cp == '\t') { cp++; } - } + /* + * Adjust cp for increment at start of loop, but + * set start to first non-space. + */ + start = cp--; + } else if (*cp == '$') { + /* + * Start of a variable spec -- contact variable module + * to find the end so we can skip over it. + */ + char *junk; + int len; + void *freeIt; + + junk = Var_Parse(cp, pgn, TRUE, &len, &freeIt); + if (junk != var_Error) { + cp += len - 1; + } - if (cp != start) { + if (freeIt) + free(freeIt); + } else if (*cp == '\\' && *cp != '\0') { /* - * Stuff left over -- add it to the list too + * Escaped something -- skip over it */ - gn = Targ_FindNode(start, TARG_CREATE); - (void)Lst_AtEnd(members, (ClientData)gn); + cp++; } - /* - * Point cp back at the beginning again so the variable value - * can be freed. - */ - cp = initcp; } - /* - * Add all elements of the members list to the parent node. - */ - while(!Lst_IsEmpty(members)) { - gn = (GNode *)Lst_DeQueue(members); - if (DEBUG(SUFF)) { - printf("%s...", gn->name); - } - if (Lst_Member(pgn->children, (ClientData)gn) == NILLNODE) { - (void)Lst_Append(pgn->children, prevLN, (ClientData)gn); - prevLN = Lst_Succ(prevLN); - (void)Lst_AtEnd(gn->parents, (ClientData)pgn); - pgn->unmade++; - } + if (cp != start) { + /* + * Stuff left over -- add it to the list too + */ + gn = Targ_FindNode(start, TARG_CREATE); + (void)Lst_AtEnd(members, gn); } - Lst_Destroy(members, NOFREE); /* - * Free the result + * Point cp back at the beginning again so the variable value + * can be freed. */ - free(cp); - } - /* - * Now the source is expanded, remove it from the list of children to - * keep it from being processed. - */ - if (DEBUG(SUFF)) { - printf("\n"); + cp = initcp; } - return(1); - } else if (Dir_HasWildcards(cgn->name)) { - Lst explist; /* List of expansions */ /* - * Expand the word along the chosen path + * Add all elements of the members list to the parent node. */ - explist = Lst_Init(FALSE); - Dir_Expand(cgn->name, Suff_FindPath(cgn), explist); - - while (!Lst_IsEmpty(explist)) { - /* - * Fetch next expansion off the list and find its GNode - */ - cp = (char *)Lst_DeQueue(explist); + while(!Lst_IsEmpty(members)) { + gn = (GNode *)Lst_DeQueue(members); if (DEBUG(SUFF)) { - printf("%s...", cp); - } - gn = Targ_FindNode(cp, TARG_CREATE); - - /* - * If gn isn't already a child of the parent, make it so and - * up the parent's count of unmade children. - */ - if (Lst_Member(pgn->children, (ClientData)gn) == NILLNODE) { - (void)Lst_Append(pgn->children, prevLN, (ClientData)gn); - prevLN = Lst_Succ(prevLN); - (void)Lst_AtEnd(gn->parents, (ClientData)pgn); - pgn->unmade++; + fprintf(debug_file, "%s...", gn->name); } + /* Add gn to the parents child list before the original child */ + (void)Lst_InsertBefore(pgn->children, cln, gn); + (void)Lst_AtEnd(gn->parents, pgn); + pgn->unmade++; + /* Expand wildcards on new node */ + SuffExpandWildcards(Lst_Prev(cln), pgn); } + Lst_Destroy(members, NOFREE); /* - * Nuke what's left of the list + * Free the result */ - Lst_Destroy(explist, NOFREE); + free(cp); + } + if (DEBUG(SUFF)) { + fprintf(debug_file, "\n"); + } + /* + * Now the source is expanded, remove it from the list of children to + * keep it from being processed. + */ + pgn->unmade--; + Lst_Remove(pgn->children, cln); + Lst_Remove(cgn->parents, Lst_Member(cgn->parents, pgn)); +} + +static void +SuffExpandWildcards(LstNode cln, GNode *pgn) +{ + GNode *cgn = (GNode *)Lst_Datum(cln); + GNode *gn; /* New source 8) */ + char *cp; /* Expanded value */ + Lst explist; /* List of expansions */ + + if (!Dir_HasWildcards(cgn->name)) + return; + + /* + * Expand the word along the chosen path + */ + explist = Lst_Init(FALSE); + Dir_Expand(cgn->name, Suff_FindPath(cgn), explist); + + while (!Lst_IsEmpty(explist)) { /* - * Now the source is expanded, remove it from the list of children to - * keep it from being processed. + * Fetch next expansion off the list and find its GNode */ + cp = (char *)Lst_DeQueue(explist); + if (DEBUG(SUFF)) { - printf("\n"); + fprintf(debug_file, "%s...", cp); } - return(1); + gn = Targ_FindNode(cp, TARG_CREATE); + + /* Add gn to the parents child list before the original child */ + (void)Lst_InsertBefore(pgn->children, cln, gn); + (void)Lst_AtEnd(gn->parents, pgn); + pgn->unmade++; } - return(0); + /* + * Nuke what's left of the list + */ + Lst_Destroy(explist, NOFREE); + + if (DEBUG(SUFF)) { + fprintf(debug_file, "\n"); + } + + /* + * Now the source is expanded, remove it from the list of children to + * keep it from being processed. + */ + pgn->unmade--; + Lst_Remove(pgn->children, cln); + Lst_Remove(cgn->parents, Lst_Member(cgn->parents, pgn)); } /*- @@ -1712,10 +1744,10 @@ Suff_FindPath(GNode* gn) LstNode ln; sd.len = strlen(gn->name); sd.ename = gn->name + sd.len; - ln = Lst_Find(sufflist, (ClientData)&sd, SuffSuffIsSuffixP); + ln = Lst_Find(sufflist, &sd, SuffSuffIsSuffixP); if (DEBUG(SUFF)) { - printf("Wildcard expanding \"%s\"...", gn->name); + fprintf(debug_file, "Wildcard expanding \"%s\"...", gn->name); } if (ln != NILLNODE) suff = (Suff *)Lst_Datum(ln); @@ -1724,7 +1756,7 @@ Suff_FindPath(GNode* gn) if (suff != NULL) { if (DEBUG(SUFF)) { - printf("suffix is \"%s\"...", suff->name); + fprintf(debug_file, "suffix is \"%s\"...", suff->name); } return suff->searchPath; } else { @@ -1769,15 +1801,15 @@ SuffApplyTransform(GNode *tGn, GNode *sGn, Suff *t, Suff *s) /* * Form the proper links between the target and source. */ - (void)Lst_AtEnd(tGn->children, (ClientData)sGn); - (void)Lst_AtEnd(sGn->parents, (ClientData)tGn); + (void)Lst_AtEnd(tGn->children, sGn); + (void)Lst_AtEnd(sGn->parents, tGn); tGn->unmade += 1; /* * Locate the transformation rule itself */ tname = str_concat(s->name, t->name, 0); - ln = Lst_Find(transforms, (ClientData)tname, SuffGNHasNameP); + ln = Lst_Find(transforms, tname, SuffGNHasNameP); free(tname); if (ln == NILLNODE) { @@ -1792,7 +1824,7 @@ SuffApplyTransform(GNode *tGn, GNode *sGn, Suff *t, Suff *s) gn = (GNode *)Lst_Datum(ln); if (DEBUG(SUFF)) { - printf("\tapplying %s -> %s to \"%s\"\n", s->name, t->name, tGn->name); + fprintf(debug_file, "\tapplying %s -> %s to \"%s\"\n", s->name, t->name, tGn->name); } /* @@ -1808,22 +1840,16 @@ SuffApplyTransform(GNode *tGn, GNode *sGn, Suff *t, Suff *s) /* * Deal with wildcards and variables in any acquired sources */ - ln = Lst_Succ(ln); - while (ln != NILLNODE) { - if (SuffExpandChildren(ln, tGn)) { - nln = Lst_Succ(ln); - tGn->unmade--; - Lst_Remove(tGn->children, ln); - ln = nln; - } else - ln = Lst_Succ(ln); + for (ln = Lst_Succ(ln); ln != NILLNODE; ln = nln) { + nln = Lst_Succ(ln); + SuffExpandChildren(ln, tGn); } /* * Keep track of another parent to which this beast is transformed so * the .IMPSRC variable can be set correctly for the parent. */ - (void)Lst_AtEnd(sGn->iParents, (ClientData)tGn); + (void)Lst_AtEnd(sGn->iParents, tGn); return(TRUE); } @@ -1885,8 +1911,8 @@ SuffFindArchiveDeps(GNode *gn, Lst slst) /* * Create the link between the two nodes right off */ - (void)Lst_AtEnd(gn->children, (ClientData)mem); - (void)Lst_AtEnd(mem->parents, (ClientData)gn); + (void)Lst_AtEnd(gn->children, mem); + (void)Lst_AtEnd(mem->parents, gn); gn->unmade += 1; /* @@ -1906,7 +1932,7 @@ SuffFindArchiveDeps(GNode *gn, Lst slst) * Didn't know what it was -- use .NULL suffix if not in make mode */ if (DEBUG(SUFF)) { - printf("using null suffix\n"); + fprintf(debug_file, "using null suffix\n"); } ms = suffNull; } @@ -1942,7 +1968,7 @@ SuffFindArchiveDeps(GNode *gn, Lst slst) if (!SuffApplyTransform(gn, mem, (Suff *)Lst_Datum(ln), ms) && DEBUG(SUFF)) { - printf("\tNo transformation from %s -> %s\n", + fprintf(debug_file, "\tNo transformation from %s -> %s\n", ms->name, ((Suff *)Lst_Datum(ln))->name); } } @@ -2074,7 +2100,7 @@ SuffFindNormalDeps(GNode *gn, Lst slst) /* * Record the target so we can nuke it */ - (void)Lst_AtEnd(targs, (ClientData)targ); + (void)Lst_AtEnd(targs, targ); /* * Search from this suffix's successor... @@ -2088,7 +2114,7 @@ SuffFindNormalDeps(GNode *gn, Lst slst) */ if (Lst_IsEmpty(targs) && suffNull != NULL) { if (DEBUG(SUFF)) { - printf("\tNo known suffix on %s. Using .NULL suffix\n", gn->name); + fprintf(debug_file, "\tNo known suffix on %s. Using .NULL suffix\n", gn->name); } targ = emalloc(sizeof(Src)); @@ -2113,13 +2139,13 @@ SuffFindNormalDeps(GNode *gn, Lst slst) SuffAddLevel(srcs, targ); else { if (DEBUG(SUFF)) - printf("not "); + fprintf(debug_file, "not "); } if (DEBUG(SUFF)) - printf("adding suffix rules\n"); + fprintf(debug_file, "adding suffix rules\n"); - (void)Lst_AtEnd(targs, (ClientData)targ); + (void)Lst_AtEnd(targs, targ); } /* @@ -2156,20 +2182,14 @@ SuffFindNormalDeps(GNode *gn, Lst slst) * Now we've got the important local variables set, expand any sources * that still contain variables or wildcards in their names. */ - ln = Lst_First(gn->children); - while (ln != NILLNODE) { - if (SuffExpandChildren(ln, gn)) { - nln = Lst_Succ(ln); - gn->unmade--; - Lst_Remove(gn->children, ln); - ln = nln; - } else - ln = Lst_Succ(ln); + for (ln = Lst_First(gn->children); ln != NILLNODE; ln = nln) { + nln = Lst_Succ(ln); + SuffExpandChildren(ln, gn); } if (targ == NULL) { if (DEBUG(SUFF)) { - printf("\tNo valid suffix on %s\n", gn->name); + fprintf(debug_file, "\tNo valid suffix on %s\n", gn->name); } sfnd_abort: @@ -2254,8 +2274,8 @@ sfnd_abort: * up to, but not including, the parent node. */ while (bottom && bottom->parent != NULL) { - if (Lst_Member(slst, (ClientData) bottom) == NILLNODE) { - Lst_AtEnd(slst, (ClientData) bottom); + if (Lst_Member(slst, bottom) == NILLNODE) { + Lst_AtEnd(slst, bottom); } bottom = bottom->parent; } @@ -2330,8 +2350,8 @@ sfnd_abort: */ sfnd_return: if (bottom) - if (Lst_Member(slst, (ClientData) bottom) == NILLNODE) - Lst_AtEnd(slst, (ClientData) bottom); + if (Lst_Member(slst, bottom) == NILLNODE) + Lst_AtEnd(slst, bottom); while (SuffRemoveSrc(srcs) || SuffRemoveSrc(targs)) continue; @@ -2398,7 +2418,7 @@ SuffFindDeps(GNode *gn, Lst slst) } if (DEBUG(SUFF)) { - printf("SuffFindDeps (%s)\n", gn->name); + fprintf(debug_file, "SuffFindDeps (%s)\n", gn->name); } if (gn->type & OP_ARCHV) { @@ -2415,7 +2435,7 @@ SuffFindDeps(GNode *gn, Lst slst) LstNode ln; Suff *s; - ln = Lst_Find(sufflist, (ClientData)UNCONST(LIBSUFF), + ln = Lst_Find(sufflist, UNCONST(LIBSUFF), SuffSuffHasNameP); if (gn->suffix) gn->suffix->refCount--; @@ -2464,7 +2484,7 @@ Suff_SetNull(char *name) Suff *s; LstNode ln; - ln = Lst_Find(sufflist, (ClientData)name, SuffSuffHasNameP); + ln = Lst_Find(sufflist, name, SuffSuffHasNameP); if (ln != NILLNODE) { s = (Suff *)Lst_Datum(ln); if (suffNull != NULL) { @@ -2556,7 +2576,7 @@ Suff_End(void) static int SuffPrintName(ClientData s, ClientData dummy) { - printf("%s ", ((Suff *)s)->name); + fprintf(debug_file, "%s ", ((Suff *)s)->name); return (dummy ? 0 : 0); } @@ -2567,38 +2587,38 @@ SuffPrintSuff(ClientData sp, ClientData dummy) int flags; int flag; - printf("# `%s' [%d] ", s->name, s->refCount); + fprintf(debug_file, "# `%s' [%d] ", s->name, s->refCount); flags = s->flags; if (flags) { - fputs(" (", stdout); + fputs(" (", debug_file); while (flags) { flag = 1 << (ffs(flags) - 1); flags &= ~flag; switch (flag) { case SUFF_NULL: - printf("NULL"); + fprintf(debug_file, "NULL"); break; case SUFF_INCLUDE: - printf("INCLUDE"); + fprintf(debug_file, "INCLUDE"); break; case SUFF_LIBRARY: - printf("LIBRARY"); + fprintf(debug_file, "LIBRARY"); break; } - fputc(flags ? '|' : ')', stdout); + fputc(flags ? '|' : ')', debug_file); } } - fputc('\n', stdout); - printf("#\tTo: "); - Lst_ForEach(s->parents, SuffPrintName, (ClientData)0); - fputc('\n', stdout); - printf("#\tFrom: "); - Lst_ForEach(s->children, SuffPrintName, (ClientData)0); - fputc('\n', stdout); - printf("#\tSearch Path: "); + fputc('\n', debug_file); + fprintf(debug_file, "#\tTo: "); + Lst_ForEach(s->parents, SuffPrintName, NULL); + fputc('\n', debug_file); + fprintf(debug_file, "#\tFrom: "); + Lst_ForEach(s->children, SuffPrintName, NULL); + fputc('\n', debug_file); + fprintf(debug_file, "#\tSearch Path: "); Dir_PrintPath(s->searchPath); - fputc('\n', stdout); + fputc('\n', debug_file); return (dummy ? 0 : 0); } @@ -2607,20 +2627,20 @@ SuffPrintTrans(ClientData tp, ClientData dummy) { GNode *t = (GNode *)tp; - printf("%-16s: ", t->name); + fprintf(debug_file, "%-16s: ", t->name); Targ_PrintType(t->type); - fputc('\n', stdout); - Lst_ForEach(t->commands, Targ_PrintCmd, (ClientData)0); - fputc('\n', stdout); + fputc('\n', debug_file); + Lst_ForEach(t->commands, Targ_PrintCmd, NULL); + fputc('\n', debug_file); return(dummy ? 0 : 0); } void Suff_PrintAll(void) { - printf("#*** Suffixes:\n"); - Lst_ForEach(sufflist, SuffPrintSuff, (ClientData)0); + fprintf(debug_file, "#*** Suffixes:\n"); + Lst_ForEach(sufflist, SuffPrintSuff, NULL); - printf("#*** Transformations:\n"); - Lst_ForEach(transforms, SuffPrintTrans, (ClientData)0); + fprintf(debug_file, "#*** Transformations:\n"); + Lst_ForEach(transforms, SuffPrintTrans, NULL); } diff --git a/devel/bmake/files/targ.c b/devel/bmake/files/targ.c index 3d8606885cb..18e1ce545fd 100644 --- a/devel/bmake/files/targ.c +++ b/devel/bmake/files/targ.c @@ -1,4 +1,4 @@ -/* $NetBSD: targ.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: targ.c,v 1.1.1.2 2008/03/09 19:39:34 joerg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: targ.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: targ.c,v 1.1.1.2 2008/03/09 19:39:34 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: targ.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: targ.c,v 1.1.1.2 2008/03/09 19:39:34 joerg Exp $"); #endif #endif /* not lint */ #endif @@ -118,6 +118,11 @@ __RCSID("$NetBSD: targ.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); * Targ_Precious Return TRUE if the target is precious and * should not be removed if we are interrupted. * + * Targ_Propagate Propagate information between related + * nodes. Should be called after the + * makefiles are parsed but before any + * action is taken. + * * Debugging: * Targ_PrintGraph Print out the entire graphm all variables * and statistics for the directory cache. Should @@ -141,7 +146,6 @@ static Hash_Table targets; /* a hash table of same */ static int TargPrintOnlySrc(ClientData, ClientData); static int TargPrintName(ClientData, ClientData); -static int TargPrintNode(ClientData, ClientData); #ifdef CLEANUP static void TargFreeGN(ClientData); #endif @@ -240,17 +244,18 @@ Targ_NewGN(const char *name) } gn->unmade = 0; gn->unmade_cohorts = 0; + gn->cohort_num[0] = 0; gn->centurion = NULL; gn->made = UNMADE; gn->flags = 0; - gn->order = 0; + gn->checked = 0; gn->mtime = gn->cmtime = 0; gn->iParents = Lst_Init(FALSE); gn->cohorts = Lst_Init(FALSE); gn->parents = Lst_Init(FALSE); gn->children = Lst_Init(FALSE); - gn->successors = Lst_Init(FALSE); - gn->preds = Lst_Init(FALSE); + gn->order_pred = Lst_Init(FALSE); + gn->order_succ = Lst_Init(FALSE); Hash_InitTable(&gn->context, 0); gn->commands = Lst_Init(FALSE); gn->suffix = NULL; @@ -260,7 +265,7 @@ Targ_NewGN(const char *name) #ifdef CLEANUP if (allGNs == NULL) allGNs = Lst_Init(FALSE); - Lst_AtEnd(allGNs, (ClientData) gn); + Lst_AtEnd(allGNs, gn); #endif return (gn); @@ -290,15 +295,14 @@ TargFreeGN(ClientData gnp) free(gn->uname); if (gn->path) free(gn->path); - if (gn->fname) - free(gn->fname); + /* gn->fname points to name allocated when file was opened, don't free */ Lst_Destroy(gn->iParents, NOFREE); Lst_Destroy(gn->cohorts, NOFREE); Lst_Destroy(gn->parents, NOFREE); Lst_Destroy(gn->children, NOFREE); - Lst_Destroy(gn->successors, NOFREE); - Lst_Destroy(gn->preds, NOFREE); + Lst_Destroy(gn->order_succ, NOFREE); + Lst_Destroy(gn->order_pred, NOFREE); Hash_DeleteTable(&gn->context); Lst_Destroy(gn->commands, NOFREE); free(gn); @@ -329,28 +333,31 @@ GNode * Targ_FindNode(const char *name, int flags) { GNode *gn; /* node in that element */ - Hash_Entry *he; /* New or used hash entry for node */ + Hash_Entry *he = NULL; /* New or used hash entry for node */ Boolean isNew; /* Set TRUE if Hash_CreateEntry had to create */ /* an entry for the node */ - - if (flags & TARG_CREATE) { - he = Hash_CreateEntry(&targets, name, &isNew); - if (isNew) { - gn = Targ_NewGN(name); - Hash_SetValue(he, gn); - Var_Append(".ALLTARGETS", name, VAR_GLOBAL); - (void)Lst_AtEnd(allTargets, (ClientData)gn); - } - } else { + if (!(flags & (TARG_CREATE | TARG_NOHASH))) { he = Hash_FindEntry(&targets, name); + if (he == NULL) + return (NILGNODE); + return (GNode *)Hash_GetValue(he); } - if (he == NULL) { - return (NILGNODE); - } else { - return ((GNode *)Hash_GetValue(he)); + if (!(flags & TARG_NOHASH)) { + he = Hash_CreateEntry(&targets, name, &isNew); + if (!isNew) + return (GNode *)Hash_GetValue(he); } + + gn = Targ_NewGN(name); + if (!(flags & TARG_NOHASH)) + Hash_SetValue(he, gn); + Var_Append(".ALLTARGETS", name, VAR_GLOBAL); + (void)Lst_AtEnd(allTargets, gn); + if (doing_depend) + gn->flags |= FROM_DEPEND; + return gn; } /*- @@ -394,7 +401,7 @@ Targ_FindList(Lst names, int flags) * are added to the list in the order in which they were * encountered in the makefile. */ - (void)Lst_AtEnd(nodes, (ClientData)gn); + (void)Lst_AtEnd(nodes, gn); } else if (flags == TARG_NOCREATE) { Error("\"%s\" -- target unknown.", name); } @@ -504,28 +511,20 @@ Targ_SetMain(GNode *gn) } static int -TargPrintName(ClientData gnp, ClientData ppath) +TargPrintName(ClientData gnp, ClientData pflags __unused) { GNode *gn = (GNode *)gnp; - printf("%s ", gn->name); -#ifdef notdef - if (ppath) { - if (gn->path) { - printf("[%s] ", gn->path); - } - if (gn == mainTarg) { - printf("(MAIN NAME) "); - } - } -#endif /* notdef */ - return (ppath ? 0 : 0); + + fprintf(debug_file, "%s%s ", gn->name, gn->cohort_num); + + return 0; } int Targ_PrintCmd(ClientData cmd, ClientData dummy) { - printf("\t%s\n", (char *)cmd); + fprintf(debug_file, "\t%s\n", (char *)cmd); return (dummy ? 0 : 0); } @@ -571,8 +570,8 @@ Targ_PrintType(int type) { int tbit; -#define PRINTBIT(attr) case CONCAT(OP_,attr): printf("." #attr " "); break -#define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG))printf("." #attr " "); break +#define PRINTBIT(attr) case CONCAT(OP_,attr): fprintf(debug_file, "." #attr " "); break +#define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG))fprintf(debug_file, "." #attr " "); break type &= ~OP_OPMASK; @@ -593,7 +592,7 @@ Targ_PrintType(int type) PRINTBIT(NOTMAIN); PRINTDBIT(LIB); /*XXX: MEMBER is defined, so CONCAT(OP_,MEMBER) gives OP_"%" */ - case OP_MEMBER: if (DEBUG(TARG))printf(".MEMBER "); break; + case OP_MEMBER: if (DEBUG(TARG))fprintf(debug_file, ".MEMBER "); break; PRINTDBIT(ARCHV); PRINTDBIT(MADE); PRINTDBIT(PHONY); @@ -601,74 +600,103 @@ Targ_PrintType(int type) } } +static const char * +made_name(enum enum_made made) +{ + switch (made) { + case UNMADE: return "unmade"; + case DEFERRED: return "deferred"; + case REQUESTED: return "requested"; + case BEINGMADE: return "being made"; + case MADE: return "made"; + case UPTODATE: return "up-to-date"; + case ERROR: return "error when made"; + case ABORTED: return "aborted"; + default: return "unknown enum_made value"; + } +} + /*- *----------------------------------------------------------------------- * TargPrintNode -- * print the contents of a node *----------------------------------------------------------------------- */ -static int -TargPrintNode(ClientData gnp, ClientData passp) +int +Targ_PrintNode(ClientData gnp, ClientData passp) { GNode *gn = (GNode *)gnp; - int pass = *(int *)passp; + int pass = passp ? *(int *)passp : 0; + + fprintf(debug_file, "# %s%s, flags %x, type %x, made %d\n", + gn->name, gn->cohort_num, gn->flags, gn->type, gn->made); + if (gn->flags == 0) + return 0; + if (!OP_NOP(gn->type)) { - printf("#\n"); + fprintf(debug_file, "#\n"); if (gn == mainTarg) { - printf("# *** MAIN TARGET ***\n"); + fprintf(debug_file, "# *** MAIN TARGET ***\n"); } - if (pass == 2) { + if (pass >= 2) { if (gn->unmade) { - printf("# %d unmade children\n", gn->unmade); + fprintf(debug_file, "# %d unmade children\n", gn->unmade); } else { - printf("# No unmade children\n"); + fprintf(debug_file, "# No unmade children\n"); } if (! (gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC))) { if (gn->mtime != 0) { - printf("# last modified %s: %s\n", + fprintf(debug_file, "# last modified %s: %s\n", Targ_FmtTime(gn->mtime), - (gn->made == UNMADE ? "unmade" : - (gn->made == MADE ? "made" : - (gn->made == UPTODATE ? "up-to-date" : - "error when made")))); + made_name(gn->made)); } else if (gn->made != UNMADE) { - printf("# non-existent (maybe): %s\n", - (gn->made == MADE ? "made" : - (gn->made == UPTODATE ? "up-to-date" : - (gn->made == ERROR ? "error when made" : - "aborted")))); + fprintf(debug_file, "# non-existent (maybe): %s\n", + made_name(gn->made)); } else { - printf("# unmade\n"); + fprintf(debug_file, "# unmade\n"); } } if (!Lst_IsEmpty (gn->iParents)) { - printf("# implicit parents: "); - Lst_ForEach(gn->iParents, TargPrintName, (ClientData)0); - fputc('\n', stdout); + fprintf(debug_file, "# implicit parents: "); + Lst_ForEach(gn->iParents, TargPrintName, NULL); + fprintf(debug_file, "\n"); } + } else { + if (gn->unmade) + fprintf(debug_file, "# %d unmade children\n", gn->unmade); } if (!Lst_IsEmpty (gn->parents)) { - printf("# parents: "); - Lst_ForEach(gn->parents, TargPrintName, (ClientData)0); - fputc('\n', stdout); + fprintf(debug_file, "# parents: "); + Lst_ForEach(gn->parents, TargPrintName, NULL); + fprintf(debug_file, "\n"); + } + if (!Lst_IsEmpty (gn->order_pred)) { + fprintf(debug_file, "# order_pred: "); + Lst_ForEach(gn->order_pred, TargPrintName, NULL); + fprintf(debug_file, "\n"); + } + if (!Lst_IsEmpty (gn->order_succ)) { + fprintf(debug_file, "# order_succ: "); + Lst_ForEach(gn->order_succ, TargPrintName, NULL); + fprintf(debug_file, "\n"); } - printf("%-16s", gn->name); + fprintf(debug_file, "%-16s", gn->name); switch (gn->type & OP_OPMASK) { case OP_DEPENDS: - printf(": "); break; + fprintf(debug_file, ": "); break; case OP_FORCE: - printf("! "); break; + fprintf(debug_file, "! "); break; case OP_DOUBLEDEP: - printf(":: "); break; + fprintf(debug_file, ":: "); break; } Targ_PrintType(gn->type); - Lst_ForEach(gn->children, TargPrintName, (ClientData)0); - fputc('\n', stdout); - Lst_ForEach(gn->commands, Targ_PrintCmd, (ClientData)0); - printf("\n\n"); + Lst_ForEach(gn->children, TargPrintName, NULL); + fprintf(debug_file, "\n"); + Lst_ForEach(gn->commands, Targ_PrintCmd, NULL); + fprintf(debug_file, "\n\n"); if (gn->type & OP_DOUBLEDEP) { - Lst_ForEach(gn->cohorts, TargPrintNode, (ClientData)&pass); + Lst_ForEach(gn->cohorts, Targ_PrintNode, &pass); } } return (0); @@ -688,13 +716,18 @@ TargPrintNode(ClientData gnp, ClientData passp) *----------------------------------------------------------------------- */ static int -TargPrintOnlySrc(ClientData gnp, ClientData dummy) +TargPrintOnlySrc(ClientData gnp, ClientData dummy __unused) { GNode *gn = (GNode *)gnp; - if (OP_NOP(gn->type)) - printf("#\t%s [%s]\n", gn->name, gn->path ? gn->path : gn->name); + if (!OP_NOP(gn->type)) + return 0; - return (dummy ? 0 : 0); + fprintf(debug_file, "#\t%s [%s] ", + gn->name, gn->path ? gn->path : gn->name); + Targ_PrintType(gn->type); + fprintf(debug_file, "\n"); + + return 0; } /*- @@ -716,42 +749,99 @@ TargPrintOnlySrc(ClientData gnp, ClientData dummy) void Targ_PrintGraph(int pass) { - printf("#*** Input graph:\n"); - Lst_ForEach(allTargets, TargPrintNode, (ClientData)&pass); - printf("\n\n"); - printf("#\n# Files that are only sources:\n"); - Lst_ForEach(allTargets, TargPrintOnlySrc, (ClientData) 0); - printf("#*** Global Variables:\n"); + fprintf(debug_file, "#*** Input graph:\n"); + Lst_ForEach(allTargets, Targ_PrintNode, &pass); + fprintf(debug_file, "\n\n"); + fprintf(debug_file, "#\n# Files that are only sources:\n"); + Lst_ForEach(allTargets, TargPrintOnlySrc, NULL); + fprintf(debug_file, "#*** Global Variables:\n"); Var_Dump(VAR_GLOBAL); - printf("#*** Command-line Variables:\n"); + fprintf(debug_file, "#*** Command-line Variables:\n"); Var_Dump(VAR_CMD); - printf("\n"); + fprintf(debug_file, "\n"); Dir_PrintDirectories(); - printf("\n"); + fprintf(debug_file, "\n"); Suff_PrintAll(); } +/*- + *----------------------------------------------------------------------- + * TargPropagateNode -- + * Propagate information from a single node to related nodes if + * appropriate. + * + * Input: + * gnp The node that we are processing. + * + * Results: + * Always returns 0, for the benefit of Lst_ForEach(). + * + * Side Effects: + * Information is propagated from this node to cohort or child + * nodes. + * + * If the node was defined with "::", then TargPropagateCohort() + * will be called for each cohort node. + * + * If the node has recursive predecessors, then + * TargPropagateRecpred() will be called for each recursive + * predecessor. + *----------------------------------------------------------------------- + */ static int -TargPropagateCohort(ClientData cgnp, ClientData pgnp) +TargPropagateNode(ClientData gnp, ClientData junk __unused) { - GNode *cgn = (GNode *)cgnp; - GNode *pgn = (GNode *)pgnp; + GNode *gn = (GNode *)gnp; - cgn->type |= pgn->type & ~OP_OPMASK; + if (gn->type & OP_DOUBLEDEP) + Lst_ForEach(gn->cohorts, TargPropagateCohort, gnp); return (0); } +/*- + *----------------------------------------------------------------------- + * TargPropagateCohort -- + * Propagate some bits in the type mask from a node to + * a related cohort node. + * + * Input: + * cnp The node that we are processing. + * gnp Another node that has cnp as a cohort. + * + * Results: + * Always returns 0, for the benefit of Lst_ForEach(). + * + * Side Effects: + * cnp's type bitmask is modified to incorporate some of the + * bits from gnp's type bitmask. (XXX need a better explanation.) + *----------------------------------------------------------------------- + */ static int -TargPropagateNode(ClientData gnp, ClientData junk __unused) +TargPropagateCohort(ClientData cgnp, ClientData pgnp) { - GNode *gn = (GNode *)gnp; - if (gn->type & OP_DOUBLEDEP) - Lst_ForEach(gn->cohorts, TargPropagateCohort, gnp); + GNode *cgn = (GNode *)cgnp; + GNode *pgn = (GNode *)pgnp; + + cgn->type |= pgn->type & ~OP_OPMASK; return (0); } +/*- + *----------------------------------------------------------------------- + * Targ_Propagate -- + * Propagate information between related nodes. Should be called + * after the makefiles are parsed but before any action is taken. + * + * Results: + * none + * + * Side Effects: + * Information is propagated between related nodes throughout the + * graph. + *----------------------------------------------------------------------- + */ void Targ_Propagate(void) { - Lst_ForEach(allTargets, TargPropagateNode, (ClientData)0); + Lst_ForEach(allTargets, TargPropagateNode, NULL); } diff --git a/devel/bmake/files/trace.c b/devel/bmake/files/trace.c index bc5b91eb9ec..37992f5508b 100644 --- a/devel/bmake/files/trace.c +++ b/devel/bmake/files/trace.c @@ -1,4 +1,4 @@ -/* $NetBSD: trace.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: trace.c,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -38,11 +38,11 @@ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: trace.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: trace.c,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $"; #else #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: trace.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: trace.c,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $"); #endif /* not lint */ #endif @@ -103,9 +103,9 @@ Trace_Log(TrEvent event, Job *job) gettimeofday(&rightnow, NULL); - fprintf(trfile, "%ld.%06d %d %d %s %d %s", + fprintf(trfile, "%ld.%06d %d %s %d %s", rightnow.tv_sec, (int)rightnow.tv_usec, - jobTokensRunning, jobTokensFree, + jobTokensRunning, evname[event], trpid, trwd); if (job != NULL) { fprintf(trfile, " %s %d %x %x", job->node->name, diff --git a/devel/bmake/files/trace.h b/devel/bmake/files/trace.h index 0f1acc9787f..3391c068de9 100644 --- a/devel/bmake/files/trace.h +++ b/devel/bmake/files/trace.h @@ -1,4 +1,4 @@ -/* $NetBSD: trace.h,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: trace.h,v 1.1.1.2 2008/03/09 19:39:33 joerg Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. diff --git a/devel/bmake/files/unit-tests/Makefile.in b/devel/bmake/files/unit-tests/Makefile.in index d24ff7838bb..b28e2a97b6f 100644 --- a/devel/bmake/files/unit-tests/Makefile.in +++ b/devel/bmake/files/unit-tests/Makefile.in @@ -1,6 +1,6 @@ -# $Id: Makefile.in,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ +# $Id: Makefile.in,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ # -# $NetBSD: Makefile.in,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ +# $NetBSD: Makefile.in,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ # # Unit tests for make(1) # The main targets are: @@ -25,7 +25,12 @@ UNIT_TESTS:= ${srcdir} SUBFILES= \ comment \ cond1 \ + export \ + export-all \ + dotwait \ + moderrs \ modmatch \ + modmisc \ modorder \ modts \ modword \ @@ -37,6 +42,7 @@ all: ${SUBFILES} # the tests are actually done with sub-makes. .PHONY: ${SUBFILES} +.PRECIOUS: ${SUBFILES} ${SUBFILES}: -@${.MAKE} -k -f ${UNIT_TESTS}/$@ @@ -55,10 +61,10 @@ TEST_MAKE?= ${.MAKE} test: @echo "${TEST_MAKE} -f ${MAKEFILE} > ${.TARGET}.out 2>&1" @cd ${.OBJDIR} && ${TEST_MAKE} -f ${MAKEFILE} 2>&1 | \ - sed -e 's,^${TEST_MAKE:T}:,make:,' \ + sed -e 's,^${TEST_MAKE:T:C/\./\\\./g}:,make:,' \ -e '/stopped/s, /.*, unit-tests,' \ - -e 's,${.CURDIR}/,,g' \ - -e 's,${UNIT_TESTS}/,,g' > ${.TARGET}.out || { \ + -e 's,${.CURDIR:C/\./\\\./g}/,,g' \ + -e 's,${UNIT_TESTS:C/\./\\\./g}/,,g' > ${.TARGET}.out || { \ tail ${.TARGET}.out; mv ${.TARGET}.out ${.TARGET}.fail; exit 1; } diff @diff_u@ ${UNIT_TESTS}/${.TARGET}.exp ${.TARGET}.out diff --git a/devel/bmake/files/unit-tests/dotwait b/devel/bmake/files/unit-tests/dotwait new file mode 100644 index 00000000000..8ae49950bf8 --- /dev/null +++ b/devel/bmake/files/unit-tests/dotwait @@ -0,0 +1,61 @@ +# $NetBSD: dotwait,v 1.1.1.1 2008/03/09 19:39:35 joerg Exp $ + +THISMAKEFILE:= ${.PARSEDIR}/${.PARSEFILE} + +TESTS= simple recursive shared cycle +PAUSE= sleep 1 + +# Use a .for loop rather than dependencies here, to ensure +# that the tests are run one by one, with parallelism +# only within tests. +# Ignore "--- target ---" lines printed by parallel make. +all: +.for t in ${TESTS} + @${.MAKE} -f ${THISMAKEFILE} -j4 $t | grep -v "^--- " +.endfor + +# +# Within each test, the names of the sub-targets follow these +# conventions: +# * If it's expected that two or more targets may be made in parallel, +# then the target names will differ only in an alphabetic component +# such as ".a" or ".b". +# * If it's expected that two or more targets should be made in sequence +# then the target names will differ in numeric components, such that +# lexical ordering of the target names matches the expected order +# in which the targets should be made. +# +# Targets may echo ${PARALLEL_TARG} to print a modified version +# of their own name, in which alphabetic components like ".a" or ".b" +# are converted to ".*". Two targets that are expected to +# be made in parallel will thus print the same strings, so that the +# output is independent of the order in which these targets are made. +# +PARALLEL_TARG= ${.TARGET:C/\.[a-z]/.*/g:Q} +.DEFAULT: + @echo ${PARALLEL_TARG}; ${PAUSE}; echo ${PARALLEL_TARG} +_ECHOUSE: .USE + @echo ${PARALLEL_TARG}; ${PAUSE}; echo ${PARALLEL_TARG} + +# simple: no recursion, no cycles +simple: simple.1 .WAIT simple.2 + +# recursive: all children of the left hand side of the .WAIT +# must be made before any child of the right hand side. +recursive: recursive.1.99 .WAIT recursive.2.99 +recursive.1.99: recursive.1.1.a recursive.1.1.b _ECHOUSE +recursive.2.99: recursive.2.1.a recursive.2.1.b _ECHOUSE + +# shared: both shared.1.99 and shared.2.99 depend on shared.0. +# shared.0 must be made first, even though it is a child of +# the right hand side of the .WAIT. +shared: shared.1.99 .WAIT shared.2.99 +shared.1.99: shared.0 _ECHOUSE +shared.2.99: shared.2.1 shared.0 _ECHOUSE + +# cycle: the cyclic dependency must not cause infinite recursion +# leading to stack overflow and a crash. +cycle: cycle.1.99 .WAIT cycle.2.99 +cycle.2.99: cycle.2.98 _ECHOUSE +cycle.2.98: cycle.2.97 _ECHOUSE +cycle.2.97: cycle.2.99 _ECHOUSE diff --git a/devel/bmake/files/unit-tests/export b/devel/bmake/files/unit-tests/export new file mode 100644 index 00000000000..1b34677a626 --- /dev/null +++ b/devel/bmake/files/unit-tests/export @@ -0,0 +1,22 @@ +# $Id: export,v 1.1.1.1 2008/03/09 19:39:35 joerg Exp $ + +UT_TEST=export +UT_FOO=foo${BAR} +UT_FU=fubar +UT_ZOO=hoopie +UT_NO=all +# belive it or not, we expect this one to come out with $UT_FU unexpanded. +UT_DOLLAR= This is $$UT_FU + +.export UT_FU UT_FOO +.export UT_DOLLAR +# this one will be ignored +.export .MAKE.PID + +BAR=bar is ${UT_FU} + +.MAKE.EXPORTED+= UT_ZOO UT_TEST + +all: + @env | grep '^UT_' | sort + diff --git a/devel/bmake/files/unit-tests/export-all b/devel/bmake/files/unit-tests/export-all new file mode 100644 index 00000000000..14d394ce2c9 --- /dev/null +++ b/devel/bmake/files/unit-tests/export-all @@ -0,0 +1,11 @@ +# $Id: export-all,v 1.1.1.1 2008/03/09 19:39:35 joerg Exp $ + +UT_OK=good +UT_F=fine + +.export + +.include "export" + +UT_TEST=export-all +UT_ALL=even this gets exported diff --git a/devel/bmake/files/unit-tests/moderrs b/devel/bmake/files/unit-tests/moderrs new file mode 100644 index 00000000000..f9c28d91bf6 --- /dev/null +++ b/devel/bmake/files/unit-tests/moderrs @@ -0,0 +1,31 @@ +# $Id: moderrs,v 1.1.1.1 2008/03/09 19:39:35 joerg Exp $ +# +# various modifier error tests + +VAR=TheVariable +# incase we have to change it ;-) +MOD_UNKN=Z +MOD_TERM=S,V,v +MOD_S:= ${MOD_TERM}, + +all: modunkn modunknV varterm vartermV modtermV + +modunkn: + @echo "Expect: Unknown modifier 'Z'" + @echo "VAR:Z=${VAR:Z}" + +modunknV: + @echo "Expect: Unknown modifier 'Z'" + @echo "VAR:${MOD_UNKN}=${VAR:${MOD_UNKN}}" + +varterm: + @echo "Expect: Unclosed variable specification for VAR" + @echo VAR:S,V,v,=${VAR:S,V,v, + +vartermV: + @echo "Expect: Unclosed variable specification for VAR" + @echo VAR:${MOD_TERM},=${VAR:${MOD_S} + +modtermV: + @echo "Expect: Unclosed substitution for VAR (, missing)" + -@echo "VAR:${MOD_TERM}=${VAR:${MOD_TERM}}" diff --git a/devel/bmake/files/unit-tests/modmisc b/devel/bmake/files/unit-tests/modmisc new file mode 100644 index 00000000000..98daa95a998 --- /dev/null +++ b/devel/bmake/files/unit-tests/modmisc @@ -0,0 +1,33 @@ +# $Id: modmisc,v 1.1.1.1 2008/03/09 19:39:35 joerg Exp $ +# +# miscellaneous modifier tests + +path=:/bin:/usr/bin::/sbin:/usr/sbin:.:/home/user/bin:. +# strip cwd from path. +MOD_NODOT=S/:/ /g:N.:ts: +# and decorate, note that $'s need to be doubled. Also note that +# the modifier_variable can be used with other modifiers. +MOD_NODOTX=S/:/ /g:N.:@d@'$$d'@ +# another mod - pretend it is more interesting +MOD_HOMES=S,/home/,/homes/, +MOD_OPT=@d@$${exists($$d):?$$d:$${d:S,/usr,/opt,}}@ +MOD_SEP=S,:, ,g + +all: modvar modvarloop + +modvar: + @echo "path='${path}'" + @echo "path='${path:${MOD_NODOT}}'" + @echo "path='${path:S,home,homes,:${MOD_NODOT}}'" + @echo "path=${path:${MOD_NODOTX}:ts:}" + @echo "path=${path:${MOD_HOMES}:${MOD_NODOTX}:ts:}" + +.for d in ${path:${MOD_SEP}:N.} /usr/xbin +path_$d?= ${d:${MOD_OPT}:${MOD_HOMES}}/ +paths+= ${d:${MOD_OPT}:${MOD_HOMES}} +.endfor + +modvarloop: + @echo "path_/usr/xbin=${path_/usr/xbin}" + @echo "paths=${paths}" + @echo "PATHS=${paths:tu}" diff --git a/devel/bmake/files/unit-tests/modorder b/devel/bmake/files/unit-tests/modorder index 276fa9eccfa..c4310b44c7f 100644 --- a/devel/bmake/files/unit-tests/modorder +++ b/devel/bmake/files/unit-tests/modorder @@ -1,6 +1,6 @@ -# $NetBSD: modorder,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ +# $NetBSD: modorder,v 1.1.1.2 2008/03/09 19:39:35 joerg Exp $ -LIST= one two three four five six seven eigth nine ten +LIST= one two three four five six seven eight nine ten LISTX= ${LIST:Ox} LISTSX:= ${LIST:Ox} TEST_RESULT= && echo Ok || echo Failed diff --git a/devel/bmake/files/unit-tests/test.exp b/devel/bmake/files/unit-tests/test.exp index c21619bca86..3433f838042 100644 --- a/devel/bmake/files/unit-tests/test.exp +++ b/devel/bmake/files/unit-tests/test.exp @@ -20,6 +20,64 @@ Passed: 4 is not prime 5 is prime +UT_DOLLAR=This is $UT_FU +UT_FOO=foobar is fubar +UT_FU=fubar +UT_TEST=export +UT_ZOO=hoopie +UT_ALL=even this gets exported +UT_DOLLAR=This is $UT_FU +UT_F=fine +UT_FOO=foobar is fubar +UT_FU=fubar +UT_NO=all +UT_OK=good +UT_TEST=export-all +UT_ZOO=hoopie +simple.1 +simple.1 +simple.2 +simple.2 +recursive.1.1.* +recursive.1.1.* +recursive.1.1.* +recursive.1.1.* +recursive.1.99 +recursive.1.99 +recursive.2.1.* +recursive.2.1.* +recursive.2.1.* +recursive.2.1.* +recursive.2.99 +recursive.2.99 +shared.0 +shared.0 +shared.1.99 +shared.1.99 +shared.2.1 +shared.2.1 +shared.2.99 +shared.2.99 +make: Graph cycles through `cycle.2.99' +make: Graph cycles through `cycle.2.98' +make: Graph cycles through `cycle.2.97' +cycle.1.99 +cycle.1.99 +Expect: Unknown modifier 'Z' +make: Unknown modifier 'Z' +VAR:Z= +Expect: Unknown modifier 'Z' +make: Unknown modifier 'Z' +VAR:Z= +Expect: Unclosed variable specification for VAR +make: Unclosed variable specification for VAR +VAR:S,V,v,=Thevariable +Expect: Unclosed variable specification for VAR +make: Unclosed variable specification for VAR +VAR:S,V,v,=Thevariable +Expect: Unclosed substitution for VAR (, missing) +make: Unclosed substitution for VAR (, missing) +VAR:S,V,v= LIB=a X_LIBS:M${LIB${LIB:tu}} is "/tmp/liba.a" LIB=a X_LIBS:M*/lib${LIB}.a is "/tmp/liba.a" LIB=a X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBA.A" @@ -35,12 +93,16 @@ LIB=d X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBD.A" LIB=e X_LIBS:M${LIB${LIB:tu}} is "/tmp/libe.a" LIB=e X_LIBS:M*/lib${LIB}.a is "/tmp/libe.a" LIB=e X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBE.A" -LIST = one two three four five six seven eigth nine ten -LIST:O = eigth five four nine one seven six ten three two -# Note that 1 in every 10! trials two independently generated -# randomized orderings will be the same. The test framework doesn't -# support checking probabilistic output, so we accept that the test -# will incorrectly fail with probability 2.8E-7. +path=':/bin:/usr/bin::/sbin:/usr/sbin:.:/home/user/bin:.' +path='/bin:/usr/bin:/sbin:/usr/sbin:/home/user/bin' +path='/bin:/usr/bin:/sbin:/usr/sbin:/homes/user/bin' +path='/bin':'/usr/bin':'/sbin':'/usr/sbin':'/home/user/bin' +path='/bin':'/usr/bin':'/sbin':'/usr/sbin':'/homes/user/bin' +path_/usr/xbin=/opt/xbin/ +paths=/bin /usr/bin /sbin /usr/sbin /homes/user/bin /opt/xbin +PATHS=/BIN /USR/BIN /SBIN /USR/SBIN /HOMES/USER/BIN /OPT/XBIN +LIST = one two three four five six seven eight nine ten +LIST:O = eight five four nine one seven six ten three two LIST:Ox = Ok LIST:O:Ox = Ok LISTX = Ok diff --git a/devel/bmake/files/util.c b/devel/bmake/files/util.c index f2a5024895e..86fae960fed 100644 --- a/devel/bmake/files/util.c +++ b/devel/bmake/files/util.c @@ -1,18 +1,18 @@ -/* $NetBSD: util.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: util.c,v 1.1.1.2 2008/03/09 19:39:34 joerg Exp $ */ /* * Missing stuff from OS's * - * $Id: util.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ + * $Id: util.c,v 1.1.1.2 2008/03/09 19:39:34 joerg Exp $ */ #include "make.h" #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: util.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"; +static char rcsid[] = "$NetBSD: util.c,v 1.1.1.2 2008/03/09 19:39:34 joerg Exp $"; #else #ifndef lint -__RCSID("$NetBSD: util.c,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $"); +__RCSID("$NetBSD: util.c,v 1.1.1.2 2008/03/09 19:39:34 joerg Exp $"); #endif #endif @@ -59,6 +59,33 @@ strdup(const char *str) } #endif +#if !defined(HAVE_EMALLOC) && !defined(HAVE_STRNDUP) +#include <string.h> + +/* strndup + * + * Make a duplicate of a string, up to a maximum length. + * For systems which lack this function. + */ +char * +strndup(const char *str, size_t maxlen) +{ + size_t len; + char *p; + + if (str == NULL) + return NULL; + len = strlen(str); + if (len > maxlen) + len = maxlen; + p = emalloc(len + 1); + + memcpy(p, str, len); + p[len] = '\0'; + return p; +} +#endif + #if !defined(HAVE_SETENV) int setenv(const char *name, const char *value, int dum) @@ -90,6 +117,14 @@ setenv(const char *name, const char *value, int dum) } #endif +#if !defined(HAVE_UNSETENV) +int +unsetenv(const char *name) +{ + return -1; /* XXX not worth it? */ +} +#endif + #if defined(__hpux__) || defined(__hpux) /* strrcpy(): * Like strcpy, going backwards and returning the new pointer @@ -145,14 +180,11 @@ char *sys_siglist[] = { #if defined(__hpux__) || defined(__hpux) #include <sys/types.h> -#include <sys/param.h> #include <sys/syscall.h> #include <sys/signal.h> #include <sys/stat.h> -#include <stdio.h> #include <dirent.h> #include <sys/time.h> -#include <time.h> #include <unistd.h> int @@ -510,3 +542,13 @@ strftime(char *buf, size_t len, const char *fmt, const struct tm *tm) } } #endif + +#if !defined(HAVE_KILLPG) +#if !defined(__hpux__) && !defined(__hpux) +int +killpg(int pid, int sig) +{ + return kill(-pid, sig); +} +#endif +#endif |