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 EnableExtensions
;
16 BOOL DelayedExpansion
;
20 /* Create a copy of the current environment */
22 DuplicateEnvironment(VOID
)
24 LPTSTR Environ
= GetEnvironmentStrings();
25 LPTSTR End
, EnvironCopy
;
27 if (!Environ
) return NULL
;
29 for (End
= Environ
; *End
; End
+= _tcslen(End
) + 1) ;
30 EnvironCopy
= cmd_alloc((End
+ 1 - Environ
) * sizeof(TCHAR
));
33 memcpy(EnvironCopy
, Environ
, (End
+ 1 - Environ
) * sizeof(TCHAR
));
35 FreeEnvironmentStrings(Environ
);
39 INT
cmd_setlocal(LPTSTR param
)
45 /* SETLOCAL only works inside a batch file */
49 Saved
= cmd_alloc(sizeof(SETLOCAL
));
52 WARN("Cannot allocate memory for Saved!\n");
53 error_out_of_memory();
56 Saved
->Prev
= bc
->setlocal
;
57 Saved
->EnableExtensions
= bEnableExtensions
;
58 Saved
->DelayedExpansion
= bDelayedExpansion
;
59 Saved
->Environment
= DuplicateEnvironment();
60 if (!Saved
->Environment
)
62 error_out_of_memory();
70 arg
= splitspace(param
, &argc
);
71 for (i
= 0; i
< argc
; i
++)
73 if (!_tcsicmp(arg
[i
], _T("enableextensions")))
74 /* FIXME: not implemented! */
75 bEnableExtensions
= TRUE
;
76 else if (!_tcsicmp(arg
[i
], _T("disableextensions")))
77 /* FIXME: not implemented! */
78 bEnableExtensions
= FALSE
;
79 else if (!_tcsicmp(arg
[i
], _T("enabledelayedexpansion")))
80 bDelayedExpansion
= TRUE
;
81 else if (!_tcsicmp(arg
[i
], _T("disabledelayedexpansion")))
82 bDelayedExpansion
= FALSE
;
85 error_invalid_parameter_format(arg
[i
]);
94 /* endlocal doesn't take any params */
95 INT
cmd_endlocal(LPTSTR param
)
97 LPTSTR Environ
, Name
, Value
;
100 /* Pop a SETLOCAL struct off of this batch file's stack */
101 if (!bc
|| !(Saved
= bc
->setlocal
))
103 bc
->setlocal
= Saved
->Prev
;
105 bEnableExtensions
= Saved
->EnableExtensions
;
106 bDelayedExpansion
= Saved
->DelayedExpansion
;
108 /* First, clear out the environment. Since making any changes to the
109 * environment invalidates pointers obtained from GetEnvironmentStrings(),
110 * we must make a copy of it and get the variable names from that */
111 Environ
= DuplicateEnvironment();
114 for (Name
= Environ
; *Name
; Name
+= _tcslen(Name
) + 1)
116 if (!(Value
= _tcschr(Name
+ 1, _T('='))))
119 SetEnvironmentVariable(Name
, NULL
);
125 /* Now, restore variables from the copy saved by cmd_setlocal */
126 for (Name
= Saved
->Environment
; *Name
; Name
+= _tcslen(Name
) + 1)
128 if (!(Value
= _tcschr(Name
+ 1, _T('='))))
131 SetEnvironmentVariable(Name
, Value
);
135 cmd_free(Saved
->Environment
);