2 * SET.C - set internal command.
7 * 06/14/97 (Tim Norman)
8 * changed static var in set() to a cmd_alloc'd space to pass to putenv.
9 * need to find a better way to do this, since it seems it is wasting
10 * memory when variables are redefined.
12 * 07/08/1998 (John P. Price)
13 * removed call to show_environment in set command.
14 * moved test for syntax before allocating memory in set command.
15 * misc clean up and optimization.
17 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
18 * added config.h include
20 * 28-Jul-1998 (John P Price <linux-guru@gcfl.net>)
21 * added set_env function to set env. variable without needing set command
23 * 09-Dec-1998 (Eric Kohl)
24 * Added help text ("/?").
26 * 24-Jan-1999 (Eric Kohl)
27 * Fixed Win32 environment handling.
28 * Unicode and redirection safe!
30 * 25-Feb-1999 (Eric Kohl)
33 * 30-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
34 * Remove all hardcode string to En.rc
39 #ifdef INCLUDE_CMD_SET
42 /* initial size of environment variable buffer */
43 #define ENV_BUFFER_SIZE 1024
46 seta_eval ( LPCTSTR expr
);
51 while (*p
&& *p
<= _T(' '))
56 /* Used to check for and handle:
57 * SET "var=value", SET /P "var=prompt", and SET /P var="prompt" */
59 GetQuotedString(TCHAR
*p
)
64 p
= (LPTSTR
)skip_ws(p
+ 1);
65 /* If a matching quote is found, truncate the string */
66 end
= _tcsrchr(p
, _T('"'));
73 INT
cmd_set (LPTSTR param
)
79 if ( !_tcsncmp (param
, _T("/?"), 2) )
81 ConOutResPaging(TRUE
,STRING_SET_HELP
);
85 param
= (LPTSTR
)skip_ws(param
);
87 /* if no parameters, show the environment */
88 if (param
[0] == _T('\0'))
90 lpEnv
= (LPTSTR
)GetEnvironmentStrings ();
96 if (*lpOutput
!= _T('='))
98 lpOutput
+= _tcslen(lpOutput
) + 1;
99 ConOutPuts(_T("\r\n"));
101 FreeEnvironmentStrings (lpEnv
);
107 /* the /A does *NOT* have to be followed by a whitespace */
108 if ( !_tcsnicmp (param
, _T("/A"), 2) )
112 Success
= seta_eval ( skip_ws(param
+2) );
115 /*might seem random but this is what windows xp does */
121 if (!_tcsnicmp(param
, _T("/P"), 2))
124 param
= GetQuotedString((LPTSTR
)skip_ws(param
+ 2));
125 p
= _tcschr(param
, _T('='));
128 ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT
);
134 ConOutPrintf(_T("%s"), GetQuotedString(p
));
135 ConInString(value
, 1023);
137 if (!*value
|| !SetEnvironmentVariable(param
, value
))
145 param
= GetQuotedString(param
);
147 p
= _tcschr (param
, _T('='));
150 /* set or remove environment variable */
153 /* handle set =val case */
154 ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT
);
160 if (!SetEnvironmentVariable(param
, *p
? p
: NULL
))
168 /* display all environment variable with the given prefix */
171 while (_istspace(*param
) || *param
== _T(',') || *param
== _T(';'))
174 p
= _tcsrchr(param
, _T(' '));
176 p
= param
+ _tcslen(param
);
179 lpEnv
= GetEnvironmentStrings();
185 if (!_tcsnicmp(lpOutput
, param
, p
- param
))
187 ConOutPuts(lpOutput
);
188 ConOutPuts(_T("\r\n"));
191 lpOutput
+= _tcslen(lpOutput
) + 1;
193 FreeEnvironmentStrings(lpEnv
);
198 ConErrResPrintf (STRING_PATH_ERROR
, param
);
208 ident_len ( LPCTSTR p
)
214 while ( __iscsym(*p2
) )
220 #define PARSE_IDENT(ident,identlen,p) \
221 identlen = ident_len(p); \
222 ident = (LPTSTR)alloca ( ( identlen + 1 ) * sizeof(TCHAR) ); \
223 memmove ( ident, p, identlen * sizeof(TCHAR) ); \
224 ident[identlen] = 0; \
228 seta_identval ( LPCTSTR ident
, INT
* result
)
230 LPCTSTR identVal
= GetEnvVarOrSpecial ( ident
);
233 /* TODO FIXME - what to do upon failure? */
237 *result
= _tcstol ( identVal
, NULL
, 0 );
242 calc ( INT
* lval
, TCHAR op
, INT rval
)
271 ConErrResPuts ( STRING_INVALID_OPERAND
);
278 seta_stmt ( LPCTSTR
* p_
, INT
* result
);
281 seta_unaryTerm ( LPCTSTR
* p_
, INT
* result
)
287 p
= skip_ws ( p
+ 1 );
288 if ( !seta_stmt ( &p
, &rval
) )
290 if ( *p
++ != _T(')') )
292 ConErrResPuts ( STRING_EXPECTED_CLOSE_PAREN
);
297 else if ( isdigit(*p
) )
299 *result
= _tcstol ( p
, (LPTSTR
*)&p
, 0 );
301 else if ( __iscsymf(*p
) )
305 PARSE_IDENT(ident
,identlen
,p
);
306 if ( !seta_identval ( ident
, result
) )
311 ConErrResPuts ( STRING_EXPECTED_NUMBER_OR_VARIABLE
);
319 seta_mulTerm ( LPCTSTR
* p_
, INT
* result
)
324 if ( _tcschr(_T("!~-"),*p
) )
327 p
= skip_ws ( p
+ 1 );
329 if ( !seta_unaryTerm ( &p
, &rval
) )
350 seta_ltorTerm ( LPCTSTR
* p_
, INT
* result
, LPCTSTR ops
, BOOL (*subTerm
)(LPCTSTR
*,INT
*) )
354 if ( !subTerm ( &p
, &lval
) )
356 while ( *p
&& _tcschr(ops
,*p
) )
363 if ( !subTerm ( &p
, &rval
) )
366 if ( !calc ( &lval
, op
, rval
) )
376 seta_addTerm ( LPCTSTR
* p_
, INT
* result
)
378 return seta_ltorTerm ( p_
, result
, _T("*/%"), seta_mulTerm
);
382 seta_logShiftTerm ( LPCTSTR
* p_
, INT
* result
)
384 return seta_ltorTerm ( p_
, result
, _T("+-"), seta_addTerm
);
388 seta_bitAndTerm ( LPCTSTR
* p_
, INT
* result
)
392 if ( !seta_logShiftTerm ( &p
, &lval
) )
394 while ( *p
&& _tcschr(_T("<>"),*p
) && p
[0] == p
[1] )
401 if ( !seta_logShiftTerm ( &p
, &rval
) )
413 ConErrResPuts ( STRING_INVALID_OPERAND
);
424 seta_bitExclOrTerm ( LPCTSTR
* p_
, INT
* result
)
426 return seta_ltorTerm ( p_
, result
, _T("&"), seta_bitAndTerm
);
430 seta_bitOrTerm ( LPCTSTR
* p_
, INT
* result
)
432 return seta_ltorTerm ( p_
, result
, _T("^"), seta_bitExclOrTerm
);
436 seta_expr ( LPCTSTR
* p_
, INT
* result
)
438 return seta_ltorTerm ( p_
, result
, _T("|"), seta_bitOrTerm
);
442 seta_assignment ( LPCTSTR
* p_
, INT
* result
)
447 INT identlen
, exprval
;
449 PARSE_IDENT(ident
,identlen
,p
);
454 op
= *p
, p
= skip_ws(p
+1);
455 else if ( _tcschr ( _T("*/%+-&^|"), *p
) && p
[1] == _T('=') )
456 op
= *p
, p
= skip_ws(p
+2);
457 else if ( _tcschr ( _T("<>"), *p
) && *p
== p
[1] && p
[2] == _T('=') )
458 op
= *p
, p
= skip_ws(p
+3);
461 /* allow to chain multiple assignments, such as: a=b=1 */
467 if ( !seta_assignment ( &p
, &exprval
) )
470 if ( !seta_identval ( ident
, &identval
) )
478 identval
<<= exprval
;
481 identval
>>= exprval
;
484 if ( !calc ( &identval
, op
, exprval
) )
487 buf
= (LPTSTR
)alloca ( 32 * sizeof(TCHAR
) );
488 _sntprintf ( buf
, 32, _T("%i"), identval
);
489 SetEnvironmentVariable ( ident
, buf
); // TODO FIXME - check return value
494 /* restore p in case we found an ident but not an op */
496 if ( !seta_expr ( &p
, &exprval
) )
506 seta_stmt ( LPCTSTR
* p_
, INT
* result
)
511 if ( !seta_assignment ( &p
, &rval
) )
513 while ( *p
== _T(',') )
517 if ( !seta_assignment ( &p
, &rval
) )
527 seta_eval ( LPCTSTR p
)
532 ConErrResPuts ( STRING_SYNTAX_COMMAND_INCORRECT
);
535 if ( !seta_stmt ( &p
, &rval
) )
538 ConOutPrintf ( _T("%i"), rval
);