2 * SETLOCAL.C - setlocal and endlocal internal batch commands.
6 * 1 Feb 2008 (Christoph von Wittich)
12 typedef struct _SETLOCAL
14 struct _SETLOCAL
*Prev
;
15 BOOL DelayedExpansion
;
19 /* Create a copy of the current environment */
21 DuplicateEnvironment(VOID
)
23 LPTSTR Environ
= GetEnvironmentStrings();
24 LPTSTR End
, EnvironCopy
;
26 if (!Environ
) return NULL
;
28 for (End
= Environ
; *End
; End
+= _tcslen(End
) + 1) ;
29 EnvironCopy
= cmd_alloc((End
+ 1 - Environ
) * sizeof(TCHAR
));
32 memcpy(EnvironCopy
, Environ
, (End
+ 1 - Environ
) * sizeof(TCHAR
));
34 FreeEnvironmentStrings(Environ
);
38 INT
cmd_setlocal(LPTSTR param
)
44 /* SETLOCAL only works inside a batch file */
48 Saved
= cmd_alloc(sizeof(SETLOCAL
));
51 error_out_of_memory();
54 Saved
->Prev
= bc
->setlocal
;
55 Saved
->DelayedExpansion
= bDelayedExpansion
;
56 Saved
->Environment
= DuplicateEnvironment();
57 if (!Saved
->Environment
)
59 error_out_of_memory();
67 arg
= splitspace(param
, &argc
);
68 for (i
= 0; i
< argc
; i
++)
70 if (!_tcsicmp(arg
[i
], _T("enableextensions")))
71 /* not implemented, ignore */;
72 else if (!_tcsicmp(arg
[i
], _T("disableextensions")))
73 /* not implemented, ignore */;
74 else if (!_tcsicmp(arg
[i
], _T("enabledelayedexpansion")))
75 bDelayedExpansion
= TRUE
;
76 else if (!_tcsicmp(arg
[i
], _T("disabledelayedexpansion")))
77 bDelayedExpansion
= FALSE
;
80 error_invalid_parameter_format(arg
[i
]);
89 /* endlocal doesn't take any params */
90 INT
cmd_endlocal(LPTSTR param
)
92 LPTSTR Environ
, Name
, Value
;
95 /* Pop a SETLOCAL struct off of this batch file's stack */
96 if (!bc
|| !(Saved
= bc
->setlocal
))
98 bc
->setlocal
= Saved
->Prev
;
100 bDelayedExpansion
= Saved
->DelayedExpansion
;
102 /* First, clear out the environment. Since making any changes to the
103 * environment invalidates pointers obtained from GetEnvironmentStrings(),
104 * we must make a copy of it and get the variable names from that */
105 Environ
= DuplicateEnvironment();
108 for (Name
= Environ
; *Name
; Name
+= _tcslen(Name
) + 1)
110 if (!(Value
= _tcschr(Name
+ 1, _T('='))))
113 SetEnvironmentVariable(Name
, NULL
);
119 /* Now, restore variables from the copy saved by cmd_setlocal */
120 for (Name
= Saved
->Environment
; *Name
; Name
+= _tcslen(Name
) + 1)
122 if (!(Value
= _tcschr(Name
+ 1, _T('='))))
125 SetEnvironmentVariable(Name
, Value
);
129 cmd_free(Saved
->Environment
);