mirror of
https://github.com/reactos/reactos.git
synced 2025-06-10 12:24:48 +00:00
- 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:
parent
317fe611cb
commit
6c2116d0cf
5 changed files with 50 additions and 38 deletions
|
@ -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;
|
HANDLE hFile;
|
||||||
LPTSTR tmp;
|
|
||||||
SetLastError(0);
|
SetLastError(0);
|
||||||
hFile = CreateFile (fullname, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, NULL,
|
hFile = CreateFile (fullname, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, NULL,
|
||||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL |
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL |
|
||||||
|
@ -238,7 +237,7 @@ BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param)
|
||||||
while (bc && bc->forvar)
|
while (bc && bc->forvar)
|
||||||
ExitBatch (NULL);
|
ExitBatch (NULL);
|
||||||
|
|
||||||
if (bc == NULL)
|
if (bc == NULL || forcenew)
|
||||||
{
|
{
|
||||||
/* No curent batch file, create a new context */
|
/* No curent batch file, create a new context */
|
||||||
LPBATCH_CONTEXT n = (LPBATCH_CONTEXT)cmd_alloc (sizeof(BATCH_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);
|
cmd_free (bc->raw_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
GetFullPathName(fullname, sizeof(bc->BatchFilePath) / sizeof(TCHAR), bc->BatchFilePath, &tmp);
|
GetFullPathName(fullname, sizeof(bc->BatchFilePath) / sizeof(TCHAR), bc->BatchFilePath, NULL);
|
||||||
*tmp = '\0';
|
|
||||||
|
|
||||||
bc->hBatchFile = hFile;
|
bc->hBatchFile = hFile;
|
||||||
SetFilePointer (bc->hBatchFile, 0, NULL, FILE_BEGIN);
|
SetFilePointer (bc->hBatchFile, 0, NULL, FILE_BEGIN);
|
||||||
bc->bEcho = bEcho; /* Preserve echo across batch calls */
|
bc->bEcho = bEcho; /* Preserve echo across batch calls */
|
||||||
bc->shiftlevel = 0;
|
bc->shiftlevel = 0;
|
||||||
bc->bCmdBlock = -1;
|
bc->bCmdBlock = -1;
|
||||||
bc->lCallPosition = 0;
|
|
||||||
bc->lCallPositionHigh = 0;
|
|
||||||
|
|
||||||
bc->ffind = NULL;
|
bc->ffind = NULL;
|
||||||
bc->forvar = _T('\0');
|
bc->forvar = _T('\0');
|
||||||
|
|
|
@ -23,8 +23,6 @@ typedef struct tagBATCHCONTEXT
|
||||||
TCHAR forvar;
|
TCHAR forvar;
|
||||||
INT bCmdBlock;
|
INT bCmdBlock;
|
||||||
BOOL bExecuteBlock[MAX_PATH];
|
BOOL bExecuteBlock[MAX_PATH];
|
||||||
LONG lCallPosition; /* store position where to return to after Call :Label */
|
|
||||||
LONG lCallPositionHigh;
|
|
||||||
} BATCH_CONTEXT, *LPBATCH_CONTEXT;
|
} BATCH_CONTEXT, *LPBATCH_CONTEXT;
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,7 +41,7 @@ extern TCHAR textline[BATCH_BUFFSIZE]; /* Buffer for reading Batch file lines */
|
||||||
LPTSTR FindArg (INT);
|
LPTSTR FindArg (INT);
|
||||||
LPTSTR BatchParams (LPTSTR, LPTSTR);
|
LPTSTR BatchParams (LPTSTR, LPTSTR);
|
||||||
VOID ExitBatch (LPTSTR);
|
VOID ExitBatch (LPTSTR);
|
||||||
BOOL Batch (LPTSTR, LPTSTR, LPTSTR);
|
BOOL Batch (LPTSTR, LPTSTR, LPTSTR, BOOL);
|
||||||
LPTSTR ReadBatchLine();
|
LPTSTR ReadBatchLine();
|
||||||
VOID AddBatchRedirection(REDIRECTION **);
|
VOID AddBatchRedirection(REDIRECTION **);
|
||||||
|
|
||||||
|
|
|
@ -53,9 +53,18 @@ INT cmd_call (LPTSTR param)
|
||||||
|
|
||||||
if (*param == _T(':') && (bc))
|
if (*param == _T(':') && (bc))
|
||||||
{
|
{
|
||||||
bc->lCallPosition = SetFilePointer(bc->hBatchFile, 0, &bc->lCallPositionHigh, FILE_CURRENT);
|
TCHAR *first = param;
|
||||||
cmd_goto(param);
|
while (*param && !_istspace(*param))
|
||||||
return 0;
|
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;
|
nErrorLevel = 0;
|
||||||
|
|
|
@ -470,7 +470,7 @@ Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest)
|
||||||
if (dot && (!_tcsicmp (dot, _T(".bat")) || !_tcsicmp (dot, _T(".cmd"))))
|
if (dot && (!_tcsicmp (dot, _T(".bat")) || !_tcsicmp (dot, _T(".cmd"))))
|
||||||
{
|
{
|
||||||
TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(rest));
|
TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(rest));
|
||||||
Batch (szFullName, first, rest);
|
Batch (szFullName, first, rest, FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1024,13 +1024,15 @@ GetEnvVarOrSpecial ( LPCTSTR varName )
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LPCTSTR
|
LPCTSTR
|
||||||
GetBatchVar ( LPCTSTR varName, UINT* varNameLen )
|
GetBatchVar ( LPCTSTR varName, UINT* varNameLen )
|
||||||
{
|
{
|
||||||
static LPTSTR ret = NULL;
|
static LPTSTR ret = NULL;
|
||||||
static UINT retlen = 0;
|
static UINT retlen = 0;
|
||||||
|
DWORD len;
|
||||||
|
|
||||||
if ( varNameLen )
|
|
||||||
*varNameLen = 1;
|
*varNameLen = 1;
|
||||||
|
|
||||||
switch ( *varName )
|
switch ( *varName )
|
||||||
|
@ -1039,10 +1041,35 @@ GetBatchVar ( LPCTSTR varName, UINT* varNameLen )
|
||||||
varName++;
|
varName++;
|
||||||
if (_tcsncicmp(varName, _T("dp0"), 3) == 0)
|
if (_tcsncicmp(varName, _T("dp0"), 3) == 0)
|
||||||
{
|
{
|
||||||
if ( varNameLen )
|
|
||||||
*varNameLen = 4;
|
*varNameLen = 4;
|
||||||
return bc->BatchFilePath;
|
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('0'):
|
||||||
case _T('1'):
|
case _T('1'):
|
||||||
case _T('2'):
|
case _T('2'):
|
||||||
|
@ -1063,16 +1090,6 @@ GetBatchVar ( LPCTSTR varName, UINT* varNameLen )
|
||||||
|
|
||||||
case _T('%'):
|
case _T('%'):
|
||||||
return _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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,15 +75,7 @@ INT cmd_goto (LPTSTR param)
|
||||||
/* jump to end of the file */
|
/* jump to end of the file */
|
||||||
if ( _tcsicmp( param, _T(":eof"))==0)
|
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);
|
SetFilePointer (bc->hBatchFile, 0, &lNewPosHigh, FILE_END);
|
||||||
else
|
|
||||||
{
|
|
||||||
SetFilePointer (bc->hBatchFile, (LONG)bc->lCallPosition, &bc->lCallPositionHigh, FILE_BEGIN);
|
|
||||||
bc->lCallPosition = 0;
|
|
||||||
bc->lCallPositionHigh = 0;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue