- Support whitespace around commands better, and support the @

prefix better
- Enhance the set support to unset, display value error correctly
- Enhance the command line support for parms, and env var expansion
- Enhance the echo command to not loose whitespace, and display
  output with % signs better
This commit is contained in:
Jason Edmeades 2000-08-01 02:14:33 +00:00 committed by Alexandre Julliard
parent 4eefb96db5
commit a5910f45bd
4 changed files with 93 additions and 21 deletions

View File

@ -95,18 +95,22 @@ BATCH_CONTEXT *prev_context;
void WCMD_batch_command (char *line) { void WCMD_batch_command (char *line) {
DWORD status; DWORD status;
char cmd[1024]; char cmd1[1024],cmd2[1024];
char *p, *s, *t; char *p, *s, *t;
int i; int i;
if (echo_mode && (line[0] != '@')) WCMD_output ("%s", line); /* Get working version of command line */
status = ExpandEnvironmentStrings (line, cmd, sizeof(cmd)); strcpy(cmd1, line);
if (!status) {
WCMD_print_error ();
return;
}
p = cmd; /* Expand environment variables in a batch file %{0-9} first */
/* Then env vars, and if any left (ie use of undefined vars,*/
/* replace with spaces */
/* FIXME: Winnt would replace %1%fred%1 with first parm, then */
/* contents of fred, then the digit 1. Would need to remove */
/* ExpandEnvStrings to achieve this */
/* Replace use of %0...%9 */
p = cmd1;
while ((p = strchr(p, '%'))) { while ((p = strchr(p, '%'))) {
i = *(p+1) - '0'; i = *(p+1) - '0';
if ((i >= 0) && (i <= 9)) { if ((i >= 0) && (i <= 9)) {
@ -115,9 +119,39 @@ int i;
strcpy (p, t); strcpy (p, t);
strcat (p, s); strcat (p, s);
free (s); free (s);
} } else {
p++;
}
} }
WCMD_process_command (cmd);
/* Now replace environment variables */
status = ExpandEnvironmentStrings(cmd1, cmd2, sizeof(cmd2));
if (!status) {
WCMD_print_error ();
return;
}
/* In a batch program, unknown variables are replace by nothing */
/* so remove any remaining %var% */
p = cmd2;
while ((p = strchr(p, '%'))) {
s = strchr(p+1, '%');
if (!s) {
*p=0x00;
} else {
t = strdup(s+1);
strcpy(p, t);
free(t);
}
}
/* Show prompt before batch line IF echo is on */
if (echo_mode && (line[0] != '@')) {
WCMD_show_prompt();
WCMD_output ("%s\n", cmd2);
}
WCMD_process_command (cmd2);
} }
/******************************************************************* /*******************************************************************

View File

@ -181,7 +181,7 @@ int count;
echo_mode = 0; echo_mode = 0;
return; return;
} }
WCMD_output (command); WCMD_output_asis (command);
WCMD_output (newline); WCMD_output (newline);
} }
@ -566,6 +566,7 @@ void WCMD_setshow_env (char *s) {
LPVOID env; LPVOID env;
char *p; char *p;
int status; int status;
char buffer[1048];
if (strlen(param1) == 0) { if (strlen(param1) == 0) {
env = GetEnvironmentStrings (); env = GetEnvironmentStrings ();
@ -578,14 +579,26 @@ int status;
else { else {
p = strchr (s, '='); p = strchr (s, '=');
if (p == NULL) { if (p == NULL) {
WCMD_output ("Command Syntax: SET variable=value\n");
/* FIXME: Emulate Win98 for now, ie "SET C" looks ONLY for an
environment variable C, whereas on NT it shows ALL variables
starting with C.
*/
status = GetEnvironmentVariable(s, buffer, sizeof(buffer));
if (status) {
WCMD_output("%s=%s\n", s, buffer);
} else {
WCMD_output ("Environment variable %s not defined\n", s);
}
return; return;
} }
*p++ = '\0'; *p++ = '\0';
status = SetEnvironmentVariable (s, p);
if (strlen(p) == 0) p = 0x00;
status = SetEnvironmentVariable (s, p);
if (!status) WCMD_print_error(); if (!status) WCMD_print_error();
} }
WCMD_output (newline); /* WCMD_output (newline); @JED*/
} }
/**************************************************************************** /****************************************************************************

View File

@ -33,6 +33,7 @@ void WCMD_goto (void);
void WCMD_if (char *); void WCMD_if (char *);
void WCMD_move (void); void WCMD_move (void);
void WCMD_output (char *format, ...); void WCMD_output (char *format, ...);
void WCMD_output_asis (char *message);
void WCMD_parse (char *s, char *q, char *p1, char *p2); void WCMD_parse (char *s, char *q, char *p1, char *p2);
void WCMD_pause (void); void WCMD_pause (void);
void WCMD_print_error (void); void WCMD_print_error (void);

View File

@ -127,6 +127,7 @@ char *p;
int status, i; int status, i;
DWORD count; DWORD count;
HANDLE old_stdin = 0, old_stdout = 0, h; HANDLE old_stdin = 0, old_stdout = 0, h;
char *whichcmd;
/* /*
* Throw away constructs we don't support yet * Throw away constructs we don't support yet
@ -156,7 +157,8 @@ HANDLE old_stdin = 0, old_stdout = 0, h;
if (!status) WCMD_print_error (); if (!status) WCMD_print_error ();
return; return;
} }
WCMD_output (newline);
/* Dont issue newline WCMD_output (newline); @JED*/
/* /*
* Redirect stdin and/or stdout if required. * Redirect stdin and/or stdout if required.
@ -185,20 +187,26 @@ HANDLE old_stdin = 0, old_stdout = 0, h;
} }
if ((p = strchr(cmd,'<')) != NULL) *p = '\0'; if ((p = strchr(cmd,'<')) != NULL) *p = '\0';
/*
* Strip leading whitespaces, and a '@' if supplied
*/
whichcmd = WCMD_strtrim_leading_spaces(cmd);
if (whichcmd[0] == '@') whichcmd++;
/* /*
* Check if the command entered is internal. If it is, pass the rest of the * Check if the command entered is internal. If it is, pass the rest of the
* line down to the command. If not try to run a program. * line down to the command. If not try to run a program.
*/ */
count = 0; count = 0;
while (IsCharAlphaNumeric(cmd[count])) { while (IsCharAlphaNumeric(whichcmd[count])) {
count++; count++;
} }
for (i=0; i<=WCMD_EXIT; i++) { for (i=0; i<=WCMD_EXIT; i++) {
if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
cmd, count, inbuilt[i], -1) == 2) break; whichcmd, count, inbuilt[i], -1) == 2) break;
} }
p = WCMD_strtrim_leading_spaces (&cmd[count]); p = WCMD_strtrim_leading_spaces (&whichcmd[count]);
WCMD_parse (p, quals, param1, param2); WCMD_parse (p, quals, param1, param2);
switch (i) { switch (i) {
@ -232,8 +240,13 @@ HANDLE old_stdin = 0, old_stdout = 0, h;
WCMD_directory (); WCMD_directory ();
break; break;
case WCMD_ECHO: case WCMD_ECHO:
WCMD_echo (p); /* Use the unstripped version of the following data - step over the space */
break; /* but only if a parameter follows */
if (strlen(&whichcmd[count]) > 0)
WCMD_echo(&whichcmd[count+1]);
else
WCMD_echo(&whichcmd[count]);
break;
case WCMD_FOR: case WCMD_FOR:
WCMD_for (p); WCMD_for (p);
break; break;
@ -299,7 +312,7 @@ HANDLE old_stdin = 0, old_stdout = 0, h;
case WCMD_EXIT: case WCMD_EXIT:
ExitProcess (0); ExitProcess (0);
default: default:
WCMD_run_program (cmd); WCMD_run_program (whichcmd);
}; };
if (old_stdin) { if (old_stdin) {
CloseHandle (GetStdHandle (STD_INPUT_HANDLE)); CloseHandle (GetStdHandle (STD_INPUT_HANDLE));
@ -543,6 +556,17 @@ DWORD count;
va_end(ap); va_end(ap);
} }
/*******************************************************************
* WCMD_output_asis - send output to current standard output device.
* without formatting eg. when message contains '%'
*/
void WCMD_output_asis (char *message) {
DWORD count;
WriteFile (GetStdHandle(STD_OUTPUT_HANDLE), message, lstrlen(message), &count, NULL);
}
/* Remove leading spaces from a string. Return a pointer to the first /* Remove leading spaces from a string. Return a pointer to the first
* non-space character. Does not modify the input string * non-space character. Does not modify the input string