From f5c7e492d8d6b7b4fa1298342ea6157bd2ada564 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Mon, 18 May 2015 19:38:13 -0400 Subject: refactor csv parsing --- src/csv.c | 38 ++++++++++++++++++++++++++++++++++++++ src/globals.h | 1 + src/util.c | 52 ++++++++++------------------------------------------ 3 files changed, 49 insertions(+), 42 deletions(-) create mode 100644 src/csv.c (limited to 'src') diff --git a/src/csv.c b/src/csv.c new file mode 100644 index 0000000..907065e --- /dev/null +++ b/src/csv.c @@ -0,0 +1,38 @@ +#include "globals.h" + +char *csv_read(char **ptr) +{ + if(!ptr) + return NULL; + + char *start = *ptr; + bool quoted = false; + + while(**ptr) + { + char c = **ptr; + + if(c == '"') + { + quoted = !quoted; + } + + else if((c == ',' && !quoted) || + c == '\0' || + c == '\n') + { + char *ret = malloc(*ptr - start + 1); + ret[*ptr - start] = '\0'; + memcpy(ret, start, *ptr - start); + (*ptr)++; + + return ret; + } + + (*ptr)++; + } + + /* shouldn't get here */ + assert(false); + return NULL; +} diff --git a/src/globals.h b/src/globals.h index cf83758..5791a69 100644 --- a/src/globals.h +++ b/src/globals.h @@ -88,6 +88,7 @@ char *read_ticker(void); char *read_string(void); ullong read_int(void); void parse_args(int argc, char *argv[]); +char *csv_read(char**); void buy_handler(struct player_t*); void sell_handler(struct player_t*); diff --git a/src/util.c b/src/util.c index 5dd902d..2754fc5 100644 --- a/src/util.c +++ b/src/util.c @@ -55,60 +55,30 @@ bool get_stock_info(char *symbol, struct money_t *price, char **name_ret) char url[256]; snprintf(url, sizeof(url), "http://download.finance.yahoo.com/d/quotes.csv?s=%s&f=nl1&e=.csv", symbol); - curl_easy_setopt(curl, CURLOPT_URL, url); - struct data_buffer_t buf; memset(&buf, 0, sizeof(buf)); + curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, download_callback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buf); CURLcode res = curl_easy_perform(curl); - curl_easy_cleanup(curl); - /** now parse the data **/ - - /* the stock name is in quotes, find it! */ - - /* check for validity */ - if(buf.back == 0 || buf.data[0] != '"' || res != CURLE_OK) - { - printf("Failed to retrieve stock data.\n"); - if(res != CURLE_OK) - { - printf("Download library error (%d): '%s'\n", res, curl_easy_strerror(res)); - } - return false; - } - - uint name_len = 0; - for(uint i = 1; i < buf.back; ++i) - { - if(buf.data[i] == '"') - break; - ++name_len; - } - - const uint name_offs = 1; - uint price_offs = name_len + 3; - uint price_len = buf.back - price_offs; - - char *name = malloc(name_len + 1); - memcpy(name, buf.data + name_offs, name_len); - name[name_len] = '\0'; + if(res != CURLE_OK || buf.data[0] != '"') + printf("Failed querying information for '%s'.\n", symbol); - *name_ret = name; + /* null-terminate buffer */ + buf.data = realloc(buf.data, buf.back + 1); + buf.data[buf.back] = '\0'; - /* get price */ + /** now parse the data **/ - char *pricebuf = malloc(price_len + 1); - memcpy(pricebuf, buf.data + price_offs, price_len); - pricebuf[price_len] = '\0'; + char ** ptr = &buf.data; - free(buf.data); + *name_ret = csv_read(ptr); + char *pricebuf = csv_read(ptr); ullong dollars, cents; /* dirty hack! */ @@ -116,8 +86,6 @@ bool get_stock_info(char *symbol, struct money_t *price, char **name_ret) price->cents = dollars * 100 + cents; - free(pricebuf); - return true; } -- cgit v1.1