diff --git a/src/common/csv.c b/src/common/csv.c new file mode 100644 --- /dev/null +++ b/src/common/csv.c @@ -0,0 +1,123 @@ +/* + * Copyright 2010 Nathan Phillip Brink + * + * This file is a part of DistRen. + * + * DistRen is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * DistRen is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with DistRen. If not, see . + */ + +#include "common/config.h" + +#include "common/csv.h" + +#include +#include +#include +#include + +/** + * \todo + * replace with a more generic function for rendering a CSV file + */ +static int csv_print_row(size_t *columns, char *row[]) +{ + size_t c; + + for (c = 0; c < *columns; c ++) + { + printf("%s", row[c]); + if (c < *columns - 1) + printf(", "); + } + printf("\n"); + + return TRUE; +} + +csv_row_t csv_row_init(size_t columns) +{ + csv_row_t row; + + row = malloc(sizeof(struct csv_row)); + if (!row) + return NULL; + + row->cols = malloc(sizeof(char *) * columns); + if (!row->cols) + { + free(row); + return NULL; + } + row->num_cols = columns; + + return row; +} + +void csv_row_free(csv_row_t row) +{ + size_t c; + + for (c = 0; c < row->num_cols; c ++) + free(row->cols[c]); + free(row); +} + +list_t csv_parse(const char *inbuf, size_t columns) +{ + list_t rows; + size_t seek; + const char newline = '\n'; + csv_row_t row; + + size_t cur_col; + + rows = list_init(); + while(*inbuf) + { + row = csv_row_init(columns); + if (!row) + { + list_free(rows, (list_dealloc_func_t)&csv_row_free); + return NULL; + } + + for(cur_col = 0; cur_col < columns; cur_col ++) + { + for(seek = 0; inbuf[seek]; seek ++) + if (inbuf[seek] == newline + || inbuf[seek] == ',') + break; + row->cols[cur_col] = malloc(seek + 1); + if (seek) + memcpy(row->cols[cur_col], inbuf, seek); + row->cols[cur_col][seek] = '\0'; + + /* get us to the ',' (or NULL or newline char, if things are bad) */ + inbuf += seek; + /* skip a comma, but not a NULL char or newline */ + if (*inbuf == ',') + inbuf ++; + } + + list_insert_after(rows, row, 0); + + /* skip the newline char */ + while (*inbuf && *inbuf != newline) + inbuf ++; + if (*inbuf == newline) + inbuf ++; + } + + return rows; +}