LCOV - code coverage report
Current view: top level - src - utils.c (source / functions) Coverage Total Hit
Test: report.info Lines: 95.9 % 146 140
Test Date: 2025-02-11 09:58:02 Functions: 100.0 % 11 11

            Line data    Source code
       1              : #include "utils.h"
       2              : 
       3         1064 : void free_if_needed(void *to_free)
       4              : {
       5         1064 :     if (to_free != NULL)
       6         1019 :         free(to_free);
       7         1064 : }
       8              : 
       9          246 : void free_command_node(command_node_t *node)
      10              : {
      11          246 :     if (node == NULL)
      12          142 :         return;
      13              : 
      14          104 :     if (node->args != NULL)
      15              :     {
      16          212 :         for (int i = 0; i < MAX_ARGS && node->args[i] != NULL; i++)
      17              :         {
      18          108 :             free_if_needed(node->args[i]);
      19          108 :             node->args[i] = NULL;
      20              :         }
      21          104 :         free_if_needed(node->args);
      22          104 :         node->args = NULL;
      23              :     }
      24          104 :     free_command_node(node->left);
      25          104 :     free_command_node(node->right);
      26          104 :     free_if_needed(node);
      27              : }
      28              : 
      29           13 : int safe_open(const char *path, int flags, mode_t mode)
      30              : {
      31           13 :     int fd = open(path, flags, mode);
      32           13 :     if (fd < 0)
      33              :     {
      34            2 :         print_error("[ERROR] open() failed");
      35            2 :         exit(EXIT_FAILURE);
      36              :     }
      37           11 :     return fd;
      38              : }
      39              : 
      40           61 : void safe_close(int fd)
      41              : {
      42           61 :     int ret = close(fd);
      43           61 :     if (ret < 0)
      44              :     {
      45            1 :         print_error("[ERROR] close() failed");
      46            1 :         exit(EXIT_FAILURE);
      47              :     }
      48           60 : }
      49              : 
      50           10 : int is_all_space(const char *str)
      51              : {
      52           20 :     while (*str)
      53              :     {
      54           17 :         if (!isspace(*str))
      55            7 :             return 0;
      56           10 :         str++;
      57              :     }
      58            3 :     return 1;
      59              : }
      60              : 
      61            8 : void add_history_entry(const char *entry)
      62              : {
      63            8 :     if (entry == NULL || is_all_space(entry))
      64            3 :         return;
      65              : 
      66            5 :     char *home = getenv(HOME_ENV_VAR);
      67            5 :     if (home == NULL)
      68              :     {
      69            1 :         print_error("[ERROR] HOME environment variable not set");
      70            1 :         return;
      71              :     }
      72              : 
      73            4 :     char *history_file = malloc(strlen(home) + strlen(HISTORY_FILE) + 2);
      74            4 :     if (history_file == NULL)
      75              :     {
      76            0 :         errno = ENOMEM;
      77            0 :         print_error("[ERROR] Failed to allocate memory for history file path");
      78            0 :         return;
      79              :     }
      80              : 
      81            4 :     sprintf(history_file, "%s/%s", home, HISTORY_FILE);
      82            4 :     int history_fd = safe_open(history_file, O_WRONLY | O_CREAT | O_APPEND, 0644);
      83              : 
      84            4 :     print_generic(history_fd, "%s\n", entry);
      85            4 :     safe_close(history_fd);
      86            4 :     free_if_needed(history_file);
      87              : }
      88              : 
      89           34 : char *get_env_var(const char *token)
      90              : {
      91           34 :     if (token[0] == DOLLAR_SIGN)
      92              :     {
      93           33 :         const char *env_name = token + 1;
      94           33 :         const char *env_value = getenv(env_name);
      95           33 :         if (env_value != NULL)
      96              :         {
      97           27 :             return strdup(env_value);
      98              :         }
      99              : 
     100            6 :         return strdup("");
     101              :     }
     102              : 
     103            1 :     return NULL;
     104              : }
     105              : 
     106           30 : int get_var_values(const char *token, char *name, char *value)
     107              : {
     108           30 :     char *equal_sign = strchr(token, EQUAL_SIGN);
     109           30 :     if (!equal_sign)
     110            1 :         return -1;
     111              : 
     112           29 :     size_t name_len = equal_sign - token;
     113           29 :     char *processed_name = strndup(token, name_len);
     114              : 
     115           29 :     if (!processed_name)
     116            0 :         return -1;
     117              : 
     118           29 :     const char *current_value = equal_sign + 1;
     119           29 :     char *processed_value = NULL;
     120              :     size_t value_len;
     121              : 
     122           30 :     while (isspace(*current_value))
     123            1 :         current_value++;
     124              : 
     125           29 :     if (*current_value == DOUBLE_QUOTES || *current_value == SINGLE_QUOTE)
     126           22 :     {
     127           22 :         char quote_char = *current_value;
     128           22 :         current_value++;
     129           22 :         const char *end_quote = strchr(current_value, quote_char);
     130              : 
     131           22 :         if (end_quote)
     132              :         {
     133            1 :             value_len = end_quote - current_value;
     134            1 :             processed_value = strndup(current_value, value_len);
     135              :         }
     136              :         else
     137              :         {
     138           21 :             processed_value = strdup(current_value);
     139              :         }
     140              :     }
     141              :     else
     142              :     {
     143            7 :         processed_value = strdup(current_value);
     144              :     }
     145              : 
     146           29 :     if (!processed_value)
     147              :     {
     148            0 :         free_if_needed(processed_name);
     149            0 :         return -1;
     150              :     }
     151              : 
     152           29 :     strcpy(name, processed_name);
     153           29 :     strcpy(value, processed_value);
     154              : 
     155           29 :     free_if_needed(processed_name);
     156           29 :     free_if_needed(processed_value);
     157              : 
     158           29 :     return 0;
     159              : }
     160              : 
     161           18 : int set_env_var(const char *token)
     162              : {
     163              :     // Get values from get_var_values
     164              :     char name[MAX_INPUT_LENGTH];
     165              :     char value[MAX_INPUT_LENGTH];
     166           18 :     int ret = get_var_values(token, name, value);
     167           18 :     if (ret < 0)
     168            1 :         return ret;
     169              : 
     170           17 :     ret = setenv(name, value, 1);
     171              : 
     172           17 :     return ret;
     173              : }
     174              : 
     175           19 : const char *get_operator_str(operator_t op_type)
     176              : {
     177           19 :     switch (op_type)
     178              :     {
     179            6 :     case OP_NONE:
     180            6 :         return "NONE";
     181            3 :     case OP_PIPE:
     182            3 :         return "PIPE";
     183            1 :     case OP_SEQ:
     184            1 :         return "SEQ";
     185            2 :     case OP_AND:
     186            2 :         return "AND";
     187            1 :     case OP_OR:
     188            1 :         return "OR";
     189            1 :     case OP_BG:
     190            1 :         return "BG";
     191            1 :     case OP_REDIR_OUT:
     192            1 :         return "REDIR_OUT";
     193            1 :     case OP_REDIR_IN:
     194            1 :         return "REDIR_IN";
     195            1 :     case OP_APPEND:
     196            1 :         return "APPEND";
     197            1 :     case OP_HEREDOC:
     198            1 :         return "HEREDOC";
     199            1 :     default:
     200            1 :         return "UNKNOWN";
     201              :     }
     202              : }
     203              : 
     204            9 : void print_command_tree(command_node_t *node, int depth)
     205              : {
     206            9 :     if (!node)
     207            1 :         return;
     208              : 
     209            8 :     print("%s", CYAN_COLOR);
     210              : 
     211            8 :     if(depth == 0)
     212            4 :         print("Root: ");
     213              : 
     214            8 :     print("OP=%s%s%s, args=[%s", YELLOW_COLOR, get_operator_str(node->op_type), CYAN_COLOR, YELLOW_COLOR);
     215              : 
     216            8 :     if (node->args)
     217              :     {
     218           18 :         for (int i = 0; node->args[i] != NULL; i++)
     219           10 :             print("%s%s", i > 0 ? CYAN_COLOR "," YELLOW_COLOR " " : "", node->args[i] ? node->args[i] : "NULL");
     220              :     }
     221            8 :     print("%s]%s\n", CYAN_COLOR, RESET_COLOR);
     222              : 
     223            8 :     if (node->left)
     224              :     {
     225            2 :         print("%s", CYAN_COLOR);
     226            5 :         for (int i = 0; i <= depth; i++)
     227              :         {
     228            3 :             if(i == depth)
     229            2 :                 print("|-- ");
     230              :             else
     231            1 :                 print("|   ");
     232              :         }
     233              : 
     234            2 :         print("Left: ");
     235            2 :         print_command_tree(node->left, depth + 1);
     236              :     }
     237              : 
     238            8 :     if (node->right)
     239              :     {
     240            2 :         print("%s", CYAN_COLOR);
     241            5 :         for (int i = 0; i <= depth; i++)
     242              :         {
     243            3 :             if(i == depth)
     244            2 :                 print("|-- ");
     245              :             else
     246            1 :                 print("|   ");
     247              :         }
     248              : 
     249            2 :         print("Right: ");
     250            2 :         print_command_tree(node->right, depth + 1);
     251              :     }
     252              : }
        

Generated by: LCOV version 2.0-1