9511_project03

Command line program that parses a bank .csv file and generates and output file in format .csv or .xml containing the debits and credits of every user.
Index Commits Files Refs README LICENSE
commit da304d4497262a05bfcee0f9d5d8e0f08a1c9d6d
parent f916511708bb2bc8095f81bd27b1091157f54077
Author: Martin J. Klöckner <64109770+klewer-martin@users.noreply.github.com>
Date:   Sat, 24 Jul 2021 00:18:36 -0300

Merge pull request #1 from klewer-martin/user_module

User module
Diffstat:
M.gitignore | 1+
MMakefile | 36++++++------------------------------
Mexamples/input_gen.py | 4++--
Minclude/io.h | 13++++++++-----
Ainclude/user.h | 18++++++++++++++++++
Msource/cla.c | 14+++++++++-----
Msource/io.c | 126++++++++++++++------------------------------------------------------------------
Msource/main.c | 15++++++++++-----
Asource/user.c | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 151 insertions(+), 152 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -5,3 +5,4 @@
 *.xml
 *.bin
 main
+*.sh
diff --git a/Makefile b/Makefile
@@ -1,13 +1,13 @@
 CC=gcc
-CFLAGS=-g -pedantic -Wall
+CFLAGS=-pedantic -Wall
 SRCFOLDER=source
 HFOLDER=include
 PROGNAME=main
 
 all: main clean
 
-main: main.o cla.o status.o io.o sort.o
-    $(CC) $(CFLAGS) main.o cla.o status.o io.o sort.o -o $(PROGNAME)
+main: main.o cla.o status.o io.o sort.o user.o
+    $(CC) $(CFLAGS) main.o cla.o status.o io.o sort.o user.o -o $(PROGNAME)
 
 main.o: $(HFOLDER)/cla.h $(HFOLDER)/status.h
     $(CC) $(CFLAGS) -c $(SRCFOLDER)/main.c
@@ -24,32 +24,8 @@ io.o: $(HFOLDER)/status.h
 sort.o: $(HFOLDER)/status.h
     $(CC) $(CFLAGS) -c $(SRCFOLDER)/sort.c
 
+user.o: $(HFOLDER)/status.h
+    $(CC) $(CFLAGS) -c $(SRCFOLDER)/user.c
+
 clean:
     rm *.o
-
-run20:
-    ./main -fmt csv -out output.csv -in examples/test_file_20.csv -ti 1320498000 -tf 1320498046
-
-run2k:
-    ./main -fmt csv -out output.csv -in examples/test_file_2k.csv -ti 1320498000 -tf 1325499000
-
-run50:
-    ./main -fmt csv -out output.csv -in examples/test_file_50.csv -ti 1320498000 -tf 1320498049
-
-run500:
-    ./main -fmt csv -out output.csv -in examples/test_file_500.csv -ti 1320498000 -tf 1320529000
-
-run5k:
-    ./main -fmt csv -out output.csv -in examples/test_file_5k.csv -ti 1320498000 -tf 1320529000
-
-run50k:
-    ./main -fmt csv -out output.csv -in examples/test_file_50k.csv -ti 1320498000 -tf 1420529000
-
-run500k:
-    ./main -fmt csv -out output.csv -in examples/test_file_500k.csv -ti 1320498000 -tf 1420529000
-
-run50xml:
-    ./main -fmt xml -out output.xml -in examples/test_file_50.csv -ti 1320498000 -tf 1320498049
-
-run5kxml:
-    ./main -fmt xml -out output.xml -in examples/test_file_5k.csv -ti 1320498000 -tf 1360498049
diff --git a/examples/input_gen.py b/examples/input_gen.py
@@ -2,7 +2,7 @@ from string import digits
 from time import strftime, gmtime
 from random import randint, choice
 
-LINES = 5000
+LINES = 500000000
 
 # OUTPUT:
 #     ID_TRANSACCION, ID_USUARIO, FECHA, MONTO, NUMERO DE TRAJETA, DESCRIPCION
@@ -16,7 +16,7 @@ def card_number_generator():
 def generate_file(max_lines):
     id_transaction_base = 123400
     id_user_base = 1
-    id_user_max = 200
+    id_user_max = 20000
     amount_base = 1
     amount_max = 10000
     for i in range(max_lines):
diff --git a/include/io.h b/include/io.h
@@ -8,13 +8,17 @@
 #include "cla.h"
 #include "status.h"
 #include "sort.h"
+#include "user.h"
 
 #define _XOPEN_SOURCE
 #define __USE_XOPEN
 #include <time.h>
 
+#define INIT_SIZE        1000
 #define INPUT_FILE_FIELDS 6
+
 #define BUFFER_SIZE        1000
+#define GROWTH_FACTOR     2
 
 #define INPUT_FILE_DELIM ","
 #define CSV_OUTPUT_DELIM    ","
@@ -46,20 +50,19 @@ typedef enum {
 
 status_t process_file(cla_t cla, user_t **users, size_t *i);
 
-status_t set_data(user_t *user, char **data);
-
 status_t string_split(char *s, char **data, char *delim);
 
 status_t load_values(FILE *, cla_t *data);
 
 status_t export_data(cla_t cla, const user_t *users, size_t size);
+void clean_data(char **data);
 
 status_t export_data_as_csv(FILE *fo, const user_t *users, size_t size);
 status_t export_data_as_xml(FILE *fo, const user_t *users, size_t size);
 
-status_t destroy_users(user_t *users, size_t size);
+status_t destroy_data(char **data);
+status_t get_date(time_t *e, char **data);
 
-status_t user_create(user_t *usr);
-status_t user_set_data(user_t usr, int id, long credit, long debt);
+void clean_buffer(char *buf);
 
 #endif
diff --git a/include/user.h b/include/user.h
@@ -0,0 +1,18 @@
+#ifndef USER__H
+#define USER__H
+
+#include "status.h"
+#include "io.h"
+
+status_t destroy_users(user_t *users, size_t size);
+
+status_t user_create(user_t *usr);
+status_t user_set_data(user_t *user, char **data);
+
+user_t user_find(const user_t *users, int id, size_t size);
+user_t user_dup(user_t src);
+
+
+void user_clean(user_t usr);
+
+#endif
diff --git a/source/cla.c b/source/cla.c
@@ -20,9 +20,11 @@ status_t validate_arguments(int argc,  char **argv)
 /* No chequea argumentos ya que se considera subfuncion de validate_arguments */
 status_t check_flags_position(int argc, char **argv)
 {
+    size_t i;
     bool prev_was_flag = 0;
     bool current_arg_is_flag = 0;
-    for(size_t i = 1; i < argc; i++, prev_was_flag = current_arg_is_flag) {
+
+    for(i = 1; i < argc; i++, prev_was_flag = current_arg_is_flag) {
         if(argv[i][0] == '-') current_arg_is_flag = 1;
         else current_arg_is_flag = 0;
 
@@ -33,7 +35,7 @@ status_t check_flags_position(int argc, char **argv)
 
 status_t check_flags_repeated(int argc, char **argv)
 {
-    size_t i, j, fflags_index;
+    size_t i, j, k, fflags_index;
     int founded_flags[FLAGS_MAX];
 
     /* Inicializa a -1 para evitar confusiones con 0 */
@@ -42,7 +44,7 @@ status_t check_flags_repeated(int argc, char **argv)
     for(i = 1, fflags_index = 0; i <= (argc - 2); i += 2) {
         for(j = 0; j < FLAGS_MAX; j++) {
             if(!strcmp(argv[i], available_flags[j])) {
-                for(size_t k = 0; k < FLAGS_MAX; k++) {
+                for(k = 0; k < FLAGS_MAX; k++) {
                     if(founded_flags[k] == j) return ERROR_FLAG_REPEATED;
                 }
                 founded_flags[fflags_index++] = j;
@@ -57,9 +59,11 @@ status_t check_flags_repeated(int argc, char **argv)
 status_t cla_setup(int argc, char **argv, cla_t *cla)
 {
     char *endptr;
+    size_t i;
+    flags_t f;
 
-    for(size_t i = 1; i < argc; i += 2) {
-        for(flags_t f = FLAG_FMT; f < FLAGS_MAX; f++) {
+    for(i = 1; i < argc; i += 2) {
+        for(f = FLAG_FMT; f < FLAGS_MAX; f++) {
             if(!strcmp(available_flags[f], argv[i])) {
                 switch (f) {
                     case FLAG_FMT: strcpy((*cla)->fmt, argv[i + 1]); break;
diff --git a/source/io.c b/source/io.c
@@ -1,19 +1,5 @@
 #include "../include/io.h"
 
-#define INIT_SIZE        1000
-#define GROWTH_FACTOR     2
-
-user_t find_user(const user_t *users, int id, size_t size);
-status_t destroy_data(char **data);
-
-status_t get_date(time_t *e, char **data);
-
-void user_clean(user_t usr);
-void clean_buffer(char *buf);
-void clean_data(char **data);
-
-user_t user_dup(user_t src);
-
 /* Lee los datos del archivo de entrada linea por linea mientras los procesa y asigna a un arreglo de usuarios */
 status_t process_file(cla_t cla, user_t **users, size_t *size)
 {
@@ -81,7 +67,7 @@ status_t process_file(cla_t cla, user_t **users, size_t *size)
         }
 
         /* Asigna a 'user' id, creditos y debitos cargados en data */
-        if((st = set_data(&user, data)) != OK) {
+        if((st = user_set_data(&user, data)) != OK) {
             destroy_data(data);
             free(buffer);
             fclose(fpi);
@@ -107,7 +93,7 @@ status_t process_file(cla_t cla, user_t **users, size_t *size)
         }
 
         /* Busca el numero de id en los usuarios ya ingresados, si no lo encuentra agrega un usuario nuevo al arreglo de usuarios */
-        if((user_found = find_user(*users, user->id, *size)) != NULL) {
+        if((user_found = user_find(*users, user->id, *size)) != NULL) {
             user_found->credit += user->credit;
             user_found->debt += user->debt;
         } else {
@@ -128,24 +114,6 @@ status_t process_file(cla_t cla, user_t **users, size_t *size)
     return OK;
 }
 
-status_t set_data(user_t *user, char **data) 
-{
-    if(data == NULL || user == NULL) return ERROR_NULL_POINTER;
-
-    char *endptr;
-    long amount;
-
-    (*user)->id = strtol(data[POS_USER_ID], &endptr, 10);
-    if(*endptr != '\0') return ERROR_CORRUPT_DATA;
-
-    amount = strtol(data[POS_AMOUNT], &endptr, 10);
-    if(*endptr != '\0') return ERROR_CORRUPT_DATA;
-
-    if(amount > 0) (*user)->credit = amount;
-    else if(amount < 0) (*user)->debt = -amount; /* '-=' Para eliminar el menos    */
-
-    return OK;
-}
 
 status_t string_split(char *s, char **data, char *delim)
 {
@@ -161,23 +129,13 @@ status_t string_split(char *s, char **data, char *delim)
     return OK;
 }
 
-
-status_t destroy_users(user_t *users, size_t size)
-{
-    if(users == NULL) return ERROR_NULL_POINTER;
-
-    for(size_t i = 0; i < size; i++)
-        free(users[i]);
-
-    free(users);
-    return OK;
-}
-
 status_t destroy_data(char **data)
 {
+    size_t i;
+
     if(data == NULL) return ERROR_NULL_POINTER;
 
-    for(size_t i = 0; i < INPUT_FILE_FIELDS; i++) {
+    for(i = 0; i < INPUT_FILE_FIELDS; i++) {
         free(data[i]);
         data[i] = NULL;
     }
@@ -188,10 +146,10 @@ status_t destroy_data(char **data)
 
 status_t export_data(cla_t cla, const user_t *users, size_t size)
 {
-    if(users == NULL) return ERROR_NULL_POINTER;
-
     FILE *fo;
 
+    if(users == NULL) return ERROR_NULL_POINTER;
+
     if((fo = fopen(cla->fo, "wt")) == NULL)
         return ERROR_OPENING_FILE;
 
@@ -207,10 +165,12 @@ status_t export_data(cla_t cla, const user_t *users, size_t size)
 
 status_t export_data_as_csv(FILE *fo, const user_t *users, size_t size)
 {
+    size_t i;
+
     if(fo == NULL || users == NULL)
         return ERROR_NULL_POINTER;
 
-    for(size_t i = 0; i < size; i++)
+    for(i = 0; i < size; i++)
         fprintf(fo, "%ld%s%ld%s%ld\n", users[i]->id, CSV_OUTPUT_DELIM,\
                 users[i]->credit, CSV_OUTPUT_DELIM, users[i]->debt);
 
@@ -219,11 +179,13 @@ status_t export_data_as_csv(FILE *fo, const user_t *users, size_t size)
 
 status_t export_data_as_xml(FILE *fo, const user_t *users, size_t size)
 {
+    size_t i;
+
     if(fo == NULL || users == NULL)
         return ERROR_NULL_POINTER;
 
     fprintf(fo, "%s\n%s\n", XML_HEADER, XML_ROOT_OPEN);
-    for(size_t i = 0; i < size; i++) {
+    for(i = 0; i < size; i++) {
         fprintf(fo, "\t%s\n", XML_ROW_OPEN);
         fprintf(fo, "\t\t%s%ld%s\n", XML_ID_OPEN, users[i]->id, XML_ID_CLOSE);
         fprintf(fo, "\t\t%s%ld%s\n", XML_CREDIT_OPEN, users[i]->credit, XML_CREDIT_CLOSE);
@@ -237,13 +199,17 @@ status_t export_data_as_xml(FILE *fo, const user_t *users, size_t size)
 
 void clean_buffer(char *buf)
 {
-    for(size_t i = 0; i < BUFFER_SIZE; i++)
+    size_t i;
+
+    for(i = 0; i < BUFFER_SIZE; i++)
         buf[i] = '\0';
 }
 
 void clean_data(char **data)
 {
-    for(size_t i = 0; i < INPUT_FILE_FIELDS; i++) {
+    size_t i;
+
+    for(i = 0; i < INPUT_FILE_FIELDS; i++) {
         free(data[i]);
         data[i] = NULL;
     }
@@ -251,10 +217,10 @@ void clean_data(char **data)
 
 status_t get_date(time_t *e, char **data)
 {
-    if(e == NULL || data == NULL) return ERROR_NULL_POINTER;
-
     struct tm tm;
 
+    if(e == NULL || data == NULL) return ERROR_NULL_POINTER;
+
     /* Desactiva el horario de verano */
     tm.tm_isdst = 0;
 
@@ -278,53 +244,3 @@ status_t get_date(time_t *e, char **data)
     return OK;
 }
 
-void user_clean(user_t usr)
-{
-    usr->id = 0;
-    usr->credit = 0;
-    usr->debt = 0;
-}
-
-status_t user_set_data(user_t usr, int id, long credit, long debt)
-{
-    usr->id = id;
-    usr->credit = credit;
-    usr->debt = debt;
-
-    return OK;
-}
-
-user_t user_dup(user_t src)
-{
-    user_t dst = NULL;
-
-    user_create(&dst);
-
-    dst->id = src->id;
-    dst->credit = src->credit;
-    dst->debt = src->debt;
-
-    return dst;
-}
-
-status_t user_create(user_t *usr)
-{
-    if(((*usr) = (user_t)malloc(sizeof(ADT_user_t))) == NULL)
-        return ERROR_MEMORY;
-
-    (*usr)->id = 0;
-    (*usr)->credit = 0;
-    (*usr)->debt = 0;
-
-    return OK;
-}
-
-user_t find_user(const user_t *users, int id, size_t size)
-{
-    for(size_t i = 0; i < size; i++) {
-        if(users[i]->id == id) {
-            return users[i];
-        }
-    }
-    return NULL;
-}
diff --git a/source/main.c b/source/main.c
@@ -1,15 +1,13 @@
 #include "../include/cla.h"
 #include "../include/status.h"
-#include "../include/io.h" /* output_gen() */
+#include "../include/io.h"
 #include "../include/sort.h"
+#include "../include/user.h"
 
 /* "ca" - creditos ascendentes | "cd" - creditos descendentes
  * "da" - debitos ascendentes  | "dd" - debitos descendentes */
 #define SORTING_ORDER    "cd"
-
-#define EXIT_SUCCESS_MSG "Ejecución terminada exitosamente"
-#define USERS_REGISTERED_MSG    "Usuarios registrados: "
-#define PROCESED_LINES_MSG        "Lineas procesadas: "
+#define PRINT_EXIT_SUCCESS_MSG
 
 int main (int argc, char *argv[])
 {
@@ -60,9 +58,16 @@ int main (int argc, char *argv[])
         return st;
     }
 
+
+#ifdef PRINT_EXIT_SUCCESS_MSG
+
+    /* Imprime un mensaje para darle a conocer al usuario
+     * que todo se ejecuto correctamente    */
     printf("\n%s\n%s%ld\n%s%ld\n", EXIT_SUCCESS_MSG, USERS_REGISTERED_MSG,\
             size, PROCESED_LINES_MSG, cla->parsed_lines);
 
+#endif
+
     cla_destroy(&cla);
     destroy_users(users, size);
 
diff --git a/source/user.c b/source/user.c
@@ -0,0 +1,76 @@
+#include "../include/user.h"
+
+status_t user_create(user_t *usr)
+{
+    if(((*usr) = (user_t)malloc(sizeof(ADT_user_t))) == NULL)
+        return ERROR_MEMORY;
+
+    (*usr)->id = 0;
+    (*usr)->credit = 0;
+    (*usr)->debt = 0;
+
+    return OK;
+}
+
+void user_clean(user_t usr)
+{
+    usr->id = 0;
+    usr->credit = 0;
+    usr->debt = 0;
+}
+
+status_t user_set_data(user_t *user, char **data) 
+{
+    char *endptr;
+    long amount;
+
+    if(data == NULL || user == NULL) return ERROR_NULL_POINTER;
+
+    (*user)->id = strtol(data[POS_USER_ID], &endptr, 10);
+    if(*endptr != '\0') return ERROR_CORRUPT_DATA;
+
+    amount = strtol(data[POS_AMOUNT], &endptr, 10);
+    if(*endptr != '\0') return ERROR_CORRUPT_DATA;
+
+    if(amount > 0) (*user)->credit = amount;
+    else if(amount < 0) (*user)->debt = -amount; /* '-=' Para eliminar el menos    */
+
+    return OK;
+}
+
+user_t user_dup(user_t src)
+{
+    user_t dst = NULL;
+
+    user_create(&dst);
+
+    dst->id = src->id;
+    dst->credit = src->credit;
+    dst->debt = src->debt;
+
+    return dst;
+}
+
+user_t user_find(const user_t *users, int id, size_t size)
+{
+    size_t i;
+    for(i = 0; i < size; i++) {
+        if(users[i]->id == id) {
+            return users[i];
+        }
+    }
+    return NULL;
+}
+
+status_t destroy_users(user_t *users, size_t size)
+{
+    size_t i;
+
+    if(users == NULL) return ERROR_NULL_POINTER;
+
+    for(i = 0; i < size; i++)
+        free(users[i]);
+
+    free(users);
+    return OK;
+}