iodine 0.7.60 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.clang-format +15 -0
- data/.rspec +1 -0
- data/.yardopts +1 -3
- data/CHANGELOG.md +132 -12
- data/Gemfile +5 -7
- data/LICENSE.txt +1 -1
- data/README.md +147 -671
- data/Rakefile +9 -16
- data/examples/chatroom.nru +9 -0
- data/examples/client +74 -0
- data/examples/config-hello.nru +9 -0
- data/examples/config-hello.ru +11 -0
- data/examples/config-hijack.ru +13 -0
- data/examples/config-shootout.ru +43 -0
- data/examples/config.nru +120 -0
- data/examples/config.rb +37 -0
- data/examples/config.ru +42 -53
- data/examples/fake +24 -0
- data/examples/hello_neorack +137 -0
- data/examples/routes.nru +29 -0
- data/examples/routes.ru +42 -0
- data/exe/iodine +218 -258
- data/ext/iodine/extconf.rb +27 -100
- data/ext/iodine/fio-stl.h +128336 -0
- data/ext/iodine/fio-stl.md +26396 -0
- data/ext/iodine/iodine.c +213 -1393
- data/ext/iodine/iodine.h +250 -55
- data/ext/iodine/iodine_arg_helper.h +329 -0
- data/ext/iodine/iodine_caller.h +234 -25
- data/ext/iodine/iodine_cli.h +434 -0
- data/ext/iodine/iodine_compression.h +312 -0
- data/ext/iodine/iodine_connection.h +3484 -34
- data/ext/iodine/iodine_core.h +363 -0
- data/ext/iodine/iodine_crypto.h +1441 -0
- data/ext/iodine/iodine_defer.h +225 -4
- data/ext/iodine/iodine_json.h +738 -4
- data/ext/iodine/iodine_listener.h +263 -0
- data/ext/iodine/iodine_log.h +297 -0
- data/ext/iodine/iodine_minimap.h +543 -0
- data/ext/iodine/iodine_mustache.h +461 -4
- data/ext/iodine/iodine_pubsub_eng.h +729 -0
- data/ext/iodine/iodine_pubsub_history.h +547 -0
- data/ext/iodine/iodine_pubsub_msg.h +228 -0
- data/ext/iodine/iodine_redis.h +322 -0
- data/ext/iodine/iodine_store.h +418 -16
- data/ext/iodine/iodine_threads.h +279 -0
- data/ext/iodine/iodine_tls.h +515 -6
- data/ext/iodine/iodine_utils.h +923 -0
- data/iodine.gemspec +37 -42
- data/lib/iodine/benchmark.rb +1690 -0
- data/lib/iodine/documentation.rb +3085 -0
- data/lib/iodine/version.rb +17 -1
- data/lib/iodine.rb +54 -255
- data/logo.svg +36 -0
- data/mustache.md +55 -0
- data/sig/iodine.rbs +4 -0
- metadata +58 -184
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -40
- data/.github/workflows/ruby.yml +0 -42
- data/.gitignore +0 -21
- data/LIMITS.md +0 -41
- data/SPEC-PubSub-Draft.md +0 -159
- data/SPEC-WebSocket-Draft.md +0 -239
- data/bin/console +0 -22
- data/bin/info.md +0 -353
- data/bin/mustache_bench.rb +0 -100
- data/bin/poc/Gemfile.lock +0 -23
- data/bin/poc/README.md +0 -37
- data/bin/poc/config.ru +0 -66
- data/bin/poc/gemfile +0 -1
- data/bin/poc/www/index.html +0 -57
- data/examples/async_task.ru +0 -92
- data/examples/bates/README.md +0 -3
- data/examples/bates/config.ru +0 -342
- data/examples/bates/david+bold.pdf +0 -0
- data/examples/bates/public/drop-pdf.png +0 -0
- data/examples/bates/public/index.html +0 -600
- data/examples/echo.ru +0 -59
- data/examples/etag.ru +0 -16
- data/examples/hello.ru +0 -29
- data/examples/pubsub_engine.ru +0 -81
- data/examples/rack3.ru +0 -12
- data/examples/redis.ru +0 -70
- data/examples/shootout.ru +0 -73
- data/examples/sub-protocols.ru +0 -90
- data/examples/tcp_client.rb +0 -66
- data/examples/x-sendfile.ru +0 -14
- data/ext/iodine/fio.c +0 -11995
- data/ext/iodine/fio.h +0 -6371
- data/ext/iodine/fio_cli.c +0 -431
- data/ext/iodine/fio_cli.h +0 -189
- data/ext/iodine/fio_json_parser.h +0 -688
- data/ext/iodine/fio_siphash.c +0 -157
- data/ext/iodine/fio_siphash.h +0 -37
- data/ext/iodine/fio_tls.h +0 -129
- data/ext/iodine/fio_tls_missing.c +0 -649
- data/ext/iodine/fio_tls_openssl.c +0 -1106
- data/ext/iodine/fio_tmpfile.h +0 -50
- data/ext/iodine/fiobj.h +0 -44
- data/ext/iodine/fiobj4fio.h +0 -21
- data/ext/iodine/fiobj_ary.c +0 -333
- data/ext/iodine/fiobj_ary.h +0 -139
- data/ext/iodine/fiobj_data.c +0 -1187
- data/ext/iodine/fiobj_data.h +0 -167
- data/ext/iodine/fiobj_hash.c +0 -409
- data/ext/iodine/fiobj_hash.h +0 -176
- data/ext/iodine/fiobj_json.c +0 -622
- data/ext/iodine/fiobj_json.h +0 -68
- data/ext/iodine/fiobj_mem.h +0 -71
- data/ext/iodine/fiobj_mustache.c +0 -317
- data/ext/iodine/fiobj_mustache.h +0 -62
- data/ext/iodine/fiobj_numbers.c +0 -344
- data/ext/iodine/fiobj_numbers.h +0 -127
- data/ext/iodine/fiobj_str.c +0 -433
- data/ext/iodine/fiobj_str.h +0 -172
- data/ext/iodine/fiobject.c +0 -620
- data/ext/iodine/fiobject.h +0 -655
- data/ext/iodine/hpack.h +0 -1923
- data/ext/iodine/http.c +0 -2743
- data/ext/iodine/http.h +0 -1002
- data/ext/iodine/http1.c +0 -910
- data/ext/iodine/http1.h +0 -29
- data/ext/iodine/http1_parser.h +0 -878
- data/ext/iodine/http_internal.c +0 -1279
- data/ext/iodine/http_internal.h +0 -237
- data/ext/iodine/http_mime_parser.h +0 -350
- data/ext/iodine/iodine_caller.c +0 -230
- data/ext/iodine/iodine_connection.c +0 -941
- data/ext/iodine/iodine_defer.c +0 -420
- data/ext/iodine/iodine_fiobj2rb.h +0 -120
- data/ext/iodine/iodine_helpers.c +0 -282
- data/ext/iodine/iodine_helpers.h +0 -12
- data/ext/iodine/iodine_http.c +0 -1181
- data/ext/iodine/iodine_http.h +0 -23
- data/ext/iodine/iodine_json.c +0 -302
- data/ext/iodine/iodine_mustache.c +0 -567
- data/ext/iodine/iodine_pubsub.c +0 -580
- data/ext/iodine/iodine_pubsub.h +0 -26
- data/ext/iodine/iodine_rack_io.c +0 -273
- data/ext/iodine/iodine_rack_io.h +0 -20
- data/ext/iodine/iodine_store.c +0 -148
- data/ext/iodine/iodine_tcp.c +0 -346
- data/ext/iodine/iodine_tcp.h +0 -13
- data/ext/iodine/iodine_tls.c +0 -261
- data/ext/iodine/mustache_parser.h +0 -1546
- data/ext/iodine/redis_engine.c +0 -957
- data/ext/iodine/redis_engine.h +0 -79
- data/ext/iodine/resp_parser.h +0 -317
- data/ext/iodine/websocket_parser.h +0 -506
- data/ext/iodine/websockets.c +0 -743
- data/ext/iodine/websockets.h +0 -185
- data/lib/iodine/connection.rb +0 -61
- data/lib/iodine/json.rb +0 -42
- data/lib/iodine/mustache.rb +0 -113
- data/lib/iodine/pubsub.rb +0 -55
- data/lib/iodine/rack_utils.rb +0 -43
- data/lib/iodine/tls.rb +0 -16
- data/lib/rack/handler/iodine.rb +0 -33
- data/logo.png +0 -0
data/ext/iodine/fio_cli.c
DELETED
|
@@ -1,431 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Copyright: Boaz segev, 2017
|
|
3
|
-
License: MIT
|
|
4
|
-
|
|
5
|
-
Feel free to copy, use and enjoy according to the license provided.
|
|
6
|
-
*/
|
|
7
|
-
#include <fio.h>
|
|
8
|
-
|
|
9
|
-
#include <fio_cli.h>
|
|
10
|
-
|
|
11
|
-
#include <stdint.h>
|
|
12
|
-
#include <stdio.h>
|
|
13
|
-
#include <stdlib.h>
|
|
14
|
-
#include <string.h>
|
|
15
|
-
#include <strings.h>
|
|
16
|
-
|
|
17
|
-
/* *****************************************************************************
|
|
18
|
-
CLI Data Stores
|
|
19
|
-
***************************************************************************** */
|
|
20
|
-
|
|
21
|
-
typedef struct {
|
|
22
|
-
size_t len;
|
|
23
|
-
const char *data;
|
|
24
|
-
} cstr_s;
|
|
25
|
-
|
|
26
|
-
#define FIO_SET_OBJ_TYPE const char *
|
|
27
|
-
#define FIO_SET_KEY_TYPE cstr_s
|
|
28
|
-
#define FIO_SET_KEY_COMPARE(o1, o2) \
|
|
29
|
-
(o1.len == o2.len && \
|
|
30
|
-
(o1.data == o2.data || !memcmp(o1.data, o2.data, o1.len)))
|
|
31
|
-
#define FIO_SET_NAME fio_cli_hash
|
|
32
|
-
#include <fio.h>
|
|
33
|
-
|
|
34
|
-
static fio_cli_hash_s fio_aliases = FIO_SET_INIT;
|
|
35
|
-
static fio_cli_hash_s fio_values = FIO_SET_INIT;
|
|
36
|
-
static size_t fio_unnamed_count = 0;
|
|
37
|
-
|
|
38
|
-
typedef struct {
|
|
39
|
-
int unnamed_min;
|
|
40
|
-
int unnamed_max;
|
|
41
|
-
int pos;
|
|
42
|
-
int unnamed_count;
|
|
43
|
-
int argc;
|
|
44
|
-
char const **argv;
|
|
45
|
-
char const *description;
|
|
46
|
-
char const **names;
|
|
47
|
-
} fio_cli_parser_data_s;
|
|
48
|
-
|
|
49
|
-
/** this will allow the function definition fio_cli_start to avoid the MACRO */
|
|
50
|
-
#define AVOID_MACRO
|
|
51
|
-
|
|
52
|
-
#define FIO_CLI_HASH_VAL(s) \
|
|
53
|
-
fio_risky_hash((s).data, (s).len, (uintptr_t)fio_cli_start)
|
|
54
|
-
|
|
55
|
-
/* *****************************************************************************
|
|
56
|
-
CLI Parsing
|
|
57
|
-
***************************************************************************** */
|
|
58
|
-
|
|
59
|
-
/* *****************************************************************************
|
|
60
|
-
CLI Parsing
|
|
61
|
-
***************************************************************************** */
|
|
62
|
-
|
|
63
|
-
static void fio_cli_map_line2alias(char const *line) {
|
|
64
|
-
cstr_s n = {.data = line};
|
|
65
|
-
while (n.data[0] == '-') {
|
|
66
|
-
while (n.data[n.len] && n.data[n.len] != ' ' && n.data[n.len] != ',') {
|
|
67
|
-
++n.len;
|
|
68
|
-
}
|
|
69
|
-
const char *old = NULL;
|
|
70
|
-
fio_cli_hash_insert(&fio_aliases, FIO_CLI_HASH_VAL(n), n, (void *)line,
|
|
71
|
-
&old);
|
|
72
|
-
if (old) {
|
|
73
|
-
FIO_LOG_WARNING("CLI argument name conflict detected\n"
|
|
74
|
-
" The following two directives conflict:\n"
|
|
75
|
-
"\t%s\n\t%s\n",
|
|
76
|
-
old, line);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
while (n.data[n.len] && (n.data[n.len] == ' ' || n.data[n.len] == ',')) {
|
|
80
|
-
++n.len;
|
|
81
|
-
}
|
|
82
|
-
n.data += n.len;
|
|
83
|
-
n.len = 0;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
static char const *fio_cli_get_line_type(fio_cli_parser_data_s *parser,
|
|
88
|
-
const char *line) {
|
|
89
|
-
if (!line) {
|
|
90
|
-
return NULL;
|
|
91
|
-
}
|
|
92
|
-
char const **pos = parser->names;
|
|
93
|
-
while (*pos) {
|
|
94
|
-
switch ((intptr_t)*pos) {
|
|
95
|
-
case FIO_CLI_STRING__TYPE_I: /* fallthrough */
|
|
96
|
-
case FIO_CLI_BOOL__TYPE_I: /* fallthrough */
|
|
97
|
-
case FIO_CLI_INT__TYPE_I: /* fallthrough */
|
|
98
|
-
case FIO_CLI_PRINT__TYPE_I: /* fallthrough */
|
|
99
|
-
case FIO_CLI_PRINT_HEADER__TYPE_I: /* fallthrough */
|
|
100
|
-
++pos;
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
if (line == *pos) {
|
|
104
|
-
goto found;
|
|
105
|
-
}
|
|
106
|
-
++pos;
|
|
107
|
-
}
|
|
108
|
-
return NULL;
|
|
109
|
-
found:
|
|
110
|
-
switch ((size_t)pos[1]) {
|
|
111
|
-
case FIO_CLI_STRING__TYPE_I: /* fallthrough */
|
|
112
|
-
case FIO_CLI_BOOL__TYPE_I: /* fallthrough */
|
|
113
|
-
case FIO_CLI_INT__TYPE_I: /* fallthrough */
|
|
114
|
-
case FIO_CLI_PRINT__TYPE_I: /* fallthrough */
|
|
115
|
-
case FIO_CLI_PRINT_HEADER__TYPE_I: /* fallthrough */
|
|
116
|
-
return pos[1];
|
|
117
|
-
}
|
|
118
|
-
return NULL;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
static void fio_cli_set_arg(cstr_s arg, char const *value, char const *line,
|
|
122
|
-
fio_cli_parser_data_s *parser) {
|
|
123
|
-
/* handle unnamed argument */
|
|
124
|
-
if (!line || !arg.len) {
|
|
125
|
-
if (!value) {
|
|
126
|
-
goto print_help;
|
|
127
|
-
}
|
|
128
|
-
if (!strcmp(value, "-?") || !strcasecmp(value, "-h") ||
|
|
129
|
-
!strcasecmp(value, "-help") || !strcasecmp(value, "--help")) {
|
|
130
|
-
goto print_help;
|
|
131
|
-
}
|
|
132
|
-
cstr_s n = {.len = ++parser->unnamed_count};
|
|
133
|
-
fio_cli_hash_insert(&fio_values, n.len, n, value, NULL);
|
|
134
|
-
if (parser->unnamed_max >= 0 &&
|
|
135
|
-
parser->unnamed_count > parser->unnamed_max) {
|
|
136
|
-
arg.len = 0;
|
|
137
|
-
goto error;
|
|
138
|
-
}
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/* validate data types */
|
|
143
|
-
char const *type = fio_cli_get_line_type(parser, line);
|
|
144
|
-
switch ((size_t)type) {
|
|
145
|
-
case FIO_CLI_BOOL__TYPE_I:
|
|
146
|
-
if (value && value != parser->argv[parser->pos + 1]) {
|
|
147
|
-
goto error;
|
|
148
|
-
}
|
|
149
|
-
value = "1";
|
|
150
|
-
break;
|
|
151
|
-
case FIO_CLI_INT__TYPE_I:
|
|
152
|
-
if (value) {
|
|
153
|
-
char const *tmp = value;
|
|
154
|
-
fio_atol((char **)&tmp);
|
|
155
|
-
if (*tmp) {
|
|
156
|
-
goto error;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
/* fallthrough */
|
|
160
|
-
case FIO_CLI_STRING__TYPE_I:
|
|
161
|
-
if (!value)
|
|
162
|
-
goto error;
|
|
163
|
-
if (!value[0])
|
|
164
|
-
goto finish;
|
|
165
|
-
break;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/* add values using all aliases possible */
|
|
169
|
-
{
|
|
170
|
-
cstr_s n = {.data = line};
|
|
171
|
-
while (n.data[0] == '-') {
|
|
172
|
-
while (n.data[n.len] && n.data[n.len] != ' ' && n.data[n.len] != ',') {
|
|
173
|
-
++n.len;
|
|
174
|
-
}
|
|
175
|
-
fio_cli_hash_insert(&fio_values, FIO_CLI_HASH_VAL(n), n, value, NULL);
|
|
176
|
-
while (n.data[n.len] && (n.data[n.len] == ' ' || n.data[n.len] == ',')) {
|
|
177
|
-
++n.len;
|
|
178
|
-
}
|
|
179
|
-
n.data += n.len;
|
|
180
|
-
n.len = 0;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
finish:
|
|
185
|
-
|
|
186
|
-
/* handle additional argv progress (if value is on separate argv) */
|
|
187
|
-
if (value && parser->pos < parser->argc &&
|
|
188
|
-
value == parser->argv[parser->pos + 1])
|
|
189
|
-
++parser->pos;
|
|
190
|
-
return;
|
|
191
|
-
|
|
192
|
-
error: /* handle errors*/
|
|
193
|
-
/* TODO! */
|
|
194
|
-
fprintf(stderr, "\n\r\x1B[31mError:\x1B[0m unknown argument %.*s %s %s\n\n",
|
|
195
|
-
(int)arg.len, arg.data, arg.len ? "with value" : "",
|
|
196
|
-
value ? (value[0] ? value : "(empty)") : "(null)");
|
|
197
|
-
print_help:
|
|
198
|
-
fprintf(stderr, "\n%s\n",
|
|
199
|
-
parser->description ? parser->description
|
|
200
|
-
: "This application accepts any of the following "
|
|
201
|
-
"possible arguments:");
|
|
202
|
-
/* print out each line's arguments */
|
|
203
|
-
char const **pos = parser->names;
|
|
204
|
-
while (*pos) {
|
|
205
|
-
switch ((intptr_t)*pos) {
|
|
206
|
-
case FIO_CLI_STRING__TYPE_I: /* fallthrough */
|
|
207
|
-
case FIO_CLI_BOOL__TYPE_I: /* fallthrough */
|
|
208
|
-
case FIO_CLI_INT__TYPE_I: /* fallthrough */
|
|
209
|
-
case FIO_CLI_PRINT__TYPE_I: /* fallthrough */
|
|
210
|
-
case FIO_CLI_PRINT_HEADER__TYPE_I:
|
|
211
|
-
++pos;
|
|
212
|
-
continue;
|
|
213
|
-
}
|
|
214
|
-
type = (char *)FIO_CLI_STRING__TYPE_I;
|
|
215
|
-
switch ((intptr_t)pos[1]) {
|
|
216
|
-
case FIO_CLI_PRINT__TYPE_I:
|
|
217
|
-
fprintf(stderr, "%s\n", pos[0]);
|
|
218
|
-
pos += 2;
|
|
219
|
-
continue;
|
|
220
|
-
case FIO_CLI_PRINT_HEADER__TYPE_I:
|
|
221
|
-
fprintf(stderr, "\n\x1B[4m%s\x1B[0m\n", pos[0]);
|
|
222
|
-
pos += 2;
|
|
223
|
-
continue;
|
|
224
|
-
|
|
225
|
-
case FIO_CLI_STRING__TYPE_I: /* fallthrough */
|
|
226
|
-
case FIO_CLI_BOOL__TYPE_I: /* fallthrough */
|
|
227
|
-
case FIO_CLI_INT__TYPE_I: /* fallthrough */
|
|
228
|
-
type = pos[1];
|
|
229
|
-
}
|
|
230
|
-
/* print line @ pos, starting with main argument name */
|
|
231
|
-
int alias_count = 0;
|
|
232
|
-
int first_len = 0;
|
|
233
|
-
size_t tmp = 0;
|
|
234
|
-
char const *const p = *pos;
|
|
235
|
-
while (p[tmp] == '-') {
|
|
236
|
-
while (p[tmp] && p[tmp] != ' ' && p[tmp] != ',') {
|
|
237
|
-
if (!alias_count)
|
|
238
|
-
++first_len;
|
|
239
|
-
++tmp;
|
|
240
|
-
}
|
|
241
|
-
++alias_count;
|
|
242
|
-
while (p[tmp] && (p[tmp] == ' ' || p[tmp] == ',')) {
|
|
243
|
-
++tmp;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
switch ((size_t)type) {
|
|
247
|
-
case FIO_CLI_STRING__TYPE_I:
|
|
248
|
-
fprintf(stderr, " \x1B[1m%.*s\x1B[0m\x1B[2m <>\x1B[0m\t%s\n", first_len,
|
|
249
|
-
p, p + tmp);
|
|
250
|
-
break;
|
|
251
|
-
case FIO_CLI_BOOL__TYPE_I:
|
|
252
|
-
fprintf(stderr, " \x1B[1m%.*s\x1B[0m \t%s\n", first_len, p, p + tmp);
|
|
253
|
-
break;
|
|
254
|
-
case FIO_CLI_INT__TYPE_I:
|
|
255
|
-
fprintf(stderr, " \x1B[1m%.*s\x1B[0m\x1B[2m ##\x1B[0m\t%s\n", first_len,
|
|
256
|
-
p, p + tmp);
|
|
257
|
-
break;
|
|
258
|
-
}
|
|
259
|
-
/* print aliase information */
|
|
260
|
-
tmp = first_len;
|
|
261
|
-
while (p[tmp] && (p[tmp] == ' ' || p[tmp] == ',')) {
|
|
262
|
-
++tmp;
|
|
263
|
-
}
|
|
264
|
-
while (p[tmp] == '-') {
|
|
265
|
-
const size_t start = tmp;
|
|
266
|
-
while (p[tmp] && p[tmp] != ' ' && p[tmp] != ',') {
|
|
267
|
-
++tmp;
|
|
268
|
-
}
|
|
269
|
-
int padding = first_len - (tmp - start);
|
|
270
|
-
if (padding < 0)
|
|
271
|
-
padding = 0;
|
|
272
|
-
switch ((size_t)type) {
|
|
273
|
-
case FIO_CLI_STRING__TYPE_I:
|
|
274
|
-
fprintf(stderr,
|
|
275
|
-
" \x1B[1m%.*s\x1B[0m\x1B[2m <>\x1B[0m%*s\t(same as "
|
|
276
|
-
"\x1B[1m%.*s\x1B[0m)\n",
|
|
277
|
-
(int)(tmp - start), p + start, padding, "", first_len, p);
|
|
278
|
-
break;
|
|
279
|
-
case FIO_CLI_BOOL__TYPE_I:
|
|
280
|
-
fprintf(stderr,
|
|
281
|
-
" \x1B[1m%.*s\x1B[0m %*s\t(same as \x1B[1m%.*s\x1B[0m)\n",
|
|
282
|
-
(int)(tmp - start), p + start, padding, "", first_len, p);
|
|
283
|
-
break;
|
|
284
|
-
case FIO_CLI_INT__TYPE_I:
|
|
285
|
-
fprintf(stderr,
|
|
286
|
-
" \x1B[1m%.*s\x1B[0m\x1B[2m ##\x1B[0m%*s\t(same as "
|
|
287
|
-
"\x1B[1m%.*s\x1B[0m)\n",
|
|
288
|
-
(int)(tmp - start), p + start, padding, "", first_len, p);
|
|
289
|
-
break;
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
++pos;
|
|
294
|
-
}
|
|
295
|
-
fprintf(stderr, "\nUse any of the following input formats:\n"
|
|
296
|
-
"\t-arg <value>\t-arg=<value>\t-arg<value>\n"
|
|
297
|
-
"\n"
|
|
298
|
-
"Use the -h, -help or -? to get this information again.\n"
|
|
299
|
-
"\n");
|
|
300
|
-
fio_cli_end();
|
|
301
|
-
exit(0);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
static void fio_cli_end_promise(void *ignr_) {
|
|
305
|
-
/* make sure fio_cli_end is called before facil.io exists. */
|
|
306
|
-
fio_cli_end();
|
|
307
|
-
(void)ignr_;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
void fio_cli_start AVOID_MACRO(int argc, char const *argv[], int unnamed_min,
|
|
311
|
-
int unnamed_max, char const *description,
|
|
312
|
-
char const **names) {
|
|
313
|
-
static fio_lock_i run_once = FIO_LOCK_INIT;
|
|
314
|
-
if (!fio_trylock(&run_once))
|
|
315
|
-
fio_state_callback_add(FIO_CALL_AT_EXIT, fio_cli_end_promise, NULL);
|
|
316
|
-
if (unnamed_max >= 0 && unnamed_max < unnamed_min)
|
|
317
|
-
unnamed_max = unnamed_min;
|
|
318
|
-
fio_cli_parser_data_s parser = {
|
|
319
|
-
.unnamed_min = unnamed_min,
|
|
320
|
-
.unnamed_max = unnamed_max,
|
|
321
|
-
.description = description,
|
|
322
|
-
.argc = argc,
|
|
323
|
-
.argv = argv,
|
|
324
|
-
.names = names,
|
|
325
|
-
.pos = 0,
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
if (fio_cli_hash_count(&fio_values)) {
|
|
329
|
-
fio_cli_end();
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
/* prepare aliases hash map */
|
|
333
|
-
|
|
334
|
-
char const **line = names;
|
|
335
|
-
while (*line) {
|
|
336
|
-
switch ((intptr_t)*line) {
|
|
337
|
-
case FIO_CLI_STRING__TYPE_I: /* fallthrough */
|
|
338
|
-
case FIO_CLI_BOOL__TYPE_I: /* fallthrough */
|
|
339
|
-
case FIO_CLI_INT__TYPE_I: /* fallthrough */
|
|
340
|
-
case FIO_CLI_PRINT__TYPE_I: /* fallthrough */
|
|
341
|
-
case FIO_CLI_PRINT_HEADER__TYPE_I: /* fallthrough */
|
|
342
|
-
++line;
|
|
343
|
-
continue;
|
|
344
|
-
}
|
|
345
|
-
if (line[1] != (char *)FIO_CLI_PRINT__TYPE_I &&
|
|
346
|
-
line[1] != (char *)FIO_CLI_PRINT_HEADER__TYPE_I)
|
|
347
|
-
fio_cli_map_line2alias(*line);
|
|
348
|
-
++line;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/* parse existing arguments */
|
|
352
|
-
|
|
353
|
-
while ((++parser.pos) < argc) {
|
|
354
|
-
char const *value = NULL;
|
|
355
|
-
cstr_s n = {.data = argv[parser.pos], .len = strlen(argv[parser.pos])};
|
|
356
|
-
if (parser.pos + 1 < argc) {
|
|
357
|
-
value = argv[parser.pos + 1];
|
|
358
|
-
}
|
|
359
|
-
const char *l = NULL;
|
|
360
|
-
while (n.len &&
|
|
361
|
-
!(l = fio_cli_hash_find(&fio_aliases, FIO_CLI_HASH_VAL(n), n))) {
|
|
362
|
-
--n.len;
|
|
363
|
-
value = n.data + n.len;
|
|
364
|
-
}
|
|
365
|
-
if (n.len && value && value[0] == '=') {
|
|
366
|
-
++value;
|
|
367
|
-
}
|
|
368
|
-
// fprintf(stderr, "Setting %.*s to %s\n", (int)n.len, n.data, value);
|
|
369
|
-
fio_cli_set_arg(n, value, l, &parser);
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/* Cleanup and save state for API */
|
|
373
|
-
fio_cli_hash_free(&fio_aliases);
|
|
374
|
-
fio_unnamed_count = parser.unnamed_count;
|
|
375
|
-
/* test for required unnamed arguments */
|
|
376
|
-
if (parser.unnamed_count < parser.unnamed_min)
|
|
377
|
-
fio_cli_set_arg((cstr_s){.len = 0}, NULL, NULL, &parser);
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
void fio_cli_end(void) {
|
|
381
|
-
fio_cli_hash_free(&fio_values);
|
|
382
|
-
fio_cli_hash_free(&fio_aliases);
|
|
383
|
-
fio_unnamed_count = 0;
|
|
384
|
-
}
|
|
385
|
-
/* *****************************************************************************
|
|
386
|
-
CLI Data Access
|
|
387
|
-
***************************************************************************** */
|
|
388
|
-
|
|
389
|
-
/** Returns the argument's value as a NUL terminated C String. */
|
|
390
|
-
char const *fio_cli_get(char const *name) {
|
|
391
|
-
cstr_s n = {.data = name, .len = strlen(name)};
|
|
392
|
-
if (!fio_cli_hash_count(&fio_values)) {
|
|
393
|
-
return NULL;
|
|
394
|
-
}
|
|
395
|
-
char const *val = fio_cli_hash_find(&fio_values, FIO_CLI_HASH_VAL(n), n);
|
|
396
|
-
return val;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
/** Returns the argument's value as an integer. */
|
|
400
|
-
int fio_cli_get_i(char const *name) {
|
|
401
|
-
char const *val = fio_cli_get(name);
|
|
402
|
-
if (!val)
|
|
403
|
-
return 0;
|
|
404
|
-
int i = (int)fio_atol((char **)&val);
|
|
405
|
-
return i;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
/** Returns the number of unrecognized argument. */
|
|
409
|
-
unsigned int fio_cli_unnamed_count(void) {
|
|
410
|
-
return (unsigned int)fio_unnamed_count;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
/** Returns the unrecognized argument using a 0 based `index`. */
|
|
414
|
-
char const *fio_cli_unnamed(unsigned int index) {
|
|
415
|
-
if (!fio_cli_hash_count(&fio_values) || !fio_unnamed_count) {
|
|
416
|
-
return NULL;
|
|
417
|
-
}
|
|
418
|
-
cstr_s n = {.data = NULL, .len = index + 1};
|
|
419
|
-
return fio_cli_hash_find(&fio_values, index + 1, n);
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
/**
|
|
423
|
-
* Sets the argument's value as a NUL terminated C String (no copy!).
|
|
424
|
-
*
|
|
425
|
-
* Note: this does NOT copy the C strings to memory. Memory should be kept
|
|
426
|
-
* alive until `fio_cli_end` is called.
|
|
427
|
-
*/
|
|
428
|
-
void fio_cli_set(char const *name, char const *value) {
|
|
429
|
-
cstr_s n = (cstr_s){.data = name, .len = strlen(name)};
|
|
430
|
-
fio_cli_hash_insert(&fio_values, FIO_CLI_HASH_VAL(n), n, value, NULL);
|
|
431
|
-
}
|
data/ext/iodine/fio_cli.h
DELETED
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Copyright: Boaz segev, 2017
|
|
3
|
-
License: MIT
|
|
4
|
-
|
|
5
|
-
Feel free to copy, use and enjoy according to the license provided.
|
|
6
|
-
*/
|
|
7
|
-
#ifndef H_FIO_CLI_HELPER_H
|
|
8
|
-
#define H_FIO_CLI_HELPER_H
|
|
9
|
-
|
|
10
|
-
/* support C++ */
|
|
11
|
-
#ifdef __cplusplus
|
|
12
|
-
extern "C" {
|
|
13
|
-
#endif
|
|
14
|
-
|
|
15
|
-
/* *****************************************************************************
|
|
16
|
-
CLI API
|
|
17
|
-
***************************************************************************** */
|
|
18
|
-
|
|
19
|
-
/** Indicates the CLI argument should be a String (default). */
|
|
20
|
-
#define FIO_CLI_STRING(line)
|
|
21
|
-
/** Indicates the CLI argument is a Boolean value. */
|
|
22
|
-
#define FIO_CLI_BOOL(line)
|
|
23
|
-
/** Indicates the CLI argument should be an Integer (numerical). */
|
|
24
|
-
#define FIO_CLI_INT(line)
|
|
25
|
-
/** Indicates the CLI string should be printed as is. */
|
|
26
|
-
#define FIO_CLI_PRINT(line)
|
|
27
|
-
/** Indicates the CLI string should be printed as a header. */
|
|
28
|
-
#define FIO_CLI_PRINT_HEADER(line)
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* This function parses the Command Line Interface (CLI), creating a temporary
|
|
32
|
-
* "dictionary" that allows easy access to the CLI using their names or aliases.
|
|
33
|
-
*
|
|
34
|
-
* Command line arguments may be typed. If an optional type requirement is
|
|
35
|
-
* provided and the provided arument fails to match the required type, execution
|
|
36
|
-
* will end and an error message will be printed along with a short "help".
|
|
37
|
-
*
|
|
38
|
-
* The function / macro accepts the following arguments:
|
|
39
|
-
* - `argc`: command line argument count.
|
|
40
|
-
* - `argv`: command line argument list (array).
|
|
41
|
-
* - `unnamed_min`: the required minimum of un-named arguments.
|
|
42
|
-
* - `unnamed_max`: the maximum limit of un-named arguments.
|
|
43
|
-
* - `description`: a C string containing the program's description.
|
|
44
|
-
* - named arguments list: a list of C strings describing named arguments.
|
|
45
|
-
*
|
|
46
|
-
* The following optional type requirements are:
|
|
47
|
-
*
|
|
48
|
-
* * FIO_CLI_STRING(desc_line) - (default) string argument.
|
|
49
|
-
* * FIO_CLI_BOOL(desc_line) - boolean argument (no value).
|
|
50
|
-
* * FIO_CLI_INT(desc_line) - integer argument.
|
|
51
|
-
* * FIO_CLI_PRINT_HEADER(desc_line) - extra header for output.
|
|
52
|
-
* * FIO_CLI_PRINT(desc_line) - extra information for output.
|
|
53
|
-
*
|
|
54
|
-
* Argument names MUST start with the '-' character. The first word starting
|
|
55
|
-
* without the '-' character will begin the description for the CLI argument.
|
|
56
|
-
*
|
|
57
|
-
* The arguments "-?", "-h", "-help" and "--help" are automatically handled
|
|
58
|
-
* unless overridden.
|
|
59
|
-
*
|
|
60
|
-
* Un-named arguments shouldn't be listed in the named arguments list.
|
|
61
|
-
*
|
|
62
|
-
* Example use:
|
|
63
|
-
*
|
|
64
|
-
* fio_cli_start(argc, argv, 0, 0, "this example accepts the following:",
|
|
65
|
-
* FIO_CLI_PRINT_HREADER("Concurrency:"),
|
|
66
|
-
* FIO_CLI_INT("-t -thread number of threads to run."),
|
|
67
|
-
* FIO_CLI_INT("-w -workers number of workers to run."),
|
|
68
|
-
* FIO_CLI_PRINT_HREADER("Address Binding:"),
|
|
69
|
-
* "-b, -address the address to bind to.",
|
|
70
|
-
* FIO_CLI_INT("-p,-port the port to bind to."),
|
|
71
|
-
* FIO_CLI_PRINT("\t\tset port to zero (0) for Unix s."),
|
|
72
|
-
* FIO_CLI_PRINT_HREADER("Logging:"),
|
|
73
|
-
* FIO_CLI_BOOL("-v -log enable logging."));
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* This would allow access to the named arguments:
|
|
77
|
-
*
|
|
78
|
-
* fio_cli_get("-b") == fio_cli_get("-address");
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* Once all the data was accessed, free the parsed data dictionary using:
|
|
82
|
-
*
|
|
83
|
-
* fio_cli_end();
|
|
84
|
-
*
|
|
85
|
-
* It should be noted, arguments will be recognized in a number of forms, i.e.:
|
|
86
|
-
*
|
|
87
|
-
* app -t=1 -p3000 -a localhost
|
|
88
|
-
*
|
|
89
|
-
* This function is NOT thread safe.
|
|
90
|
-
*/
|
|
91
|
-
#define fio_cli_start(argc, argv, unnamed_min, unnamed_max, description, ...) \
|
|
92
|
-
fio_cli_start((argc), (argv), (unnamed_min), (unnamed_max), (description), \
|
|
93
|
-
(char const *[]){__VA_ARGS__, NULL})
|
|
94
|
-
#define FIO_CLI_IGNORE
|
|
95
|
-
/**
|
|
96
|
-
* Never use the function directly, always use the MACRO, because the macro
|
|
97
|
-
* attaches a NULL marker at the end of the `names` argument collection.
|
|
98
|
-
*/
|
|
99
|
-
void fio_cli_start FIO_CLI_IGNORE(int argc, char const *argv[], int unnamed_min,
|
|
100
|
-
int unnamed_max, char const *description,
|
|
101
|
-
char const **names);
|
|
102
|
-
/**
|
|
103
|
-
* Clears the memory used by the CLI dictionary, removing all parsed data.
|
|
104
|
-
*
|
|
105
|
-
* This function is NOT thread safe.
|
|
106
|
-
*/
|
|
107
|
-
void fio_cli_end(void);
|
|
108
|
-
|
|
109
|
-
/** Returns the argument's value as a NUL terminated C String. */
|
|
110
|
-
char const *fio_cli_get(char const *name);
|
|
111
|
-
|
|
112
|
-
/** Returns the argument's value as an integer. */
|
|
113
|
-
int fio_cli_get_i(char const *name);
|
|
114
|
-
|
|
115
|
-
/** This MACRO returns the argument's value as a boolean. */
|
|
116
|
-
#define fio_cli_get_bool(name) (fio_cli_get((name)) != NULL)
|
|
117
|
-
|
|
118
|
-
/** Returns the number of unnamed argument. */
|
|
119
|
-
unsigned int fio_cli_unnamed_count(void);
|
|
120
|
-
|
|
121
|
-
/** Returns the unnamed argument using a 0 based `index`. */
|
|
122
|
-
char const *fio_cli_unnamed(unsigned int index);
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Sets the argument's value as a NUL terminated C String (no copy!).
|
|
126
|
-
*
|
|
127
|
-
* CAREFUL: This does not automatically detect aliases or type violations! it
|
|
128
|
-
* will only effect the specific name given, even if invalid. i.e.:
|
|
129
|
-
*
|
|
130
|
-
* fio_cli_start(argc, argv,
|
|
131
|
-
* "this is example accepts the following options:",
|
|
132
|
-
* "-p -port the port to bind to", FIO_CLI_INT;
|
|
133
|
-
*
|
|
134
|
-
* fio_cli_set("-p", "hello"); // fio_cli_get("-p") != fio_cli_get("-port");
|
|
135
|
-
*
|
|
136
|
-
* Note: this does NOT copy the C strings to memory. Memory should be kept alive
|
|
137
|
-
* until `fio_cli_end` is called.
|
|
138
|
-
*
|
|
139
|
-
* This function is NOT thread safe.
|
|
140
|
-
*/
|
|
141
|
-
void fio_cli_set(char const *name, char const *value);
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* This MACRO is the same as:
|
|
145
|
-
*
|
|
146
|
-
* if(!fio_cli_get(name)) {
|
|
147
|
-
* fio_cli_set(name, value)
|
|
148
|
-
* }
|
|
149
|
-
*
|
|
150
|
-
* See fio_cli_set for notes and restrictions.
|
|
151
|
-
*/
|
|
152
|
-
#define fio_cli_set_default(name, value) \
|
|
153
|
-
if (!fio_cli_get((name))) \
|
|
154
|
-
fio_cli_set(name, value);
|
|
155
|
-
|
|
156
|
-
#ifdef __cplusplus
|
|
157
|
-
} /* extern "C" */
|
|
158
|
-
#endif
|
|
159
|
-
|
|
160
|
-
/* *****************************************************************************
|
|
161
|
-
Internal Macro Implementation
|
|
162
|
-
***************************************************************************** */
|
|
163
|
-
|
|
164
|
-
/** Used internally. */
|
|
165
|
-
#define FIO_CLI_STRING__TYPE_I 0x1
|
|
166
|
-
#define FIO_CLI_BOOL__TYPE_I 0x2
|
|
167
|
-
#define FIO_CLI_INT__TYPE_I 0x3
|
|
168
|
-
#define FIO_CLI_PRINT__TYPE_I 0x4
|
|
169
|
-
#define FIO_CLI_PRINT_HEADER__TYPE_I 0x5
|
|
170
|
-
|
|
171
|
-
#undef FIO_CLI_STRING
|
|
172
|
-
#undef FIO_CLI_BOOL
|
|
173
|
-
#undef FIO_CLI_INT
|
|
174
|
-
#undef FIO_CLI_PRINT
|
|
175
|
-
#undef FIO_CLI_PRINT_HEADER
|
|
176
|
-
|
|
177
|
-
/** Indicates the CLI argument should be a String (default). */
|
|
178
|
-
#define FIO_CLI_STRING(line) (line), ((char *)FIO_CLI_STRING__TYPE_I)
|
|
179
|
-
/** Indicates the CLI argument is a Boolean value. */
|
|
180
|
-
#define FIO_CLI_BOOL(line) (line), ((char *)FIO_CLI_BOOL__TYPE_I)
|
|
181
|
-
/** Indicates the CLI argument should be an Integer (numerical). */
|
|
182
|
-
#define FIO_CLI_INT(line) (line), ((char *)FIO_CLI_INT__TYPE_I)
|
|
183
|
-
/** Indicates the CLI string should be printed as is. */
|
|
184
|
-
#define FIO_CLI_PRINT(line) (line), ((char *)FIO_CLI_PRINT__TYPE_I)
|
|
185
|
-
/** Indicates the CLI string should be printed as a header. */
|
|
186
|
-
#define FIO_CLI_PRINT_HEADER(line) \
|
|
187
|
-
(line), ((char *)FIO_CLI_PRINT_HEADER__TYPE_I)
|
|
188
|
-
|
|
189
|
-
#endif
|