From cd2ecb5c8f6952bb639521ca5899cdd617b22ec9 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Thu, 24 Mar 2022 16:04:16 +0900 Subject: [PATCH] Cleanup by breaking up C impl to separate sources --- c_impl/Makefile | 5 +- c_impl/src/argparse.c | 33 ++++++++ c_impl/src/argparse.h | 16 ++++ c_impl/src/csventry.c | 64 ++++++++++++++ c_impl/src/csventry.h | 19 +++++ c_impl/src/main.c | 191 ++---------------------------------------- c_impl/src/strdlist.c | 77 +++++++++++++++++ c_impl/src/strdlist.h | 23 +++++ 8 files changed, 245 insertions(+), 183 deletions(-) create mode 100644 c_impl/src/argparse.c create mode 100644 c_impl/src/argparse.h create mode 100644 c_impl/src/csventry.c create mode 100644 c_impl/src/csventry.h create mode 100644 c_impl/src/strdlist.c create mode 100644 c_impl/src/strdlist.h diff --git a/c_impl/Makefile b/c_impl/Makefile index 32cbceb..4245f34 100644 --- a/c_impl/Makefile +++ b/c_impl/Makefile @@ -6,7 +6,10 @@ else endif SOURCES = \ - src/main.o + src/main.o \ + src/argparse.o \ + src/csventry.o \ + src/strdlist.o all: fields_from_csv diff --git a/c_impl/src/argparse.c b/c_impl/src/argparse.c new file mode 100644 index 0000000..56dcceb --- /dev/null +++ b/c_impl/src/argparse.c @@ -0,0 +1,33 @@ +#include "argparse.h" + +ParsedArgs parse_args(int argc, char **argv) { + // init + ParsedArgs args; + args.input_filename = NULL; + args.fields = create_strdlist(); + args.usage_print = 0; + args.error = 0; + + --argc; + ++argv; + + // get filename and field from args + if (argc > 1) { + args.input_filename = argv[0]; + } else { + args.error = 1; + args.usage_print = 1; + } + + --argc; + ++argv; + + while (argc > 0) { + append_strdlist(args.fields, argv[0]); + --argc; + ++argv; + } + + return args; +} +// vim: et: ts=2: sts=2: sw=2 diff --git a/c_impl/src/argparse.h b/c_impl/src/argparse.h new file mode 100644 index 0000000..6d8e9bb --- /dev/null +++ b/c_impl/src/argparse.h @@ -0,0 +1,16 @@ +#ifndef SEODISPARATE_FIELDS_FROM_CSV_ARG_PARSE_H_ +#define SEODISPARATE_FIELDS_FROM_CSV_ARG_PARSE_H_ + +#include "strdlist.h" + +typedef struct ParsedArgs { + const char *input_filename; + StrDList *fields; + int usage_print; + int error; +} ParsedArgs; + +ParsedArgs parse_args(int argc, char **argv); + +#endif +// vim: et: ts=2: sts=2: sw=2 diff --git a/c_impl/src/csventry.c b/c_impl/src/csventry.c new file mode 100644 index 0000000..9b41838 --- /dev/null +++ b/c_impl/src/csventry.c @@ -0,0 +1,64 @@ +#include "csventry.h" + +CSVEntry get_field(FILE *fd, size_t field_idx) { + size_t current_size = 512; + CSVEntry entry; + entry.is_end_of_line = 0; + entry.is_end_of_file = 0; + entry.is_chosen_field = 0; + entry.buf = NULL; + size_t idx = 0; + int next = fgetc(fd); + + while (next != EOF) { + if (next == ',') { + break; + } else if (next == '\n') { + entry.is_end_of_line = 1; + break; + } else if (next == ' ' || next == '\t') { + next = fgetc(fd); + continue; + } + if (!entry.buf) { + // malloc of buf deferred to here in case a field reaches EOF + entry.buf = malloc(current_size); + } + entry.buf[idx++] = next; + if (idx >= current_size) { + current_size *= 2; + entry.buf = realloc(entry.buf, current_size); + } + + next = fgetc(fd); + } + + if (next == EOF) { + entry.is_end_of_file = 1; + } + + if (entry.buf) { + if (idx >= current_size) { + current_size += 1; + entry.buf = realloc(entry.buf, current_size); + entry.buf[idx] = 0; + } else { + entry.buf[idx] = 0; + } + } + + entry.idx = field_idx; + + return entry; +} + +void cleanup_csventry(CSVEntry *csvEntry, int nullify) { + if (csvEntry->buf) { + free(csvEntry->buf); + } + if (nullify) { + csvEntry->buf = NULL; + } +} + +// vim: et: ts=2: sts=2: sw=2 diff --git a/c_impl/src/csventry.h b/c_impl/src/csventry.h new file mode 100644 index 0000000..01f4dc4 --- /dev/null +++ b/c_impl/src/csventry.h @@ -0,0 +1,19 @@ +#ifndef SEODISPARATE_FIELDS_FROM_CSV_CSVENTRY_H_ +#define SEODISPARATE_FIELDS_FROM_CSV_CSVENTRY_H_ + +#include +#include + +typedef struct CSVEntry { + char *buf; + size_t idx; + int is_end_of_line; + int is_end_of_file; + int is_chosen_field; +} CSVEntry; + +CSVEntry get_field(FILE *fd, size_t field_idx); +void cleanup_csventry(CSVEntry *csvEntry, int nullify); + +#endif +// vim: et: ts=2: sts=2: sw=2 diff --git a/c_impl/src/main.c b/c_impl/src/main.c index 0d033ea..051016c 100644 --- a/c_impl/src/main.c +++ b/c_impl/src/main.c @@ -2,18 +2,9 @@ #include #include -typedef struct StrDList { - char *string; - struct StrDList *next; - struct StrDList *prev; -} StrDList; - -typedef struct ParsedArgs { - const char *input_filename; - StrDList *fields; - int usage_printed; - int error; -} ParsedArgs; +#include "argparse.h" +#include "csventry.h" +#include "strdlist.h" void usage() { puts( @@ -21,176 +12,14 @@ void usage() { "./fields_from_csv [...]\n"); } -StrDList *create_strdlist() { return calloc(1, sizeof(StrDList)); } - -void append_strdlist(StrDList *head, const char *string) { - StrDList *current = head; - - while (current->next) { - current = current->next; - } - - current->next = calloc(1, sizeof(StrDList)); - current->next->prev = current; - size_t string_size = strlen(string); - current->next->string = malloc(string_size + 1); - memcpy(current->next->string, string, string_size); - current->next->string[string_size] = 0; -} - -void cleanup_strdlist(StrDList **head) { - if (!head || !*head) { - return; - } - - StrDList *current = *head; - while (current->next) { - current = current->next; - } - - while (current->prev) { - current = current->prev; - if (current->next->string) { - free(current->next->string); - } - free(current->next); - current->next = NULL; - } - - (*head)->next = NULL; - - free(*head); - *head = NULL; -} - -size_t print_and_count_strdlist(StrDList *head) { - size_t count = 0; - StrDList *current = head; - puts("Printing strdlist..."); - while (current->next) { - current = current->next; - printf("%s ", current->string); - ++count; - } - printf("\n"); - - return count; -} - -int strdlist_has_str(StrDList *head, const char *str) { - StrDList *current = head; - int idx = 0; - while (current->next) { - current = current->next; - if (strcmp(current->string, str) == 0) { - return idx; - } else { - ++idx; - } - } - - return -1; -} - -ParsedArgs parse_args(int argc, char **argv) { - // init - ParsedArgs args; - args.input_filename = NULL; - args.fields = create_strdlist(); - args.usage_printed = 0; - args.error = 0; - - --argc; - ++argv; - - // get filename and field from args - if (argc > 1) { - args.input_filename = argv[0]; - } else { - args.error = 1; - usage(); - args.usage_printed = 1; - } - - --argc; - ++argv; - - while (argc > 0) { - append_strdlist(args.fields, argv[0]); - --argc; - ++argv; - } - - return args; -} - -typedef struct CSVEntry { - char *buf; - size_t idx; - int is_end_of_line; - int is_end_of_file; - int is_chosen_field; -} CSVEntry; - -CSVEntry get_field(FILE *fd, size_t field_idx) { - size_t current_size = 512; - CSVEntry entry; - entry.is_end_of_line = 0; - entry.is_end_of_file = 0; - entry.is_chosen_field = 0; - entry.buf = NULL; - size_t idx = 0; - int next = fgetc(fd); - - while (next != EOF) { - if (next == ',') { - break; - } else if (next == '\n') { - entry.is_end_of_line = 1; - break; - } else if (next == ' ' || next == '\t') { - next = fgetc(fd); - continue; - } - if (!entry.buf) { - // malloc of buf deferred to here in case a field reaches EOF - entry.buf = malloc(current_size); - } - entry.buf[idx++] = next; - if (idx >= current_size) { - current_size *= 2; - entry.buf = realloc(entry.buf, current_size); - } - - next = fgetc(fd); - } - - if (next == EOF) { - entry.is_end_of_file = 1; - } - - if (entry.buf) { - if (idx >= current_size) { - current_size += 1; - entry.buf = realloc(entry.buf, current_size); - entry.buf[idx] = 0; - } else { - entry.buf[idx] = 0; - } - } - - entry.idx = field_idx; - - return entry; -} - int main(int argc, char **argv) { ParsedArgs args = parse_args(argc, argv); if (args.error) { cleanup_strdlist(&args.fields); return 1; - } else if (args.usage_printed) { + } else if (args.usage_print) { + usage(); cleanup_strdlist(&args.fields); return 0; } @@ -242,9 +71,7 @@ int main(int argc, char **argv) { printf("%s, ", entry.buf); } - if (entry.buf) { - free(entry.buf); - } + cleanup_csventry(&entry, 1); if (entry.is_end_of_file) { break; @@ -258,11 +85,11 @@ int main(int argc, char **argv) { fclose(csv_fd); for (size_t i = 0; i < number_of_entries; ++i) { - if (entries[i].buf) { - free(entries[i].buf); - } + cleanup_csventry(entries + i, 0); } free(entries); cleanup_strdlist(&args.fields); return 0; } + +// vim: et: ts=2: sts=2: sw=2 diff --git a/c_impl/src/strdlist.c b/c_impl/src/strdlist.c new file mode 100644 index 0000000..0b98b41 --- /dev/null +++ b/c_impl/src/strdlist.c @@ -0,0 +1,77 @@ +#include "strdlist.h" + +#include +#include + +StrDList *create_strdlist() { return calloc(1, sizeof(StrDList)); } + +void append_strdlist(StrDList *head, const char *string) { + StrDList *current = head; + + while (current->next) { + current = current->next; + } + + current->next = calloc(1, sizeof(StrDList)); + current->next->prev = current; + size_t string_size = strlen(string); + current->next->string = malloc(string_size + 1); + memcpy(current->next->string, string, string_size); + current->next->string[string_size] = 0; +} + +void cleanup_strdlist(StrDList **head) { + if (!head || !*head) { + return; + } + + StrDList *current = *head; + while (current->next) { + current = current->next; + } + + while (current->prev) { + current = current->prev; + if (current->next->string) { + free(current->next->string); + } + free(current->next); + current->next = NULL; + } + + (*head)->next = NULL; + + free(*head); + *head = NULL; +} + +size_t print_and_count_strdlist(StrDList *head) { + size_t count = 0; + StrDList *current = head; + puts("Printing strdlist..."); + while (current->next) { + current = current->next; + printf("%s ", current->string); + ++count; + } + printf("\n"); + + return count; +} + +int strdlist_has_str(StrDList *head, const char *str) { + StrDList *current = head; + int idx = 0; + while (current->next) { + current = current->next; + if (strcmp(current->string, str) == 0) { + return idx; + } else { + ++idx; + } + } + + return -1; +} + +// vim: et: ts=2: sts=2: sw=2 diff --git a/c_impl/src/strdlist.h b/c_impl/src/strdlist.h new file mode 100644 index 0000000..60ff9ba --- /dev/null +++ b/c_impl/src/strdlist.h @@ -0,0 +1,23 @@ +#ifndef SEODISPARATE_FIELDS_FROM_CSV_STRDLIST_H_ +#define SEODISPARATE_FIELDS_FROM_CSV_STRDLIST_H_ + +#include + +typedef struct StrDList { + char *string; + struct StrDList *next; + struct StrDList *prev; +} StrDList; + +StrDList *create_strdlist(); + +void append_strdlist(StrDList *head, const char *string); + +void cleanup_strdlist(StrDList **head); + +size_t print_and_count_strdlist(StrDList *head); + +int strdlist_has_str(StrDList *head, const char *str); + +#endif +// vim: et: ts=2: sts=2: sw=2