bcalc.c (2421B)
1 2 #include <stdlib.h> 3 #include <stdio.h> 4 #include <string.h> 5 #include "commander/commander.h" 6 #include "num.h" 7 8 extern int yy_scan_string(const char *str); 9 extern void yy_delete_buffer(int); 10 extern int yylex(); 11 extern int yyparse(); 12 extern enum unit g_output_format; 13 extern int g_print_unit; 14 struct num g_other; 15 char *g_other_name = "other"; 16 17 void yyerror(const char* s); 18 19 struct settings { 20 enum unit format; 21 int print_unit; 22 }; 23 24 static void no_print_unit(command_t *self) { \ 25 ((struct settings*)self->data)->print_unit = 0; \ 26 } 27 28 static void 29 setprice(command_t *cmd) { 30 const char *p = cmd->arg; 31 char *endptr; 32 g_other.unit = UNIT_OTHER; 33 g_other.type = TYPE_INT; 34 g_other.intval = strtoull(p, &endptr, 10); 35 36 // float? 37 if (endptr) { 38 if (*endptr == '.') { 39 g_other.floatval = atof(p); 40 g_other.type = TYPE_FLOAT; 41 if (g_other.floatval == 0) { 42 fprintf(stderr, "error: invalid --price value '%s'", p); 43 exit(1); 44 } 45 } 46 } 47 } 48 49 char * 50 join(char *strs[], int len, char *sep) { 51 char *buf, *p; 52 size_t alloc = 0; 53 54 for(int i = 0; i < len; ++i) 55 alloc += strlen(strs[i]); 56 57 // 5 for some wiggle room 58 alloc += len * strlen(sep) + 5; 59 p = buf = (char*)malloc(alloc); 60 61 for(int i = 0; i < len; ++i) { 62 strcpy(p, strs[i]); 63 p += strlen(strs[i]); 64 if (i != len-1) { 65 strcpy(p, sep); 66 p += strlen(sep); 67 } 68 } 69 70 return buf; 71 } 72 73 int main(int argc, char *argv[]) { 74 command_t cmd; 75 char *buffer, *p; 76 int yybuffer; 77 struct settings settings = { .print_unit = 1, .format = UNIT_SATOSHI }; 78 cmd.data = (void*)&settings; 79 g_other.unit = UNIT_NONE; 80 81 command_init(&cmd, argv[0], "0.0.1"); 82 83 command_option(&cmd, "-P", "--price <arg>", "set price for arbitrary unit per BTC", setprice); 84 command_option(&cmd, "-n", "--no-unit", "dont output the selected unit at the end", 85 no_print_unit); 86 87 command_parse(&cmd, argc, argv); 88 89 g_output_format = settings.format; 90 g_print_unit = settings.print_unit; 91 92 if (cmd.argc) { 93 buffer = join(cmd.argv, cmd.argc, " "); 94 p = &buffer[strlen(buffer)]; 95 *p++ = '\n'; 96 *p++ = '\0'; 97 yybuffer = yy_scan_string(buffer); 98 yyparse(); 99 yy_delete_buffer(yybuffer); 100 free(buffer); 101 } 102 else { 103 do { 104 yyparse(); 105 } while(!feof(stdin)); 106 } 107 108 command_free(&cmd); 109 return 0; 110 } 111 112 void yyerror(const char* s) { 113 fprintf(stderr, "Parse error: %s\n", s); 114 exit(1); 115 }