Author: jmorlan Date: Tue Aug 26 15:36:38 2008 New Revision: 35681
URL: http://svn.reactos.org/svn/reactos?rev=35681&view=rev Log: - Implement call :label by creating a new batch context; this way calls can be nested and have their own %0-%9 parameters. - GetBatchVar: Implement %~n. Remove %? (an old FreeDOS-ism; the Windows equivalent is %ERRORLEVEL%)
Modified: trunk/reactos/base/shell/cmd/batch.c trunk/reactos/base/shell/cmd/batch.h trunk/reactos/base/shell/cmd/call.c trunk/reactos/base/shell/cmd/cmd.c trunk/reactos/base/shell/cmd/goto.c
Modified: trunk/reactos/base/shell/cmd/batch.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/batch.c?rev=... ============================================================================== --- trunk/reactos/base/shell/cmd/batch.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/batch.c [iso-8859-1] Tue Aug 26 15:36:38 2008 @@ -216,10 +216,9 @@ * */
-BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param) +BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, BOOL forcenew) { HANDLE hFile; - LPTSTR tmp; SetLastError(0); hFile = CreateFile (fullname, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | @@ -238,7 +237,7 @@ while (bc && bc->forvar) ExitBatch (NULL);
- if (bc == NULL) + if (bc == NULL || forcenew) { /* No curent batch file, create a new context */ LPBATCH_CONTEXT n = (LPBATCH_CONTEXT)cmd_alloc (sizeof(BATCH_CONTEXT)); @@ -264,16 +263,13 @@ cmd_free (bc->raw_params); }
- GetFullPathName(fullname, sizeof(bc->BatchFilePath) / sizeof(TCHAR), bc->BatchFilePath, &tmp); - *tmp = '\0'; + GetFullPathName(fullname, sizeof(bc->BatchFilePath) / sizeof(TCHAR), bc->BatchFilePath, NULL);
bc->hBatchFile = hFile; SetFilePointer (bc->hBatchFile, 0, NULL, FILE_BEGIN); bc->bEcho = bEcho; /* Preserve echo across batch calls */ bc->shiftlevel = 0; bc->bCmdBlock = -1; - bc->lCallPosition = 0; - bc->lCallPositionHigh = 0; bc->ffind = NULL; bc->forvar = _T('\0');
Modified: trunk/reactos/base/shell/cmd/batch.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/batch.h?rev=... ============================================================================== --- trunk/reactos/base/shell/cmd/batch.h [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/batch.h [iso-8859-1] Tue Aug 26 15:36:38 2008 @@ -23,8 +23,6 @@ TCHAR forvar; INT bCmdBlock; BOOL bExecuteBlock[MAX_PATH]; - LONG lCallPosition; /* store position where to return to after Call :Label */ - LONG lCallPositionHigh; } BATCH_CONTEXT, *LPBATCH_CONTEXT;
@@ -43,7 +41,7 @@ LPTSTR FindArg (INT); LPTSTR BatchParams (LPTSTR, LPTSTR); VOID ExitBatch (LPTSTR); -BOOL Batch (LPTSTR, LPTSTR, LPTSTR); +BOOL Batch (LPTSTR, LPTSTR, LPTSTR, BOOL); LPTSTR ReadBatchLine(); VOID AddBatchRedirection(REDIRECTION **);
Modified: trunk/reactos/base/shell/cmd/call.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/call.c?rev=3... ============================================================================== --- trunk/reactos/base/shell/cmd/call.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/call.c [iso-8859-1] Tue Aug 26 15:36:38 2008 @@ -53,9 +53,18 @@
if (*param == _T(':') && (bc)) { - bc->lCallPosition = SetFilePointer(bc->hBatchFile, 0, &bc->lCallPositionHigh, FILE_CURRENT); - cmd_goto(param); - return 0; + TCHAR *first = param; + while (*param && !_istspace(*param)) + param++; + if (*param) + { + *param++ = _T('\0'); + while (_istspace(*param)) + param++; + } + if (!Batch(bc->BatchFilePath, first, param, TRUE)) + return 1; + return cmd_goto(first); }
nErrorLevel = 0;
Modified: trunk/reactos/base/shell/cmd/cmd.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/cmd.c?rev=35... ============================================================================== --- trunk/reactos/base/shell/cmd/cmd.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/cmd.c [iso-8859-1] Tue Aug 26 15:36:38 2008 @@ -470,7 +470,7 @@ if (dot && (!_tcsicmp (dot, _T(".bat")) || !_tcsicmp (dot, _T(".cmd")))) { TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(rest)); - Batch (szFullName, first, rest); + Batch (szFullName, first, rest, FALSE); } else { @@ -1024,14 +1024,16 @@ return NULL; }
+ + LPCTSTR GetBatchVar ( LPCTSTR varName, UINT* varNameLen ) { static LPTSTR ret = NULL; static UINT retlen = 0; - - if ( varNameLen ) - *varNameLen = 1; + DWORD len; + + *varNameLen = 1;
switch ( *varName ) { @@ -1039,10 +1041,35 @@ varName++; if (_tcsncicmp(varName, _T("dp0"), 3) == 0) { - if ( varNameLen ) - *varNameLen = 4; - return bc->BatchFilePath; - } + *varNameLen = 4; + len = _tcsrchr(bc->BatchFilePath, _T('\')) + 1 - bc->BatchFilePath; + if (!GrowIfNecessary(len + 1, &ret, &retlen)) + return NULL; + memcpy(ret, bc->BatchFilePath, len * sizeof(TCHAR)); + ret[len] = _T('\0'); + return ret; + } + + *varNameLen = 2; + if (*varName >= _T('0') && *varName <= _T('9')) { + LPTSTR arg = FindArg(*varName - _T('0')); + + if (*arg != _T('"')) + return arg; + + /* Exclude the leading and trailing quotes */ + arg++; + len = _tcslen(arg); + if (arg[len - 1] == _T('"')) + len--; + + if (!GrowIfNecessary(len + 1, &ret, &retlen)) + return NULL; + memcpy(ret, arg, len * sizeof(TCHAR)); + ret[len] = _T('\0'); + return ret; + } + break; case _T('0'): case _T('1'): case _T('2'): @@ -1063,16 +1090,6 @@
case _T('%'): return _T("%"); - - case _T('?'): - /* TODO FIXME 10 is only max size for 32-bit */ - if ( !GrowIfNecessary ( 11, &ret, &retlen ) ) - return NULL; - _sntprintf ( ret, retlen, _T("%u"), nErrorLevel); - ret[retlen-1] = 0; - if ( varNameLen ) - *varNameLen = 1; - return ret; } return NULL; }
Modified: trunk/reactos/base/shell/cmd/goto.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/goto.c?rev=3... ============================================================================== --- trunk/reactos/base/shell/cmd/goto.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/goto.c [iso-8859-1] Tue Aug 26 15:36:38 2008 @@ -75,15 +75,7 @@ /* jump to end of the file */ if ( _tcsicmp( param, _T(":eof"))==0) { - /* when lCallPosition != 0 we have to return to the caller */ - if (bc->lCallPosition == 0) - SetFilePointer (bc->hBatchFile, 0, &lNewPosHigh, FILE_END); - else - { - SetFilePointer (bc->hBatchFile, (LONG)bc->lCallPosition, &bc->lCallPositionHigh, FILE_BEGIN); - bc->lCallPosition = 0; - bc->lCallPositionHigh = 0; - } + SetFilePointer (bc->hBatchFile, 0, &lNewPosHigh, FILE_END); return 0; }