36Fermer38
Kevin KoflerLe 11/01/2015 à 03:17
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. tongue)

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.