Quiero reducir la ramificación anidada profunda de este código C y me pregunto si existe una herramienta de análisis que pueda hacer una tabla de verdad para las condiciones o si debo analizarla manualmente. Me gustaría hacer que el código sea más legible y menos ramificado. Mi IDE CLion de JetBrains no dice nada sobre cómo realizar tal refactorización. ¿Se puede automatizar? No intenté usar Lint pero pude probarlo.
if (ptr + j) {if (* (ptr + j) [0] == '{') {keep = true; } if (testFn (* (ptr + j))) {/ * prueba para el último carácter * / cadena [i] [j - p] = concat (* pString1, * (ptr + j)); mantener = falso; libre (* pString1); goto mylabel; } if (mantener) {* pString1 = concat (* pString1, * (ptr + j)); * pString1 = concat (* pString1, ""); p ++; } más {b1 = falso; int q = j; for (e = 0; * (ptr + q + e); e ++) {/ * paso a través de la cadena * / b1 = true; if (* (ptr + e + q)) {* pString = concat (* pString, * (ptr + e + q)); * pString = concat (* pString, ""); } j = e; } if (makeArgs (* pString, &argc, (const char ***) &argv, pipe, i, h)) {write_command (&w, argv, string [w]); w ++; } else {if (! b1) {/ * no args (?) * / for (int r = 0; argv [r]! = NULL; r ++) {string [i] [r] = argv [r]; /* ¿Es esto necesario? * /}}}}}
He podido reducir la ramificación condicional manualmente, pero no he hecho una tabla de verdad. Creo que los análisis de código deberían decir qué ramas son idénticas y cuándo con una tabla de verdad.
La función completa se ve así hoy:
static int runCmd (const char * cmd) {const char * cp; pid_t pid; estado int; comando de estructura comando de estructura [15]; char ** argv = 0; int argc = 1; bool pipe = falso; char * cadena [z] [z];
char * pString3 [40]; char * pString2 [40]; int n = 0; char ** ptr1; char string1 [z]; bool mantener = falso; char * pString1 [z]; char * pString [z]; * pString1 = "\ 0"; * pString = "\ 0"; char * temp = {'\ 0'}; int w = 0; bool quote = false; int rrs [256]; int j = 0; int i; int p = 0; char ** ptr; int count = 0; char * cmdtmp; bool b1 = falso; int y = 0; i = 0; int h = 0; char * str; char * freeme [75] [75]; char ** dealloc [75]; char ** dealloca [75] [75]; int acount [128]; nullterminate (cadena); int rr = 0; para (z = 0; z < 128; z ++) {cuenta [z] = -1; } para (int f = 0; f < 75; f ++) {dealloc [f] = NULL; para (z = 0; z < 75; z ++) {freeme [f] [z] = NULL; }} if (cmd) {for (cp = cmd; * cp; cp ++) {if ((* cp > = 'a') && (* cp < = 'z')) {continuar; } if ((* cp > = 'A') && (* cp < = 'Z')) {continuar; } if (isDecimal (* cp)) {continuar; } if (isBlank (* cp)) {continuar; } si ((* cp == '.') || (* cp == '/') || (* cp == '-') || (* cp == '+') || (* cp == '=') || (* cp == '_') || (* cp == ':') || (* cp == ',') || (* cp == '\' ' ) || (* cp == '"')) {continuar;}} cmdtmp = strdup (cmd); ptr1 = str_split (pString3, cmdtmp, '|'); if (strstr (cmd," | ") == NULL) {/ * no es una canalización * / makeArgs (cmd, &argc, (const char ***) &argv, pipe, 0, 0); write_argument (&argc, structcommand, argv, string [0]); n ++;} else {for (i = 0; * (ptr1 + i); i ++) {/ * bucle para cada canalización * / n ++;
/ * guardar número de canalizaciones * / dealloc [n] = NULL; int e = 0; / * un contador * / * pString = "\ 0"; / * ¿Debería malloc y liberar esto? * / strcpy (cadena1, * (ptr1 + i)); if ((string1 [0]! = '\ 0') &&! isspace (string1 [0])) {/ * este no es ni el final ni un nuevo argumento * / / * ¿Error BSD? comprobar * / ptr = str_split (pString2, * (&string1), ''); / * divide la cadena en los argumentos * / dealloc [rr] = ptr; rr ++; h = 0; for (j = 0; * (ptr + j); j ++) {/ * recorrer los argumentos * / dealloca [n] [n - 1] = NULL; / * la canalización está en cmdtmp y el argumento / programa está en ptr [i] * / if (ptr + j &&! quote && strstr (* (ptr + j), "'")) {/ * es una cita? * / quote = true; strcpy (temp, * (ptr + j)); / * punto donde chocan los piipelines citados * / if (y < 1) {y ++; }} while (quote) {if (* (ptr + j) && strstr (* (ptr + j), "'")) {/ * fin de la cita * / quote = false; if (y < 1) {cadena [i] [j] = strcpy (temp, * (ptr + j)); } y = 0; } else if (* (ptr + j)) {/ * leer hasta el final de la cita * / string [i] [j] = temp; Seguir; } más {cita = falso; romper;
}} si (ptr + j) {; if (* (ptr + j) [0] == '{') {mantener = verdadero; } if (testFn (* (ptr + j))) {/ * prueba para el último carácter * / string [i] [j - p] = concat (* pString1, * (ptr + j)); mantener = falso; libre (* pString1); continuar; // ir a mylabel; } if (mantener) {str = concat (* pString1, * (ptr + j)); * pString1 = concat (str, ""); libre (str); p ++; } más {b1 = falso; int q = j; freeme [i] [0] = * pString; for (e = 0; * (ptr + q + e); e ++) {/ * paso a través de la cadena * / b1 = true; if (* (ptr + e + q)) {str = concat (* pString, * (ptr + e + q)); * pString = concat (str, ""); / * ¿cómo liberar ()? * / libre (str); freeme [i] [e] = * pString; } j = e; / * ajustar el contador * /} if (makeArgs (freeme [i] [e - 1], &argc, (const char ***) &argv, pipe, i, h)) {write_command (&w, argv, string [w ]); w ++; para (int qwe = 0; qwe < argc; qwe ++) {
dealloca [n - 1] [qwe] = &argv [qwe]; } cuenta [n - 1] = argc; } else {if (! b1) {/ * no args (?) * / for (int r = 0; argv [r]! = NULL; r ++) {string [i] [r] = argv [r]; /* ¿Es esto necesario? * /}}}}}} bool boo = falso; dump_argv ((const char *) "d", argc, argv, boo); }}} para (i = 0; i < n; i ++) {structcommand [i] .argv = string [i]; for (j = 0; string [i] [j]! = NULL; j ++) {if (string [i]! = NULL) {}}} libre (cmdtmp); if (ptr1) {int i; para (i = 0; * (ptr1 + i); i ++) {libre (* (ptr1 + i)); } printf ("\ n"); libre (ptr1); } fflush (NULL); pid = tenedor (); if (pid < 0) {perror ("error de bifurcación"); return -1; } / * Si somos el proceso hijo, entonces ejecutamos la cadena. * / If (pid == 0) {/ * spawn (cmd); * / fork_pipes (n, structcommand); } / * * Somos el proceso padre. * Espere a que el niño complete. * / estado = 0; while (((pid = waitpid (pid, &status, 0)) < 0) && (errno == EINTR)); if (pid < 0) {fprintf (stderr, "Error de waitpid:% s", strerror (errno)); return -1; } if (WIFSIGNALED (estado)) {fprintf (stderr, "pid% ld: asesinado por la señal% d \ n",
(largo) pid, WTERMSIG (estado)); return -1; }} para (i = 0; i < n; i ++) {para (j = 0; cadena [i] [j]! = NULL; j ++) {if (cadena [i]! = NULL) {if (cadena [ i] [j]) libre (cadena [i] [j]); }}} int z; para (int f = 0; f < n; f ++) {if (f > 0) {} para (z = 0; freeme [f] [z]; z ++) {free (freeme [f] [z]); }} size_t idx; for (int f = 0; n > 1 && f < n; f ++) {for (idx = 0; * (dealloc [f] + idx)! = NULL; idx ++) {free (* (dealloc [f] + idx )); } libre (dealloc [f]); } return WEXITSTATUS (estado);}
El código está escaneando y analizando otro programa, es por eso que hay tanta manipulación de cadenas, guardando y mirando hacia adelante en caracteres y punteros.