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.