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 return p
+ _tcsspn ( p
, _T(" \t") );
54 INT
cmd_set (LPTSTR cmd
, LPTSTR param
)
59 if ( !_tcsncmp (param
, _T("/?"), 2) )
61 ConOutResPaging(TRUE
,STRING_SET_HELP
);
66 if ( param
[0] ) for ( i
= 0; param
[i
+1]; i
++ )
68 if ( param
[i
] == _T('^') )
70 memmove ( ¶m
[i
], ¶m
[i
+1], _tcslen(¶m
[i
]) * sizeof(TCHAR
) );
74 /* if no parameters, show the environment */
75 if (param
[0] == _T('\0'))
81 lpEnv
= (LPTSTR
)GetEnvironmentStrings ();
87 len
= _tcslen(lpOutput
);
90 if (*lpOutput
!= _T('='))
91 ConOutPuts (lpOutput
);
92 lpOutput
+= (len
+ 1);
95 FreeEnvironmentStrings (lpEnv
);
101 /* the /A does *NOT* have to be followed by a whitespace */
102 if ( !_tcsnicmp (param
, _T("/A"), 2) )
104 BOOL Success
= seta_eval ( skip_ws(param
+2) );
107 /*might seem random but this is what windows xp does */
110 /* TODO FIXME - what are we supposed to return? */
114 if ( !_tcsnicmp (param
, _T("/"), 1) )
116 ConErrResPrintf (STRING_SYNTAX_COMMAND_INCORRECT
, param
);
120 p
= _tcschr (param
, _T('='));
123 /* set or remove environment variable */
126 /* handle set =val case */
127 ConErrResPrintf (STRING_SYNTAX_COMMAND_INCORRECT
, param
);
137 SetEnvironmentVariable (param
, p
);
141 /* display environment variable */
145 pszBuffer
= (LPTSTR
)cmd_alloc (ENV_BUFFER_SIZE
* sizeof(TCHAR
));
146 dwBuffer
= GetEnvironmentVariable (param
, pszBuffer
, ENV_BUFFER_SIZE
);
149 ConErrResPrintf (STRING_PATH_ERROR
, param
);
152 else if (dwBuffer
> ENV_BUFFER_SIZE
)
154 pszBuffer
= (LPTSTR
)cmd_realloc (pszBuffer
, dwBuffer
* sizeof (TCHAR
));
155 GetEnvironmentVariable (param
, pszBuffer
, dwBuffer
);
157 ConOutPrintf (_T("%s\n"), pszBuffer
);
159 cmd_free (pszBuffer
);
168 ident_len ( LPCTSTR p
)
174 while ( __iscsym(*p2
) )
180 #define PARSE_IDENT(ident,identlen,p) \
181 identlen = ident_len(p); \
182 ident = (LPTSTR)alloca ( ( identlen + 1 ) * sizeof(TCHAR) ); \
183 memmove ( ident, p, identlen * sizeof(TCHAR) ); \
184 ident[identlen] = 0; \
188 seta_identval ( LPCTSTR ident
, INT
* result
)
190 LPCTSTR identVal
= GetEnvVarOrSpecial ( ident
);
193 /* TODO FIXME - what to do upon failure? */
197 *result
= _ttoi ( identVal
);
202 calc ( INT
* lval
, TCHAR op
, INT rval
)
231 ConErrResPuts ( STRING_INVALID_OPERAND
);
238 seta_stmt ( LPCTSTR
* p_
, INT
* result
);
241 seta_unaryTerm ( LPCTSTR
* p_
, INT
* result
)
247 p
= skip_ws ( p
+ 1 );
248 if ( !seta_stmt ( &p
, &rval
) )
252 ConErrResPuts ( STRING_EXPECTED_CLOSE_PAREN
);
256 p
= skip_ws ( p
+ 1 );
258 else if ( isdigit(*p
) )
260 *result
= _ttoi ( p
);
261 p
= skip_ws ( p
+ _tcsspn ( p
, _T("1234567890") ) );
263 else if ( __iscsymf(*p
) )
267 PARSE_IDENT(ident
,identlen
,p
);
268 if ( !seta_identval ( ident
, result
) )
273 ConErrResPuts ( STRING_EXPECTED_NUMBER_OR_VARIABLE
);
281 seta_mulTerm ( LPCTSTR
* p_
, INT
* result
)
286 if ( _tcschr(_T("!~-"),*p
) )
289 p
= skip_ws ( p
+ 1 );
291 if ( !seta_unaryTerm ( &p
, &rval
) )
312 seta_ltorTerm ( LPCTSTR
* p_
, INT
* result
, LPCTSTR ops
, BOOL (*subTerm
)(LPCTSTR
*,INT
*) )
316 if ( !subTerm ( &p
, &lval
) )
318 while ( *p
&& _tcschr(ops
,*p
) )
325 if ( !subTerm ( &p
, &rval
) )
328 if ( !calc ( &lval
, op
, rval
) )
338 seta_addTerm ( LPCTSTR
* p_
, INT
* result
)
340 return seta_ltorTerm ( p_
, result
, _T("*/%"), seta_mulTerm
);
344 seta_logShiftTerm ( LPCTSTR
* p_
, INT
* result
)
346 return seta_ltorTerm ( p_
, result
, _T("+-"), seta_addTerm
);
350 seta_bitAndTerm ( LPCTSTR
* p_
, INT
* result
)
354 if ( !seta_logShiftTerm ( &p
, &lval
) )
356 while ( *p
&& _tcschr(_T("<>"),*p
) && p
[0] == p
[1] )
363 if ( !seta_logShiftTerm ( &p
, &rval
) )
375 ConErrResPuts ( STRING_INVALID_OPERAND
);
386 seta_bitExclOrTerm ( LPCTSTR
* p_
, INT
* result
)
388 return seta_ltorTerm ( p_
, result
, _T("&"), seta_bitAndTerm
);
392 seta_bitOrTerm ( LPCTSTR
* p_
, INT
* result
)
394 return seta_ltorTerm ( p_
, result
, _T("^"), seta_bitExclOrTerm
);
398 seta_expr ( LPCTSTR
* p_
, INT
* result
)
400 return seta_ltorTerm ( p_
, result
, _T("|"), seta_bitOrTerm
);
404 seta_assignment ( LPCTSTR
* p_
, INT
* result
)
409 INT identlen
, exprval
;
411 PARSE_IDENT(ident
,identlen
,p
);
415 op
= *p
, p
= skip_ws(p
+1);
416 else if ( _tcschr ( _T("*/%+-&^|"), *p
) && p
[1] == _T('=') )
417 op
= *p
, p
= skip_ws(p
+2);
418 else if ( _tcschr ( _T("<>"), *p
) && *p
== p
[1] && p
[2] == _T('=') )
419 op
= *p
, p
= skip_ws(p
+3);
422 /* allow to chain multiple assignments, such as: a=b=1 */
428 if ( !seta_assignment ( &p
, &exprval
) )
431 if ( !seta_identval ( ident
, &identval
) )
439 identval
<<= exprval
;
442 identval
>>= exprval
;
445 if ( !calc ( &identval
, op
, exprval
) )
448 buf
= (LPTSTR
)alloca ( 32 * sizeof(TCHAR
) );
449 _sntprintf ( buf
, 32, _T("%i"), identval
);
450 SetEnvironmentVariable ( ident
, buf
); // TODO FIXME - check return value
455 /* restore p in case we found an ident but not an op */
457 if ( !seta_expr ( &p
, &exprval
) )
467 seta_stmt ( LPCTSTR
* p_
, INT
* result
)
472 if ( !seta_assignment ( &p
, &rval
) )
474 while ( *p
== _T(',') )
478 if ( !seta_assignment ( &p
, &rval
) )
488 seta_eval ( LPCTSTR p
)
493 ConErrResPuts ( STRING_SYNTAX_COMMAND_INCORRECT
);
496 if ( !seta_stmt ( &p
, &rval
) )
498 ConOutPrintf ( _T("%i"), rval
);