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