C Funktion verbessern



  • Ich habe eine Funktion, Sie ist sehr lang geworden. Wie kann ich sie gekommt verkleinern? Lauter kleine Funktionen daraus zu machen kanns auch nicht sein. Hinweis: Das Makro IS_CMD ist #define IS_CMD(x) (strcmp(command->ptrs[0],(x)) == 0)

    // Main command handler
    static int PerformCommand (stringhack_t *command, int lasterror)
    {
      // Ex: OUT <Portnumber> <ON|OFF>
      // Switcher I/O pin on or off
      if (IS_CMD("OUT"))
      {
        PARAMCHECK(3);
    
        int port = atoi(command->ptrs[1]);
        PORTCOMMAND cmd;
    
        if (strcmp(command->ptrs[2],"OFF")==0)
        {
          cmd = PT_CLR;  
        }
        else if (strcmp(command->ptrs[2],"ON")==0)
        {
          cmd = PT_SET;  
        }
        else
        {
          return 0;  
        }
    
        CMD_Port (port, cmd, 0, 0, 0);
      }
    
      // Ex: RESET
      // Reboots the tester
      else if (IS_CMD("RESET"))
      {
        CMD_Reboot(FALSE);    
      }
    
      // Ex: WAITKEY <ms>
      // Waits until key pressed or optional time-out expires
      else if (IS_CMD("WAITKEY"))
      {
        PARAMCHECK_RANGE(1,2);
    
        int key4;
        UINT32 timeout;
    
        // With timeout
        if (command->num == 2)
        {
          timeout = GET_MILLISEC_COUNTER_VALUE() + atoi(command->ptrs[1]);
          do
          {
            CMD_Port (4, PT_GET, &key4, 0, 0);
            if (timeout < GET_MILLISEC_COUNTER_VALUE())
              return 0; // timed out
          } while (key4 != 0);
        }
        // Without timeout
        else
        {
          do
          {
            CMD_Port (4, PT_GET, &key4, 0, 0);
          } while (key4 != 0);
        }
    
        // Wait until key released (poor debouncing)    
        do
        {
          CMD_Port (4, PT_GET, &key4, 0, 0);
        } while (key4 == 0);
      }
    
      // Ex: PROTOCOL 1
      // Switches to I/O protocol (0...9) allowed
      // 0 is RS232 #1
      // 1 is RS232 #2
      // 2 is CAN1 and so on...
      else if (IS_CMD ("PROTOCOL"))
      {
        PARAMCHECK(2);
    
        int prot = *command->ptrs[1] - '0';
        SwitchToProtocol (prot);
      }
    
      // Ex: SENDFILE filename
      // Sends file to the test object
      // Ex: SENDFILE dir DIRECTORY
      // Sends first file in dierctory 'dir' to the test object
      else if (IS_CMD ("SENDFILE"))
      {
        PARAMCHECK_RANGE(2,3);
    
        FIL fil;
        FRESULT res;
    
        if (command->num == 2)
        {
          res = f_open (&fil, command->ptrs[1], FA_READ | FA_OPEN_EXISTING);
          if (res != FR_OK)
            return 0; // fopen error
        }
        else
        {
          if (strcmp (command->ptrs[2], "DIRECTORY") != 0)
            return 0; // wrong keyword
    
          if (0 == FindFirstFileOfDirectory (command->ptrs[1], CurrentLine))
            return 0;  // file not found
    
          res = f_open (&fil, CurrentLine, FA_READ | FA_OPEN_EXISTING);
          if (res != FR_OK)
            return 0; // fopen error
        }
    
        // Do for all bytes
        for (;;)
        {
          WORD bytes_read;
          res = f_read (&fil, CurrentLine, sizeof(CurrentLine), &bytes_read);
          if (res != FR_OK)
            break;   // f_read error
          if (bytes_read == 0)
            break;   // file pionter has reached the end
          WriteFunction ((UINT8*)CurrentLine, bytes_read);
        }
    
        f_close (&fil);
      }
    
      // Ex: LOGOPEN hello.txt
      // Opens a log file for writing
      else if (IS_CMD ("LOGOPEN"))
      {
        PARAMCHECK (2);
    
        return LOG_open (command->ptrs[1]);
      }
    
      // Ex: LOG "hello"
      // Writes string to logfile
      else if (IS_CMD ("LOG"))
      {
        PARAMCHECK (2);
    
        return LOG_write_string (command->ptrs[1]);
      }
    
      // Ex: CALL LABEL1
      // Call a subroutine
      else if (IS_CMD("CALL"))
      {
        PARAMCHECK(2);
    
        GosubStackPush (SCRIPT_GetCurrentLineNumber());
    
        if (SeekToLabel (command->ptrs[1]) == 0)
          return 0;
      }
    
      // Ex: RETURN
      // Return from subroutine
      else if (IS_CMD ("RETURN"))
      {
        int line = GosubStackPop();
    
        if (SeekToLineNumber (line) == 0)
          return 0;
      }
    
      // Ex: SETLOCALTIME a b c d e f
      // Sets date and time of this device
      else if (IS_CMD("SETLOCALTIME"))
      {
        PARAMCHECK(7);
    
        DATE_AND_TIME dt;
    
        dt.year = atoi (command->ptrs[1]);
        dt.month = atoi (command->ptrs[2]);
        dt.day = atoi (command->ptrs[3]);
        dt.hour = atoi (command->ptrs[4]);
        dt.minute = atoi (command->ptrs[5]);
        dt.second = atoi (command->ptrs[6]);
    
        RTC_SetDateAndTime (&dt);
      }
    
      // Ex: SYNCTIME
      // Set time of test object
      else if (IS_CMD("SYNCTIME"))
      {
        PARAMCHECK(1);
    
        UINT16 year = CLOCK_READ_YEARS(); 
    
        if (year < 2000 || year > 2100)  // Local time not set
          return 0;
    
        UINT8 month = CLOCK_READ_MONTHS(); 
        UINT8 day = CLOCK_READ_DAYS(); 
        UINT8 hour = CLOCK_READ_HOURS(); 
        UINT8 minute = CLOCK_READ_MINUTES(); 
        UINT8 sec = CLOCK_READ_SECONDS();
    
        sprintf (CurrentLine, "TIME %d %d %d %d %d %d\r\n",   
                 year, month, day, hour, minute, sec);
        WriteFunction ((UINT8*)CurrentLine, strlen (CurrentLine));
      }
    
      else if (IS_CMD("CHECKTIME"))
      {
        PARAMCHECK(1);
    
        char *t = "TIME?\r\n";
        UINT32 timeout;
        int idx;
    
        // Send request
        WriteFunction ((UINT8*)t, strlen(t));
    
        // Collect response (only the numbers)     
        timeout = GET_MILLISEC_COUNTER_VALUE() + 3000;
        idx = 0;
        for (;;)
        {
          // Timed out?
          if (timeout < GET_MILLISEC_COUNTER_VALUE())
            break;
    
          char b;
          if (0 == ReadFunction ((UINT8*)&b, 1))
            continue;
    
          // Filter valid chars
          if (b < '0' || b > '9')
            continue;
    
          CurrentLine[idx++] = (char)b;
          if (idx == 14)
            break;
        }
    
        // Make numbers
        DATE_AND_TIME dt1;
        dt1.year = ToNumber (CurrentLine, 4);
        dt1.month = ToNumber (CurrentLine+4, 2);
        dt1.day = ToNumber (CurrentLine+6, 2);
        dt1.hour = ToNumber (CurrentLine+8, 2);
        dt1.minute = ToNumber (CurrentLine+10, 2);
        dt1.second = ToNumber (CurrentLine+12, 2);
    
        // Compare to local time
        DATE_AND_TIME dt2;
        RTC_GetDateAndTime (&dt2);
    
        UINT32 t1 = GetTimeStamp (TIMEOFFSET_1900, &dt2);
        UINT32 t2 = GetTimeStamp (TIMEOFFSET_1900, &dt1);
        UINT32 diff;
    
        if (t1 < t2)
          diff = t2-t1;
        else
          diff = t1-t2;
    
        // Check difference
        if (diff > 10)
          return 0;  // 0 == invalid time
      }
    
      // Ex: DRAIN <RX|TX>
      // Clears input and output buffers
      // If argument is not present, both buffers are cleared
      else if (IS_CMD("DRAIN"))
      {
        PARAMCHECK_RANGE (1,2);
    
        int s;
    
        // Do it two times
        for (s=0; s<2; s++)
        {
          WaitMS (100);
          if (strcmp (command->ptrs[1], "RX") == 0)
          {
            PurgeFunction (PURGE_RX);  
          }
          else if (strcmp (command->ptrs[1], "TX") == 0)
          {
            PurgeFunction (PURGE_TX);  
          }
          else
          {
            PurgeFunction (PURGE_TX | PURGE_RX);
          }
        }
      }
    
      // Ex: ONERROR labelname
      // Jumps to label if last error != 1
      else if (IS_CMD("ONERROR"))
      {
        PARAMCHECK(2);
    
        if (lasterror == 0)
        {
          if (SeekToLabel (command->ptrs[1]) == 0)
            return 0;
        }
      }
    
      // Ex: ONSUCCESS labelname
      // Jumps to label if last error != 1
      else if (IS_CMD("ONSUCCESS"))
      {
        PARAMCHECK(2);
    
        if (lasterror != 0)
        {
          if (SeekToLabel (command->ptrs[1]) == 0)
            return 0;
        }
      }
    
      // Ex: JUMP labelname
      // Jump to label
      else if (IS_CMD("JUMP"))
      {
        PARAMCHECK(2);
    
        if (SeekToLabel (command->ptrs[1]) == 0)
          return 0;
      }
    
      // Ex: SEND "hello world" <delay>
      // Send string to test object with optional delay
      else if (IS_CMD("SEND"))  
      {
        PARAMCHECK_RANGE(2, 3);
    
        WriteFunction ((UINT8*)command->ptrs[1], strlen (command->ptrs[1]));
    
        // Optional wait argument
        if (NUMPARAMS(3))
        {
          WaitMS (atoi(command->ptrs[2]));
        }
      }
    
      // Ex: SENDLINE "hello world" <delay>
      // Send string to test object, appends CR/LF, with optional delay
      else if (IS_CMD("SENDLINE"))  
      {
        PARAMCHECK_RANGE(2, 3);
    
        UINT8 crlf[] = {0x0d, 0x0a};
    
        WriteFunction ((UINT8*)command->ptrs[1], strlen (command->ptrs[1]));
        WriteFunction (crlf, sizeof(crlf));
    
        // Optional wait argument
        if (NUMPARAMS(3))
        {
          WaitMS (atoi(command->ptrs[2]));
        }
      }
    
      // Ex: SENDBYTES 00112233aabbdd <delay>
      // Send HEX bytes to test object with optional delay
      else if (IS_CMD("SENDBYTES"))
      {
        PARAMCHECK_RANGE(2, 3);
    
        int num = FromHexString (command->ptrs[1], (UINT8*)command->ptrs[1]);
        WriteFunction ((UINT8*)command->ptrs[1], num);
    
        // Optional wait argument
        if (NUMPARAMS(3))
        {
          WaitMS (atoi(command->ptrs[2]));
        }
      }
    
      // Ex: WAIT 1000
      // Wait for X ms 
      else if (IS_CMD("WAIT")) 
      {
        PARAMCHECK(2);
    
        WaitMS (atoi(command->ptrs[1]));
      }
    
      // Ex: WAITSTRING "hello world" 1000
      // Wait for a string for X ms from the test object
      else if (IS_CMD ("WAITSTRING"))
      {
        PARAMCHECK(3);
    
        UINT32 timeout = GET_MILLISEC_COUNTER_VALUE() + atoi(command->ptrs[2]);
        char *p = command->ptrs[1];
    
        while (timeout > GET_MILLISEC_COUNTER_VALUE())
        {
          char b;
    
          // Get a character
          if (0 == ReadFunction ((UINT8*)&b, 1))
            continue;
    
          if (b == *p)
          {
            p++;
            if (*p == 0)
            {
              return 1;  // OK (found)
            }
          }
          else
          {
            p = command->ptrs[1];  // Wrong char, Reset pointer  
          }
        }
        return 0; // Time out
      }
    
      // Ex: WAITBYTES 0D0A 1000
      // Wait for a sequence of HEX bytes with timeout
      else if (IS_CMD ("WAITBYTES"))
      {
        PARAMCHECK(3);
    
        int num = FromHexString (command->ptrs[1], (UINT8*)command->ptrs[1]);
    
        UINT32 timeout = GET_MILLISEC_COUNTER_VALUE() + atoi(command->ptrs[2]);
        char *p = command->ptrs[1];
    
        while (timeout > GET_MILLISEC_COUNTER_VALUE())
        {
          char b;
          if (ReadFunction((UINT8*)&b, 1) == 0)
            continue;
    
          if (b == *p)
          {
            p++;
            if (p-command->ptrs[1] >= num)
            {
              return 1;  // OK (found)
            }
          }
          else
          {
            p = command->ptrs[1];  // Wrong char, Reset pointer  
          }
        }
        return 0; // Time out
    
      }
    
      // Ex: AUXRS232 9600 8 N 1
      // Activates and configures aux RS232
      // Does !NOT! switch to this protocol
      else if (IS_CMD ("AUXRS232"))
      {
        PARAMCHECK(5);            // cmd baud 8 n 1
    
        RS232_SETTINGS set;
        set.baudrate = atoi (command->ptrs[1]);
        set.handshake = RS232_HS_NONE;
        set.mode = RS232_MODE_RS232;
        switch (*command->ptrs[2]-'0')
        {
          case 5:
          set.bits_per_char = RS232_CS_5;
          break;
    
          case 6:
          set.bits_per_char = RS232_CS_6;
          break;
    
          case 7:
          set.bits_per_char = RS232_CS_7;
          break;
    
          case 8:
          set.bits_per_char = RS232_CS_8;
          break;
        }
    
        switch (*command->ptrs[3])
        {
          case 'E':
          set.parity = RS232_PAR_EVEN;
          break;
    
          case 'O':
          set.parity = RS232_PAR_ODD;
          break;
    
          case 'N':
          set.parity = RS232_PAR_NONE;
          break;
        }
        switch (*command->ptrs[4]-'0')
        {
          case 1:
          set.stopbits = RS232_STP_ONE;
          break;
    
          case 2:
          set.stopbits = RS232_STP_TWO;
          break;
        }
    
        // Make the fifos
        static char rxbuff[256];
        static char txbuff[256];
        static sfifo_t rxfifo;
        static sfifo_t txfifo;
        sfifo_init (&rxfifo, sizeof(rxbuff)-1, rxbuff);
        sfifo_init (&txfifo, sizeof(txbuff)-1, txbuff);
    
        // Start RS232 #2
        AUXRS232_Init (&set, &rxfifo, &txfifo);
      }
    
      // Ex: RS232 9600 8 N 1
      // Activate and configure RS232 
      else if (IS_CMD("RS232"))   
      {
        PARAMCHECK(5);            // cmd baud 8 n 1
    
        RS232_SETTINGS set;
        set.baudrate = atoi (command->ptrs[1]);
        set.handshake = RS232_HS_NONE;
        set.mode = RS232_MODE_RS232;
        switch (*command->ptrs[2]-'0')
        {
          case 5:
          set.bits_per_char = RS232_CS_5;
          break;
    
          case 6:
          set.bits_per_char = RS232_CS_6;
          break;
    
          case 7:
          set.bits_per_char = RS232_CS_7;
          break;
    
          case 8:
          set.bits_per_char = RS232_CS_8;
          break;
        }
    
        switch (*command->ptrs[3])
        {
          case 'E':
          set.parity = RS232_PAR_EVEN;
          break;
    
          case 'O':
          set.parity = RS232_PAR_ODD;
          break;
    
          case 'N':
          set.parity = RS232_PAR_NONE;
          break;
        }
        switch (*command->ptrs[4]-'0')
        {
          case 1:
          set.stopbits = RS232_STP_ONE;
          break;
    
          case 2:
          set.stopbits = RS232_STP_TWO;
          break;
        }
        RS232_Init (&set);
        SwitchToProtocol (0);
      }
    
      // Ex: CAN xxxx yyyy zzzz
      // Activates CAN1 and switches to it
      // xxxx --> Local message ID
      // yyyy --> Remote message ID
      // zzzz --> Baud rate to be used
      else if (IS_CMD("CAN"))
      {
        CAN_SETTINGS set;
        CAN_FILTERSETTINGS flt;
        CAN_EXTENDED_SETTINGS ext;
    
        PARAMCHECK(4);
    
        // General can settings
        set.rx_id = atoi (command->ptrs[1]);
        set.tx_id = atoi (command->ptrs[2]);
        set.baudrate = atoi (command->ptrs[3]);
        set.rx_id_extended = FALSE;
        set.tx_id_extended = FALSE;
    
        // Filter settings
        flt.from = 0;
        flt.to = CAN_MAX_STD_ID;
        flt.mode = CANFLT_BYPASS;
    
        // Extended settings
        ext.listen_only = FALSE;
        ext.extension_chip = EXTENSION_DISABLED;
    
        // Start and activate
        CAN1_Init (&set, &flt, FALSE, &ext);
        SwitchToProtocol(2);
      }
    
      // Ex: AUXCAN zzzz
      // Activates CAN2 and switches to it
      // zzzz --> Baud rate to be used
      else if (IS_CMD("AUXCAN"))
      {
        CAN_SETTINGS set;
        CAN_FILTERSETTINGS flt;
    
        PARAMCHECK(2);
    
        // Create a FIFO
        static char rxbuff[256];
        static sfifo_t rxfifo;
        sfifo_init (&rxfifo, sizeof(rxbuff)-1, rxbuff);
    
        // General settings
        set.rx_id = 0;
        set.tx_id = 0;
        set.baudrate = atoi (command->ptrs[1]);
        set.rx_id_extended = FALSE;
        set.tx_id_extended = FALSE;
    
        // Filter settings
        flt.from = 0;
        flt.to = CAN_MAX_STD_ID;
        flt.mode = CANFLT_BYPASS;
    
        AUXCAN_Init (&rxfifo, &set, 0, &flt);
      }
    
      // Ex: CANMESSAGE xx 001122334455667788
      // Sends data to CAN1 using ID xx. data is given as hex string
      // Hex string must not contain more than 16 digits (8 bytes)
      else if (IS_CMD("CANMESSAGE"))
      {
        CAN_MSG msg;
    
        PARAMCHECK(3);
    
        int num = FromHexString (command->ptrs[2], (UINT8*)command->ptrs[1]);
        if (num > 8)
          return 0;  // too much
    
        msg.Frame = (num<<16);
        msg.MsgID = atoi (command->ptrs[1]);
        memcpy (msg.Data, command->ptrs[2], num);
        CAN1_SendMessage (&msg);
      }
    
      // Ex: AUXCANMESSAGE xx 001122334455667788
      // Sends data to CAN2 using ID xx. data is given as hex string
      // Hex string must not contain more than 16 digits (8 bytes)
      else if (IS_CMD ("AUXCANMESSAGE"))
      {
        CAN_MSG msg;
    
        PARAMCHECK(3);
    
        int num = FromHexString (command->ptrs[2], (UINT8*)command->ptrs[1]);
        if (num > 8)
          return 0;  // too much
    
        msg.Frame = (num<<16);
        msg.MsgID = atoi (command->ptrs[1]);
        memcpy (msg.Data, command->ptrs[2], num);
        AUXCAN_SendMessage (&msg);
      }
    
      // Ex: ISCANMESSAGE 001122334455667788 wait
    
      else if (IS_CMD ("ISCANMESSAGE"))
      {
         // Not yet implemented 
    
      }
    
      else if (IS_CMD ("ISAUXCANMESSAGE"))
      {
         // Not yet implemented 
      }
    
      //////// End of function /////////
      return 1; // 1 means OK
    }
    

    Viele dank für eure Ideen 👍 :p



  • Lass den ganzen grünen Text weg. Bei if() wo nur eine Zeile folgt brauchst du keine {}, wenn du doch irgendwo {} brauchst schreib die { hinter deine if Anweisung.



  • ______ schrieb:

    Lass den ganzen grünen Text weg.

    quatsch. mach dir ein array aus structs. jedes element enthält das keyword und einen function pointer, der auf die dazugehörige funktion zeigt. dann kannste mit 'ner schleife alles abklappern und hast keine if-else-else-else-orgie mehr.
    🙂


Anmelden zum Antworten