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);
|
||||
|
||||
struct env_stack
|
||||
{
|
||||
struct env_stack *next;
|
||||
WCHAR *strings;
|
||||
};
|
||||
|
||||
struct env_stack *saved_environment;
|
||||
|
||||
extern HINSTANCE hinst;
|
||||
extern char *inbuilt[];
|
||||
extern char nyi[];
|
||||
|
@ -506,6 +514,133 @@ int status;
|
|||
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
|
||||
*
|
||||
|
|
|
@ -35,6 +35,7 @@ void WCMD_create_dir (void);
|
|||
void WCMD_delete (int recurse);
|
||||
void WCMD_directory (void);
|
||||
void WCMD_echo (const char *);
|
||||
void WCMD_endlocal (void);
|
||||
void WCMD_enter_paged_mode(void);
|
||||
void WCMD_for (char *);
|
||||
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_rename (void);
|
||||
void WCMD_run_program (char *command);
|
||||
void WCMD_setlocal (const char *command);
|
||||
void WCMD_setshow_attrib (void);
|
||||
void WCMD_setshow_date (void);
|
||||
void WCMD_setshow_default (void);
|
||||
|
@ -130,5 +132,8 @@ typedef struct {
|
|||
#define WCMD_VER 34
|
||||
#define WCMD_VOL 35
|
||||
|
||||
#define WCMD_ENDLOCAL 36
|
||||
#define WCMD_SETLOCAL 37
|
||||
|
||||
/* 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",
|
||||
"HELP", "IF", "LABEL", "MD", "MKDIR", "MOVE", "PATH", "PAUSE",
|
||||
"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;
|
||||
DWORD errorlevel;
|
||||
|
@ -427,6 +428,12 @@ void WCMD_process_command (char *command)
|
|||
case WCMD_RMDIR:
|
||||
WCMD_remove_dir ();
|
||||
break;
|
||||
case WCMD_SETLOCAL:
|
||||
WCMD_setlocal(p);
|
||||
break;
|
||||
case WCMD_ENDLOCAL:
|
||||
WCMD_endlocal();
|
||||
break;
|
||||
case WCMD_SET:
|
||||
WCMD_setshow_env (p);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue