110d63b7dSRichard Lowe /*
210d63b7dSRichard Lowe * CDDL HEADER START
310d63b7dSRichard Lowe *
410d63b7dSRichard Lowe * The contents of this file are subject to the terms of the
510d63b7dSRichard Lowe * Common Development and Distribution License (the "License").
610d63b7dSRichard Lowe * You may not use this file except in compliance with the License.
710d63b7dSRichard Lowe *
810d63b7dSRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910d63b7dSRichard Lowe * or http://www.opensolaris.org/os/licensing.
1010d63b7dSRichard Lowe * See the License for the specific language governing permissions
1110d63b7dSRichard Lowe * and limitations under the License.
1210d63b7dSRichard Lowe *
1310d63b7dSRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
1410d63b7dSRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510d63b7dSRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
1610d63b7dSRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
1710d63b7dSRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
1810d63b7dSRichard Lowe *
1910d63b7dSRichard Lowe * CDDL HEADER END
2010d63b7dSRichard Lowe */
2110d63b7dSRichard Lowe /*
2210d63b7dSRichard Lowe * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
2310d63b7dSRichard Lowe * Use is subject to license terms.
2410d63b7dSRichard Lowe */
2510d63b7dSRichard Lowe
2610d63b7dSRichard Lowe /*
2710d63b7dSRichard Lowe * state.c
2810d63b7dSRichard Lowe *
2910d63b7dSRichard Lowe * This file contains the routines that write the .make.state file
3010d63b7dSRichard Lowe */
3110d63b7dSRichard Lowe
3210d63b7dSRichard Lowe /*
3310d63b7dSRichard Lowe * Included files
3410d63b7dSRichard Lowe */
3510d63b7dSRichard Lowe #include <mk/defs.h>
3610d63b7dSRichard Lowe #include <mksh/misc.h> /* errmsg() */
3710d63b7dSRichard Lowe #include <setjmp.h> /* setjmp() */
3810d63b7dSRichard Lowe #include <unistd.h> /* getpid() */
3910d63b7dSRichard Lowe #include <errno.h> /* errno */
4010d63b7dSRichard Lowe #include <locale.h> /* MB_CUR_MAX */
4110d63b7dSRichard Lowe
4210d63b7dSRichard Lowe /*
4310d63b7dSRichard Lowe * Defined macros
4410d63b7dSRichard Lowe */
4510d63b7dSRichard Lowe #define LONGJUMP_VALUE 17
4610d63b7dSRichard Lowe #define XFWRITE(string, length, fd) {if (fwrite(string, 1, length, fd) == 0) \
4710d63b7dSRichard Lowe longjmp(long_jump, LONGJUMP_VALUE);}
4810d63b7dSRichard Lowe #define XPUTC(ch, fd) { \
4910d63b7dSRichard Lowe if (putc((int) ch, fd) == EOF) \
5010d63b7dSRichard Lowe longjmp(long_jump, LONGJUMP_VALUE); \
5110d63b7dSRichard Lowe }
5210d63b7dSRichard Lowe #define XFPUTS(string, fd) fputs(string, fd)
5310d63b7dSRichard Lowe
5410d63b7dSRichard Lowe /*
5510d63b7dSRichard Lowe * typedefs & structs
5610d63b7dSRichard Lowe */
5710d63b7dSRichard Lowe
5810d63b7dSRichard Lowe /*
5910d63b7dSRichard Lowe * Static variables
6010d63b7dSRichard Lowe */
6110d63b7dSRichard Lowe
6210d63b7dSRichard Lowe /*
6310d63b7dSRichard Lowe * File table of contents
6410d63b7dSRichard Lowe */
escape_target_name(Name np)6510d63b7dSRichard Lowe static char * escape_target_name(Name np)
6610d63b7dSRichard Lowe {
6710d63b7dSRichard Lowe if(np->dollar) {
6810d63b7dSRichard Lowe int len = strlen(np->string_mb);
6910d63b7dSRichard Lowe char * buff = (char*)malloc(2 * len);
7010d63b7dSRichard Lowe int pos = 0;
7110d63b7dSRichard Lowe wchar_t wc;
7210d63b7dSRichard Lowe int pp = 0;
7310d63b7dSRichard Lowe while(pos < len) {
7410d63b7dSRichard Lowe int n = mbtowc(&wc, np->string_mb + pos, MB_CUR_MAX);
7510d63b7dSRichard Lowe if(n < 0) { // error - this shouldn't happen
7610d63b7dSRichard Lowe (void)free(buff);
7710d63b7dSRichard Lowe return strdup(np->string_mb);
7810d63b7dSRichard Lowe }
7910d63b7dSRichard Lowe if(wc == dollar_char) {
8010d63b7dSRichard Lowe buff[pp] = '\\'; pp++;
8110d63b7dSRichard Lowe buff[pp] = '$'; pp++;
8210d63b7dSRichard Lowe } else {
8310d63b7dSRichard Lowe for(int j=0;j<n;j++) {
8410d63b7dSRichard Lowe buff[pp] = np->string_mb[pos+j]; pp++;
8510d63b7dSRichard Lowe }
8610d63b7dSRichard Lowe }
8710d63b7dSRichard Lowe pos += n;
8810d63b7dSRichard Lowe }
8910d63b7dSRichard Lowe buff[pp] = '\0';
9010d63b7dSRichard Lowe return buff;
9110d63b7dSRichard Lowe } else {
9210d63b7dSRichard Lowe return strdup(np->string_mb);
9310d63b7dSRichard Lowe }
9410d63b7dSRichard Lowe }
9510d63b7dSRichard Lowe
96*e7afc443SToomas Soome static void print_auto_depes(Dependency dependency, FILE *fd, Boolean built_this_run, int *line_length, char *target_name, jmp_buf long_jump);
9710d63b7dSRichard Lowe
9810d63b7dSRichard Lowe /*
9910d63b7dSRichard Lowe * write_state_file(report_recursive, exiting)
10010d63b7dSRichard Lowe *
10110d63b7dSRichard Lowe * Write a new version of .make.state
10210d63b7dSRichard Lowe *
10310d63b7dSRichard Lowe * Parameters:
10410d63b7dSRichard Lowe * report_recursive Should only be done at end of run
10510d63b7dSRichard Lowe * exiting true if called from the exit handler
10610d63b7dSRichard Lowe *
10710d63b7dSRichard Lowe * Global variables used:
10810d63b7dSRichard Lowe * built_last_make_run The Name ".BUILT_LAST_MAKE_RUN", written
10910d63b7dSRichard Lowe * command_changed If no command changed we do not need to write
11010d63b7dSRichard Lowe * current_make_version The Name "<current version>", written
11110d63b7dSRichard Lowe * do_not_exec_rule If -n is on we do not write statefile
11210d63b7dSRichard Lowe * hashtab The hashtable that contains all names
11310d63b7dSRichard Lowe * keep_state If .KEEP_STATE is no on we do not write file
11410d63b7dSRichard Lowe * make_state The Name ".make.state", used for opening file
11510d63b7dSRichard Lowe * make_version The Name ".MAKE_VERSION", written
11610d63b7dSRichard Lowe * recursive_name The Name ".RECURSIVE", written
11710d63b7dSRichard Lowe * rewrite_statefile Indicates that something changed
11810d63b7dSRichard Lowe */
11910d63b7dSRichard Lowe
12010d63b7dSRichard Lowe void
write_state_file(int,Boolean exiting)12110d63b7dSRichard Lowe write_state_file(int, Boolean exiting)
12210d63b7dSRichard Lowe {
123*e7afc443SToomas Soome FILE *fd;
12410d63b7dSRichard Lowe int lock_err;
12510d63b7dSRichard Lowe char buffer[MAXPATHLEN];
12610d63b7dSRichard Lowe char make_state_tempfile[MAXPATHLEN];
12710d63b7dSRichard Lowe jmp_buf long_jump;
128*e7afc443SToomas Soome int attempts = 0;
12910d63b7dSRichard Lowe Name_set::iterator np, e;
130*e7afc443SToomas Soome Property lines;
131*e7afc443SToomas Soome int m;
13210d63b7dSRichard Lowe Dependency dependency;
133*e7afc443SToomas Soome Boolean name_printed;
13410d63b7dSRichard Lowe Boolean built_this_run = false;
13510d63b7dSRichard Lowe char *target_name;
13610d63b7dSRichard Lowe int line_length;
137*e7afc443SToomas Soome Cmd_line cp;
13810d63b7dSRichard Lowe
13910d63b7dSRichard Lowe
14010d63b7dSRichard Lowe if (!rewrite_statefile ||
14110d63b7dSRichard Lowe !command_changed ||
14210d63b7dSRichard Lowe !keep_state ||
14310d63b7dSRichard Lowe do_not_exec_rule ||
14410d63b7dSRichard Lowe (report_dependencies_level > 0)) {
14510d63b7dSRichard Lowe return;
14610d63b7dSRichard Lowe }
14710d63b7dSRichard Lowe /* Lock the file for writing. */
148ae389aa9SAndy Fiddaman make_state_lockfile = getmem(strlen(make_state->string_mb) + strlen(".lock") + 1);
149ae389aa9SAndy Fiddaman (void) sprintf(make_state_lockfile,
150ae389aa9SAndy Fiddaman "%s.lock",
151ae389aa9SAndy Fiddaman make_state->string_mb);
152ae389aa9SAndy Fiddaman if (lock_err = file_lock(make_state->string_mb,
153ae389aa9SAndy Fiddaman make_state_lockfile,
15410d63b7dSRichard Lowe (int *) &make_state_locked, 0)) {
155ae389aa9SAndy Fiddaman retmem_mb(make_state_lockfile);
15610d63b7dSRichard Lowe make_state_lockfile = NULL;
157ae389aa9SAndy Fiddaman
15810d63b7dSRichard Lowe /*
15910d63b7dSRichard Lowe * We need to make sure that we are not being
16010d63b7dSRichard Lowe * called by the exit handler so we don't call
16110d63b7dSRichard Lowe * it again.
16210d63b7dSRichard Lowe */
163ae389aa9SAndy Fiddaman
16410d63b7dSRichard Lowe if (exiting) {
16510d63b7dSRichard Lowe (void) sprintf(buffer, "%s/.make.state.%d.XXXXXX", tmpdir, getpid());
16610d63b7dSRichard Lowe report_pwd = true;
16710d63b7dSRichard Lowe warning(gettext("Writing to %s"), buffer);
16810d63b7dSRichard Lowe int fdes = mkstemp(buffer);
16910d63b7dSRichard Lowe if ((fdes < 0) || (fd = fdopen(fdes, "w")) == NULL) {
17010d63b7dSRichard Lowe fprintf(stderr,
17110d63b7dSRichard Lowe gettext("Could not open statefile `%s': %s"),
17210d63b7dSRichard Lowe buffer,
17310d63b7dSRichard Lowe errmsg(errno));
17410d63b7dSRichard Lowe return;
17510d63b7dSRichard Lowe }
17610d63b7dSRichard Lowe } else {
17710d63b7dSRichard Lowe report_pwd = true;
17810d63b7dSRichard Lowe fatal(gettext("Can't lock .make.state"));
17910d63b7dSRichard Lowe }
18010d63b7dSRichard Lowe }
18110d63b7dSRichard Lowe
18210d63b7dSRichard Lowe (void) sprintf(make_state_tempfile,
18310d63b7dSRichard Lowe "%s.tmp",
18410d63b7dSRichard Lowe make_state->string_mb);
18510d63b7dSRichard Lowe /* Delete old temporary statefile (in case it exists) */
18610d63b7dSRichard Lowe (void) unlink(make_state_tempfile);
18710d63b7dSRichard Lowe if ((fd = fopen(make_state_tempfile, "w")) == NULL) {
18810d63b7dSRichard Lowe lock_err = errno; /* Save it! unlink() can change errno */
18910d63b7dSRichard Lowe (void) unlink(make_state_lockfile);
190ae389aa9SAndy Fiddaman retmem_mb(make_state_lockfile);
19110d63b7dSRichard Lowe make_state_lockfile = NULL;
19210d63b7dSRichard Lowe make_state_locked = false;
19310d63b7dSRichard Lowe fatal(gettext("Could not open temporary statefile `%s': %s"),
19410d63b7dSRichard Lowe make_state_tempfile,
19510d63b7dSRichard Lowe errmsg(lock_err));
19610d63b7dSRichard Lowe }
19710d63b7dSRichard Lowe /*
19810d63b7dSRichard Lowe * Set a trap for failed writes. If a write fails, the routine
19910d63b7dSRichard Lowe * will try saving the .make.state file under another name in /tmp.
20010d63b7dSRichard Lowe */
20110d63b7dSRichard Lowe if (setjmp(long_jump)) {
20210d63b7dSRichard Lowe (void) fclose(fd);
20310d63b7dSRichard Lowe if (attempts++ > 5) {
20410d63b7dSRichard Lowe if ((make_state_lockfile != NULL) &&
20510d63b7dSRichard Lowe make_state_locked) {
20610d63b7dSRichard Lowe (void) unlink(make_state_lockfile);
207ae389aa9SAndy Fiddaman retmem_mb(make_state_lockfile);
20810d63b7dSRichard Lowe make_state_lockfile = NULL;
20910d63b7dSRichard Lowe make_state_locked = false;
21010d63b7dSRichard Lowe }
21110d63b7dSRichard Lowe fatal(gettext("Giving up on writing statefile"));
21210d63b7dSRichard Lowe }
21310d63b7dSRichard Lowe sleep(10);
21410d63b7dSRichard Lowe (void) sprintf(buffer, "%s/.make.state.%d.XXXXXX", tmpdir, getpid());
21510d63b7dSRichard Lowe int fdes = mkstemp(buffer);
21610d63b7dSRichard Lowe if ((fdes < 0) || (fd = fdopen(fdes, "w")) == NULL) {
21710d63b7dSRichard Lowe fatal(gettext("Could not open statefile `%s': %s"),
21810d63b7dSRichard Lowe buffer,
21910d63b7dSRichard Lowe errmsg(errno));
22010d63b7dSRichard Lowe }
22110d63b7dSRichard Lowe warning(gettext("Initial write of statefile failed. Trying again on %s"),
22210d63b7dSRichard Lowe buffer);
22310d63b7dSRichard Lowe }
22410d63b7dSRichard Lowe
22510d63b7dSRichard Lowe /* Write the version stamp. */
22610d63b7dSRichard Lowe XFWRITE(make_version->string_mb,
22710d63b7dSRichard Lowe strlen(make_version->string_mb),
22810d63b7dSRichard Lowe fd);
22910d63b7dSRichard Lowe XPUTC(colon_char, fd);
23010d63b7dSRichard Lowe XPUTC(tab_char, fd);
23110d63b7dSRichard Lowe XFWRITE(current_make_version->string_mb,
23210d63b7dSRichard Lowe strlen(current_make_version->string_mb),
23310d63b7dSRichard Lowe fd);
23410d63b7dSRichard Lowe XPUTC(newline_char, fd);
23510d63b7dSRichard Lowe
23610d63b7dSRichard Lowe /*
23710d63b7dSRichard Lowe * Go through all the targets, dump their dependencies and
23810d63b7dSRichard Lowe * command used.
23910d63b7dSRichard Lowe */
24010d63b7dSRichard Lowe for (np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
24110d63b7dSRichard Lowe /*
24210d63b7dSRichard Lowe * If the target has no command used nor dependencies,
24310d63b7dSRichard Lowe * we can go to the next one.
24410d63b7dSRichard Lowe */
24510d63b7dSRichard Lowe if ((lines = get_prop(np->prop, line_prop)) == NULL) {
24610d63b7dSRichard Lowe continue;
24710d63b7dSRichard Lowe }
24810d63b7dSRichard Lowe /* If this target is a special target, don't print. */
24910d63b7dSRichard Lowe if (np->special_reader != no_special) {
25010d63b7dSRichard Lowe continue;
25110d63b7dSRichard Lowe }
25210d63b7dSRichard Lowe /*
25310d63b7dSRichard Lowe * Find out if any of the targets dependencies should
25410d63b7dSRichard Lowe * be written to .make.state.
25510d63b7dSRichard Lowe */
25610d63b7dSRichard Lowe for (m = 0, dependency = lines->body.line.dependencies;
25710d63b7dSRichard Lowe dependency != NULL;
25810d63b7dSRichard Lowe dependency = dependency->next) {
25910d63b7dSRichard Lowe if (m = !dependency->stale
26010d63b7dSRichard Lowe && (dependency->name != force)
26110d63b7dSRichard Lowe #ifndef PRINT_EXPLICIT_DEPEN
26210d63b7dSRichard Lowe && dependency->automatic
26310d63b7dSRichard Lowe #endif
26410d63b7dSRichard Lowe ) {
26510d63b7dSRichard Lowe break;
26610d63b7dSRichard Lowe }
26710d63b7dSRichard Lowe }
26810d63b7dSRichard Lowe /* Only print if dependencies listed. */
26910d63b7dSRichard Lowe if (m || (lines->body.line.command_used != NULL)) {
27010d63b7dSRichard Lowe name_printed = false;
27110d63b7dSRichard Lowe /*
27210d63b7dSRichard Lowe * If this target was built during this make run,
27310d63b7dSRichard Lowe * we mark it.
27410d63b7dSRichard Lowe */
27510d63b7dSRichard Lowe built_this_run = false;
27610d63b7dSRichard Lowe if (np->has_built) {
27710d63b7dSRichard Lowe built_this_run = true;
27810d63b7dSRichard Lowe XFWRITE(built_last_make_run->string_mb,
27910d63b7dSRichard Lowe strlen(built_last_make_run->string_mb),
28010d63b7dSRichard Lowe fd);
28110d63b7dSRichard Lowe XPUTC(colon_char, fd);
28210d63b7dSRichard Lowe XPUTC(newline_char, fd);
28310d63b7dSRichard Lowe }
28410d63b7dSRichard Lowe /* If the target has dependencies, we dump them. */
28510d63b7dSRichard Lowe target_name = escape_target_name(np);
28610d63b7dSRichard Lowe if (np->has_long_member_name) {
28710d63b7dSRichard Lowe target_name =
28810d63b7dSRichard Lowe get_prop(np->prop, long_member_name_prop)
28910d63b7dSRichard Lowe ->body.long_member_name.member_name->
29010d63b7dSRichard Lowe string_mb;
29110d63b7dSRichard Lowe }
29210d63b7dSRichard Lowe if (m) {
29310d63b7dSRichard Lowe XFPUTS(target_name, fd);
29410d63b7dSRichard Lowe XPUTC(colon_char, fd);
29510d63b7dSRichard Lowe XFPUTS("\t", fd);
29610d63b7dSRichard Lowe name_printed = true;
29710d63b7dSRichard Lowe line_length = 0;
29810d63b7dSRichard Lowe for (dependency =
29910d63b7dSRichard Lowe lines->body.line.dependencies;
30010d63b7dSRichard Lowe dependency != NULL;
30110d63b7dSRichard Lowe dependency = dependency->next) {
30210d63b7dSRichard Lowe print_auto_depes(dependency,
30310d63b7dSRichard Lowe fd,
30410d63b7dSRichard Lowe built_this_run,
30510d63b7dSRichard Lowe &line_length,
30610d63b7dSRichard Lowe target_name,
30710d63b7dSRichard Lowe long_jump);
30810d63b7dSRichard Lowe }
30910d63b7dSRichard Lowe XFPUTS("\n", fd);
31010d63b7dSRichard Lowe }
31110d63b7dSRichard Lowe /* If there is a command used, we dump it. */
31210d63b7dSRichard Lowe if (lines->body.line.command_used != NULL) {
31310d63b7dSRichard Lowe /*
31410d63b7dSRichard Lowe * Only write the target name if it
31510d63b7dSRichard Lowe * wasn't done for the dependencies.
31610d63b7dSRichard Lowe */
31710d63b7dSRichard Lowe if (!name_printed) {
31810d63b7dSRichard Lowe XFPUTS(target_name, fd);
31910d63b7dSRichard Lowe XPUTC(colon_char, fd);
32010d63b7dSRichard Lowe XPUTC(newline_char, fd);
32110d63b7dSRichard Lowe }
32210d63b7dSRichard Lowe /*
32310d63b7dSRichard Lowe * Write the command lines.
32410d63b7dSRichard Lowe * Prefix each textual line with a tab.
32510d63b7dSRichard Lowe */
32610d63b7dSRichard Lowe for (cp = lines->body.line.command_used;
32710d63b7dSRichard Lowe cp != NULL;
32810d63b7dSRichard Lowe cp = cp->next) {
32910d63b7dSRichard Lowe char *csp;
33010d63b7dSRichard Lowe int n;
33110d63b7dSRichard Lowe
33210d63b7dSRichard Lowe XPUTC(tab_char, fd);
33310d63b7dSRichard Lowe if (cp->command_line != NULL) {
33410d63b7dSRichard Lowe for (csp = cp->
33510d63b7dSRichard Lowe command_line->
33610d63b7dSRichard Lowe string_mb,
33710d63b7dSRichard Lowe n = strlen(cp->
33810d63b7dSRichard Lowe command_line->
33910d63b7dSRichard Lowe string_mb);
34010d63b7dSRichard Lowe n > 0;
34110d63b7dSRichard Lowe n--, csp++) {
34210d63b7dSRichard Lowe XPUTC(*csp, fd);
34310d63b7dSRichard Lowe if (*csp ==
34410d63b7dSRichard Lowe (int) newline_char) {
34510d63b7dSRichard Lowe XPUTC(tab_char,
34610d63b7dSRichard Lowe fd);
34710d63b7dSRichard Lowe }
34810d63b7dSRichard Lowe }
34910d63b7dSRichard Lowe }
35010d63b7dSRichard Lowe XPUTC(newline_char, fd);
35110d63b7dSRichard Lowe }
35210d63b7dSRichard Lowe }
35310d63b7dSRichard Lowe (void)free(target_name);
35410d63b7dSRichard Lowe }
35510d63b7dSRichard Lowe }
35610d63b7dSRichard Lowe if (fclose(fd) == EOF) {
35710d63b7dSRichard Lowe longjmp(long_jump, LONGJUMP_VALUE);
35810d63b7dSRichard Lowe }
35910d63b7dSRichard Lowe if (attempts == 0) {
36010d63b7dSRichard Lowe if (unlink(make_state->string_mb) != 0 && errno != ENOENT) {
36110d63b7dSRichard Lowe lock_err = errno; /* Save it! unlink() can change errno */
36210d63b7dSRichard Lowe /* Delete temporary statefile */
36310d63b7dSRichard Lowe (void) unlink(make_state_tempfile);
36410d63b7dSRichard Lowe (void) unlink(make_state_lockfile);
365ae389aa9SAndy Fiddaman retmem_mb(make_state_lockfile);
36610d63b7dSRichard Lowe make_state_lockfile = NULL;
36710d63b7dSRichard Lowe make_state_locked = false;
36810d63b7dSRichard Lowe fatal(gettext("Could not delete old statefile `%s': %s"),
36910d63b7dSRichard Lowe make_state->string_mb,
37010d63b7dSRichard Lowe errmsg(lock_err));
37110d63b7dSRichard Lowe }
37210d63b7dSRichard Lowe if (rename(make_state_tempfile, make_state->string_mb) != 0) {
37310d63b7dSRichard Lowe lock_err = errno; /* Save it! unlink() can change errno */
37410d63b7dSRichard Lowe /* Delete temporary statefile */
37510d63b7dSRichard Lowe (void) unlink(make_state_tempfile);
37610d63b7dSRichard Lowe (void) unlink(make_state_lockfile);
377ae389aa9SAndy Fiddaman retmem_mb(make_state_lockfile);
37810d63b7dSRichard Lowe make_state_lockfile = NULL;
37910d63b7dSRichard Lowe make_state_locked = false;
38010d63b7dSRichard Lowe fatal(gettext("Could not rename `%s' to `%s': %s"),
38110d63b7dSRichard Lowe make_state_tempfile,
38210d63b7dSRichard Lowe make_state->string_mb,
38310d63b7dSRichard Lowe errmsg(lock_err));
38410d63b7dSRichard Lowe }
38510d63b7dSRichard Lowe }
38610d63b7dSRichard Lowe if ((make_state_lockfile != NULL) && make_state_locked) {
38710d63b7dSRichard Lowe (void) unlink(make_state_lockfile);
388ae389aa9SAndy Fiddaman retmem_mb(make_state_lockfile);
38910d63b7dSRichard Lowe make_state_lockfile = NULL;
39010d63b7dSRichard Lowe make_state_locked = false;
39110d63b7dSRichard Lowe }
39210d63b7dSRichard Lowe }
39310d63b7dSRichard Lowe
39410d63b7dSRichard Lowe /*
39510d63b7dSRichard Lowe * print_auto_depes(dependency, fd, built_this_run,
39610d63b7dSRichard Lowe * line_length, target_name, long_jump)
39710d63b7dSRichard Lowe *
39810d63b7dSRichard Lowe * Will print a dependency list for automatic entries.
39910d63b7dSRichard Lowe *
40010d63b7dSRichard Lowe * Parameters:
40110d63b7dSRichard Lowe * dependency The dependency to print
40210d63b7dSRichard Lowe * fd The file to print it to
40310d63b7dSRichard Lowe * built_this_run If on we prefix each line with .BUILT_THIS...
40410d63b7dSRichard Lowe * line_length Pointer to line length var that we update
40510d63b7dSRichard Lowe * target_name We need this when we restart line
40610d63b7dSRichard Lowe * long_jump setjmp/longjmp buffer used for IO error action
40710d63b7dSRichard Lowe *
40810d63b7dSRichard Lowe * Global variables used:
40910d63b7dSRichard Lowe * built_last_make_run The Name ".BUILT_LAST_MAKE_RUN", written
41010d63b7dSRichard Lowe * force The Name " FORCE", compared against
41110d63b7dSRichard Lowe */
41210d63b7dSRichard Lowe static void
print_auto_depes(Dependency dependency,FILE * fd,Boolean built_this_run,int * line_length,char * target_name,jmp_buf long_jump)413*e7afc443SToomas Soome print_auto_depes(Dependency dependency, FILE *fd, Boolean built_this_run, int *line_length, char *target_name, jmp_buf long_jump)
41410d63b7dSRichard Lowe {
41510d63b7dSRichard Lowe if (!dependency->automatic ||
41610d63b7dSRichard Lowe dependency->stale ||
41710d63b7dSRichard Lowe (dependency->name == force)) {
41810d63b7dSRichard Lowe return;
41910d63b7dSRichard Lowe }
420ae389aa9SAndy Fiddaman XFWRITE(dependency->name->string_mb,
42110d63b7dSRichard Lowe strlen(dependency->name->string_mb),
42210d63b7dSRichard Lowe fd);
42310d63b7dSRichard Lowe /*
42410d63b7dSRichard Lowe * Check if the dependency line is too long.
42510d63b7dSRichard Lowe * If so, break it and start a new one.
42610d63b7dSRichard Lowe */
42710d63b7dSRichard Lowe if ((*line_length += (int) strlen(dependency->name->string_mb) + 1) > 450) {
42810d63b7dSRichard Lowe *line_length = 0;
42910d63b7dSRichard Lowe XPUTC(newline_char, fd);
43010d63b7dSRichard Lowe if (built_this_run) {
43110d63b7dSRichard Lowe XFPUTS(built_last_make_run->string_mb, fd);
43210d63b7dSRichard Lowe XPUTC(colon_char, fd);
43310d63b7dSRichard Lowe XPUTC(newline_char, fd);
43410d63b7dSRichard Lowe }
43510d63b7dSRichard Lowe XFPUTS(target_name, fd);
43610d63b7dSRichard Lowe XPUTC(colon_char, fd);
43710d63b7dSRichard Lowe XPUTC(tab_char, fd);
43810d63b7dSRichard Lowe } else {
43910d63b7dSRichard Lowe XFPUTS(" ", fd);
44010d63b7dSRichard Lowe }
44110d63b7dSRichard Lowe return;
44210d63b7dSRichard Lowe }
44310d63b7dSRichard Lowe
44410d63b7dSRichard Lowe
445