From b05123ca8b967a31cd074792ca920a3a74f61bc4 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Tue, 12 May 2015 19:59:44 -0400 Subject: split into multiple files --- src/buy.c | 88 +++++++++++ src/globals.h | 20 +++ src/load.c | 75 ++++++++++ src/main.c | 461 +--------------------------------------------------------- src/save.c | 37 +++++ src/sell.c | 79 ++++++++++ src/util.c | 177 ++++++++++++++++++++++ 7 files changed, 477 insertions(+), 460 deletions(-) create mode 100644 src/buy.c create mode 100644 src/load.c create mode 100644 src/save.c create mode 100644 src/sell.c create mode 100644 src/util.c (limited to 'src') diff --git a/src/buy.c b/src/buy.c new file mode 100644 index 0000000..7419bbf --- /dev/null +++ b/src/buy.c @@ -0,0 +1,88 @@ +#include "globals.h" + +void buy_handler(struct player_t *player) +{ + char *sym = malloc(16); + printf("Enter the ticker symbol of the stock you wish to purchase: "); + scanf("%15s", sym); + all_upper(sym); + + struct money_t price; + + printf("Getting stock information...\n"); + + char *name; + + if(!get_stock_info(sym, &price, &name)) + { + printf("Failed to get query information for '%s'.\n", sym); + return; + } + + printf("Stock name: %s\n", name); + printf("Price per share: $%llu.%02llu\n", price.cents / 100, price.cents % 100); + printf("Enter the number of shares to be purchased (maximum %llu): ", player->cash.cents / price.cents); + + ullong count = 0; + + scanf("%llu", &count); + + if(count <= 0) + { + printf("Purchase cancelled.\n"); + return; + } + + ullong cost = price.cents * count; + + if(cost > player->cash.cents) + { + printf("Not enough money!\n"); + return; + } + + printf("This will cost $%llu.%02llu. Are you sure? ", cost / 100, cost % 100); + char response[16]; + scanf("%15s", response); + all_lower(response); + + if(response[0] == 'y') + { + printf("Confirmed.\n"); + + /* add the stock to the portfolio or increase the count of a stock */ + + for(uint i = 0; i < player->portfolio_len; ++i) + { + if(strcmp(player->portfolio[i].symbol, sym) == 0) + { + struct stock_t *stock = player->portfolio + i; + stock->count += count; + stock->current_price.cents = price.cents; + goto done; + } + } + + /* not found, add a new one */ + player->portfolio_len += 1; + player->portfolio = realloc(player->portfolio, player->portfolio_len * sizeof(struct stock_t)); + player->need_to_free_portfolio = true; + + printf("sym: %s\n", sym); + printf("name: %s\n", name); + player->portfolio[player->portfolio_len - 1].symbol = sym; + player->portfolio[player->portfolio_len - 1].fullname = name; + player->portfolio[player->portfolio_len - 1].count = count; + player->portfolio[player->portfolio_len - 1].current_price.cents = price.cents; + done: + + player->cash.cents -= cost; + + /* sort the portfolio alphabetically by ticker symbol */ + qsort(player->portfolio, player->portfolio_len, sizeof(struct stock_t), compare_stocks); + } + else + { + printf("Not confirmed.\n"); + } +} diff --git a/src/globals.h b/src/globals.h index a220d79..cecb62b 100644 --- a/src/globals.h +++ b/src/globals.h @@ -1,5 +1,9 @@ +#include #include #include +#include +#include +#include #define ARRAYLEN(x) (sizeof(x) / sizeof(x[0])) @@ -27,3 +31,19 @@ struct player_t { struct stock_t *portfolio; bool need_to_free_portfolio; }; + +/*** prototypes ***/ +void cleanup(void); +int compare_stocks(const void*, const void*); +void all_lower(char*); +void all_upper(char*); +bool get_stock_info(char *sym, struct money_t*, char **name); +uint64_t to_sys64(uint64_t); +uint64_t to_be64(uint64_t); + +void buy_handler(struct player_t*); +void sell_handler(struct player_t*); +void update_handler(struct player_t*); +void save_handler(struct player_t*); +void load_handler(struct player_t*); +void quit_handler(struct player_t*); diff --git a/src/load.c b/src/load.c new file mode 100644 index 0000000..34acd73 --- /dev/null +++ b/src/load.c @@ -0,0 +1,75 @@ +#include "globals.h" + +/* NOTE: integers are represented internally by unsigned long long ints, but in the save they are always 64 bits */ + +void load_handler(struct player_t *player) +{ + printf("Enter the file to load portfolio from: "); + char buf[128]; + scanf("%127s", buf); + + printf("Loading portfolio...\n"); + + if(player->need_to_free_portfolio) + free(player->portfolio); + player->portfolio_len = 0; + + FILE *f = fopen(buf, "r"); + char magic[6]; + if(!f || fread(magic, 1, sizeof(magic), f) != 6 || memcmp(magic, "PORTv1", sizeof(magic)) != 0) + { + printf("FATAL: Failed to load save."); + exit(EXIT_FAILURE); + } + + uint64_t cash; + if(fread(&cash, sizeof(cash), 1, f) != 1) + { + printf("FATAL: Failed to load save."); + exit(EXIT_FAILURE); + } + cash = to_sys64(cash); + + player->cash.cents = cash; + + fflush(stdout); + do { + /* read portfolio data */ + + player->portfolio_len += 1; + player->portfolio = realloc(player->portfolio, player->portfolio_len * sizeof(struct stock_t)); + player->need_to_free_portfolio = true; + + uint64_t symlen; + if(fread(&symlen, sizeof(symlen), 1, f) != 1) + { + printf("FATAL: Save is corrupted (symbol length too short).\n"); + exit(EXIT_FAILURE); + } + symlen = to_sys64(symlen); + char *sym = malloc(symlen + 1); + if(fread(sym, symlen + 1, 1, f) != 1) + { + printf("FATAL: Save is corrupted (symbol too short).\n"); + exit(EXIT_FAILURE); + } + + player->portfolio[player->portfolio_len - 1].symbol = sym; + + uint64_t count; + if(fread(&count, sizeof(count), 1, f) != 1) + { + printf("FATAL: Save is corrupted (count too short).\n"); + exit(EXIT_FAILURE); + } + count = to_sys64(count); + + player->portfolio[player->portfolio_len - 1].count = count; + + int junk = fgetc(f); + ungetc(junk, f); + + } while (!feof(f) && !ferror(f)); + + update_handler(player); +} diff --git a/src/main.c b/src/main.c index b8685b7..9cda381 100644 --- a/src/main.c +++ b/src/main.c @@ -1,400 +1,14 @@ #include "globals.h" -#include - #include #include #include #include -/*** prototypes ***/ - -void buy_handler(struct player_t*); -void sell_handler(struct player_t*); -void update_handler(struct player_t*); -void save_handler(struct player_t*); -void load_handler(struct player_t*); -void quit_handler(struct player_t*); +#include /*** utility functions ***/ -void cleanup(void) -{ - curl_global_cleanup(); -} - -struct data_buffer_t { - char *data; - uint back; -}; - -void all_upper(char *str) -{ - while(*str) - { - *str = toupper(*str); - ++str; - } -} - -void all_lower(char *str) -{ - while(*str) - { - *str = tolower(*str); - ++str; - } -} - -size_t download_callback(char *ptr, size_t size, size_t nmemb, void *userdata) -{ - struct data_buffer_t *buf = userdata; - - buf->data = realloc(buf->data, buf->back + size * nmemb); - - memcpy(buf->data + buf->back, ptr, size * nmemb); - - buf->back += size * nmemb; - - return size * nmemb; -} - -bool get_stock_info(char *symbol, struct money_t *price, char **name_ret) -{ - CURL *curl = curl_easy_init(); - if(!curl) - { - return false; - } - - 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_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'; - - *name_ret = name; - - /* get price */ - - char *pricebuf = malloc(price_len + 1); - memcpy(pricebuf, buf.data + price_offs, price_len); - pricebuf[price_len] = '\0'; - - free(buf.data); - - /* remove the decimal point */ - - for(int i = 0; i < price_len; ++i) - { - if(pricebuf[i] == '.') - memmove(pricebuf + i, pricebuf + i + 1, price_len - i); - } - - price->cents = strtoull(pricebuf, NULL, 10); - - free(pricebuf); - - return true; -} - -int compare_stocks(const void *a, const void *b) -{ - const struct stock_t *a1 = a, *b1 = b; - return strcmp(a1->symbol, - b1->symbol); -} - -static enum { OTHER = 0, LITTLE = 1, BIG = 2 } endianness; - -static void detect_endianness(void) -{ - ulong test = 0x12345678; - uchar *ptr = (uchar*)&test; - if(*ptr == 0x12) - endianness = BIG; - else if(*ptr == 0x78) - endianness = LITTLE; - else - { - printf("FATAL: failed to detect system endianness!\n"); - exit(EXIT_FAILURE); - } -} - -uint64_t to_be64(ullong n) -{ - if(!endianness) - { - detect_endianness(); - } - - if(BIG) - { - n = (n & 0x00000000FFFFFFFF) << 32 | (n & 0xFFFFFFFF00000000) >> 32; - n = (n & 0x0000FFFF0000FFFF) << 16 | (n & 0xFFFF0000FFFF0000) >> 16; - n = (n & 0x00FF00FF00FF00FF) << 8 | (n & 0xFF00FF00FF00FF00) >> 8; - } - return n; -} - -uint64_t to_sys64(ullong n) -{ - if(!endianness) - { - detect_endianness(); - } - - if(endianness == BIG) - return n; - else - return to_be64(n); -} - -/*** driver functions ***/ - -void buy_handler(struct player_t *player) -{ - char *sym = malloc(16); - printf("Enter the ticker symbol of the stock you wish to purchase: "); - scanf("%15s", sym); - all_upper(sym); - - struct money_t price; - - printf("Getting stock information...\n"); - - char *name; - - if(!get_stock_info(sym, &price, &name)) - { - printf("Failed to get query information for '%s'.\n", sym); - return; - } - - printf("Stock name: %s\n", name); - printf("Price per share: $%llu.%02llu\n", price.cents / 100, price.cents % 100); - printf("Enter the number of shares to be purchased (maximum %llu): ", player->cash.cents / price.cents); - - ullong count = 0; - - scanf("%llu", &count); - - if(count <= 0) - { - printf("Purchase cancelled.\n"); - return; - } - - ullong cost = price.cents * count; - - if(cost > player->cash.cents) - { - printf("Not enough money!\n"); - return; - } - - printf("This will cost $%llu.%02llu. Are you sure? ", cost / 100, cost % 100); - char response[16]; - scanf("%15s", response); - all_lower(response); - - if(response[0] == 'y') - { - printf("Confirmed.\n"); - - /* add the stock to the portfolio or increase the count of a stock */ - - for(uint i = 0; i < player->portfolio_len; ++i) - { - if(strcmp(player->portfolio[i].symbol, sym) == 0) - { - struct stock_t *stock = player->portfolio + i; - stock->count += count; - stock->current_price.cents = price.cents; - goto done; - } - } - - /* not found, add a new one */ - player->portfolio_len += 1; - player->portfolio = realloc(player->portfolio, player->portfolio_len * sizeof(struct stock_t)); - player->need_to_free_portfolio = true; - - printf("sym: %s\n", sym); - printf("name: %s\n", name); - player->portfolio[player->portfolio_len - 1].symbol = sym; - player->portfolio[player->portfolio_len - 1].fullname = name; - player->portfolio[player->portfolio_len - 1].count = count; - player->portfolio[player->portfolio_len - 1].current_price.cents = price.cents; - done: - - player->cash.cents -= cost; - - /* sort the portfolio alphabetically by ticker symbol */ - qsort(player->portfolio, player->portfolio_len, sizeof(struct stock_t), compare_stocks); - } - else - { - printf("Not confirmed.\n"); - } -} - -void sell_handler(struct player_t *player) -{ - char *sym = malloc(16); - printf("Enter the ticker symbol of the stock you wish to sell: "); - scanf("%15s", sym); - all_upper(sym); - - printf("Getting stock information...\n"); - - struct stock_t *stock = NULL; - uint stock_idx; - - for(stock_idx = 0; stock_idx < player->portfolio_len; ++stock_idx) - { - if(strcmp(player->portfolio[stock_idx].symbol, sym) == 0) - { - stock = player->portfolio + stock_idx; - break; - } - } - - if(!stock) - { - printf("Couldn't find '%s' in portfolio.\n", sym); - return; - } - - update_handler(player); - - printf("You currently own %llu shares of '%s' (%s) valued at $%llu.%02llu each.\n", - stock->count, stock->fullname, stock->symbol, stock->current_price.cents / 100, stock->current_price.cents % 100); - - ullong sell = 0; - printf("How many shares do you wish to sell? "); - scanf("%llu", &sell); - - if(!sell) - { - printf("Sale cancelled.\n"); - return; - } - - if(stock->count < sell) - { - printf("You don't own enough shares!\n"); - return; - } - - ullong sell_total = stock->current_price.cents * sell; - - printf("This will sell %llu shares for $%llu.%02llu total. Proceed? ", sell, sell_total / 100, sell_total % 100); - - char response[16]; - scanf("%15s", response); - all_lower(response); - - if(response[0] == 'y') - { - stock->count -= sell; - - if(stock->count == 0) - { - /* remove this item from the portfolio */ - memmove(player->portfolio + stock_idx, player->portfolio + stock_idx + 1, sizeof(struct stock_t) * (player->portfolio_len - stock_idx - 1)); - player->portfolio_len -= 1; - player->portfolio = realloc(player->portfolio, sizeof(struct stock_t) * player->portfolio_len); - } - - player->cash.cents += sell_total; - - printf("%llu shares sold for $%llu.%02llu total.\n", sell, sell_total / 100, sell_total % 100); - } - else - { - printf("Not confirmed.\n"); - } -} - -/* NOTE: integers are represented internally by unsigned long long ints, but in the save they are always 64 bits */ - -void save_handler(struct player_t *player) -{ - printf("Enter the file to save your portfolio in: "); - - char buf[128]; - scanf("%127s", buf); - - printf("Writing data...\n"); - FILE *f = fopen(buf, "w"); - - const char *magic = "PORTv1"; - fwrite(magic, strlen(magic), 1, f); - - ullong be_cash = to_be64(player->cash.cents); - - fwrite(&be_cash, sizeof(be_cash), 1, f); - - for(uint i = 0; i < player->portfolio_len; ++i) - { - struct stock_t *stock = player->portfolio + i; - - ullong be_symlen = to_be64(strlen(stock->symbol)); - fwrite(&be_symlen, sizeof(be_symlen), 1, f); - fwrite(stock->symbol, strlen(stock->symbol) + 1, 1, f); - - ullong be_count = to_be64(stock->count); - fwrite(&be_count, sizeof(be_count), 1, f); - } - - fclose(f); - - printf("Done saving."); -} - void update_handler(struct player_t *player) { printf("Updating stock prices...\n"); @@ -406,79 +20,6 @@ void update_handler(struct player_t *player) } } -void load_handler(struct player_t *player) -{ - printf("Enter the file to load portfolio from: "); - char buf[128]; - scanf("%127s", buf); - - printf("Loading portfolio...\n"); - - if(player->need_to_free_portfolio) - free(player->portfolio); - player->portfolio_len = 0; - - FILE *f = fopen(buf, "r"); - char magic[6]; - if(!f || fread(magic, 1, sizeof(magic), f) != 6 || memcmp(magic, "PORTv1", sizeof(magic)) != 0) - { - printf("FATAL: Failed to load save."); - exit(EXIT_FAILURE); - } - - ullong cash; - if(fread(&cash, sizeof(cash), 1, f) != 1) - { - printf("cash: %llu\n", cash); - printf("FATAL: Failed to load save."); - exit(EXIT_FAILURE); - } - cash = to_sys64(cash); - - player->cash.cents = cash; - - fflush(stdout); - do { - /* read portfolio data */ - - player->portfolio_len += 1; - player->portfolio = realloc(player->portfolio, player->portfolio_len * sizeof(struct stock_t)); - player->need_to_free_portfolio = true; - - ullong symlen; - if(fread(&symlen, sizeof(symlen), 1, f) != 1) - { - printf("FATAL: Save is corrupted (symbol length too short).\n"); - exit(EXIT_FAILURE); - } - symlen = to_sys64(symlen); - char *sym = malloc(symlen + 1); - if(fread(sym, symlen + 1, 1, f) != 1) - { - printf("FATAL: Save is corrupted (symbol too short).\n"); - exit(EXIT_FAILURE); - } - - player->portfolio[player->portfolio_len - 1].symbol = sym; - - ullong count; - if(fread(&count, sizeof(count), 1, f) != 1) - { - printf("FATAL: Save is corrupted (count too short).\n"); - exit(EXIT_FAILURE); - } - count = to_sys64(count); - - player->portfolio[player->portfolio_len - 1].count = count; - - int junk = fgetc(f); - ungetc(junk, f); - - } while (!feof(f) && !ferror(f)); - - update_handler(player); -} - void quit_handler(struct player_t *player) { exit(EXIT_SUCCESS); diff --git a/src/save.c b/src/save.c new file mode 100644 index 0000000..989ab60 --- /dev/null +++ b/src/save.c @@ -0,0 +1,37 @@ +#include "globals.h" + +/* NOTE: integers are represented internally by unsigned long long ints, but in the save they are always 64 bits */ + +void save_handler(struct player_t *player) +{ + printf("Enter the file to save your portfolio in: "); + + char buf[128]; + scanf("%127s", buf); + + printf("Writing data...\n"); + FILE *f = fopen(buf, "w"); + + const char *magic = "PORTv1"; + fwrite(magic, strlen(magic), 1, f); + + uint64_t be_cash = to_be64(player->cash.cents); + + fwrite(&be_cash, sizeof(be_cash), 1, f); + + for(uint i = 0; i < player->portfolio_len; ++i) + { + struct stock_t *stock = player->portfolio + i; + + uint64_t be_symlen = to_be64(strlen(stock->symbol)); + fwrite(&be_symlen, sizeof(be_symlen), 1, f); + fwrite(stock->symbol, strlen(stock->symbol) + 1, 1, f); + + uint64_t be_count = to_be64(stock->count); + fwrite(&be_count, sizeof(be_count), 1, f); + } + + fclose(f); + + printf("Done saving."); +} diff --git a/src/sell.c b/src/sell.c new file mode 100644 index 0000000..1a04adc --- /dev/null +++ b/src/sell.c @@ -0,0 +1,79 @@ +#include "globals.h" + +void sell_handler(struct player_t *player) +{ + char *sym = malloc(16); + printf("Enter the ticker symbol of the stock you wish to sell: "); + scanf("%15s", sym); + all_upper(sym); + + printf("Getting stock information...\n"); + + struct stock_t *stock = NULL; + uint stock_idx; + + for(stock_idx = 0; stock_idx < player->portfolio_len; ++stock_idx) + { + if(strcmp(player->portfolio[stock_idx].symbol, sym) == 0) + { + stock = player->portfolio + stock_idx; + break; + } + } + + if(!stock) + { + printf("Couldn't find '%s' in portfolio.\n", sym); + return; + } + + update_handler(player); + + printf("You currently own %llu shares of '%s' (%s) valued at $%llu.%02llu each.\n", + stock->count, stock->fullname, stock->symbol, stock->current_price.cents / 100, stock->current_price.cents % 100); + + ullong sell = 0; + printf("How many shares do you wish to sell? "); + scanf("%llu", &sell); + + if(!sell) + { + printf("Sale cancelled.\n"); + return; + } + + if(stock->count < sell) + { + printf("You don't own enough shares!\n"); + return; + } + + ullong sell_total = stock->current_price.cents * sell; + + printf("This will sell %llu shares for $%llu.%02llu total. Proceed? ", sell, sell_total / 100, sell_total % 100); + + char response[16]; + scanf("%15s", response); + all_lower(response); + + if(response[0] == 'y') + { + stock->count -= sell; + + if(stock->count == 0) + { + /* remove this item from the portfolio */ + memmove(player->portfolio + stock_idx, player->portfolio + stock_idx + 1, sizeof(struct stock_t) * (player->portfolio_len - stock_idx - 1)); + player->portfolio_len -= 1; + player->portfolio = realloc(player->portfolio, sizeof(struct stock_t) * player->portfolio_len); + } + + player->cash.cents += sell_total; + + printf("%llu shares sold for $%llu.%02llu total.\n", sell, sell_total / 100, sell_total % 100); + } + else + { + printf("Not confirmed.\n"); + } +} diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..cf5283f --- /dev/null +++ b/src/util.c @@ -0,0 +1,177 @@ +#include "globals.h" + +#include + +void cleanup(void) +{ + curl_global_cleanup(); +} + +struct data_buffer_t { + char *data; + uint back; +}; + +void all_upper(char *str) +{ + while(*str) + { + *str = toupper(*str); + ++str; + } +} + +void all_lower(char *str) +{ + while(*str) + { + *str = tolower(*str); + ++str; + } +} + +size_t download_callback(char *ptr, size_t size, size_t nmemb, void *userdata) +{ + struct data_buffer_t *buf = userdata; + + buf->data = realloc(buf->data, buf->back + size * nmemb); + + memcpy(buf->data + buf->back, ptr, size * nmemb); + + buf->back += size * nmemb; + + return size * nmemb; +} + +bool get_stock_info(char *symbol, struct money_t *price, char **name_ret) +{ + CURL *curl = curl_easy_init(); + if(!curl) + { + return false; + } + + 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_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'; + + *name_ret = name; + + /* get price */ + + char *pricebuf = malloc(price_len + 1); + memcpy(pricebuf, buf.data + price_offs, price_len); + pricebuf[price_len] = '\0'; + + free(buf.data); + + /* remove the decimal point */ + + for(int i = 0; i < price_len; ++i) + { + if(pricebuf[i] == '.') + memmove(pricebuf + i, pricebuf + i + 1, price_len - i); + } + + price->cents = strtoull(pricebuf, NULL, 10); + + free(pricebuf); + + return true; +} + +int compare_stocks(const void *a, const void *b) +{ + const struct stock_t *a1 = a, *b1 = b; + return strcmp(a1->symbol, + b1->symbol); +} + +static enum { OTHER = 0, LITTLE = 1, BIG = 2 } endianness; + +static void detect_endianness(void) +{ + ulong test = 0x12345678; + uchar *ptr = (uchar*)&test; + if(*ptr == 0x12) + endianness = BIG; + else if(*ptr == 0x78) + endianness = LITTLE; + else + { + printf("FATAL: failed to detect system endianness!\n"); + exit(EXIT_FAILURE); + } +} + +uint64_t to_be64(uint64_t n) +{ + if(!endianness) + { + detect_endianness(); + } + + if(BIG) + { + n = (n & 0x00000000FFFFFFFF) << 32 | (n & 0xFFFFFFFF00000000) >> 32; + n = (n & 0x0000FFFF0000FFFF) << 16 | (n & 0xFFFF0000FFFF0000) >> 16; + n = (n & 0x00FF00FF00FF00FF) << 8 | (n & 0xFF00FF00FF00FF00) >> 8; + } + return n; +} + +uint64_t to_sys64(uint64_t n) +{ + if(!endianness) + { + detect_endianness(); + } + + if(endianness == BIG) + return n; + else + return to_be64(n); +} -- cgit v1.1