summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpsmith <>2010-11-06 21:56:23 +0000
committerpsmith <>2010-11-06 21:56:23 +0000
commit19a994a3b1beedd9f770675a8d323a6c64508254 (patch)
treefe7bbf6d28dbee370f385832aeed139d9276faaf
parent3f43c62db8ed565a2b0f63a209f5c3d690f604f6 (diff)
downloadmake-19a994a3b1beedd9f770675a8d323a6c64508254.tar.gz
Improve backslash/newline handling to adhere to POSIX requirements.
-rw-r--r--ChangeLog34
-rw-r--r--NEWS13
-rw-r--r--commands.c17
-rw-r--r--commands.h5
-rw-r--r--default.c63
-rw-r--r--doc/make.texi25
-rw-r--r--file.c13
-rw-r--r--filedef.h1
-rw-r--r--job.c32
-rw-r--r--make.h4
-rw-r--r--misc.c3
-rw-r--r--read.c36
-rw-r--r--rule.c1
-rw-r--r--tests/ChangeLog8
-rw-r--r--tests/scripts/features/targetvars2
-rw-r--r--tests/scripts/functions/call2
-rw-r--r--tests/scripts/misc/bs-nl76
-rw-r--r--tests/scripts/variables/special2
-rw-r--r--variable.c52
-rw-r--r--variable.h3
20 files changed, 298 insertions, 94 deletions
diff --git a/ChangeLog b/ChangeLog
index 07665226..fdcb106f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+2010-11-06 Paul Smith <psmith@gnu.org>
+
+ * variable.c (print_auto_variable): Print auto variables; ignore others.
+ (print_noauto_variable): Print non-auto variables; ignore others.
+ (print_variable_set): Allow the caller to select which type to print.
+ (print_target_variables): Show all the non-auto variables for a target.
+
+ * default.c (install_default_suffix_rules): Initialize recipe_prefix.
+ * rule.c (install_pattern_rule): Ditto.
+ * read.c (record_files): Pass in the current recipe prefix. Remember
+ it in the struct command for these targets.
+ (eval): Remember the value of RECIPEPREFIX when we start parsing.
+ Do not remove recipe prefixes from the recipe here: we'll do it later.
+ * job.c (start_job_command): Remove recipe prefix characters early,
+ before we print the output or chop it up.
+ * file.c (print_file): If recipe_prefix is not standard, reset it
+ in -p output. Assign target variables in -p output as well.
+
+ * commands.c (chop_commands): Max command lines is USHRT_MAX.
+ Set any_recurse as a bitfield.
+ * make.h (USHRT_MAX): Define if not set.
+
+2010-10-27 Paul Smith <psmith@gnu.org>
+
+ * commands.h (struct commands): Rearrange to make better use of
+ memory. Add new recipe_prefix value.
+
+2010-10-26 Paul Smith <psmith@gnu.org>
+
+ * doc/make.texi (Setting): Document the treatment of
+ backslash-newline in variable values.
+ * misc.c (collapse_continuations): Do not collapse multiple
+ backslash-newlines into a single space. Fixes Savannah bug #16670.
+
2010-08-29 Paul Smith <psmith@gnu.org>
* doc/make.texi (Implicit Variables): Document LDLIBS and LOADLIBES.
diff --git a/NEWS b/NEWS
index 36bae59d..a4213753 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,13 @@ A complete list of bugs fixed in this version is available here:
http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set=custom
+* WARNING: Backward-incompatibility!
+ This version of make adheres to the POSIX backslash/newline handling,
+ introducing the following differences:
+ * Each backslash/newline in a variable value is replaced with a space;
+ multiple consecutive backslash/newlines do not condense into one space.
+ * In recipes, a recipe prefix following a backslash-newlines is removed.
+
* New command line option: --trace enables tracing of targets. When enabled
the recipe to be invoked is printed even if it would otherwise be suppressed
by .SILENT or a "@" prefix character. Also before each recipe is run the
@@ -24,6 +31,12 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set
* On failure, the makefile name and linenumber of the recipe that failed are
shown.
+* A .RECIPEPREFIX setting is remembered per-recipe and variables expanded
+ in that recipe also use that recipe prefix setting.
+
+* In -p output, .RECIPEPREFIX settings are shown and all target-specific
+ variables are output as if in a makefile, instead of as comments.
+
Version 3.82
diff --git a/commands.c b/commands.c
index f360bd40..ba3840ec 100644
--- a/commands.c
+++ b/commands.c
@@ -402,6 +402,9 @@ chop_commands (struct commands *cmds)
/* Finally, set the corresponding CMDS->lines_flags elements and the
CMDS->any_recurse flag. */
+ if (nlines > USHRT_MAX)
+ fatal (&cmds->fileinfo, _("Recipe has too many lines (%ud)"), nlines);
+
cmds->ncommand_lines = nlines;
cmds->command_lines = lines;
@@ -433,7 +436,7 @@ chop_commands (struct commands *cmds)
flags |= COMMANDS_RECURSE;
cmds->lines_flags[idx] = flags;
- cmds->any_recurse |= flags & COMMANDS_RECURSE;
+ cmds->any_recurse |= flags & COMMANDS_RECURSE ? 1 : 0;
}
}
@@ -685,10 +688,16 @@ print_commands (const struct commands *cmds)
while (*s != '\0')
{
const char *end;
+ int bs;
- end = strchr (s, '\n');
- if (end == 0)
- end = s + strlen (s);
+ /* Print one full logical recipe line: find a non-escaped newline. */
+ for (end = s, bs = 0; *end != '\0'; ++end)
+ {
+ if (*end == '\n' && !bs)
+ break;
+
+ bs = *end == '\\' ? !bs : 0;
+ }
printf ("%c%.*s\n", cmd_prefix, (int) (end - s), s);
diff --git a/commands.h b/commands.h
index 24426fa7..643347d1 100644
--- a/commands.h
+++ b/commands.h
@@ -23,10 +23,11 @@ struct commands
{
struct floc fileinfo; /* Where commands were defined. */
char *commands; /* Commands text. */
- unsigned int ncommand_lines;/* Number of command lines. */
char **command_lines; /* Commands chopped up into lines. */
char *lines_flags; /* One set of flag bits for each line. */
- int any_recurse; /* Nonzero if any `lines_recurse' elt has */
+ unsigned short ncommand_lines;/* Number of command lines. */
+ char recipe_prefix; /* Recipe prefix for this command set. */
+ unsigned int any_recurse:1; /* Nonzero if any `lines_flags' elt has */
/* the COMMANDS_RECURSE bit set. */
};
diff --git a/default.c b/default.c
index 4d6d984b..46e023e6 100644
--- a/default.c
+++ b/default.c
@@ -53,7 +53,7 @@ static char default_suffixes[]
static struct pspec default_pattern_rules[] =
{
{ "(%)", "%",
- "$(AR) $(ARFLAGS) $@ $<" },
+ "$(AR) $(ARFLAGS) $@ $<" },
/* The X.out rules are only in BSD's default set because
BSD Make has no null-suffix rules, so `foo.out' and
@@ -63,13 +63,13 @@ static struct pspec default_pattern_rules[] =
"copy $< $@" },
#else
{ "%.out", "%",
- "@rm -f $@ \n cp $< $@" },
+ "@rm -f $@ \n cp $< $@" },
#endif
/* Syntax is "ctangle foo.w foo.ch foo.c". */
{ "%.c", "%.w %.ch",
- "$(CTANGLE) $^ $@" },
+ "$(CTANGLE) $^ $@" },
{ "%.tex", "%.w %.ch",
- "$(CWEAVE) $^ $@" },
+ "$(CWEAVE) $^ $@" },
{ 0, 0, 0 }
};
@@ -88,21 +88,21 @@ static struct pspec default_terminal_rules[] =
"if f$$search($@) .nes. \"\" then +$(CHECKOUT,v)" },
/* SCCS. */
- /* ain't no SCCS on vms */
+ /* ain't no SCCS on vms */
#else
/* RCS. */
{ "%", "%,v",
- "$(CHECKOUT,v)" },
+ "$(CHECKOUT,v)" },
{ "%", "RCS/%,v",
- "$(CHECKOUT,v)" },
+ "$(CHECKOUT,v)" },
{ "%", "RCS/%",
- "$(CHECKOUT,v)" },
+ "$(CHECKOUT,v)" },
/* SCCS. */
{ "%", "s.%",
- "$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" },
+ "$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" },
{ "%", "SCCS/s.%",
- "$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" },
+ "$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" },
#endif /* !VMS */
{ 0, 0, 0 }
};
@@ -293,13 +293,13 @@ static char *default_suffix_rules[] =
"$(TEXI2DVI) $(TEXI2DVI_FLAGS) $<",
".w.c",
- "$(CTANGLE) $< - $@", /* The `-' says there is no `.ch' file. */
+ "$(CTANGLE) $< - $@", /* The `-' says there is no `.ch' file. */
".web.p",
"$(TANGLE) $<",
".w.tex",
- "$(CWEAVE) $< - $@", /* The `-' says there is no `.ch' file. */
+ "$(CWEAVE) $< - $@", /* The `-' says there is no `.ch' file. */
".web.tex",
"$(WEAVE) $<",
@@ -401,7 +401,7 @@ static const char *default_variables[] =
#ifdef GCC_IS_NATIVE
"CC", "gcc",
# ifdef __MSDOS__
- "CXX", "gpp", /* g++ is an invalid name on MSDOS */
+ "CXX", "gpp", /* g++ is an invalid name on MSDOS */
# else
"CXX", "gcc",
# endif /* __MSDOS__ */
@@ -419,17 +419,17 @@ static const char *default_variables[] =
"COFLAGS", "",
"CPP", "$(CC) -E",
-#ifdef CRAY
+#ifdef CRAY
"CF77PPFLAGS", "-P",
"CF77PP", "/lib/cpp",
"CFT", "cft77",
"CF", "cf77",
"FC", "$(CF)",
-#else /* Not CRAY. */
-#ifdef _IBMR2
+#else /* Not CRAY. */
+#ifdef _IBMR2
"FC", "xlf",
#else
-#ifdef __convex__
+#ifdef __convex__
"FC", "fc",
#else
"FC", "f77",
@@ -439,7 +439,7 @@ static const char *default_variables[] =
However, there is no way to make implicit rules use them and FC. */
"F77", "$(FC)",
"F77FLAGS", "$(FFLAGS)",
-#endif /* Cray. */
+#endif /* Cray. */
"GET", SCCS_GET,
"LD", "ld",
#ifdef GCC_IS_NATIVE
@@ -449,20 +449,20 @@ static const char *default_variables[] =
#endif
"LINT", "lint",
"M2C", "m2c",
-#ifdef pyr
+#ifdef pyr
"PC", "pascal",
#else
-#ifdef CRAY
+#ifdef CRAY
"PC", "PASCAL",
"SEGLDR", "segldr",
#else
"PC", "pc",
-#endif /* CRAY. */
-#endif /* pyr. */
+#endif /* CRAY. */
+#endif /* pyr. */
#ifdef GCC_IS_NATIVE
"YACC", "bison -y",
#else
- "YACC", "yacc", /* Or "bison -y" */
+ "YACC", "yacc", /* Or "bison -y" */
#endif
"MAKEINFO", "makeinfo",
"TEX", "tex",
@@ -508,11 +508,11 @@ static const char *default_variables[] =
"PREPROCESS.r", "$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -F",
"LINT.c", "$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
-#ifndef NO_MINUS_C_MINUS_O
+#ifndef NO_MINUS_C_MINUS_O
"OUTPUT_OPTION", "-o $@",
#endif
-#ifdef SCCS_GET_MINUS_G
+#ifdef SCCS_GET_MINUS_G
"SCCS_OUTPUT_OPTION", "-G$@",
#endif
@@ -567,12 +567,13 @@ install_default_suffix_rules (void)
struct file *f = enter_file (strcache_add (s[0]));
/* Don't clobber cmds given in a makefile if there were any. */
if (f->cmds == 0)
- {
- f->cmds = xmalloc (sizeof (struct commands));
- f->cmds->fileinfo.filenm = 0;
- f->cmds->commands = s[1];
- f->cmds->command_lines = 0;
- }
+ {
+ f->cmds = xmalloc (sizeof (struct commands));
+ f->cmds->fileinfo.filenm = 0;
+ f->cmds->commands = s[1];
+ f->cmds->command_lines = 0;
+ f->cmds->recipe_prefix = RECIPEPREFIX_DEFAULT;
+ }
}
}
diff --git a/doc/make.texi b/doc/make.texi
index 548117fd..e5fe6b85 100644
--- a/doc/make.texi
+++ b/doc/make.texi
@@ -4,7 +4,7 @@
@include version.texi
@set EDITION 0.71
-@set RCSID $Id: make.texi,v 1.67 2010/08/29 23:05:27 psmith Exp $
+@set RCSID $Id: make.texi,v 1.68 2010/11/06 21:56:25 psmith Exp $
@settitle GNU @code{make}
@setchapternewpage odd
@@ -1633,7 +1633,7 @@ expands to @file{bar}, @code{$$^} expands to @file{bar boo},
Note that the directory prefix (D), as described in @ref{Implicit Rule
Search, ,Implicit Rule Search Algorithm}, is appended (after
expansion) to all the patterns in the prerequisites list. As an
-example:
+example:@refill
@example
.SECONDEXPANSION:
@@ -1641,12 +1641,14 @@ example:
/tmp/foo.o:
%.o: $$(addsuffix /%.c,foo bar) foo.h
+ @@echo $^
@end example
-The prerequisite list after the secondary expansion and directory
-prefix reconstruction will be @file{/tmp/foo/foo.c /tmp/var/bar/foo.c
-foo.h}. If you are not interested in this reconstruction, you can use
-@code{$$*} instead of @code{%} in the prerequisites list.
+The prerequisite list printed, after the secondary expansion and
+directory prefix reconstruction, will be @file{/tmp/foo/foo.c
+/tmp/bar/foo.c foo.h}. If you are not interested in this
+reconstruction, you can use @code{$$*} instead of @code{%} in the
+prerequisites list.
@node Rules, Recipes, Makefiles, Top
@chapter Writing Rules
@@ -5422,11 +5424,12 @@ The variable name may contain function and variable references, which
are expanded when the line is read to find the actual variable name to use.
There is no limit on the length of the value of a variable except the
-amount of swapping space on the computer. When a variable definition is
-long, it is a good idea to break it into several lines by inserting
-backslash-newline at convenient places in the definition. This will not
-affect the functioning of @code{make}, but it will make the makefile easier
-to read.
+amount of memory on the computer. When a variable definition is long,
+it is a good idea to break it into several lines by inserting
+backslash-newline at convenient places in the definition. This will
+make the makefile easier to read. Every backslash-newline, along with
+any leading whitespace on the following line, will be replaced by a
+single space in the value of the variable.
Most variable names are considered to have the empty string as a value if
you have never set them. Several variables have built-in initial values
diff --git a/file.c b/file.c
index 0a4edb25..93212d1c 100644
--- a/file.c
+++ b/file.c
@@ -920,6 +920,19 @@ print_file (const void *item)
const struct file *f = item;
putchar ('\n');
+
+ if (f->cmds && f->cmds->recipe_prefix != cmd_prefix)
+ {
+ fputs (".RECIPEPREFIX = ", stdout);
+ cmd_prefix = f->cmds->recipe_prefix;
+ if (cmd_prefix != RECIPEPREFIX_DEFAULT)
+ putchar (cmd_prefix);
+ putchar ('\n');
+ }
+
+ if (f->variables != 0)
+ print_target_variables (f);
+
if (!f->is_target)
puts (_("# Not a target:"));
printf ("%s:%s", f->name, f->double_colon ? ":" : "");
diff --git a/filedef.h b/filedef.h
index 0a621b9b..98e3f49f 100644
--- a/filedef.h
+++ b/filedef.h
@@ -63,7 +63,6 @@ struct file
short int update_status; /* Status of the last attempt to update,
or -1 if none has been made. */
-
enum cmd_state /* State of the commands. */
{ /* Note: It is important that cs_not_started be zero. */
cs_not_started, /* Not yet started. */
diff --git a/job.c b/job.c
index f4e6fa46..67b402d7 100644
--- a/job.c
+++ b/job.c
@@ -1088,8 +1088,23 @@ start_job_command (struct child *child)
child->file->cmds->lines_flags[child->command_line - 1]
|= flags & COMMANDS_RECURSE;
- /* Figure out an argument list from this command line. */
+ /* POSIX requires that a recipe prefix after a backslash-newline should
+ be ignored. Remove it now so the output is correct. */
+ {
+ char prefix = child->file->cmds->recipe_prefix;
+ char *p1, *p2;
+ p1 = p2 = p;
+ while (*p1 != '\0')
+ {
+ *(p2++) = *p1;
+ if (p1[0] == '\n' && p1[1] == prefix)
+ ++p1;
+ ++p1;
+ }
+ *p2 = *p1;
+ }
+ /* Figure out an argument list from this command line. */
{
char *end = 0;
#ifdef VMS
@@ -1097,7 +1112,7 @@ start_job_command (struct child *child)
#else
argv = construct_command_argv (p, &end, child->file,
child->file->cmds->lines_flags[child->command_line - 1],
- &child->sh_batch_file);
+ &child->sh_batch_file);
#endif
if (end == NULL)
child->command_ptr = NULL;
@@ -2321,7 +2336,7 @@ void clean_tmp (void)
static char **
construct_command_argv_internal (char *line, char **restp, char *shell,
char *shellflags, char *ifs, int flags,
- char **batch_filename_ptr)
+ char **batch_filename_p)
{
#ifdef __MSDOS__
/* MSDOS supports both the stock DOS shell and ports of Unixy shells.
@@ -2567,10 +2582,9 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
{
/* Backslash-newline is handled differently depending on what
kind of string we're in: inside single-quoted strings you
- keep them; in double-quoted strings they disappear.
- For DOS/Windows/OS2, if we don't have a POSIX shell,
- we keep the pre-POSIX behavior of removing the
- backslash-newline. */
+ keep them; in double-quoted strings they disappear. For
+ DOS/Windows/OS2, if we don't have a POSIX shell, we keep the
+ pre-POSIX behavior of removing the backslash-newline. */
if (instring == '"'
#if defined (__MSDOS__) || defined (__EMX__) || defined (WINDOWS32)
|| !unixy_shell
@@ -3126,7 +3140,7 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
char **
construct_command_argv (char *line, char **restp, struct file *file,
- int cmd_flags, char **batch_filename_ptr)
+ int cmd_flags, char **batch_filename_p)
{
char *shell, *ifs, *shellflags;
char **argv;
@@ -3240,7 +3254,7 @@ construct_command_argv (char *line, char **restp, struct file *file,
}
argv = construct_command_argv_internal (line, restp, shell, shellflags, ifs,
- cmd_flags, batch_filename_ptr);
+ cmd_flags, batch_filename_p);
free (shell);
free (shellflags);
diff --git a/make.h b/make.h
index e563da47..ea282df6 100644
--- a/make.h
+++ b/make.h
@@ -148,6 +148,10 @@ unsigned int get_path_max (void);
# define CHAR_BIT 8
#endif
+#ifndef USHRT_MAX
+# define USHRT_MAX 65535
+#endif
+
/* Nonzero if the integer type T is signed. */
#define INTEGER_TYPE_SIGNED(t) ((t) -1 < 0)
diff --git a/misc.c b/misc.c
index 7a6f7731..607e2a7e 100644
--- a/misc.c
+++ b/misc.c
@@ -118,9 +118,6 @@ collapse_continuations (char *line)
if (backslash)
{
in = next_token (in);
- /* Removing this loop will fix Savannah bug #16670: do we want to? */
- while (out > line && isblank ((unsigned char)out[-1]))
- --out;
*out++ = ' ';
}
else
diff --git a/read.c b/read.c
index 9dfd4ea0..7b5b0dd0 100644
--- a/read.c
+++ b/read.c
@@ -146,7 +146,7 @@ static void record_files (struct nameseq *filenames, const char *pattern,
const char *pattern_percent, char *depstr,
unsigned int cmds_started, char *commands,
unsigned int commands_idx, int two_colon,
- const struct floc *flocp);
+ char prefix, const struct floc *flocp);
static void record_target_var (struct nameseq *filenames, char *defn,
enum variable_origin origin,
struct vmodifiers *vmod,
@@ -559,6 +559,7 @@ eval (struct ebuffer *ebuf, int set_default)
char *depstr = 0;
long nlines = 0;
int two_colon = 0;
+ char prefix;
const char *pattern = 0;
const char *pattern_percent;
struct floc *fstart;
@@ -572,7 +573,7 @@ eval (struct ebuffer *ebuf, int set_default)
fi.lineno = tgts_started; \
record_files (filenames, pattern, pattern_percent, depstr, \
cmds_started, commands, commands_idx, two_colon, \
- &fi); \
+ prefix, &fi); \
filenames = 0; \
} \
commands_idx = 0; \
@@ -624,7 +625,7 @@ eval (struct ebuffer *ebuf, int set_default)
linelen = strlen (line);
/* Check for a shell command line first.
- If it is not one, we can stop treating tab specially. */
+ If it is not one, we can stop treating cmd_prefix specially. */
if (line[0] == cmd_prefix)
{
if (no_targets)
@@ -641,32 +642,19 @@ eval (struct ebuffer *ebuf, int set_default)
/* Yep, this is a shell command, and we don't care. */
continue;
- /* Append this command line to the line being accumulated.
- Strip command prefix chars that appear after newlines. */
if (commands_idx == 0)
cmds_started = ebuf->floc.lineno;
+ /* Append this command line to the line being accumulated.
+ Skip the initial command prefix character. */
if (linelen + commands_idx > commands_len)
{
commands_len = (linelen + commands_idx) * 2;
commands = xrealloc (commands, commands_len);
}
- p = &commands[commands_idx];
- p2 = line + 1;
- while (--linelen)
- {
- ++commands_idx;
- *(p++) = *p2;
- if (p2[0] == '\n' && p2[1] == cmd_prefix)
- {
- ++p2;
- --linelen;
- }
- ++p2;
- }
- *p = '\n';
- ++commands_idx;
-
+ memcpy (&commands[commands_idx], line + 1, linelen - 1);
+ commands_idx += linelen - 1;
+ commands[commands_idx++] = '\n';
continue;
}
}
@@ -1089,6 +1077,9 @@ eval (struct ebuffer *ebuf, int set_default)
Unquote any = in the dependency list. */
find_char_unquote (lb_next, '=', 0, 0, 0);
+ /* Remember the command prefix for this target. */
+ prefix = cmd_prefix;
+
/* We have some targets, so don't ignore the following commands. */
no_targets = 0;
@@ -1840,7 +1831,7 @@ record_files (struct nameseq *filenames, const char *pattern,
const char *pattern_percent, char *depstr,
unsigned int cmds_started, char *commands,
unsigned int commands_idx, int two_colon,
- const struct floc *flocp)
+ char prefix, const struct floc *flocp)
{
struct commands *cmds;
struct dep *deps;
@@ -1866,6 +1857,7 @@ record_files (struct nameseq *filenames, const char *pattern,
cmds->fileinfo.lineno = cmds_started;
cmds->commands = xstrndup (commands, commands_idx);
cmds->command_lines = 0;
+ cmds->recipe_prefix = prefix;
}
else
cmds = 0;
diff --git a/rule.c b/rule.c
index a966cc99..3ad38ebe 100644
--- a/rule.c
+++ b/rule.c
@@ -389,6 +389,7 @@ install_pattern_rule (struct pspec *p, int terminal)
anyway because somebody might want to free them later. */
r->cmds->commands = xstrdup (p->commands);
r->cmds->command_lines = 0;
+ r->cmds->recipe_prefix = RECIPEPREFIX_DEFAULT;
}
}
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 527ecd80..b13e2ae2 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,11 @@
+2010-11-06 Paul Smith <psmith@gnu.org>
+
+ * scripts/features/targetvars: Fix known-good output for BS/NL changes.
+ * scripts/functions/call: Ditto.
+ * scripts/variables/special: Ditto.
+
+ * scripts/misc/bs-nl: New test suite for backslash/newline testing.
+
2010-08-29 Paul Smith <psmith@gnu.org>
* scripts/features/errors: Add new error message to output text.
diff --git a/tests/scripts/features/targetvars b/tests/scripts/features/targetvars
index ddd6c1f5..6afd48aa 100644
--- a/tests/scripts/features/targetvars
+++ b/tests/scripts/features/targetvars
@@ -240,7 +240,7 @@ run_make_test(undef, 'FOO=C', "C f1\n");
# TEST #20: Check for continuation after semicolons
run_make_test(q!
-a: A = 'hello; \
+a: A = 'hello;\
world'
a: ; @echo $(A)
!,
diff --git a/tests/scripts/functions/call b/tests/scripts/functions/call
index f3c54708..6dd48b13 100644
--- a/tests/scripts/functions/call
+++ b/tests/scripts/functions/call
@@ -38,7 +38,7 @@ two = $(call one,$(1),foo,$(2))
DEP_foo = bar baz quux
DEP_baz = quux blarp
rest = $(wordlist 2,$(words ${1}),${1})
-tclose = $(if $1,$(firstword $1) \
+tclose = $(if $1,$(firstword $1)\
$(call tclose,$(sort ${DEP_$(firstword $1)} $(call rest,$1))))
all: ; @echo '$(call reverse,bar,foo)'; \
diff --git a/tests/scripts/misc/bs-nl b/tests/scripts/misc/bs-nl
new file mode 100644
index 00000000..979abb5b
--- /dev/null
+++ b/tests/scripts/misc/bs-nl
@@ -0,0 +1,76 @@
+# -*-perl-*-
+$description = "Test backslash-newline handling.";
+
+$details = "";
+
+# TEST #1
+# -------
+
+# Backslash-newlines in recipes
+
+# These are basic backslash-newlines with no tricks
+run_make_test("fast:;\@echo fa\\\nst\n",
+ '', 'fast');
+
+run_make_test("slow:;\@: no-op; echo sl\\\now\n",
+ '', 'slow');
+
+run_make_test("dquote:;\@echo \"dqu\\\note\"\n",
+ '', 'dquote');
+
+run_make_test("squote:;\@echo 'squ\\\note'\n",
+ '', "squ\\\note");
+
+# Ensure that a leading prefix character is omitted
+run_make_test("fast:;\@echo fa\\\n\tst\n",
+ '', 'fast');
+
+run_make_test("slow:;\@: no-op; echo sl\\\n\tow\n",
+ '', 'slow');
+
+run_make_test("dquote:;\@echo \"dqu\\\n\tote\"\n",
+ '', 'dquote');
+
+run_make_test("squote:;\@echo 'squ\\\n\tote'\n",
+ '', "squ\\\note");
+
+# Ensure that ONLY the leading prefix character is omitted
+run_make_test("fast:;\@echo fa\\\n\t st\n",
+ '', 'fa st');
+
+run_make_test("slow:;\@: no-op; echo sl\\\n\t\tow\n",
+ '', "sl ow");
+
+run_make_test("dquote:;\@echo \"dqu\\\n\t ote\"\n",
+ '', 'dqu ote');
+
+run_make_test("squote:;\@echo 'squ\\\n\t\t ote'\n",
+ '', "squ\\\n\t ote");
+
+# Backslash-newlines in variable values
+
+# Simple
+run_make_test("
+var = he\\\nllo
+var:;\@echo '|\$(var)|'",
+ '', "|he llo|");
+
+# Preserve preceding space
+run_make_test("
+var = he \\\nllo
+var:;\@echo '|\$(var)|'",
+ '', "|he llo|");
+
+# Remove leading space
+run_make_test("
+var = he\\\n llo
+var:;\@echo '|\$(var)|'",
+ '', "|he llo|");
+
+# One space per bs-nl
+run_make_test("
+var = he\\\n\\\n\\\n llo
+var:;\@echo '|\$(var)|'",
+ '', "|he llo|");
+
+1;
diff --git a/tests/scripts/variables/special b/tests/scripts/variables/special
index a1e15c22..4637b2a2 100644
--- a/tests/scripts/variables/special
+++ b/tests/scripts/variables/special
@@ -53,7 +53,7 @@ all:
# Test the .RECIPEPREFIX variable
&run_make_test('
define foo
-: foo-one \
+: foo-one\
foo-two
: foo-three
: foo-four
diff --git a/variable.c b/variable.c
index 0d85546c..b6990887 100644
--- a/variable.c
+++ b/variable.c
@@ -1553,6 +1553,9 @@ print_variable (const void *item, void *arg)
switch (v->origin)
{
+ case o_automatic:
+ origin = _("automatic");
+ break;
case o_default:
origin = _("default");
break;
@@ -1571,9 +1574,6 @@ print_variable (const void *item, void *arg)
case o_override:
origin = _("`override' directive");
break;
- case o_automatic:
- origin = _("automatic");
- break;
case o_invalid:
default:
abort ();
@@ -1617,13 +1617,34 @@ print_variable (const void *item, void *arg)
}
+static void
+print_auto_variable (const void *item, void *arg)
+{
+ const struct variable *v = item;
+
+ if (v->origin == o_automatic)
+ print_variable (item, arg);
+}
+
+
+static void
+print_noauto_variable (const void *item, void *arg)
+{
+ const struct variable *v = item;
+
+ if (v->origin != o_automatic)
+ print_variable (item, arg);
+}
+
+
/* Print all the variables in SET. PREFIX is printed before
the actual variable definitions (everything else is comments). */
void
-print_variable_set (struct variable_set *set, char *prefix)
+print_variable_set (struct variable_set *set, char *prefix, int pauto)
{
- hash_map_arg (&set->table, print_variable, prefix);
+ hash_map_arg (&set->table, (pauto ? print_auto_variable : print_variable),
+ prefix);
fputs (_("# variable set hash-table stats:\n"), stdout);
fputs ("# ", stdout);
@@ -1638,7 +1659,7 @@ print_variable_data_base (void)
{
puts (_("\n# Variables\n"));
- print_variable_set (&global_variable_set, "");
+ print_variable_set (&global_variable_set, "", 0);
puts (_("\n# Pattern-specific Variable Values"));
@@ -1667,7 +1688,24 @@ void
print_file_variables (const struct file *file)
{
if (file->variables != 0)
- print_variable_set (file->variables->set, "# ");
+ print_variable_set (file->variables->set, "# ", 1);
+}
+
+void
+print_target_variables (const struct file *file)
+{
+ if (file->variables != 0)
+ {
+ int l = strlen (file->name);
+ char *t = alloca (l + 3);
+
+ strcpy (t, file->name);
+ t[l] = ':';
+ t[l+1] = ' ';
+ t[l+2] = '\0';
+
+ hash_map_arg (&file->variables->set->table, print_noauto_variable, t);
+ }
}
#ifdef WINDOWS32
diff --git a/variable.h b/variable.h
index c2158672..04ca0740 100644
--- a/variable.h
+++ b/variable.h
@@ -147,7 +147,8 @@ void pop_variable_scope (void);
void define_automatic_variables (void);
void initialize_file_variables (struct file *file, int reading);
void print_file_variables (const struct file *file);
-void print_variable_set (struct variable_set *set, char *prefix);
+void print_file_variables (const struct file *file);
+void print_target_variables (const struct file *file);
void merge_variable_set_lists (struct variable_set_list **to_list,
struct variable_set_list *from_list);
struct variable *do_variable_definition (const struct floc *flocp,