Commit a5910f45 authored by Jason Edmeades's avatar Jason Edmeades Committed by Alexandre Julliard

- 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
parent 4eefb96d
......@@ -95,18 +95,22 @@ BATCH_CONTEXT *prev_context;
void WCMD_batch_command (char *line) {
DWORD status;
char cmd[1024];
char cmd1[1024],cmd2[1024];
char *p, *s, *t;
int i;
if (echo_mode && (line[0] != '@')) WCMD_output ("%s", line);
status = ExpandEnvironmentStrings (line, cmd, sizeof(cmd));
if (!status) {
WCMD_print_error ();
return;
}
/* Get working version of command line */
strcpy(cmd1, line);
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, '%'))) {
i = *(p+1) - '0';
if ((i >= 0) && (i <= 9)) {
......@@ -115,9 +119,39 @@ int i;
strcpy (p, t);
strcat (p, 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);
}
/*******************************************************************
......
......@@ -181,7 +181,7 @@ int count;
echo_mode = 0;
return;
}
WCMD_output (command);
WCMD_output_asis (command);
WCMD_output (newline);
}
......@@ -566,6 +566,7 @@ void WCMD_setshow_env (char *s) {
LPVOID env;
char *p;
int status;
char buffer[1048];
if (strlen(param1) == 0) {
env = GetEnvironmentStrings ();
......@@ -578,14 +579,26 @@ int status;
else {
p = strchr (s, '=');
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;
}
*p++ = '\0';
status = SetEnvironmentVariable (s, p);
if (strlen(p) == 0) p = 0x00;
status = SetEnvironmentVariable (s, p);
if (!status) WCMD_print_error();
}
WCMD_output (newline);
/* WCMD_output (newline); @JED*/
}
/****************************************************************************
......
......@@ -33,6 +33,7 @@ void WCMD_goto (void);
void WCMD_if (char *);
void WCMD_move (void);
void WCMD_output (char *format, ...);
void WCMD_output_asis (char *message);
void WCMD_parse (char *s, char *q, char *p1, char *p2);
void WCMD_pause (void);
void WCMD_print_error (void);
......
......@@ -127,6 +127,7 @@ char *p;
int status, i;
DWORD count;
HANDLE old_stdin = 0, old_stdout = 0, h;
char *whichcmd;
/*
* 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 ();
return;
}
WCMD_output (newline);
/* Dont issue newline WCMD_output (newline); @JED*/
/*
* 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';
/*
* 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
* line down to the command. If not try to run a program.
*/
count = 0;
while (IsCharAlphaNumeric(cmd[count])) {
while (IsCharAlphaNumeric(whichcmd[count])) {
count++;
}
for (i=0; i<=WCMD_EXIT; i++) {
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);
switch (i) {
......@@ -232,8 +240,13 @@ HANDLE old_stdin = 0, old_stdout = 0, h;
WCMD_directory ();
break;
case WCMD_ECHO:
WCMD_echo (p);
break;
/* Use the unstripped version of the following data - step over the space */
/* 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:
WCMD_for (p);
break;
......@@ -299,7 +312,7 @@ HANDLE old_stdin = 0, old_stdout = 0, h;
case WCMD_EXIT:
ExitProcess (0);
default:
WCMD_run_program (cmd);
WCMD_run_program (whichcmd);
};
if (old_stdin) {
CloseHandle (GetStdHandle (STD_INPUT_HANDLE));
......@@ -543,6 +556,17 @@ DWORD count;
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
* non-space character. Does not modify the input string
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment