2006-02-16 23:23:37 +00:00
|
|
|
/*
|
|
|
|
* GOTO.C - goto internal batch command.
|
|
|
|
*
|
|
|
|
* History:
|
|
|
|
*
|
|
|
|
* 16 Jul 1998 (Hans B Pufal)
|
|
|
|
* started.
|
|
|
|
*
|
|
|
|
* 16 Jul 1998 (John P Price)
|
2016-11-05 14:55:55 +00:00
|
|
|
* Separated commands into individual files.
|
2006-02-16 23:23:37 +00:00
|
|
|
*
|
|
|
|
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
|
|
|
|
* added config.h include
|
|
|
|
*
|
|
|
|
* 28 Jul 1998 (Hans B Pufal) [HBP_003]
|
|
|
|
* Terminate label on first space character, use only first 8 chars of
|
|
|
|
* label string
|
|
|
|
*
|
2007-05-05 11:32:25 +00:00
|
|
|
* 24-Jan-1999 (Eric Kohl)
|
2006-02-16 23:23:37 +00:00
|
|
|
* Unicode and redirection safe!
|
|
|
|
*
|
2007-05-05 11:32:25 +00:00
|
|
|
* 27-Jan-1999 (Eric Kohl)
|
2006-02-16 23:23:37 +00:00
|
|
|
* Added help text ("/?").
|
|
|
|
*
|
2013-06-30 13:23:30 +00:00
|
|
|
* 28-Apr-2005 (Magnus Olsen <magnus@greatlord.com>)
|
2013-06-30 00:08:43 +00:00
|
|
|
* Remove all hardcoded strings in En.rc
|
2006-02-16 23:23:37 +00:00
|
|
|
*/
|
|
|
|
|
2013-01-24 23:00:42 +00:00
|
|
|
#include "precomp.h"
|
2006-02-16 23:23:37 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Perform GOTO command.
|
|
|
|
*
|
2020-07-26 18:30:03 +00:00
|
|
|
* Only valid when a batch context is active.
|
2006-02-16 23:23:37 +00:00
|
|
|
*/
|
2020-07-26 18:30:03 +00:00
|
|
|
INT cmd_goto(LPTSTR param)
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
2020-07-21 23:16:53 +00:00
|
|
|
LPTSTR label, tmp;
|
2020-05-22 21:58:12 +00:00
|
|
|
DWORD dwCurrPos;
|
|
|
|
BOOL bRetry;
|
2013-06-30 00:08:43 +00:00
|
|
|
|
2020-07-26 18:30:03 +00:00
|
|
|
TRACE("cmd_goto(\'%s\')\n", debugstr_aw(param));
|
2013-06-30 00:08:43 +00:00
|
|
|
|
2020-07-26 18:30:03 +00:00
|
|
|
if (!_tcsncmp(param, _T("/?"), 2))
|
2013-06-30 00:08:43 +00:00
|
|
|
{
|
2020-07-26 18:30:03 +00:00
|
|
|
ConOutResPaging(TRUE, STRING_GOTO_HELP1);
|
2013-06-30 00:08:43 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-07-26 18:30:03 +00:00
|
|
|
/* If not in batch, fail */
|
2013-06-30 00:08:43 +00:00
|
|
|
if (bc == NULL)
|
|
|
|
return 1;
|
|
|
|
|
2020-07-26 18:30:03 +00:00
|
|
|
/* Fail if no label has been provided */
|
2013-06-30 00:08:43 +00:00
|
|
|
if (*param == _T('\0'))
|
|
|
|
{
|
|
|
|
ConErrResPrintf(STRING_GOTO_ERROR1);
|
|
|
|
ExitBatch();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-07-21 23:16:53 +00:00
|
|
|
/* Strip leading whitespace */
|
|
|
|
while (_istspace(*param))
|
|
|
|
++param;
|
2013-06-30 00:08:43 +00:00
|
|
|
|
2020-07-12 15:53:20 +00:00
|
|
|
/* Support jumping to the end of the file, only if extensions are enabled */
|
|
|
|
if (bEnableExtensions &&
|
|
|
|
(_tcsnicmp(param, _T(":EOF"), 4) == 0) &&
|
|
|
|
(!param[4] || _istspace(param[4])))
|
2013-06-30 00:08:43 +00:00
|
|
|
{
|
[CMD] Fixes for Batch error execution control flow.
CORE-13713 CORE-13736
- In case execution of all batch contexts is stopped (by selecting "All"
at the Ctrl-C/Ctrl-Break prompt), notify as well the CheckCtrlBreak()
signal handler once there are no more batch contexts (this in effect
resets the internal 'bLeaveAll' static flag in CheckCtrlBreak).
This is an adaptation of the fix present in FreeCOM 1.5, first
described in https://gcfl.net/FreeDOS/command.com/bugs074g.html .
- Introduce a ParseErrorEx() helper that sets the 'bParseError' flag and
displays a customized syntax-error message, only for the first syntax
error encountered. Implement ParseError() around the *Ex function.
- In batch mode, echo the original pre-parsed batch file line if a parse
error has been encountered.
- When running a compound command - including IF, FOR, command blocks -,
and that control flow is modified by any CALL/GOTO/EXIT command,
detect this while running the compound command so as to stop it and go
back to the main batch execution loop, that will then set up the actual
new command to run.
- In GOTO, do not process any more parts of a compound command only when
we have found a valid label.
2020-05-18 00:05:53 +00:00
|
|
|
/* Position at the end of the batch file */
|
|
|
|
bc->mempos = bc->memsize;
|
|
|
|
|
|
|
|
/* Do not process any more parts of a compound command */
|
|
|
|
bc->current = NULL;
|
2013-06-30 00:08:43 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-07-21 23:16:53 +00:00
|
|
|
/* Skip the first colon or plus sign */
|
|
|
|
if (*param == _T(':') || *param == _T('+'))
|
|
|
|
++param;
|
|
|
|
/* Terminate the label at the first delimiter character */
|
|
|
|
tmp = param;
|
|
|
|
while (!_istcntrl(*tmp) && !_istspace(*tmp) &&
|
|
|
|
!_tcschr(_T(":+"), *tmp) && !_tcschr(STANDARD_SEPS, *tmp) /* &&
|
|
|
|
!_tcschr(_T("&|<>"), *tmp) */)
|
|
|
|
{
|
|
|
|
++tmp;
|
|
|
|
}
|
|
|
|
*tmp = _T('\0');
|
|
|
|
|
|
|
|
/* If we don't have any label, bail out */
|
|
|
|
if (!*param)
|
|
|
|
goto NotFound;
|
|
|
|
|
2020-05-22 21:58:12 +00:00
|
|
|
/*
|
|
|
|
* Search the next label starting our position, until the end of the file.
|
|
|
|
* If none has been found, restart at the beginning of the file, and continue
|
|
|
|
* until reaching back our old current position.
|
|
|
|
*/
|
|
|
|
bRetry = FALSE;
|
|
|
|
dwCurrPos = bc->mempos;
|
2013-06-30 00:08:43 +00:00
|
|
|
|
2020-05-22 21:58:12 +00:00
|
|
|
retry:
|
2020-07-26 18:30:03 +00:00
|
|
|
while (BatchGetString(textline, ARRAYSIZE(textline)))
|
2013-06-30 00:08:43 +00:00
|
|
|
{
|
2020-05-22 21:58:12 +00:00
|
|
|
if (bRetry && (bc->mempos >= dwCurrPos))
|
|
|
|
break;
|
|
|
|
|
2020-07-21 23:16:53 +00:00
|
|
|
#if 0
|
|
|
|
/* If this is not a label, continue searching */
|
|
|
|
if (!_tcschr(textline, _T(':')))
|
|
|
|
continue;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
label = textline;
|
|
|
|
|
|
|
|
/* A bug in Windows' CMD makes it always ignore the
|
|
|
|
* first character of the line, unless it's a colon. */
|
|
|
|
if (*label != _T(':'))
|
|
|
|
++label;
|
|
|
|
|
|
|
|
/* Strip any leading whitespace */
|
|
|
|
while (_istspace(*label))
|
|
|
|
++label;
|
|
|
|
|
|
|
|
/* If this is not a label, continue searching */
|
|
|
|
if (*label != _T(':'))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Skip the first colon or plus sign */
|
|
|
|
#if 0
|
|
|
|
if (*label == _T(':') || *label == _T('+'))
|
|
|
|
++label;
|
|
|
|
#endif
|
|
|
|
++label;
|
|
|
|
/* Strip any whitespace between the colon and the label */
|
|
|
|
while (_istspace(*label))
|
|
|
|
++label;
|
|
|
|
/* Terminate the label at the first delimiter character */
|
|
|
|
tmp = label;
|
|
|
|
while (!_istcntrl(*tmp) && !_istspace(*tmp) &&
|
|
|
|
!_tcschr(_T(":+"), *tmp) && !_tcschr(STANDARD_SEPS, *tmp) &&
|
|
|
|
!_tcschr(_T("&|<>"), *tmp))
|
|
|
|
{
|
|
|
|
/* Support the escape caret */
|
|
|
|
if (*tmp == _T('^'))
|
|
|
|
{
|
|
|
|
/* Move the buffer back one character */
|
|
|
|
memmove(tmp, tmp + 1, (_tcslen(tmp + 1) + 1) * sizeof(TCHAR));
|
|
|
|
/* We will ignore the new character */
|
|
|
|
}
|
2013-06-30 00:08:43 +00:00
|
|
|
|
2020-07-26 18:30:03 +00:00
|
|
|
++tmp;
|
2013-06-30 00:08:43 +00:00
|
|
|
}
|
2020-07-21 23:16:53 +00:00
|
|
|
*tmp = _T('\0');
|
2013-06-30 00:08:43 +00:00
|
|
|
|
2020-07-21 23:16:53 +00:00
|
|
|
/* Jump if the labels are identical */
|
|
|
|
if (_tcsicmp(label, param) == 0)
|
[CMD] Fixes for Batch error execution control flow.
CORE-13713 CORE-13736
- In case execution of all batch contexts is stopped (by selecting "All"
at the Ctrl-C/Ctrl-Break prompt), notify as well the CheckCtrlBreak()
signal handler once there are no more batch contexts (this in effect
resets the internal 'bLeaveAll' static flag in CheckCtrlBreak).
This is an adaptation of the fix present in FreeCOM 1.5, first
described in https://gcfl.net/FreeDOS/command.com/bugs074g.html .
- Introduce a ParseErrorEx() helper that sets the 'bParseError' flag and
displays a customized syntax-error message, only for the first syntax
error encountered. Implement ParseError() around the *Ex function.
- In batch mode, echo the original pre-parsed batch file line if a parse
error has been encountered.
- When running a compound command - including IF, FOR, command blocks -,
and that control flow is modified by any CALL/GOTO/EXIT command,
detect this while running the compound command so as to stop it and go
back to the main batch execution loop, that will then set up the actual
new command to run.
- In GOTO, do not process any more parts of a compound command only when
we have found a valid label.
2020-05-18 00:05:53 +00:00
|
|
|
{
|
|
|
|
/* Do not process any more parts of a compound command */
|
|
|
|
bc->current = NULL;
|
2013-06-30 00:08:43 +00:00
|
|
|
return 0;
|
[CMD] Fixes for Batch error execution control flow.
CORE-13713 CORE-13736
- In case execution of all batch contexts is stopped (by selecting "All"
at the Ctrl-C/Ctrl-Break prompt), notify as well the CheckCtrlBreak()
signal handler once there are no more batch contexts (this in effect
resets the internal 'bLeaveAll' static flag in CheckCtrlBreak).
This is an adaptation of the fix present in FreeCOM 1.5, first
described in https://gcfl.net/FreeDOS/command.com/bugs074g.html .
- Introduce a ParseErrorEx() helper that sets the 'bParseError' flag and
displays a customized syntax-error message, only for the first syntax
error encountered. Implement ParseError() around the *Ex function.
- In batch mode, echo the original pre-parsed batch file line if a parse
error has been encountered.
- When running a compound command - including IF, FOR, command blocks -,
and that control flow is modified by any CALL/GOTO/EXIT command,
detect this while running the compound command so as to stop it and go
back to the main batch execution loop, that will then set up the actual
new command to run.
- In GOTO, do not process any more parts of a compound command only when
we have found a valid label.
2020-05-18 00:05:53 +00:00
|
|
|
}
|
2013-06-30 00:08:43 +00:00
|
|
|
}
|
2020-05-22 21:58:12 +00:00
|
|
|
if (!bRetry && (bc->mempos >= bc->memsize))
|
|
|
|
{
|
|
|
|
bRetry = TRUE;
|
|
|
|
bc->mempos = 0;
|
|
|
|
goto retry;
|
|
|
|
}
|
2013-06-30 00:08:43 +00:00
|
|
|
|
2020-07-21 23:16:53 +00:00
|
|
|
NotFound:
|
2013-06-30 00:08:43 +00:00
|
|
|
ConErrResPrintf(STRING_GOTO_ERROR2, param);
|
|
|
|
ExitBatch();
|
|
|
|
return 1;
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|