iodine 0.7.59 → 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.
Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/.clang-format +15 -0
  3. data/.rspec +1 -0
  4. data/.yardopts +1 -3
  5. data/CHANGELOG.md +132 -12
  6. data/Gemfile +5 -7
  7. data/LICENSE.txt +1 -1
  8. data/README.md +147 -671
  9. data/Rakefile +9 -16
  10. data/examples/chatroom.nru +9 -0
  11. data/examples/client +74 -0
  12. data/examples/config-hello.nru +9 -0
  13. data/examples/config-hello.ru +11 -0
  14. data/examples/config-hijack.ru +13 -0
  15. data/examples/config-shootout.ru +43 -0
  16. data/examples/config.nru +120 -0
  17. data/examples/config.rb +37 -0
  18. data/examples/config.ru +42 -53
  19. data/examples/fake +24 -0
  20. data/examples/hello_neorack +137 -0
  21. data/examples/routes.nru +29 -0
  22. data/examples/routes.ru +42 -0
  23. data/exe/iodine +218 -258
  24. data/ext/iodine/extconf.rb +27 -100
  25. data/ext/iodine/fio-stl.h +128336 -0
  26. data/ext/iodine/fio-stl.md +26396 -0
  27. data/ext/iodine/iodine.c +213 -1393
  28. data/ext/iodine/iodine.h +250 -55
  29. data/ext/iodine/iodine_arg_helper.h +329 -0
  30. data/ext/iodine/iodine_caller.h +234 -25
  31. data/ext/iodine/iodine_cli.h +434 -0
  32. data/ext/iodine/iodine_compression.h +312 -0
  33. data/ext/iodine/iodine_connection.h +3484 -34
  34. data/ext/iodine/iodine_core.h +363 -0
  35. data/ext/iodine/iodine_crypto.h +1441 -0
  36. data/ext/iodine/iodine_defer.h +225 -4
  37. data/ext/iodine/iodine_json.h +738 -4
  38. data/ext/iodine/iodine_listener.h +263 -0
  39. data/ext/iodine/iodine_log.h +297 -0
  40. data/ext/iodine/iodine_minimap.h +543 -0
  41. data/ext/iodine/iodine_mustache.h +461 -4
  42. data/ext/iodine/iodine_pubsub_eng.h +729 -0
  43. data/ext/iodine/iodine_pubsub_history.h +547 -0
  44. data/ext/iodine/iodine_pubsub_msg.h +228 -0
  45. data/ext/iodine/iodine_redis.h +322 -0
  46. data/ext/iodine/iodine_store.h +418 -16
  47. data/ext/iodine/iodine_threads.h +279 -0
  48. data/ext/iodine/iodine_tls.h +515 -6
  49. data/ext/iodine/iodine_utils.h +923 -0
  50. data/iodine.gemspec +37 -42
  51. data/lib/iodine/benchmark.rb +1690 -0
  52. data/lib/iodine/documentation.rb +3085 -0
  53. data/lib/iodine/version.rb +17 -1
  54. data/lib/iodine.rb +54 -255
  55. data/logo.svg +36 -0
  56. data/mustache.md +55 -0
  57. data/sig/iodine.rbs +4 -0
  58. metadata +58 -184
  59. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -40
  60. data/.github/workflows/ruby.yml +0 -42
  61. data/.gitignore +0 -20
  62. data/LIMITS.md +0 -41
  63. data/SPEC-PubSub-Draft.md +0 -159
  64. data/SPEC-WebSocket-Draft.md +0 -239
  65. data/bin/console +0 -22
  66. data/bin/info.md +0 -353
  67. data/bin/mustache_bench.rb +0 -100
  68. data/bin/poc/Gemfile.lock +0 -23
  69. data/bin/poc/README.md +0 -37
  70. data/bin/poc/config.ru +0 -66
  71. data/bin/poc/gemfile +0 -1
  72. data/bin/poc/www/index.html +0 -57
  73. data/examples/async_task.ru +0 -92
  74. data/examples/bates/README.md +0 -3
  75. data/examples/bates/config.ru +0 -342
  76. data/examples/bates/david+bold.pdf +0 -0
  77. data/examples/bates/public/drop-pdf.png +0 -0
  78. data/examples/bates/public/index.html +0 -600
  79. data/examples/echo.ru +0 -59
  80. data/examples/etag.ru +0 -16
  81. data/examples/hello.ru +0 -29
  82. data/examples/pubsub_engine.ru +0 -81
  83. data/examples/rack3.ru +0 -12
  84. data/examples/redis.ru +0 -70
  85. data/examples/shootout.ru +0 -73
  86. data/examples/sub-protocols.ru +0 -90
  87. data/examples/tcp_client.rb +0 -66
  88. data/examples/x-sendfile.ru +0 -14
  89. data/ext/iodine/fio.c +0 -11995
  90. data/ext/iodine/fio.h +0 -6371
  91. data/ext/iodine/fio_cli.c +0 -431
  92. data/ext/iodine/fio_cli.h +0 -189
  93. data/ext/iodine/fio_json_parser.h +0 -688
  94. data/ext/iodine/fio_siphash.c +0 -157
  95. data/ext/iodine/fio_siphash.h +0 -37
  96. data/ext/iodine/fio_tls.h +0 -129
  97. data/ext/iodine/fio_tls_missing.c +0 -649
  98. data/ext/iodine/fio_tls_openssl.c +0 -1106
  99. data/ext/iodine/fio_tmpfile.h +0 -50
  100. data/ext/iodine/fiobj.h +0 -44
  101. data/ext/iodine/fiobj4fio.h +0 -21
  102. data/ext/iodine/fiobj_ary.c +0 -333
  103. data/ext/iodine/fiobj_ary.h +0 -139
  104. data/ext/iodine/fiobj_data.c +0 -1187
  105. data/ext/iodine/fiobj_data.h +0 -167
  106. data/ext/iodine/fiobj_hash.c +0 -409
  107. data/ext/iodine/fiobj_hash.h +0 -176
  108. data/ext/iodine/fiobj_json.c +0 -622
  109. data/ext/iodine/fiobj_json.h +0 -68
  110. data/ext/iodine/fiobj_mem.h +0 -71
  111. data/ext/iodine/fiobj_mustache.c +0 -317
  112. data/ext/iodine/fiobj_mustache.h +0 -62
  113. data/ext/iodine/fiobj_numbers.c +0 -344
  114. data/ext/iodine/fiobj_numbers.h +0 -127
  115. data/ext/iodine/fiobj_str.c +0 -433
  116. data/ext/iodine/fiobj_str.h +0 -172
  117. data/ext/iodine/fiobject.c +0 -620
  118. data/ext/iodine/fiobject.h +0 -655
  119. data/ext/iodine/hpack.h +0 -1923
  120. data/ext/iodine/http.c +0 -2743
  121. data/ext/iodine/http.h +0 -1002
  122. data/ext/iodine/http1.c +0 -910
  123. data/ext/iodine/http1.h +0 -29
  124. data/ext/iodine/http1_parser.h +0 -878
  125. data/ext/iodine/http_internal.c +0 -1279
  126. data/ext/iodine/http_internal.h +0 -237
  127. data/ext/iodine/http_mime_parser.h +0 -350
  128. data/ext/iodine/iodine_caller.c +0 -230
  129. data/ext/iodine/iodine_connection.c +0 -941
  130. data/ext/iodine/iodine_defer.c +0 -420
  131. data/ext/iodine/iodine_fiobj2rb.h +0 -120
  132. data/ext/iodine/iodine_helpers.c +0 -282
  133. data/ext/iodine/iodine_helpers.h +0 -12
  134. data/ext/iodine/iodine_http.c +0 -1181
  135. data/ext/iodine/iodine_http.h +0 -23
  136. data/ext/iodine/iodine_json.c +0 -302
  137. data/ext/iodine/iodine_mustache.c +0 -567
  138. data/ext/iodine/iodine_pubsub.c +0 -580
  139. data/ext/iodine/iodine_pubsub.h +0 -26
  140. data/ext/iodine/iodine_rack_io.c +0 -273
  141. data/ext/iodine/iodine_rack_io.h +0 -20
  142. data/ext/iodine/iodine_store.c +0 -146
  143. data/ext/iodine/iodine_tcp.c +0 -346
  144. data/ext/iodine/iodine_tcp.h +0 -13
  145. data/ext/iodine/iodine_tls.c +0 -261
  146. data/ext/iodine/mustache_parser.h +0 -1546
  147. data/ext/iodine/redis_engine.c +0 -957
  148. data/ext/iodine/redis_engine.h +0 -79
  149. data/ext/iodine/resp_parser.h +0 -317
  150. data/ext/iodine/websocket_parser.h +0 -506
  151. data/ext/iodine/websockets.c +0 -743
  152. data/ext/iodine/websockets.h +0 -185
  153. data/lib/iodine/connection.rb +0 -61
  154. data/lib/iodine/json.rb +0 -42
  155. data/lib/iodine/mustache.rb +0 -113
  156. data/lib/iodine/pubsub.rb +0 -55
  157. data/lib/iodine/rack_utils.rb +0 -43
  158. data/lib/iodine/tls.rb +0 -16
  159. data/lib/rack/handler/iodine.rb +0 -33
  160. 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