mirror of
https://github.com/mirror/make.git
synced 2025-03-26 12:04:42 +08:00
Support .ONESHELL on MS-Windows, for default Windows shells.
read.c (record_files): Pay attention to .ONESHELL in MS-Windows. job.c (construct_command_argv_internal): Support .ONESHELL on MS-Windows, when the shell is not a Unixy shell.
This commit is contained in:
parent
049f8e88fc
commit
e56aad4061
@ -1,3 +1,10 @@
|
|||||||
|
2013-04-27 Eli Zaretskii <eliz@gnu.org>
|
||||||
|
|
||||||
|
* read.c (record_files): Pay attention to .ONESHELL in MS-Windows.
|
||||||
|
|
||||||
|
* job.c (construct_command_argv_internal): Support .ONESHELL on
|
||||||
|
MS-Windows, when the shell is not a Unixy shell.
|
||||||
|
|
||||||
2013-04-27 Eli Zaretskii <eliz@gnu.org>
|
2013-04-27 Eli Zaretskii <eliz@gnu.org>
|
||||||
|
|
||||||
* job.c: Fix compilation error on GNU/Linux due to "label at end
|
* job.c: Fix compilation error on GNU/Linux due to "label at end
|
||||||
|
119
job.c
119
job.c
@ -3232,7 +3232,12 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
|
|||||||
#if defined __MSDOS__ || defined (__EMX__)
|
#if defined __MSDOS__ || defined (__EMX__)
|
||||||
if (unixy_shell) /* the test is complicated and we already did it */
|
if (unixy_shell) /* the test is complicated and we already did it */
|
||||||
#else
|
#else
|
||||||
if (is_bourne_compatible_shell(shell))
|
if (is_bourne_compatible_shell(shell)
|
||||||
|
#ifdef WINDOWS32
|
||||||
|
/* If we didn't find any sh.exe, don't behave is if we did! */
|
||||||
|
&& !no_default_sh_exe
|
||||||
|
#endif
|
||||||
|
)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
const char *f = line;
|
const char *f = line;
|
||||||
@ -3267,31 +3272,103 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*t = '\0';
|
*t = '\0';
|
||||||
|
|
||||||
|
/* Create an argv list for the shell command line. */
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
new_argv = xmalloc ((4 + sflags_len/2) * sizeof (char *));
|
||||||
|
new_argv[n++] = xstrdup (shell);
|
||||||
|
|
||||||
|
/* Chop up the shellflags (if any) and assign them. */
|
||||||
|
if (! shellflags)
|
||||||
|
new_argv[n++] = xstrdup ("");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char *s = shellflags;
|
||||||
|
char *t;
|
||||||
|
unsigned int len;
|
||||||
|
while ((t = find_next_token (&s, &len)) != 0)
|
||||||
|
new_argv[n++] = xstrndup (t, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the command to invoke. */
|
||||||
|
new_argv[n++] = line;
|
||||||
|
new_argv[n++] = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef WINDOWS32
|
||||||
|
else /* non-Posix shell */
|
||||||
|
{
|
||||||
|
const char *f = line;
|
||||||
|
char *t = line;
|
||||||
|
char *tstart = t;
|
||||||
|
int temp_fd;
|
||||||
|
FILE* batch = NULL;
|
||||||
|
int id = GetCurrentProcessId();
|
||||||
|
PATH_VAR(fbuf);
|
||||||
|
|
||||||
/* Create an argv list for the shell command line. */
|
/* Generate a file name for the temporary batch file. */
|
||||||
{
|
sprintf(fbuf, "make%d", id);
|
||||||
int n = 0;
|
*batch_filename = create_batch_file (fbuf, 0, &temp_fd);
|
||||||
|
DB (DB_JOBS, (_("Creating temporary batch file %s\n"),
|
||||||
|
*batch_filename));
|
||||||
|
|
||||||
new_argv = xmalloc ((4 + sflags_len/2) * sizeof (char *));
|
/* Create a FILE object for the batch file, and write to it the
|
||||||
new_argv[n++] = xstrdup (shell);
|
commands to be executed. Put the batch file in TEXT mode. */
|
||||||
|
_setmode (temp_fd, _O_TEXT);
|
||||||
|
batch = _fdopen (temp_fd, "wt");
|
||||||
|
fputs ("@echo off\n", batch);
|
||||||
|
DB (DB_JOBS, (_("Batch file contents:\n\t@echo off\n")));
|
||||||
|
|
||||||
/* Chop up the shellflags (if any) and assign them. */
|
/* Copy the recipe, removing and ignoring interior prefix chars
|
||||||
if (! shellflags)
|
[@+-]: they're meaningless in .ONESHELL mode. */
|
||||||
new_argv[n++] = xstrdup ("");
|
while (*f != '\0')
|
||||||
else
|
{
|
||||||
{
|
/* This is the start of a new recipe line.
|
||||||
const char *s = shellflags;
|
Skip whitespace and prefix characters. */
|
||||||
char *t;
|
while (isblank (*f) || *f == '-' || *f == '@' || *f == '+')
|
||||||
unsigned int len;
|
++f;
|
||||||
while ((t = find_next_token (&s, &len)) != 0)
|
|
||||||
new_argv[n++] = xstrndup (t, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the command to invoke. */
|
/* Copy until we get to the next logical recipe line. */
|
||||||
new_argv[n++] = line;
|
while (*f != '\0')
|
||||||
new_argv[n++] = NULL;
|
{
|
||||||
}
|
/* Remove the escaped newlines in the command, and
|
||||||
|
the whitespace that follows them. Windows
|
||||||
|
shells cannot handle escaped newlines. */
|
||||||
|
if (*f == '\\' && f[1] == '\n')
|
||||||
|
{
|
||||||
|
f += 2;
|
||||||
|
while (isblank (*f))
|
||||||
|
++f;
|
||||||
|
}
|
||||||
|
*(t++) = *(f++);
|
||||||
|
/* On an unescaped newline, we're done with this
|
||||||
|
line. */
|
||||||
|
if (f[-1] == '\n')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Write another line into the batch file. */
|
||||||
|
if (t > tstart)
|
||||||
|
{
|
||||||
|
int c = *t;
|
||||||
|
*t = '\0';
|
||||||
|
fputs (tstart, batch);
|
||||||
|
DB (DB_JOBS, ("\t%s", tstart));
|
||||||
|
tstart = t;
|
||||||
|
*t = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DB (DB_JOBS, ("\n"));
|
||||||
|
fclose (batch);
|
||||||
|
|
||||||
|
/* Create an argv list for the shell command line that
|
||||||
|
will run the batch file. */
|
||||||
|
new_argv = xmalloc (2 * sizeof (char *));
|
||||||
|
new_argv[0] = xstrdup (*batch_filename);
|
||||||
|
new_argv[1] = NULL;
|
||||||
|
}
|
||||||
|
#endif /* WINDOWS32 */
|
||||||
return new_argv;
|
return new_argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
read.c
2
read.c
@ -2048,7 +2048,7 @@ record_files (struct nameseq *filenames, const char *pattern,
|
|||||||
}
|
}
|
||||||
else if (streq (name, ".SECONDEXPANSION"))
|
else if (streq (name, ".SECONDEXPANSION"))
|
||||||
second_expansion = 1;
|
second_expansion = 1;
|
||||||
#if !defined(WINDOWS32) && !defined (__MSDOS__) && !defined (__EMX__)
|
#if !defined (__MSDOS__) && !defined (__EMX__)
|
||||||
else if (streq (name, ".ONESHELL"))
|
else if (streq (name, ".ONESHELL"))
|
||||||
one_shell = 1;
|
one_shell = 1;
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user