aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2015-05-18 19:38:13 -0400
committerFranklin Wei <git@fwei.tk>2015-05-18 19:38:13 -0400
commitf5c7e492d8d6b7b4fa1298342ea6157bd2ada564 (patch)
treecbfc8b7c5e5dfce6aac62b49f5cc50735da38663
parent9b9697747aa55651680b196d4930203ef15d1c47 (diff)
downloadmarket-sim-f5c7e492d8d6b7b4fa1298342ea6157bd2ada564.zip
market-sim-f5c7e492d8d6b7b4fa1298342ea6157bd2ada564.tar.gz
market-sim-f5c7e492d8d6b7b4fa1298342ea6157bd2ada564.tar.bz2
market-sim-f5c7e492d8d6b7b4fa1298342ea6157bd2ada564.tar.xz
refactor csv parsing
-rw-r--r--Makefile2
-rw-r--r--src/csv.c38
-rw-r--r--src/globals.h1
-rw-r--r--src/util.c52
4 files changed, 50 insertions, 43 deletions
diff --git a/Makefile b/Makefile
index 22f290d..c05ba83 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ CC = cc
SRC := $(wildcard src/*.c)
OBJ := $(SRC:.c=.o)
-CFLAGS = -Isrc/ -O0 -g -Wall -Wextra -std=c99
+CFLAGS = -Isrc/ -O0 -g -Wall -Wextra -std=c99 -fsanitize=address
HEADERS := $(wildcard src/*.h)
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;
}