2 * SETLOCAL.C - setlocal and endlocal internal batch commands.
6 * 1 Feb 2008 (Christoph von Wittich)
12 typedef struct _SETLOCAL
{
13 struct _SETLOCAL
*Prev
;
14 BOOL DelayedExpansion
;
18 /* Create a copy of the current environment */
20 DuplicateEnvironment(VOID
)
22 LPTSTR Environ
= GetEnvironmentStrings();
23 LPTSTR End
, EnvironCopy
;
26 for (End
= Environ
; *End
; End
+= _tcslen(End
) + 1)
28 EnvironCopy
= cmd_alloc((End
+ 1 - Environ
) * sizeof(TCHAR
));
30 memcpy(EnvironCopy
, Environ
, (End
+ 1 - Environ
) * sizeof(TCHAR
));
31 FreeEnvironmentStrings(Environ
);
35 INT
cmd_setlocal(LPTSTR param
)
41 /* SETLOCAL only works inside a batch file */
45 Saved
= cmd_alloc(sizeof(SETLOCAL
));
48 error_out_of_memory();
51 Saved
->Prev
= bc
->setlocal
;
52 Saved
->DelayedExpansion
= bDelayedExpansion
;
53 Saved
->Environment
= DuplicateEnvironment();
54 if (!Saved
->Environment
)
56 error_out_of_memory();
64 arg
= splitspace(param
, &argc
);
65 for (i
= 0; i
< argc
; i
++)
67 if (!_tcsicmp(arg
[i
], _T("enableextensions")))
68 /* not implemented, ignore */;
69 else if (!_tcsicmp(arg
[i
], _T("disableextensions")))
70 /* not implemented, ignore */;
71 else if (!_tcsicmp(arg
[i
], _T("enabledelayedexpansion")))
72 bDelayedExpansion
= TRUE
;
73 else if (!_tcsicmp(arg
[i
], _T("disabledelayedexpansion")))
74 bDelayedExpansion
= FALSE
;
77 error_invalid_parameter_format(arg
[i
]);
86 /* endlocal doesn't take any params */
87 INT
cmd_endlocal(LPTSTR param
)
89 LPTSTR Environ
, Name
, Value
;
92 /* Pop a SETLOCAL struct off of this batch file's stack */
93 if (!bc
|| !(Saved
= bc
->setlocal
))
95 bc
->setlocal
= Saved
->Prev
;
97 bDelayedExpansion
= Saved
->DelayedExpansion
;
99 /* First, clear out the environment. Since making any changes to the
100 * environment invalidates pointers obtained from GetEnvironmentStrings(),
101 * we must make a copy of it and get the variable names from that */
102 Environ
= DuplicateEnvironment();
105 for (Name
= Environ
; *Name
; Name
+= _tcslen(Name
) + 1)
107 if (!(Value
= _tcschr(Name
+ 1, _T('='))))
110 SetEnvironmentVariable(Name
, NULL
);
116 /* Now, restore variables from the copy saved by cmd_setlocal */
117 for (Name
= Saved
->Environment
; *Name
; Name
+= _tcslen(Name
) + 1)
119 if (!(Value
= _tcschr(Name
+ 1, _T('='))))
122 SetEnvironmentVariable(Name
, Value
);
126 cmd_free(Saved
->Environment
);