- 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%)

svn path=/trunk/; revision=35681
This commit is contained in:
Jeffrey Morlan 2008-08-26 20:36:38 +00:00
parent 317fe611cb
commit 6c2116d0cf
5 changed files with 50 additions and 38 deletions

View file

@ -216,10 +216,9 @@ VOID ExitBatch (LPTSTR msg)
*
*/
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 @@ BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param)
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 @@ BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param)
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');

View file

@ -23,8 +23,6 @@ typedef struct tagBATCHCONTEXT
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 @@ extern TCHAR textline[BATCH_BUFFSIZE]; /* Buffer for reading Batch file lines */
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 **);

View file

@ -53,9 +53,18 @@ INT cmd_call (LPTSTR param)
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;

View file

@ -470,7 +470,7 @@ Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest)
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 @@ GetEnvVarOrSpecial ( LPCTSTR varName )
return NULL;
}
LPCTSTR
GetBatchVar ( LPCTSTR varName, UINT* varNameLen )
{
static LPTSTR ret = NULL;
static UINT retlen = 0;
DWORD len;
if ( varNameLen )
*varNameLen = 1;
*varNameLen = 1;
switch ( *varName )
{
@ -1039,10 +1041,35 @@ GetBatchVar ( LPCTSTR varName, UINT* varNameLen )
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 @@ GetBatchVar ( LPCTSTR varName, UINT* varNameLen )
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;
}

View file

@ -75,15 +75,7 @@ INT cmd_goto (LPTSTR param)
/* 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;
}