iodine 0.4.19 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of iodine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +1 -2
- data/CHANGELOG.md +22 -0
- data/LIMITS.md +19 -9
- data/README.md +92 -77
- data/SPEC-PubSub-Draft.md +113 -0
- data/SPEC-Websocket-Draft.md +127 -143
- data/bin/http-hello +0 -1
- data/bin/raw-rbhttp +1 -1
- data/bin/raw_broadcast +8 -10
- data/bin/updated api +2 -2
- data/bin/ws-broadcast +2 -4
- data/bin/ws-echo +2 -2
- data/examples/config.ru +13 -13
- data/examples/echo.ru +5 -6
- data/examples/hello.ru +2 -3
- data/examples/info.md +316 -0
- data/examples/pubsub_engine.ru +81 -0
- data/examples/redis.ru +9 -9
- data/examples/shootout.ru +45 -11
- data/ext/iodine/defer.c +194 -297
- data/ext/iodine/defer.h +61 -53
- data/ext/iodine/evio.c +0 -260
- data/ext/iodine/evio.h +50 -22
- data/ext/iodine/evio_callbacks.c +26 -0
- data/ext/iodine/evio_epoll.c +251 -0
- data/ext/iodine/evio_kqueue.c +193 -0
- data/ext/iodine/extconf.rb +1 -1
- data/ext/iodine/facil.c +1420 -542
- data/ext/iodine/facil.h +151 -64
- data/ext/iodine/fio_ary.h +418 -0
- data/ext/iodine/{base64.c → fio_base64.c} +33 -24
- data/ext/iodine/{base64.h → fio_base64.h} +6 -7
- data/ext/iodine/{fio_cli_helper.c → fio_cli.c} +77 -58
- data/ext/iodine/{fio_cli_helper.h → fio_cli.h} +9 -4
- data/ext/iodine/fio_hashmap.h +759 -0
- data/ext/iodine/fio_json_parser.h +651 -0
- data/ext/iodine/fio_llist.h +257 -0
- data/ext/iodine/fio_mem.c +672 -0
- data/ext/iodine/fio_mem.h +140 -0
- data/ext/iodine/fio_random.c +248 -0
- data/ext/iodine/{random.h → fio_random.h} +11 -14
- data/ext/iodine/{sha1.c → fio_sha1.c} +28 -24
- data/ext/iodine/{sha1.h → fio_sha1.h} +38 -16
- data/ext/iodine/{sha2.c → fio_sha2.c} +66 -49
- data/ext/iodine/{sha2.h → fio_sha2.h} +57 -26
- data/ext/iodine/{fiobj_internal.c → fio_siphash.c} +9 -90
- data/ext/iodine/fio_siphash.h +18 -0
- data/ext/iodine/fio_tmpfile.h +38 -0
- data/ext/iodine/fiobj.h +24 -7
- data/ext/iodine/fiobj4sock.h +23 -0
- data/ext/iodine/fiobj_ary.c +143 -226
- data/ext/iodine/fiobj_ary.h +17 -16
- data/ext/iodine/fiobj_data.c +1160 -0
- data/ext/iodine/fiobj_data.h +164 -0
- data/ext/iodine/fiobj_hash.c +298 -406
- data/ext/iodine/fiobj_hash.h +101 -54
- data/ext/iodine/fiobj_json.c +478 -601
- data/ext/iodine/fiobj_json.h +34 -9
- data/ext/iodine/fiobj_numbers.c +383 -51
- data/ext/iodine/fiobj_numbers.h +87 -11
- data/ext/iodine/fiobj_str.c +423 -184
- data/ext/iodine/fiobj_str.h +81 -32
- data/ext/iodine/fiobject.c +273 -522
- data/ext/iodine/fiobject.h +477 -112
- data/ext/iodine/http.c +2243 -83
- data/ext/iodine/http.h +842 -121
- data/ext/iodine/http1.c +810 -385
- data/ext/iodine/http1.h +16 -39
- data/ext/iodine/http1_parser.c +146 -74
- data/ext/iodine/http1_parser.h +15 -4
- data/ext/iodine/http_internal.c +1258 -0
- data/ext/iodine/http_internal.h +226 -0
- data/ext/iodine/http_mime_parser.h +341 -0
- data/ext/iodine/iodine.c +86 -68
- data/ext/iodine/iodine.h +26 -11
- data/ext/iodine/iodine_helpers.c +8 -7
- data/ext/iodine/iodine_http.c +487 -324
- data/ext/iodine/iodine_json.c +304 -0
- data/ext/iodine/iodine_json.h +6 -0
- data/ext/iodine/iodine_protocol.c +107 -45
- data/ext/iodine/iodine_pubsub.c +526 -225
- data/ext/iodine/iodine_pubsub.h +10 -0
- data/ext/iodine/iodine_websockets.c +268 -510
- data/ext/iodine/iodine_websockets.h +2 -4
- data/ext/iodine/pubsub.c +726 -432
- data/ext/iodine/pubsub.h +85 -103
- data/ext/iodine/rb-call.c +4 -4
- data/ext/iodine/rb-defer.c +46 -22
- data/ext/iodine/rb-fiobj2rb.h +117 -0
- data/ext/iodine/rb-rack-io.c +73 -238
- data/ext/iodine/rb-rack-io.h +2 -2
- data/ext/iodine/rb-registry.c +35 -93
- data/ext/iodine/rb-registry.h +1 -0
- data/ext/iodine/redis_engine.c +742 -304
- data/ext/iodine/redis_engine.h +42 -39
- data/ext/iodine/resp_parser.h +311 -0
- data/ext/iodine/sock.c +627 -490
- data/ext/iodine/sock.h +345 -297
- data/ext/iodine/spnlock.inc +15 -4
- data/ext/iodine/websocket_parser.h +16 -20
- data/ext/iodine/websockets.c +188 -257
- data/ext/iodine/websockets.h +24 -133
- data/lib/iodine.rb +52 -7
- data/lib/iodine/cli.rb +6 -24
- data/lib/iodine/json.rb +40 -0
- data/lib/iodine/version.rb +1 -1
- data/lib/iodine/websocket.rb +5 -3
- data/lib/rack/handler/iodine.rb +58 -13
- metadata +38 -48
- data/bin/ws-shootout +0 -107
- data/examples/broadcast.ru +0 -56
- data/ext/iodine/bscrypt-common.h +0 -116
- data/ext/iodine/bscrypt.h +0 -49
- data/ext/iodine/fio2resp.c +0 -60
- data/ext/iodine/fio2resp.h +0 -51
- data/ext/iodine/fio_dict.c +0 -446
- data/ext/iodine/fio_dict.h +0 -99
- data/ext/iodine/fio_hash_table.h +0 -370
- data/ext/iodine/fio_list.h +0 -111
- data/ext/iodine/fiobj_internal.h +0 -280
- data/ext/iodine/fiobj_primitives.c +0 -131
- data/ext/iodine/fiobj_primitives.h +0 -55
- data/ext/iodine/fiobj_sym.c +0 -135
- data/ext/iodine/fiobj_sym.h +0 -60
- data/ext/iodine/hex.c +0 -124
- data/ext/iodine/hex.h +0 -70
- data/ext/iodine/http1_request.c +0 -81
- data/ext/iodine/http1_request.h +0 -58
- data/ext/iodine/http1_response.c +0 -417
- data/ext/iodine/http1_response.h +0 -95
- data/ext/iodine/http_request.c +0 -111
- data/ext/iodine/http_request.h +0 -102
- data/ext/iodine/http_response.c +0 -1703
- data/ext/iodine/http_response.h +0 -250
- data/ext/iodine/misc.c +0 -182
- data/ext/iodine/misc.h +0 -74
- data/ext/iodine/random.c +0 -208
- data/ext/iodine/redis_connection.c +0 -278
- data/ext/iodine/redis_connection.h +0 -86
- data/ext/iodine/resp.c +0 -842
- data/ext/iodine/resp.h +0 -261
- data/ext/iodine/siphash.c +0 -154
- data/ext/iodine/siphash.h +0 -22
- data/ext/iodine/xor-crypt.c +0 -193
- data/ext/iodine/xor-crypt.h +0 -107
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
Copyright: Boaz
|
2
|
+
Copyright: Boaz Segev, 2016-2018
|
3
3
|
License: MIT except for any non-public-domain algorithms (none that I'm aware
|
4
4
|
of), which might be subject to their own licenses.
|
5
5
|
|
@@ -8,11 +8,13 @@ Feel free to copy, use and enjoy in accordance with to the license(s).
|
|
8
8
|
#ifndef _GNU_SOURCE
|
9
9
|
#define _GNU_SOURCE
|
10
10
|
#endif
|
11
|
-
#include "
|
11
|
+
#include "fio_base64.h"
|
12
12
|
|
13
|
-
|
13
|
+
#include <stdint.h>
|
14
|
+
#include <stdlib.h>
|
15
|
+
/* ****************************************************************************
|
14
16
|
Base64 encoding
|
15
|
-
*/
|
17
|
+
***************************************************************************** */
|
16
18
|
|
17
19
|
/** the base64 encoding array */
|
18
20
|
static char base64_encodes[] =
|
@@ -53,7 +55,7 @@ Returns the number of bytes actually written to the target buffer
|
|
53
55
|
|
54
56
|
A NULL terminator char is NOT written to the target buffer.
|
55
57
|
*/
|
56
|
-
int
|
58
|
+
int fio_base64_encode(char *target, const char *data, int len) {
|
57
59
|
/* walk backwards, allowing fo inplace decoding (target == data) */
|
58
60
|
int groups = len / 3;
|
59
61
|
const int mod = len - (groups * 3);
|
@@ -110,7 +112,7 @@ be, at least, `base64_len/4*3 + 3` long.
|
|
110
112
|
Returns the number of bytes actually written to the target buffer (excluding
|
111
113
|
the NULL terminator byte).
|
112
114
|
*/
|
113
|
-
int
|
115
|
+
int fio_base64_decode(char *target, char *encoded, int base64_len) {
|
114
116
|
if (!target)
|
115
117
|
target = encoded;
|
116
118
|
if (base64_len <= 0) {
|
@@ -192,11 +194,15 @@ int bscrypt_base64_decode(char *target, char *encoded, int base64_len) {
|
|
192
194
|
return written;
|
193
195
|
}
|
194
196
|
|
195
|
-
|
196
|
-
Base64
|
197
|
-
*/
|
197
|
+
/* *****************************************************************************
|
198
|
+
Base64 Testing
|
199
|
+
***************************************************************************** */
|
198
200
|
#if defined(DEBUG) && DEBUG == 1
|
199
|
-
|
201
|
+
#include <stdio.h>
|
202
|
+
#include <string.h>
|
203
|
+
#include <time.h>
|
204
|
+
|
205
|
+
void fio_base64_test(void) {
|
200
206
|
struct {
|
201
207
|
char *str;
|
202
208
|
char *base64;
|
@@ -226,12 +232,12 @@ void bscrypt_test_base64(void) {
|
|
226
232
|
};
|
227
233
|
int i = 0;
|
228
234
|
char buffer[1024];
|
229
|
-
fprintf(stderr, "+
|
235
|
+
fprintf(stderr, "+ fio");
|
230
236
|
while (sets[i].str) {
|
231
|
-
|
237
|
+
fio_base64_encode(buffer, sets[i].str, strlen(sets[i].str));
|
232
238
|
if (strcmp(buffer, sets[i].base64)) {
|
233
239
|
fprintf(stderr,
|
234
|
-
":\n---
|
240
|
+
":\n--- fio Base64 Test FAILED!\nstring: %s\nlength: %lu\n "
|
235
241
|
"expected: %s\ngot: %s\n\n",
|
236
242
|
sets[i].str, strlen(sets[i].str), sets[i].base64, buffer);
|
237
243
|
break;
|
@@ -242,12 +248,12 @@ void bscrypt_test_base64(void) {
|
|
242
248
|
fprintf(stderr, " Base64 encode passed.\n");
|
243
249
|
|
244
250
|
i = 0;
|
245
|
-
fprintf(stderr, "+
|
251
|
+
fprintf(stderr, "+ fio");
|
246
252
|
while (sets[i].str) {
|
247
|
-
|
253
|
+
fio_base64_decode(buffer, sets[i].base64, strlen(sets[i].base64));
|
248
254
|
if (strcmp(buffer, sets[i].str)) {
|
249
255
|
fprintf(stderr,
|
250
|
-
":\n---
|
256
|
+
":\n--- fio Base64 Test FAILED!\nbase64: %s\nexpected: "
|
251
257
|
"%s\ngot: %s\n\n",
|
252
258
|
sets[i].base64, sets[i].str, buffer);
|
253
259
|
return;
|
@@ -255,14 +261,17 @@ void bscrypt_test_base64(void) {
|
|
255
261
|
i++;
|
256
262
|
}
|
257
263
|
fprintf(stderr, " Base64 decode passed.\n");
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
+
{
|
265
|
+
char buff_b64[] = "any carnal pleasure.";
|
266
|
+
clock_t start = clock();
|
267
|
+
for (i = 0; i < 100000; i++) {
|
268
|
+
size_t b64_len =
|
269
|
+
fio_base64_encode(buffer, buff_b64, sizeof(buff_b64) - 1);
|
270
|
+
fio_base64_decode(buff_b64, buffer, b64_len);
|
271
|
+
}
|
272
|
+
fprintf(stderr, "fio 100K Base64: %lf\n",
|
273
|
+
(double)(clock() - start) / CLOCKS_PER_SEC);
|
274
|
+
(void)buff_b64;
|
264
275
|
}
|
265
|
-
fprintf(stderr, "bscrypt 100K Base64: %lf\n",
|
266
|
-
(double)(clock() - start) / CLOCKS_PER_SEC);
|
267
276
|
}
|
268
277
|
#endif
|
@@ -1,13 +1,12 @@
|
|
1
1
|
/*
|
2
|
-
Copyright: Boaz
|
2
|
+
Copyright: Boaz Segev, 2016-2018
|
3
3
|
License: MIT except for any non-public-domain algorithms (none that I'm aware
|
4
4
|
of), which might be subject to their own licenses.
|
5
5
|
|
6
6
|
Feel free to copy, use and enjoy in accordance with to the license(s).
|
7
7
|
*/
|
8
|
-
#ifndef
|
9
|
-
#define
|
10
|
-
#include "bscrypt-common.h"
|
8
|
+
#ifndef H_FIO_BASE64_H
|
9
|
+
#define H_FIO_BASE64_H
|
11
10
|
/* *****************************************************************************
|
12
11
|
C++ extern
|
13
12
|
*/
|
@@ -35,7 +34,7 @@ Returns the number of bytes actually written to the target buffer
|
|
35
34
|
|
36
35
|
A NULL terminator char is NOT written to the target buffer.
|
37
36
|
*/
|
38
|
-
int
|
37
|
+
int fio_base64_encode(char *target, const char *data, int len);
|
39
38
|
|
40
39
|
/**
|
41
40
|
This will decode a Base64 encoded string of a specified length (len) and
|
@@ -56,10 +55,10 @@ be, at least, `base64_len/4*3 + 3` long.
|
|
56
55
|
Returns the number of bytes actually written to the target buffer (excluding
|
57
56
|
the NULL terminator byte).
|
58
57
|
*/
|
59
|
-
int
|
58
|
+
int fio_base64_decode(char *target, char *encoded, int base64_len);
|
60
59
|
|
61
60
|
#if defined(DEBUG) && DEBUG == 1
|
62
|
-
void
|
61
|
+
void fio_base64_test(void);
|
63
62
|
#endif
|
64
63
|
|
65
64
|
/* *****************************************************************************
|
@@ -4,7 +4,7 @@ License: MIT
|
|
4
4
|
|
5
5
|
Feel free to copy, use and enjoy according to the license provided.
|
6
6
|
*/
|
7
|
-
#include "
|
7
|
+
#include "fio_cli.h"
|
8
8
|
#include "fiobj.h"
|
9
9
|
|
10
10
|
#include <string.h>
|
@@ -13,14 +13,15 @@ State (static data)
|
|
13
13
|
***************************************************************************** */
|
14
14
|
|
15
15
|
/* static variables are automatically initialized to 0, which is what we need.*/
|
16
|
-
static int
|
17
|
-
static const char **
|
18
|
-
static
|
19
|
-
static
|
20
|
-
static
|
21
|
-
static
|
22
|
-
static
|
16
|
+
static int FIO_CLI_ARGC;
|
17
|
+
static const char **FIO_CLI_ARGV;
|
18
|
+
static FIOBJ arg_aliases; /* a hash for translating aliases */
|
19
|
+
static FIOBJ arg_type; /* a with information about each argument */
|
20
|
+
static FIOBJ parsed; /* a with information about each argument */
|
21
|
+
static FIOBJ help_str; /* The CLI help string */
|
22
|
+
static FIOBJ info_str; /* The CLI information string */
|
23
23
|
static int is_parsed;
|
24
|
+
static int ignore_unknown;
|
24
25
|
|
25
26
|
const char DEFAULT_CLI_INFO[] =
|
26
27
|
"This application accepts any of the following possible arguments:";
|
@@ -28,7 +29,12 @@ const char DEFAULT_CLI_INFO[] =
|
|
28
29
|
Error / Help handling - printing the information and exiting.
|
29
30
|
***************************************************************************** */
|
30
31
|
|
32
|
+
/** Tells the CLI helper to ignore invalid command line arguments. */
|
33
|
+
void fio_cli_ignore_unknown(void) { ignore_unknown = 1; }
|
34
|
+
|
31
35
|
static void fio_cli_handle_error(void) {
|
36
|
+
if (ignore_unknown)
|
37
|
+
return;
|
32
38
|
fio_cstr_s info = fiobj_obj2cstr(info_str);
|
33
39
|
fio_cstr_s args = fiobj_obj2cstr(help_str);
|
34
40
|
fprintf(stdout,
|
@@ -53,7 +59,7 @@ static void fio_cli_init(void) {
|
|
53
59
|
/* if init is called after parsing, discard previous result */
|
54
60
|
if (parsed) {
|
55
61
|
fiobj_free(parsed);
|
56
|
-
parsed =
|
62
|
+
parsed = FIOBJ_INVALID;
|
57
63
|
}
|
58
64
|
/* avoid overwriting existing data */
|
59
65
|
if (arg_aliases)
|
@@ -62,7 +68,7 @@ static void fio_cli_init(void) {
|
|
62
68
|
arg_type = fiobj_hash_new();
|
63
69
|
help_str = fiobj_str_buf(1024);
|
64
70
|
if (!info_str) /* might exist through `fio_cli_start` */
|
65
|
-
info_str =
|
71
|
+
info_str = fiobj_str_new(DEFAULT_CLI_INFO, sizeof(DEFAULT_CLI_INFO) - 1);
|
66
72
|
}
|
67
73
|
|
68
74
|
/* *****************************************************************************
|
@@ -70,8 +76,9 @@ Matching arguments to C string
|
|
70
76
|
***************************************************************************** */
|
71
77
|
|
72
78
|
/* returns the primamry symbol for the argument, of NULL (if none) */
|
73
|
-
static inline
|
74
|
-
|
79
|
+
static inline FIOBJ fio_cli_get_name(const char *str, size_t len) {
|
80
|
+
const uint64_t key = fio_siphash(str, len);
|
81
|
+
return fiobj_hash_get2(arg_aliases, key);
|
75
82
|
}
|
76
83
|
|
77
84
|
/* *****************************************************************************
|
@@ -81,8 +88,7 @@ typedef enum { CLI_BOOL, CLI_NUM, CLI_STR } cli_type;
|
|
81
88
|
static void fio_cli_set(const char *aliases, const char *desc, cli_type type) {
|
82
89
|
fio_cli_init();
|
83
90
|
const char *start = aliases;
|
84
|
-
|
85
|
-
fiobj_s *arg_name = NULL;
|
91
|
+
FIOBJ arg_name = FIOBJ_INVALID;
|
86
92
|
|
87
93
|
while (1) {
|
88
94
|
/* get rid of any white space or commas */
|
@@ -91,41 +97,43 @@ static void fio_cli_set(const char *aliases, const char *desc, cli_type type) {
|
|
91
97
|
/* we're done */
|
92
98
|
if (!start[0])
|
93
99
|
return;
|
94
|
-
len = 0;
|
100
|
+
size_t len = 0;
|
95
101
|
/* find the length of the argument name */
|
96
102
|
while (start[len] != 0 && start[len] != ' ' && start[len] != ',')
|
97
103
|
len++;
|
98
104
|
|
99
105
|
if (!arg_name) {
|
100
106
|
/* this is the main identifier */
|
101
|
-
arg_name =
|
107
|
+
arg_name = fiobj_str_new(start, len);
|
102
108
|
/* add to aliases hash */
|
103
109
|
fiobj_hash_set(arg_aliases, arg_name, arg_name);
|
104
110
|
/* add the help section and set type*/
|
105
111
|
switch (type) {
|
106
112
|
case CLI_BOOL:
|
107
|
-
fiobj_str_write2(help_str, "\t\
|
113
|
+
fiobj_str_write2(help_str, "\t\x1B[1m-%s\x1B[0m\t\t%s\n",
|
108
114
|
fiobj_obj2cstr(arg_name).data, desc);
|
109
115
|
fiobj_hash_set(arg_type, arg_name, fiobj_null());
|
110
116
|
break;
|
111
117
|
case CLI_NUM:
|
112
|
-
fiobj_str_write2(help_str,
|
118
|
+
fiobj_str_write2(help_str,
|
119
|
+
"\t\x1B[1m-%s\x1B[0m\x1B[2m ###\x1B[0m\t%s\n",
|
113
120
|
fiobj_obj2cstr(arg_name).data, desc);
|
114
121
|
fiobj_hash_set(arg_type, arg_name, fiobj_true());
|
115
122
|
break;
|
116
123
|
case CLI_STR:
|
117
|
-
fiobj_str_write2(help_str,
|
124
|
+
fiobj_str_write2(help_str,
|
125
|
+
"\t\x1B[1m-%s\x1B[0m\x1B[2m <val>\x1B[0m\t%s\n",
|
118
126
|
fiobj_obj2cstr(arg_name).data, desc);
|
119
127
|
fiobj_hash_set(arg_type, arg_name, fiobj_false());
|
120
128
|
break;
|
121
129
|
}
|
122
130
|
} else {
|
123
131
|
/* this is an alias */
|
124
|
-
|
132
|
+
FIOBJ tmp = fiobj_str_new(start, len);
|
125
133
|
/* add to aliases hash */
|
126
134
|
fiobj_hash_set(arg_aliases, tmp, fiobj_dup(arg_name));
|
127
135
|
/* add to description + free it*/
|
128
|
-
fiobj_str_write2(help_str, "\t\t\
|
136
|
+
fiobj_str_write2(help_str, "\t\t\x1B[1m-%s\x1B[0m\tsame as -%s\n",
|
129
137
|
fiobj_obj2cstr(tmp).data, fiobj_obj2cstr(arg_name).data);
|
130
138
|
fiobj_free(tmp);
|
131
139
|
}
|
@@ -138,7 +146,7 @@ parsing the arguments
|
|
138
146
|
***************************************************************************** */
|
139
147
|
|
140
148
|
static void fio_cli_parse(void) {
|
141
|
-
if (!
|
149
|
+
if (!FIO_CLI_ARGC || !FIO_CLI_ARGV) {
|
142
150
|
fprintf(
|
143
151
|
stderr,
|
144
152
|
"ERROR: (fio_cli) fio_cli_get_* "
|
@@ -153,35 +161,46 @@ static void fio_cli_parse(void) {
|
|
153
161
|
if (parsed)
|
154
162
|
return;
|
155
163
|
parsed = fiobj_hash_new();
|
164
|
+
// {
|
165
|
+
// FIOBJ json = fiobj_obj2json(arg_aliases, 1);
|
166
|
+
// fprintf(stderr, "%s\n", fiobj_obj2cstr(json).data);
|
167
|
+
// fiobj_free(json);
|
168
|
+
// json = fiobj_obj2json(arg_type, 1);
|
169
|
+
// fprintf(stderr, "%s\n", fiobj_obj2cstr(json).data);
|
170
|
+
// fiobj_free(json);
|
171
|
+
// }
|
156
172
|
|
157
173
|
const char *start;
|
158
|
-
|
159
|
-
fiobj_s *arg_name;
|
174
|
+
FIOBJ arg_name;
|
160
175
|
|
161
176
|
/* ignore the first element, it's the program's name. */
|
162
|
-
for (int i = 1; i <
|
177
|
+
for (int i = 1; i < FIO_CLI_ARGC; i++) {
|
163
178
|
/* test for errors or help requests */
|
164
|
-
if (
|
165
|
-
|
179
|
+
if (FIO_CLI_ARGV[i][0] != '-' || FIO_CLI_ARGV[i][1] == 0) {
|
180
|
+
if (ignore_unknown)
|
181
|
+
continue;
|
182
|
+
start = FIO_CLI_ARGV[i];
|
166
183
|
goto error;
|
167
184
|
}
|
168
|
-
if ((
|
169
|
-
(
|
170
|
-
(
|
171
|
-
|
185
|
+
if ((FIO_CLI_ARGV[i][1] == '?' && FIO_CLI_ARGV[i][2] == 0) ||
|
186
|
+
(FIO_CLI_ARGV[i][1] == 'h' &&
|
187
|
+
(FIO_CLI_ARGV[i][2] == 0 ||
|
188
|
+
(FIO_CLI_ARGV[i][2] == 'e' && FIO_CLI_ARGV[i][3] == 'l' &&
|
189
|
+
FIO_CLI_ARGV[i][4] == 'p' && FIO_CLI_ARGV[i][5] == 0)))) {
|
172
190
|
fio_cli_handle_error();
|
191
|
+
continue;
|
173
192
|
}
|
174
193
|
/* we walk the name backwards, so `name` is tested before `n` */
|
175
|
-
start =
|
176
|
-
len = strlen(start);
|
194
|
+
start = FIO_CLI_ARGV[i] + 1;
|
195
|
+
size_t len = strlen(start);
|
177
196
|
while (len && !(arg_name = fio_cli_get_name(start, len))) {
|
178
|
-
len
|
197
|
+
--len;
|
179
198
|
}
|
180
199
|
if (!len)
|
181
200
|
goto error;
|
182
201
|
/* at this point arg_name is a handle to the argument's Symbol */
|
183
|
-
|
184
|
-
if (type
|
202
|
+
FIOBJ type = fiobj_hash_get(arg_type, arg_name);
|
203
|
+
if (FIOBJ_TYPE_IS(type, FIOBJ_T_NULL)) {
|
185
204
|
/* type is BOOL, no further processing required */
|
186
205
|
start = "1";
|
187
206
|
len = 1;
|
@@ -189,15 +208,15 @@ static void fio_cli_parse(void) {
|
|
189
208
|
}
|
190
209
|
if (start[len] == 0) {
|
191
210
|
i++;
|
192
|
-
if (i ==
|
211
|
+
if (i == FIO_CLI_ARGC)
|
193
212
|
goto error;
|
194
|
-
start =
|
213
|
+
start = FIO_CLI_ARGV[i];
|
195
214
|
} else if (start[len] == '=') {
|
196
215
|
start = start + len + 1;
|
197
216
|
} else
|
198
217
|
start = start + len;
|
199
218
|
len = 0;
|
200
|
-
if (type
|
219
|
+
if (FIOBJ_TYPE_IS(type, FIOBJ_T_FALSE)) /* no restrictions on data */
|
201
220
|
goto set_arg;
|
202
221
|
/* test that the argument is numerical */
|
203
222
|
if (start[len] == '-') /* negative number? */
|
@@ -211,10 +230,10 @@ static void fio_cli_parse(void) {
|
|
211
230
|
if (start[len]) /* if there's data left, this aint a number. */
|
212
231
|
goto error;
|
213
232
|
set_arg:
|
214
|
-
fiobj_hash_set(parsed, arg_name,
|
233
|
+
fiobj_hash_set(parsed, arg_name, fiobj_str_new(start, strlen(start)));
|
215
234
|
continue;
|
216
235
|
error:
|
217
|
-
fprintf(stderr, "\n*** Argument Error: %s
|
236
|
+
fprintf(stderr, "\n\t*** Argument Error: %s ***\n", start);
|
218
237
|
fio_cli_handle_error();
|
219
238
|
}
|
220
239
|
}
|
@@ -225,14 +244,14 @@ CLI API
|
|
225
244
|
|
226
245
|
/** Initialize the CLI helper */
|
227
246
|
void fio_cli_start(int argc, const char **argv, const char *info) {
|
228
|
-
|
229
|
-
|
247
|
+
FIO_CLI_ARGV = argv;
|
248
|
+
FIO_CLI_ARGC = argc;
|
230
249
|
if (info_str)
|
231
250
|
fiobj_free(info_str);
|
232
251
|
if (info) {
|
233
|
-
info_str =
|
252
|
+
info_str = fiobj_str_new(info, strlen(info));
|
234
253
|
} else {
|
235
|
-
info_str =
|
254
|
+
info_str = fiobj_str_new(DEFAULT_CLI_INFO, sizeof(DEFAULT_CLI_INFO) - 1);
|
236
255
|
}
|
237
256
|
}
|
238
257
|
|
@@ -241,7 +260,7 @@ void fio_cli_end(void) {
|
|
241
260
|
#define free_and_reset(o) \
|
242
261
|
do { \
|
243
262
|
fiobj_free((o)); \
|
244
|
-
o =
|
263
|
+
o = FIOBJ_INVALID; \
|
245
264
|
} while (0);
|
246
265
|
|
247
266
|
free_and_reset(arg_aliases);
|
@@ -253,8 +272,8 @@ void fio_cli_end(void) {
|
|
253
272
|
|
254
273
|
#undef free_and_reset
|
255
274
|
|
256
|
-
|
257
|
-
|
275
|
+
FIO_CLI_ARGC = 0;
|
276
|
+
FIO_CLI_ARGV = NULL;
|
258
277
|
is_parsed = 0;
|
259
278
|
}
|
260
279
|
|
@@ -314,10 +333,10 @@ void fio_cli_accept_bool(const char *aliases, const char *desc) {
|
|
314
333
|
*/
|
315
334
|
const char *fio_cli_get_str(const char *opt) {
|
316
335
|
fio_cli_parse();
|
317
|
-
|
336
|
+
FIOBJ name = fio_cli_get_name(opt, strlen(opt));
|
318
337
|
if (!name)
|
319
338
|
return NULL;
|
320
|
-
|
339
|
+
FIOBJ result = fiobj_hash_get(parsed, name);
|
321
340
|
if (!result)
|
322
341
|
return NULL;
|
323
342
|
return fiobj_obj2cstr(result).data;
|
@@ -330,10 +349,10 @@ const char *fio_cli_get_str(const char *opt) {
|
|
330
349
|
*/
|
331
350
|
int fio_cli_get_int(const char *opt) {
|
332
351
|
fio_cli_parse();
|
333
|
-
|
352
|
+
FIOBJ name = fio_cli_get_name(opt, strlen(opt));
|
334
353
|
if (!name)
|
335
354
|
return 0;
|
336
|
-
|
355
|
+
FIOBJ result = fiobj_hash_get(parsed, name);
|
337
356
|
if (!result)
|
338
357
|
return 0;
|
339
358
|
return (int)fiobj_obj2num(result);
|
@@ -346,10 +365,10 @@ int fio_cli_get_int(const char *opt) {
|
|
346
365
|
*/
|
347
366
|
double fio_cli_get_float(const char *opt) {
|
348
367
|
fio_cli_parse();
|
349
|
-
|
368
|
+
FIOBJ name = fio_cli_get_name(opt, strlen(opt));
|
350
369
|
if (!name)
|
351
370
|
return 0;
|
352
|
-
|
371
|
+
FIOBJ result = fiobj_hash_get(parsed, name);
|
353
372
|
if (!result)
|
354
373
|
return 0;
|
355
374
|
return fiobj_obj2float(result);
|
@@ -362,13 +381,13 @@ double fio_cli_get_float(const char *opt) {
|
|
362
381
|
*/
|
363
382
|
void fio_cli_set_str(const char *opt, const char *value) {
|
364
383
|
fio_cli_parse();
|
365
|
-
|
384
|
+
FIOBJ name = fio_cli_get_name(opt, strlen(opt));
|
366
385
|
if (!name) {
|
367
386
|
fprintf(stderr, "ERROR: facil.io's CLI helper can only override values for "
|
368
387
|
"valid options\n");
|
369
388
|
exit(-1);
|
370
389
|
}
|
371
|
-
fiobj_hash_set(parsed, name,
|
390
|
+
fiobj_hash_set(parsed, name, fiobj_str_new(value, strlen(value)));
|
372
391
|
}
|
373
392
|
|
374
393
|
/**
|
@@ -378,7 +397,7 @@ void fio_cli_set_str(const char *opt, const char *value) {
|
|
378
397
|
*/
|
379
398
|
void fio_cli_set_int(const char *opt, int value) {
|
380
399
|
fio_cli_parse();
|
381
|
-
|
400
|
+
FIOBJ name = fio_cli_get_name(opt, strlen(opt));
|
382
401
|
if (!name) {
|
383
402
|
fprintf(stderr, "ERROR: facil.io's CLI helper can only override values for "
|
384
403
|
"valid options\n");
|
@@ -394,7 +413,7 @@ void fio_cli_set_int(const char *opt, int value) {
|
|
394
413
|
*/
|
395
414
|
void fio_cli_set_float(const char *opt, double value) {
|
396
415
|
fio_cli_parse();
|
397
|
-
|
416
|
+
FIOBJ name = fio_cli_get_name(opt, strlen(opt));
|
398
417
|
if (!name) {
|
399
418
|
fprintf(stderr, "ERROR: facil.io's CLI helper can only override values for "
|
400
419
|
"valid options\n");
|