Quelques utilisations de
goto dans mes logiciels:
Backgammon:
if (numlegalfullmoves) return numlegalfullmoves; else {
// if possible, the HIGHER die must be played
if (!numlegaldie1moves) goto die2;
if (!numlegaldie2moves) goto die1;
if (abs(die2)>abs(die1)) goto die2;
die1: // play die1
for (unsigned short i=0;i<numlegaldie1moves;i++) {
legalmoves[i][0]=legaldie1moves[i];
legalmoves[i][3]=legalmoves[i][2]=legalmoves[i][1]=-128;
}
return numlegaldie1moves;
die2: // play die2
for (unsigned short i=0;i<numlegaldie2moves;i++) {
legalmoves[i][1]=legaldie2moves[i];
legalmoves[i][3]=legalmoves[i][2]=legalmoves[i][0]=-128;
}
return numlegaldie2moves;
}
(Et il y a 41
gotos en total dans
Backgammon.) L'algorithme ci-dessus est aussi la manière la plus efficace de tester si une année est bissextile ou non:
if (x&3) goto notleapyear;
if (x%100) goto leapyear;
if (x%400) goto notleapyear;
leapyear:
KTIGCC:
if (CURRENT_VIEW && CURRENT_VIEW->hasFocus()) {
switch (index) {
case 0: editUndo(); break;
case 1: editRedo(); break;
case 2: editCut(); break;
case 3: editCopy(); break;
case 4: editPaste(); break;
case 5: // F1 context help
{
int line,col,i;
CURRENT_VIEW->cursorPosition().position(line,col);
QString textLine=CURRENT_VIEW->document()->line(line);
QString wordUnderCursor;
for (i=col-1;i>=0;i--) {
QChar c=textLine[i];
if ((c>='A' && c<='Z') || (c>='a' && c<='z') || (c>='0' && c<='9')
|| c=='_' || c=='$' || c=='#')
wordUnderCursor.prepend(c);
}
int len=textLine.length();
for (i=col;i<len;i++) {
QChar c=textLine[i];
if ((c>='A' && c<='Z') || (c>='a' && c<='z') || (c>='0' && c<='9')
|| c=='_' || c=='$' || c=='#')
wordUnderCursor.append(c);
}
// always open at least the index
force_qt_assistant_page(1);
assistant->openAssistant();
if (wordUnderCursor.isEmpty()) return;
QString docFile=lookup_doc_keyword(wordUnderCursor);
if (docFile.isEmpty()) return;
// wait for Qt Assistant to actually open
while (!assistant->isOpen())
QCoreApplication::processEvents(QEventLoop::ExcludeUserInput,1000);
assistant->showPage(QString(tigcc_base)+QString("/doc/html/")+docFile);
break;
}
case 6:
case 7:
// keyReturn is not in any interface, but it's a public slot...
CURRENT_VIEW->qt_metacall(QMetaObject::InvokeMetaMethod,
CURRENT_VIEW->metaObject()->indexOfMethod("keyReturn()"),NULL);
current_view_newLineHook();
break;
case 8:
new TemplatePopup(CURRENT_VIEW);
break;
case 9:
case 10:
if (IS_FILE(currentListItem)
&& CURRENT_VIEW==static_cast<ListViewFile *>(currentListItem)->kateView) {
QString fileText=CURRENT_VIEW->document()->text();
CATEGORY_OF(category,currentListItem);
// Completion only operates on C files.
if (category==cFilesListItem || category==qllFilesListItem
|| (category==hFilesListItem && !fileText.isEmpty()
&& fileText[0]!='|' && fileText[0]!=';')) {
// Disable newLineHook.
shortcuts[6]->setEnabled(FALSE);
shortcuts[7]->setEnabled(FALSE);
new CompletionPopup(CURRENT_VIEW,pathInProject(currentListItem),this,this);
}
}
break;
case 11: // next file
case 12:
case_11:
{
Q3ListViewItem *item=currentListItem;
if (!item) item=rootListItem;
Q3ListViewItem *origItem=item;
do {
item=item->itemBelow();
if (!item) item=rootListItem;
if (item==origItem) return; // no suitable items to select
} while (item==rootListItem || IS_CATEGORY(item));
fileTreeClicked(item);
if (CURRENT_VIEW) CURRENT_VIEW->setFocus();
break;
}
case 13: // switch transfer target
case 14:
case_13:
{
preferences.linkTarget=(preferences.linkTarget==LT_TIEMU)?LT_REALCALC:LT_TIEMU;
savePreferences();
// Apply the preferences to the debug menu.
debugPauseAction->setEnabled(!compiling&&preferences.linkTarget==LT_TIEMU);
debugResetAction->setEnabled(!compiling&&preferences.linkTarget==LT_TIEMU);
bool runnable=!settings.archive&&!settings.flash_os&&preferences.linkTarget!=LT_NONE;
menuBar()->setItemVisible(5,runnable); //debugMenu
debugRunAction->setVisible(runnable);
debugPauseAction->setVisible(runnable);
break;
}
case 15: projectCompile(); break;
case 16: projectMake(); break;
default: break;
}
} else {
switch (index) {
case 6:
case 7:
{
QKeyEvent *keyEvent=new QKeyEvent(QEvent::KeyPress,Qt::Key_Return,'\n',0,"\n");
QApplication::postEvent(focusWidget(),keyEvent);
break;
}
case 11: goto case_11;
case 12: goto case_11;
case 13: goto case_13;
case 14: goto case_13;
case 15: projectCompile(); break;
case 16: projectMake(); break;
default: break;
}
}
(Je saute d'un switch à un autre.

)
xctigcc, le plugin de news de
tigcc_bot sur IRC:
switch (ret) {
case 1:
data = xmliter_data(1);
if (!data || strlen(data)>255) {
xml_parse_error:
free(data);
xmliter_done();
goto parse_error;
}
strcpy(title,data);
free(data);
break;
case 2:
data = xmliter_data(1);
if (is_atom) {
if (!data || sscanf(data,"%4d-%2d-%2dT%2d:%2d:%2dZ",&y,&m,&d,&hr,&mn,&sc)<6)
goto xml_parse_error;
} else {
if (!data || sscanf(data,"%*3c, %d %3c %d %2d:%2d:%2d",&d,datebuffer,&y,&hr,&mn,&sc)<6)
goto xml_parse_error;
if (!strncmp(datebuffer,"Jan",3)) m=1;
else if (!strncmp(datebuffer,"Feb",3)) m=2;
else if (!strncmp(datebuffer,"Mar",3)) m=3;
else if (!strncmp(datebuffer,"Apr",3)) m=4;
else if (!strncmp(datebuffer,"May",3)) m=5;
else if (!strncmp(datebuffer,"Jun",3)) m=6;
else if (!strncmp(datebuffer,"Jul",3)) m=7;
else if (!strncmp(datebuffer,"Aug",3)) m=8;
else if (!strncmp(datebuffer,"Sep",3)) m=9;
else if (!strncmp(datebuffer,"Oct",3)) m=10;
else if (!strncmp(datebuffer,"Nov",3)) m=11;
else if (!strncmp(datebuffer,"Dec",3)) m=12;
else goto xml_parse_error;
}
tm.tm_year = y-1900; tm.tm_mon = m-1; tm.tm_mday = d;
tm.tm_hour = hr; tm.tm_min = mn; tm.tm_sec = sc;
{
const char *oldlocale = setlocale(LC_TIME,NULL);
setlocale(LC_TIME,"C");
strftime(datebuffer, 99, "%B %d, %Y %H:%M:%S", &tm);
setlocale(LC_TIME,oldlocale);
}
free(data);
break;
case 3:
data = xmliter_data(1);
if (!data || strlen(data)>255) goto xml_parse_error;
strcpy(author,data);
free(data);
break;
case 4:
xchat_commandf(ph, "notice %s %s %s", nick, datebuffer, author);
xchat_commandf(ph, "notice %s %s", nick, title);
nc++;
break;
}
(Autre grand classique, le saut dans un
if d'erreur.)
Et j'en ai plein d'autres.