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:
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;
+}