9511_project03

project 3 for algorithms & programming I (9511) prof. Cardozo
Index Commits Files Refs README LICENSE
source/cla.c (3426B)
   1 #include "../include/cla.h"
   2 
   3 const char *available_flags[] = { "-fmt", "-out", "-in", "-ti", "-tf" };
   4 const char *available_formats[] = { "csv", "xml" };
   5 
   6 status_t validate_arguments(int argc, char **argv, cla_t cla)
   7 {
   8     status_t st;
   9 
  10     if(argv == NULL || cla == NULL) return ERROR_NULL_POINTER;
  11     if((argc == NO_ARGS_ENTERED) || (argc != NORMAL_AMOUNT_ARGS))
  12         return ERROR_MISSING_ARGS;
  13 
  14     if((st = check_flags_position(argc, argv))) return st;
  15     if((st = check_flags_repeated(argc, argv))) return st;
  16 
  17     /* Asigna a la estructura 'cla' los argumentos ingresados */
  18     if((st = cla_setup(argc, argv, cla))) return st;
  19 
  20     return OK;
  21 }
  22 
  23 /* No chequea argumentos ya que se considera subfuncion de validate_arguments */
  24 status_t check_flags_position(int argc, char **argv)
  25 {
  26     size_t i;
  27     bool prev_was_flag = 0;
  28     bool current_arg_is_flag = 0;
  29 
  30     for(i = 1; i < argc; i++, prev_was_flag = current_arg_is_flag) {
  31         if(argv[i][0] == '-') current_arg_is_flag = 1;
  32         else current_arg_is_flag = 0;
  33 
  34         if(current_arg_is_flag && prev_was_flag) return ERROR_WRONG_FLAGS;
  35     }
  36     return OK;
  37 }
  38 
  39 status_t check_flags_repeated(int argc, char **argv)
  40 {
  41     size_t i, j, k, fflags_index;
  42     int founded_flags[FLAGS_MAX];
  43 
  44     if(argv == NULL) return ERROR_NULL_POINTER;
  45 
  46     /* Inicializa a -1 para evitar confusiones con 0 */
  47     for(i = 0; i < FLAGS_MAX; i++) founded_flags[i] = -1;
  48 
  49     /* Itera solo sobre las flags, guarda la posicion de la flag con respecto
  50      * a available_flags a forma de tener una manera de checkear por repeticiones,
  51      * si la posicion aparece multiples veces es un error */
  52     for(i = 1, fflags_index = 0; i <= (argc - 2); i += 2) {
  53         for(j = 0; j < FLAGS_MAX; j++) {
  54             if(!strcmp(argv[i], available_flags[j])) {
  55                 for(k = 0; k < fflags_index; k++)
  56                     if(founded_flags[k] == j)
  57                         return ERROR_FLAG_REPEATED;
  58                 
  59                 founded_flags[fflags_index++] = j;
  60                 break;
  61             }
  62             if((j + 1) == FLAGS_MAX) return ERROR_FLAG_NOT_FOUND;
  63         }
  64     }
  65     return OK;
  66 }
  67 
  68 status_t cla_setup(int argc, char **argv, cla_t cla)
  69 {
  70     char *endptr;
  71     size_t i;
  72     FILE *fp;
  73     flags_t f;
  74 
  75     for(i = 1; i < argc; i += 2) {
  76         for(f = FLAG_FMT; f < FLAGS_MAX; f++) {
  77             if(!strcmp(available_flags[f], argv[i])) {
  78                 switch (f) {
  79                     case FLAG_FMT: 
  80                         strcpy(cla->fmt, argv[i + 1]);
  81                        break;
  82 
  83                     case FLAG_OUT:
  84                        if((fp = fopen(argv[i + 1], "wt")) == NULL)
  85                            return ERROR_OPENING_FILE;
  86 
  87                        cla->fo = fp; 
  88                        break;
  89 
  90                     case FLAG_IN:
  91                        if((fp = fopen(argv[i + 1], "rt")) == NULL)
  92                            return ERROR_OPENING_FILE;
  93 
  94                        cla->fi = fp; 
  95                        break;
  96 
  97                     case FLAG_TI:
  98                        cla->ti = strtoul(argv[i + 1], &endptr, 10); 
  99                        if(*endptr != '\0') return ERROR_WRONG_TIME;
 100                        break;
 101 
 102                     case FLAG_TF:
 103                        cla->tf = strtoul(argv[i + 1], &endptr, 10); 
 104                        if(*endptr != '\0') return ERROR_WRONG_TIME;
 105                        break;
 106 
 107                     default: return ERROR_FLAG_NOT_FOUND;
 108                 }
 109             }
 110         }
 111     }
 112     return OK;
 113 }
 114 
 115 
 116 status_t cla_create(cla_t *cla)
 117 {
 118     if(cla == NULL) return ERROR_NULL_POINTER;
 119 
 120     if((*cla = (cla_t)malloc(sizeof(cla_T))) == NULL)
 121         return ERROR_MEMORY;
 122 
 123     if(((*cla)->fmt = calloc(sizeof(char), 100)) == NULL) {
 124         free(cla);
 125         cla = NULL;
 126         return ERROR_MEMORY;
 127     }
 128 
 129     (*cla)->fi = NULL;
 130     (*cla)->fo = NULL;
 131 
 132     return OK;
 133 }
 134 
 135 status_t cla_destroy(cla_t cla)
 136 {
 137     if(cla == NULL) return ERROR_NULL_POINTER;
 138 
 139     if(cla->fi != NULL) fclose(cla->fi);
 140     if(cla->fo != NULL)    fclose(cla->fo);
 141 
 142     free(cla->fmt);
 143     free(cla);
 144 
 145     return OK;
 146 }