Implement setlocal/endlocal.
This commit is contained in:
parent
9d61aee357
commit
9643b79842
|
@ -36,6 +36,14 @@
|
||||||
|
|
||||||
void WCMD_execute (char *orig_command, char *parameter, char *substitution);
|
void WCMD_execute (char *orig_command, char *parameter, char *substitution);
|
||||||
|
|
||||||
|
struct env_stack
|
||||||
|
{
|
||||||
|
struct env_stack *next;
|
||||||
|
WCHAR *strings;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct env_stack *saved_environment;
|
||||||
|
|
||||||
extern HINSTANCE hinst;
|
extern HINSTANCE hinst;
|
||||||
extern char *inbuilt[];
|
extern char *inbuilt[];
|
||||||
extern char nyi[];
|
extern char nyi[];
|
||||||
|
@ -506,6 +514,133 @@ int status;
|
||||||
if (!status) WCMD_print_error ();
|
if (!status) WCMD_print_error ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* WCMD_dupenv
|
||||||
|
*
|
||||||
|
* Make a copy of the environment.
|
||||||
|
*/
|
||||||
|
WCHAR *WCMD_dupenv( const WCHAR *env )
|
||||||
|
{
|
||||||
|
WCHAR *env_copy;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if( !env )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
while ( env[len] )
|
||||||
|
len += (lstrlenW(&env[len]) + 1);
|
||||||
|
|
||||||
|
env_copy = LocalAlloc (LMEM_FIXED, (len+1) * sizeof (WCHAR) );
|
||||||
|
if (!env_copy)
|
||||||
|
{
|
||||||
|
WCMD_output ("out of memory\n");
|
||||||
|
return env_copy;
|
||||||
|
}
|
||||||
|
memcpy (env_copy, env, len*sizeof (WCHAR));
|
||||||
|
env_copy[len] = 0;
|
||||||
|
|
||||||
|
return env_copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* WCMD_setlocal
|
||||||
|
*
|
||||||
|
* setlocal pushes the environment onto a stack
|
||||||
|
* Save the environment as unicode so we don't screw anything up.
|
||||||
|
*/
|
||||||
|
void WCMD_setlocal (const char *s) {
|
||||||
|
WCHAR *env;
|
||||||
|
struct env_stack *env_copy;
|
||||||
|
|
||||||
|
/* DISABLEEXTENSIONS ignored */
|
||||||
|
|
||||||
|
env_copy = LocalAlloc (LMEM_FIXED, sizeof (struct env_stack));
|
||||||
|
if( !env_copy )
|
||||||
|
{
|
||||||
|
WCMD_output ("out of memory\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
env = GetEnvironmentStringsW ();
|
||||||
|
|
||||||
|
env_copy->strings = WCMD_dupenv (env);
|
||||||
|
if (env_copy->strings)
|
||||||
|
{
|
||||||
|
env_copy->next = saved_environment;
|
||||||
|
saved_environment = env_copy;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LocalFree (env_copy);
|
||||||
|
|
||||||
|
FreeEnvironmentStringsW (env);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* WCMD_strchrW
|
||||||
|
*/
|
||||||
|
inline WCHAR *WCMD_strchrW(WCHAR *str, WCHAR ch)
|
||||||
|
{
|
||||||
|
while(*str)
|
||||||
|
{
|
||||||
|
if(*str == ch)
|
||||||
|
return str;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* WCMD_endlocal
|
||||||
|
*
|
||||||
|
* endlocal pops the environment off a stack
|
||||||
|
*/
|
||||||
|
void WCMD_endlocal (void) {
|
||||||
|
WCHAR *env, *old, *p;
|
||||||
|
struct env_stack *temp;
|
||||||
|
int len, n;
|
||||||
|
|
||||||
|
if (!saved_environment)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* pop the old environment from the stack */
|
||||||
|
temp = saved_environment;
|
||||||
|
saved_environment = temp->next;
|
||||||
|
|
||||||
|
/* delete the current environment, totally */
|
||||||
|
env = GetEnvironmentStringsW ();
|
||||||
|
old = WCMD_dupenv (GetEnvironmentStringsW ());
|
||||||
|
len = 0;
|
||||||
|
while (old[len]) {
|
||||||
|
n = lstrlenW(&old[len]) + 1;
|
||||||
|
p = WCMD_strchrW(&old[len], '=');
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
*p++ = 0;
|
||||||
|
SetEnvironmentVariableW (&old[len], NULL);
|
||||||
|
}
|
||||||
|
len += n;
|
||||||
|
}
|
||||||
|
LocalFree (old);
|
||||||
|
FreeEnvironmentStringsW (env);
|
||||||
|
|
||||||
|
/* restore old environment */
|
||||||
|
env = temp->strings;
|
||||||
|
len = 0;
|
||||||
|
while (env[len]) {
|
||||||
|
n = lstrlenW(&env[len]) + 1;
|
||||||
|
p = WCMD_strchrW(&env[len], '=');
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
*p++ = 0;
|
||||||
|
SetEnvironmentVariableW (&env[len], p);
|
||||||
|
}
|
||||||
|
len += n;
|
||||||
|
}
|
||||||
|
LocalFree (env);
|
||||||
|
LocalFree (temp);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* WCMD_setshow_attrib
|
* WCMD_setshow_attrib
|
||||||
*
|
*
|
||||||
|
|
|
@ -35,6 +35,7 @@ void WCMD_create_dir (void);
|
||||||
void WCMD_delete (int recurse);
|
void WCMD_delete (int recurse);
|
||||||
void WCMD_directory (void);
|
void WCMD_directory (void);
|
||||||
void WCMD_echo (const char *);
|
void WCMD_echo (const char *);
|
||||||
|
void WCMD_endlocal (void);
|
||||||
void WCMD_enter_paged_mode(void);
|
void WCMD_enter_paged_mode(void);
|
||||||
void WCMD_for (char *);
|
void WCMD_for (char *);
|
||||||
void WCMD_give_help (char *command);
|
void WCMD_give_help (char *command);
|
||||||
|
@ -53,6 +54,7 @@ int WCMD_read_console (char *string, int str_len);
|
||||||
void WCMD_remove_dir (void);
|
void WCMD_remove_dir (void);
|
||||||
void WCMD_rename (void);
|
void WCMD_rename (void);
|
||||||
void WCMD_run_program (char *command);
|
void WCMD_run_program (char *command);
|
||||||
|
void WCMD_setlocal (const char *command);
|
||||||
void WCMD_setshow_attrib (void);
|
void WCMD_setshow_attrib (void);
|
||||||
void WCMD_setshow_date (void);
|
void WCMD_setshow_date (void);
|
||||||
void WCMD_setshow_default (void);
|
void WCMD_setshow_default (void);
|
||||||
|
@ -130,5 +132,8 @@ typedef struct {
|
||||||
#define WCMD_VER 34
|
#define WCMD_VER 34
|
||||||
#define WCMD_VOL 35
|
#define WCMD_VOL 35
|
||||||
|
|
||||||
|
#define WCMD_ENDLOCAL 36
|
||||||
|
#define WCMD_SETLOCAL 37
|
||||||
|
|
||||||
/* Must be last in list */
|
/* Must be last in list */
|
||||||
#define WCMD_EXIT 36
|
#define WCMD_EXIT 38
|
||||||
|
|
|
@ -31,7 +31,8 @@ const char *inbuilt[] = {"ATTRIB", "CALL", "CD", "CHDIR", "CLS", "COPY", "CTTY",
|
||||||
"DATE", "DEL", "DIR", "ECHO", "ERASE", "FOR", "GOTO",
|
"DATE", "DEL", "DIR", "ECHO", "ERASE", "FOR", "GOTO",
|
||||||
"HELP", "IF", "LABEL", "MD", "MKDIR", "MOVE", "PATH", "PAUSE",
|
"HELP", "IF", "LABEL", "MD", "MKDIR", "MOVE", "PATH", "PAUSE",
|
||||||
"PROMPT", "REM", "REN", "RENAME", "RD", "RMDIR", "SET", "SHIFT",
|
"PROMPT", "REM", "REN", "RENAME", "RD", "RMDIR", "SET", "SHIFT",
|
||||||
"TIME", "TITLE", "TYPE", "VERIFY", "VER", "VOL", "EXIT" };
|
"TIME", "TITLE", "TYPE", "VERIFY", "VER", "VOL",
|
||||||
|
"ENDLOCAL", "SETLOCAL", "EXIT" };
|
||||||
|
|
||||||
HINSTANCE hinst;
|
HINSTANCE hinst;
|
||||||
DWORD errorlevel;
|
DWORD errorlevel;
|
||||||
|
@ -427,6 +428,12 @@ void WCMD_process_command (char *command)
|
||||||
case WCMD_RMDIR:
|
case WCMD_RMDIR:
|
||||||
WCMD_remove_dir ();
|
WCMD_remove_dir ();
|
||||||
break;
|
break;
|
||||||
|
case WCMD_SETLOCAL:
|
||||||
|
WCMD_setlocal(p);
|
||||||
|
break;
|
||||||
|
case WCMD_ENDLOCAL:
|
||||||
|
WCMD_endlocal();
|
||||||
|
break;
|
||||||
case WCMD_SET:
|
case WCMD_SET:
|
||||||
WCMD_setshow_env (p);
|
WCMD_setshow_env (p);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue