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:
Eli Zaretskii 2013-04-27 19:12:01 +03:00
parent 049f8e88fc
commit e56aad4061
3 changed files with 106 additions and 22 deletions

View file

@ -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>
* job.c: Fix compilation error on GNU/Linux due to "label at end

119
job.c
View file

@ -3232,7 +3232,12 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
#if defined __MSDOS__ || defined (__EMX__)
if (unixy_shell) /* the test is complicated and we already did it */
#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
{
const char *f = line;
@ -3267,31 +3272,103 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
}
}
*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. */
{
int n = 0;
/* Generate a file name for the temporary batch file. */
sprintf(fbuf, "make%d", id);
*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 *));
new_argv[n++] = xstrdup (shell);
/* Create a FILE object for the batch file, and write to it the
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. */
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);
}
/* Copy the recipe, removing and ignoring interior prefix chars
[@+-]: they're meaningless in .ONESHELL mode. */
while (*f != '\0')
{
/* This is the start of a new recipe line.
Skip whitespace and prefix characters. */
while (isblank (*f) || *f == '-' || *f == '@' || *f == '+')
++f;
/* Set the command to invoke. */
new_argv[n++] = line;
new_argv[n++] = NULL;
}
/* Copy until we get to the next logical recipe line. */
while (*f != '\0')
{
/* 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;
}

2
read.c
View file

@ -2048,7 +2048,7 @@ record_files (struct nameseq *filenames, const char *pattern,
}
else if (streq (name, ".SECONDEXPANSION"))
second_expansion = 1;
#if !defined(WINDOWS32) && !defined (__MSDOS__) && !defined (__EMX__)
#if !defined (__MSDOS__) && !defined (__EMX__)
else if (streq (name, ".ONESHELL"))
one_shell = 1;
#endif