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.

Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -2
  3. data/CHANGELOG.md +22 -0
  4. data/LIMITS.md +19 -9
  5. data/README.md +92 -77
  6. data/SPEC-PubSub-Draft.md +113 -0
  7. data/SPEC-Websocket-Draft.md +127 -143
  8. data/bin/http-hello +0 -1
  9. data/bin/raw-rbhttp +1 -1
  10. data/bin/raw_broadcast +8 -10
  11. data/bin/updated api +2 -2
  12. data/bin/ws-broadcast +2 -4
  13. data/bin/ws-echo +2 -2
  14. data/examples/config.ru +13 -13
  15. data/examples/echo.ru +5 -6
  16. data/examples/hello.ru +2 -3
  17. data/examples/info.md +316 -0
  18. data/examples/pubsub_engine.ru +81 -0
  19. data/examples/redis.ru +9 -9
  20. data/examples/shootout.ru +45 -11
  21. data/ext/iodine/defer.c +194 -297
  22. data/ext/iodine/defer.h +61 -53
  23. data/ext/iodine/evio.c +0 -260
  24. data/ext/iodine/evio.h +50 -22
  25. data/ext/iodine/evio_callbacks.c +26 -0
  26. data/ext/iodine/evio_epoll.c +251 -0
  27. data/ext/iodine/evio_kqueue.c +193 -0
  28. data/ext/iodine/extconf.rb +1 -1
  29. data/ext/iodine/facil.c +1420 -542
  30. data/ext/iodine/facil.h +151 -64
  31. data/ext/iodine/fio_ary.h +418 -0
  32. data/ext/iodine/{base64.c → fio_base64.c} +33 -24
  33. data/ext/iodine/{base64.h → fio_base64.h} +6 -7
  34. data/ext/iodine/{fio_cli_helper.c → fio_cli.c} +77 -58
  35. data/ext/iodine/{fio_cli_helper.h → fio_cli.h} +9 -4
  36. data/ext/iodine/fio_hashmap.h +759 -0
  37. data/ext/iodine/fio_json_parser.h +651 -0
  38. data/ext/iodine/fio_llist.h +257 -0
  39. data/ext/iodine/fio_mem.c +672 -0
  40. data/ext/iodine/fio_mem.h +140 -0
  41. data/ext/iodine/fio_random.c +248 -0
  42. data/ext/iodine/{random.h → fio_random.h} +11 -14
  43. data/ext/iodine/{sha1.c → fio_sha1.c} +28 -24
  44. data/ext/iodine/{sha1.h → fio_sha1.h} +38 -16
  45. data/ext/iodine/{sha2.c → fio_sha2.c} +66 -49
  46. data/ext/iodine/{sha2.h → fio_sha2.h} +57 -26
  47. data/ext/iodine/{fiobj_internal.c → fio_siphash.c} +9 -90
  48. data/ext/iodine/fio_siphash.h +18 -0
  49. data/ext/iodine/fio_tmpfile.h +38 -0
  50. data/ext/iodine/fiobj.h +24 -7
  51. data/ext/iodine/fiobj4sock.h +23 -0
  52. data/ext/iodine/fiobj_ary.c +143 -226
  53. data/ext/iodine/fiobj_ary.h +17 -16
  54. data/ext/iodine/fiobj_data.c +1160 -0
  55. data/ext/iodine/fiobj_data.h +164 -0
  56. data/ext/iodine/fiobj_hash.c +298 -406
  57. data/ext/iodine/fiobj_hash.h +101 -54
  58. data/ext/iodine/fiobj_json.c +478 -601
  59. data/ext/iodine/fiobj_json.h +34 -9
  60. data/ext/iodine/fiobj_numbers.c +383 -51
  61. data/ext/iodine/fiobj_numbers.h +87 -11
  62. data/ext/iodine/fiobj_str.c +423 -184
  63. data/ext/iodine/fiobj_str.h +81 -32
  64. data/ext/iodine/fiobject.c +273 -522
  65. data/ext/iodine/fiobject.h +477 -112
  66. data/ext/iodine/http.c +2243 -83
  67. data/ext/iodine/http.h +842 -121
  68. data/ext/iodine/http1.c +810 -385
  69. data/ext/iodine/http1.h +16 -39
  70. data/ext/iodine/http1_parser.c +146 -74
  71. data/ext/iodine/http1_parser.h +15 -4
  72. data/ext/iodine/http_internal.c +1258 -0
  73. data/ext/iodine/http_internal.h +226 -0
  74. data/ext/iodine/http_mime_parser.h +341 -0
  75. data/ext/iodine/iodine.c +86 -68
  76. data/ext/iodine/iodine.h +26 -11
  77. data/ext/iodine/iodine_helpers.c +8 -7
  78. data/ext/iodine/iodine_http.c +487 -324
  79. data/ext/iodine/iodine_json.c +304 -0
  80. data/ext/iodine/iodine_json.h +6 -0
  81. data/ext/iodine/iodine_protocol.c +107 -45
  82. data/ext/iodine/iodine_pubsub.c +526 -225
  83. data/ext/iodine/iodine_pubsub.h +10 -0
  84. data/ext/iodine/iodine_websockets.c +268 -510
  85. data/ext/iodine/iodine_websockets.h +2 -4
  86. data/ext/iodine/pubsub.c +726 -432
  87. data/ext/iodine/pubsub.h +85 -103
  88. data/ext/iodine/rb-call.c +4 -4
  89. data/ext/iodine/rb-defer.c +46 -22
  90. data/ext/iodine/rb-fiobj2rb.h +117 -0
  91. data/ext/iodine/rb-rack-io.c +73 -238
  92. data/ext/iodine/rb-rack-io.h +2 -2
  93. data/ext/iodine/rb-registry.c +35 -93
  94. data/ext/iodine/rb-registry.h +1 -0
  95. data/ext/iodine/redis_engine.c +742 -304
  96. data/ext/iodine/redis_engine.h +42 -39
  97. data/ext/iodine/resp_parser.h +311 -0
  98. data/ext/iodine/sock.c +627 -490
  99. data/ext/iodine/sock.h +345 -297
  100. data/ext/iodine/spnlock.inc +15 -4
  101. data/ext/iodine/websocket_parser.h +16 -20
  102. data/ext/iodine/websockets.c +188 -257
  103. data/ext/iodine/websockets.h +24 -133
  104. data/lib/iodine.rb +52 -7
  105. data/lib/iodine/cli.rb +6 -24
  106. data/lib/iodine/json.rb +40 -0
  107. data/lib/iodine/version.rb +1 -1
  108. data/lib/iodine/websocket.rb +5 -3
  109. data/lib/rack/handler/iodine.rb +58 -13
  110. metadata +38 -48
  111. data/bin/ws-shootout +0 -107
  112. data/examples/broadcast.ru +0 -56
  113. data/ext/iodine/bscrypt-common.h +0 -116
  114. data/ext/iodine/bscrypt.h +0 -49
  115. data/ext/iodine/fio2resp.c +0 -60
  116. data/ext/iodine/fio2resp.h +0 -51
  117. data/ext/iodine/fio_dict.c +0 -446
  118. data/ext/iodine/fio_dict.h +0 -99
  119. data/ext/iodine/fio_hash_table.h +0 -370
  120. data/ext/iodine/fio_list.h +0 -111
  121. data/ext/iodine/fiobj_internal.h +0 -280
  122. data/ext/iodine/fiobj_primitives.c +0 -131
  123. data/ext/iodine/fiobj_primitives.h +0 -55
  124. data/ext/iodine/fiobj_sym.c +0 -135
  125. data/ext/iodine/fiobj_sym.h +0 -60
  126. data/ext/iodine/hex.c +0 -124
  127. data/ext/iodine/hex.h +0 -70
  128. data/ext/iodine/http1_request.c +0 -81
  129. data/ext/iodine/http1_request.h +0 -58
  130. data/ext/iodine/http1_response.c +0 -417
  131. data/ext/iodine/http1_response.h +0 -95
  132. data/ext/iodine/http_request.c +0 -111
  133. data/ext/iodine/http_request.h +0 -102
  134. data/ext/iodine/http_response.c +0 -1703
  135. data/ext/iodine/http_response.h +0 -250
  136. data/ext/iodine/misc.c +0 -182
  137. data/ext/iodine/misc.h +0 -74
  138. data/ext/iodine/random.c +0 -208
  139. data/ext/iodine/redis_connection.c +0 -278
  140. data/ext/iodine/redis_connection.h +0 -86
  141. data/ext/iodine/resp.c +0 -842
  142. data/ext/iodine/resp.h +0 -261
  143. data/ext/iodine/siphash.c +0 -154
  144. data/ext/iodine/siphash.h +0 -22
  145. data/ext/iodine/xor-crypt.c +0 -193
  146. data/ext/iodine/xor-crypt.h +0 -107
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright: Boaz segev, 2016-2017
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 "base64.h"
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 bscrypt_base64_encode(char *target, const char *data, int len) {
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 bscrypt_base64_decode(char *target, char *encoded, int base64_len) {
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
- void bscrypt_test_base64(void) {
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, "+ bscrypt");
235
+ fprintf(stderr, "+ fio");
230
236
  while (sets[i].str) {
231
- bscrypt_base64_encode(buffer, sets[i].str, strlen(sets[i].str));
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--- bscrypt Base64 Test FAILED!\nstring: %s\nlength: %lu\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, "+ bscrypt");
251
+ fprintf(stderr, "+ fio");
246
252
  while (sets[i].str) {
247
- bscrypt_base64_decode(buffer, sets[i].base64, strlen(sets[i].base64));
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--- bscrypt Base64 Test FAILED!\nbase64: %s\nexpected: "
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
- char buff_b64[] = "any carnal pleasure.";
259
- size_t b64_len;
260
- clock_t start = clock();
261
- for (size_t i = 0; i < 100000; i++) {
262
- b64_len = bscrypt_base64_encode(buffer, buff_b64, sizeof(buff_b64) - 1);
263
- bscrypt_base64_decode(buff_b64, buffer, b64_len);
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 segev, 2016-2017
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 BSCRYPT_BASE64_H
9
- #define BSCRYPT_BASE64_H
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 bscrypt_base64_encode(char *target, const char *data, int len);
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 bscrypt_base64_decode(char *target, char *encoded, int base64_len);
58
+ int fio_base64_decode(char *target, char *encoded, int base64_len);
60
59
 
61
60
  #if defined(DEBUG) && DEBUG == 1
62
- void bscrypt_test_base64(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 "fio_cli_helper.h"
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 ARGC;
17
- static const char **ARGV;
18
- static fiobj_s *arg_aliases; /* a hash for translating aliases */
19
- static fiobj_s *arg_type; /* a with information about each argument */
20
- static fiobj_s *parsed; /* a with information about each argument */
21
- static fiobj_s *help_str; /* The CLI help string */
22
- static fiobj_s *info_str; /* The CLI information string */
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 = NULL;
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 = fiobj_str_static(DEFAULT_CLI_INFO, sizeof(DEFAULT_CLI_INFO) - 1);
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 fiobj_s *fio_cli_get_name(const char *str, size_t len) {
74
- return fiobj_hash_get2(arg_aliases, str, len);
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
- size_t len = 0;
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 = fiobj_sym_new(start, len);
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\e[1m-%s\e[0m\t\t%s\n",
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, "\t\e[1m-%s\e[0m \e[2###\e[0m\t%s\n",
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, "\t\e[1m-%s\e[0m \e[2<val>\e[0m\t%s\n",
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
- fiobj_s *tmp = fiobj_sym_new(start, len);
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\e[1m-%s\e[0m\tsame as -%s\n",
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 (!ARGC || !ARGV) {
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
- size_t len;
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 < ARGC; i++) {
177
+ for (int i = 1; i < FIO_CLI_ARGC; i++) {
163
178
  /* test for errors or help requests */
164
- if (ARGV[i][0] != '-' || ARGV[i][1] == 0) {
165
- start = ARGV[i];
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 ((ARGV[i][1] == '?' && ARGV[i][2] == 0) ||
169
- (ARGV[i][1] == 'h' &&
170
- (ARGV[i][2] == 0 || (ARGV[i][2] == 'e' && ARGV[i][3] == 'l' &&
171
- ARGV[i][4] == 'p' && ARGV[i][5] == 0)))) {
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 = ARGV[i] + 1;
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
- fiobj_s *type = fiobj_hash_get(arg_type, arg_name);
184
- if (type->type == FIOBJ_T_NULL) {
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 == ARGC)
211
+ if (i == FIO_CLI_ARGC)
193
212
  goto error;
194
- start = ARGV[i];
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->type == FIOBJ_T_FALSE) /* no restrictions on data */
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, fiobj_str_static(start, len));
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\n", start);
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
- ARGV = argv;
229
- ARGC = argc;
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 = fiobj_str_static(info, 0);
252
+ info_str = fiobj_str_new(info, strlen(info));
234
253
  } else {
235
- info_str = fiobj_str_static(DEFAULT_CLI_INFO, sizeof(DEFAULT_CLI_INFO) - 1);
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 = NULL; \
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
- ARGC = 0;
257
- ARGV = NULL;
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
- fiobj_s *name = fio_cli_get_name(opt, strlen(opt));
336
+ FIOBJ name = fio_cli_get_name(opt, strlen(opt));
318
337
  if (!name)
319
338
  return NULL;
320
- fiobj_s *result = fiobj_hash_get(parsed, name);
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
- fiobj_s *name = fio_cli_get_name(opt, strlen(opt));
352
+ FIOBJ name = fio_cli_get_name(opt, strlen(opt));
334
353
  if (!name)
335
354
  return 0;
336
- fiobj_s *result = fiobj_hash_get(parsed, name);
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
- fiobj_s *name = fio_cli_get_name(opt, strlen(opt));
368
+ FIOBJ name = fio_cli_get_name(opt, strlen(opt));
350
369
  if (!name)
351
370
  return 0;
352
- fiobj_s *result = fiobj_hash_get(parsed, name);
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
- fiobj_s *name = fio_cli_get_name(opt, strlen(opt));
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, fiobj_str_static(value, strlen(value)));
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
- fiobj_s *name = fio_cli_get_name(opt, strlen(opt));
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
- fiobj_s *name = fio_cli_get_name(opt, strlen(opt));
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");