# Complexité Cyclomatique
## Calcul de la complexité cyclomatique pour chaque fonctions
----------------
Pour chaque fonction, un diagramme est proposé dans ping-report/diagrammes/*nom de la fonction approprié*.

-- Dans daemon.c
- create_daemon() : 4
- ping_request() : 2 
- send_check() : 2
- check_keep_working() : 4
- daemon_work() : 3
- ping-report main() : 5
- write_pid_file() : 2
- get_ping_from_temp_log : 12
- write_ping_log : 3
- set_stats_ping() : 10

Toute fonction non mentionnée dans la liste a une complexité cyclomatique de 1, et donc ne nécessite pas un diagramme.

-------------------
Dans un second temps, on va amélorier la complexité cyclomatique des fonctions les plus lourdes si possible. On va commencer par get_ping_from_temp_log.
La méthode la plus efficace pour réduire la compléxité cyclomatique d'un programme, outre
changer la nature du code, est de factoriser la fonction, c'est à dire d'écrire un segment
du code coûteux dans une fonction à part puis de l'appeler.

On a décidé de faire cela pour la boucle while de la fonction. Cela nous donne le code suivant :

```c
void while_from_gpftl(char* read_line, size_t* n, FILE* fd, regex_t* p_reg, regmatch_t* pmatch, size_t* nmatch, int* start, int* end, size_t* size_ping, char* ping){
    while(getline(&read_line,n,fd) != -1){
        
        if(read_line == NULL){
            break;
        }

        /* Exec regex to find ping */

        if(regexec(p_reg,read_line,*nmatch,pmatch,0) == 0){

            /* Extract ping position from read line */
            *start = (int) pmatch[1].rm_so;
            *end = (int) pmatch[1].rm_eo;
            *size_ping = (size_t) ((*end) - (*start));

            /* ping string memory allocation */
            ping = malloc(sizeof(char) * ((*size_ping)+2));
            if(ping == NULL){
                free(read_line);
                read_line = NULL;
                *n = 0;
                break;
            }

            /* Create ping string */
            (void) strncpy(ping, &read_line[*start], *size_ping);
            ping[*size_ping]='\n';
            ping[*size_ping+1]='\0';

            /* Free memory */
            free(read_line);
            read_line = NULL;
            *n = 0;
            break;
        }
}


char* better_get_ping_from_temp_log(){
    /* Variables */
    FILE* fd = NULL;
    char* read_line = NULL;
    size_t n = 0;
    size_t nmatch = 2;
    regex_t* p_reg;
    regmatch_t* pmatch;
    char* ping = NULL;
    int start;
    int end;
    size_t size_ping;

    /* regex struct memory allocation */
    p_reg = (regex_t *) malloc(sizeof(*p_reg));
    if(p_reg == NULL){
        return ping; /* NULL */
    }

    /* Open ping log file */
    fd = fopen("/var/log/ping-report/last-ping.log","r");
    if(fd == NULL){
        free(p_reg);
        return ping; /* NULL */
    }

    /* Construct regex to get ping from log file */
    if(regcomp(p_reg,"time=(.*) ms",REG_EXTENDED) != 0){
        if(p_reg != NULL){
            free(p_reg);
        }
        (void) fclose(fd);
        return ping; /* NULL */
    }

    /* match info memory allocation */
    pmatch = malloc(sizeof(*pmatch) * nmatch);
    if(pmatch == NULL){
        (void) fclose(fd);
        regfree(p_reg);
        free(p_reg);
        return ping; /* NULL */
    }

    while_from_gpftl(read_line, &n, fd, p_reg, pmatch, &nmatch, &start, &end, &size_ping, ping);

    /* free allocated memory */
    regfree(p_reg);
    free(p_reg);
    free(pmatch);
    if(read_line != NULL){
        free(read_line);
    }

    (void) fclose(fd);

    /* ping may be null, then it must mean that the ping request was lost */
    return ping;
}
```

Vous pouvez retrouver le diagramme dans le répertoire ping-report/diagrammes/better_get_ping_from_temp_log.mdj. La complexité cyclomatique de l'algorithme sous cette forme est de 7.

On peut appliquer le même principe à set_stats_ping en factorisant le segment suivant de la fonction :

```c
void trop_de_ifs(char* read_line, int* nb_loss, double* ping, int* nb_ping, double* max, double* min, int* nb_high, double* sum){
    if(strcmp(read_line,"LOSS") == 0){
        (*nb_loss)++;
    }else{
        /* Evaluate the ping as a double */
        *ping = strtod(read_line,NULL);
        /* Test null ping */
        if(*ping < 0.1){
            /* Ignore null ping */
        }else{
            /* Number of ping readed (for mean calculation) */
            *nb_ping++;
            /* Max ping */
            if(*ping > *max){
                *max = *ping;
            }
            /* Min ping */
            if(*ping < *min){
                *min = *ping;
            }
            /* Number of ping above 100 ms */
            if(*ping > 100.0){
                *nb_high++;
            }
            /* Sum (for mean calculation) */
            sum += *ping;
        }
    } 
}
```

Vous pouvez retrouver le diagramme dans le répertoire ping-report/diagrammes/better_set_stats_ping. La complexité cyclomatique de l'algorithme sous cette forme est de 4.
