Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197/* * GOTO.C - goto internal batch command. * * History: * * 16 Jul 1998 (Hans B Pufal) * started. * * 16 Jul 1998 (John P Price) * Separated commands into individual files. * * 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 * * 24-Jan-1999 (Eric Kohl) * Unicode and redirection safe! * * 27-Jan-1999 (Eric Kohl) * Added help text ("/?"). * * 28-Apr-2005 (Magnus Olsen <magnus@greatlord.com>) * Remove all hardcoded strings in En.rc */
#include "precomp.h"
/* * Perform GOTO command. * * Only valid when a batch context is active. */INT cmd_goto(LPTSTR param){ LPTSTR label, tmp; DWORD dwCurrPos; BOOL bRetry;
TRACE("cmd_goto(\'%s\')\n", debugstr_aw(param));
/* * Keep the help message handling here too. * This allows us to reproduce the Windows' CMD "bug" * (from a batch script): * * SET label=/? * CALL :%%label%% * * calls GOTO help, due to how CALL :label functionality * is internally implemented. * * See https://stackoverflow.com/q/31987023/13530036 * for more details. * * Note that the choice of help parsing forbids * any label containing '/?' in it. */ if (_tcsstr(param, _T("/?"))) { ConOutResPaging(TRUE, STRING_GOTO_HELP1); return 0; }
/* If not in batch, fail */ if (bc == NULL) return 1;
/* Fail if no label has been provided */ if (*param == _T('\0')) { ConErrResPrintf(STRING_GOTO_ERROR1); ExitBatch(); return 1; }
/* Strip leading whitespace */ while (_istspace(*param)) ++param;
/* 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]))) { /* 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; return 0; }
/* 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;
/* * 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;
retry: while (BatchGetString(textline, ARRAYSIZE(textline))) { if (bRetry && (bc->mempos >= dwCurrPos)) break;
#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 */ }
++tmp; } *tmp = _T('\0');
/* Jump if the labels are identical */ if (_tcsicmp(label, param) == 0) { /* Do not process any more parts of a compound command */ bc->current = NULL; return 0; } } if (!bRetry && (bc->mempos >= bc->memsize)) { bRetry = TRUE; bc->mempos = 0; goto retry; }
NotFound: ConErrResPrintf(STRING_GOTO_ERROR2, param); ExitBatch(); return 1;}
/* EOF */