mirror of
https://github.com/mirror/make.git
synced 2025-03-25 01:00:30 +08:00
Formerly job.c.~95~
This commit is contained in:
parent
db545dffcc
commit
573ddaf6da
99
job.c
99
job.c
@ -690,8 +690,103 @@ new_job (file)
|
||||
/* Expand the command lines and store the results in LINES. */
|
||||
lines = (char **) xmalloc (cmds->ncommand_lines * sizeof (char *));
|
||||
for (i = 0; i < cmds->ncommand_lines; ++i)
|
||||
lines[i] = allocated_variable_expand_for_file (cmds->command_lines[i],
|
||||
file);
|
||||
{
|
||||
/* Collapse backslash-newline combinations that are inside variable
|
||||
or function references. These are left alone by the parser so
|
||||
that they will appear in the echoing of commands (where they look
|
||||
nice); and collapsed by construct_command_argv when it tokenizes.
|
||||
But letting them survive inside function invocations loses because
|
||||
we don't want the functions to see them as part of the text. */
|
||||
|
||||
char *in, *out, *ref;
|
||||
|
||||
/* IN points to where in the line we are scanning.
|
||||
OUT points to where in the line we are writing.
|
||||
When we collapse a backslash-newline combination,
|
||||
IN gets ahead out OUT. */
|
||||
|
||||
in = out = cmds->command_lines[i];
|
||||
while ((ref = index (in, '$')) != 0)
|
||||
{
|
||||
++ref; /* Move past the $. */
|
||||
|
||||
if (out != in)
|
||||
/* Copy the text between the end of the last chunk
|
||||
we processed (where IN points) and the new chunk
|
||||
we are about to process (where REF points). */
|
||||
bcopy (in, out, ref - in);
|
||||
|
||||
/* Move both pointers past the boring stuff. */
|
||||
out += ref - in;
|
||||
in = ref;
|
||||
|
||||
if (*ref == '(' || *ref == '{')
|
||||
{
|
||||
char openparen = *ref;
|
||||
char closeparen = openparen == '(' ? ')' : '}';
|
||||
int count;
|
||||
char *p;
|
||||
|
||||
*out++ = *in++; /* Copy OPENPAREN. */
|
||||
/* IN now points past the opening paren or brace.
|
||||
Count parens or braces until it is matched. */
|
||||
count = 0;
|
||||
while (*in != '\0')
|
||||
{
|
||||
if (*in == closeparen && --count < 0)
|
||||
break;
|
||||
else if (*in == '\\' && in[1] == '\n')
|
||||
{
|
||||
/* We have found a backslash-newline inside a
|
||||
variable or function reference. Eat it and
|
||||
any following whitespace. */
|
||||
|
||||
int quoted = 0;
|
||||
for (p = in - 1; p > ref && *p == '\\'; --p)
|
||||
quoted = !quoted;
|
||||
|
||||
if (quoted)
|
||||
/* There were two or more backslashes, so this is
|
||||
not really a continuation line. We don't collapse
|
||||
the quoting backslashes here as is done in
|
||||
collapse_continuations, because the line will
|
||||
be collapsed again after expansion. */
|
||||
*out++ = *in++;
|
||||
else
|
||||
{
|
||||
/* Skip the backslash, newline and
|
||||
any following whitespace. */
|
||||
in = next_token (in + 2);
|
||||
|
||||
/* Discard any preceding whitespace that has
|
||||
already been written to the output. */
|
||||
while (out > ref && isblank (out[-1]))
|
||||
--out;
|
||||
|
||||
/* Replace it all with a single space. */
|
||||
*out++ = ' ';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*in == openparen)
|
||||
++count;
|
||||
|
||||
*out++ = *in++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* There are no more references in this line to worry about.
|
||||
Copy the remaining uninteresting text to the output. */
|
||||
if (out != in)
|
||||
strcpy (out, in);
|
||||
|
||||
/* Finally, expand the line. */
|
||||
lines[i] = allocated_variable_expand_for_file (cmds->command_lines[i],
|
||||
file);
|
||||
}
|
||||
|
||||
/* Start the command sequence, record it in a new
|
||||
`struct child', and add that to the chain. */
|
||||
|
Loading…
Reference in New Issue
Block a user