iodine 0.7.11 → 0.7.12

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.

@@ -182,8 +182,8 @@ Version and helper macros
182
182
 
183
183
  #ifndef FIO_IGNORE_MACRO
184
184
  /**
185
- * This is used internally to ignor macros that shadow functions (avoiding named
186
- * arguments when required.
185
+ * This is used internally to ignore macros that shadow functions (avoiding
186
+ * named arguments when required).
187
187
  */
188
188
  #define FIO_IGNORE_MACRO
189
189
  #endif
@@ -298,6 +298,18 @@ Memory pool / custom allocator for short lived objects
298
298
 
299
299
  ***************************************************************************** */
300
300
 
301
+ /* inform the compiler that the returned value is aligned on 16 byte marker */
302
+ #if FIO_FORCE_MALLOC
303
+ #define FIO_ALIGN
304
+ #define FIO_ALIGN_NEW
305
+ #elif __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 8)
306
+ #define FIO_ALIGN __attribute__((assume_aligned(16)))
307
+ #define FIO_ALIGN_NEW __attribute__((malloc, assume_aligned(16)))
308
+ #else
309
+ #define FIO_ALIGN
310
+ #define FIO_ALIGN_NEW
311
+ #endif
312
+
301
313
  /**
302
314
  * Allocates memory using a per-CPU core block memory pool.
303
315
  * Memory is zeroed out.
@@ -305,7 +317,7 @@ Memory pool / custom allocator for short lived objects
305
317
  * Allocations above FIO_MEMORY_BLOCK_ALLOC_LIMIT (12,288 bytes when using 32Kb
306
318
  * blocks) will be redirected to `mmap`, as if `fio_mmap` was called.
307
319
  */
308
- void *fio_malloc(size_t size);
320
+ void *FIO_ALIGN_NEW fio_malloc(size_t size);
309
321
 
310
322
  /**
311
323
  * same as calling `fio_malloc(size_per_unit * unit_count)`;
@@ -313,7 +325,7 @@ void *fio_malloc(size_t size);
313
325
  * Allocations above FIO_MEMORY_BLOCK_ALLOC_LIMIT (12,288 bytes when using 32Kb
314
326
  * blocks) will be redirected to `mmap`, as if `fio_mmap` was called.
315
327
  */
316
- void *fio_calloc(size_t size_per_unit, size_t unit_count);
328
+ void *FIO_ALIGN_NEW fio_calloc(size_t size_per_unit, size_t unit_count);
317
329
 
318
330
  /** Frees memory that was allocated using this library. */
319
331
  void fio_free(void *ptr);
@@ -322,7 +334,7 @@ void fio_free(void *ptr);
322
334
  * Re-allocates memory. An attempt to avoid copying the data is made only for
323
335
  * big memory allocations (larger than FIO_MEMORY_BLOCK_ALLOC_LIMIT).
324
336
  */
325
- void *fio_realloc(void *ptr, size_t new_size);
337
+ void *FIO_ALIGN fio_realloc(void *ptr, size_t new_size);
326
338
 
327
339
  /**
328
340
  * Re-allocates memory. An attempt to avoid copying the data is made only for
@@ -330,7 +342,7 @@ void *fio_realloc(void *ptr, size_t new_size);
330
342
  *
331
343
  * This variation is slightly faster as it might copy less data.
332
344
  */
333
- void *fio_realloc2(void *ptr, size_t new_size, size_t copy_length);
345
+ void *FIO_ALIGN fio_realloc2(void *ptr, size_t new_size, size_t copy_length);
334
346
 
335
347
  /**
336
348
  * Allocates memory directly using `mmap`, this is prefered for objects that
@@ -341,7 +353,7 @@ void *fio_realloc2(void *ptr, size_t new_size, size_t copy_length);
341
353
  *
342
354
  * `fio_free` can be used for deallocating the memory.
343
355
  */
344
- void *fio_mmap(size_t size);
356
+ void *FIO_ALIGN_NEW fio_mmap(size_t size);
345
357
 
346
358
  /**
347
359
  * When forking is called manually, call this function to reset the facil.io
@@ -349,6 +361,8 @@ void *fio_mmap(size_t size);
349
361
  */
350
362
  void fio_malloc_after_fork(void);
351
363
 
364
+ #undef FIO_ALIGN
365
+
352
366
  #if FIO_FORCE_MALLOC
353
367
  #define FIO_MALLOC(size) calloc((size), 1)
354
368
  #define FIO_CALLOC(size, units) calloc((size), (units))
@@ -445,15 +459,12 @@ extern int FIO_LOG_LEVEL;
445
459
  #define FIO_LOG_STATE(...)
446
460
  #endif
447
461
 
448
- #if DEBUG
449
462
  #define FIO_ASSERT(cond, ...) \
450
463
  if (!(cond)) { \
451
- FIO_LOG_DEBUG(__VA_ARGS__); \
464
+ FIO_LOG_FATAL("(" __FILE__ ":" FIO_MACRO2STR(__LINE__) ") "__VA_ARGS__); \
465
+ perror(" errno"); \
452
466
  exit(-1); \
453
467
  }
454
- #else
455
- #define FIO_ASSERT(...)
456
- #endif
457
468
 
458
469
  #ifndef FIO_ASSERT_ALLOC
459
470
  /** Tests for an allocation failure. The behavior can be overridden. */
@@ -466,6 +477,17 @@ extern int FIO_LOG_LEVEL;
466
477
  }
467
478
  #endif
468
479
 
480
+ #if DEBUG
481
+ #define FIO_ASSERT_DEBUG(cond, ...) \
482
+ if (!(cond)) { \
483
+ FIO_LOG_DEBUG(__VA_ARGS__); \
484
+ perror(" errno"); \
485
+ exit(-1); \
486
+ }
487
+ #else
488
+ #define FIO_ASSERT_DEBUG(...)
489
+ #endif
490
+
469
491
  /* *****************************************************************************
470
492
 
471
493
 
@@ -564,9 +586,24 @@ void fio_attach(intptr_t uuid, fio_protocol_s *protocol);
564
586
  * The old protocol's `on_close` (if any) will be scheduled.
565
587
  *
566
588
  * On error, the new protocol's `on_close` callback will be called immediately.
589
+ *
590
+ * NOTE: before attaching a file descriptor that was created outside of
591
+ * facil.io's library, make sure it is set to non-blocking mode (see
592
+ * `fio_set_non_block`). facil.io file descriptors are all non-blocking and it
593
+ * will assumes this is the case for the attached fd.
567
594
  */
568
595
  void fio_attach_fd(int fd, fio_protocol_s *protocol);
569
596
 
597
+ /**
598
+ * Sets a socket to non blocking state.
599
+ *
600
+ * This will also set the O_CLOEXEC flag for the file descriptor.
601
+ *
602
+ * This function is called automatically for the new socket, when using
603
+ * `fio_accept` or `fio_connect`.
604
+ */
605
+ int fio_set_non_block(int fd);
606
+
570
607
  /**
571
608
  * Returns the maximum number of open files facil.io can handle per worker
572
609
  * process.
@@ -926,6 +963,9 @@ intptr_t fio_socket(const char *address, const char *port, uint8_t is_server);
926
963
  * `fio_accept` accepts a new socket connection from a server socket - see the
927
964
  * server flag on `fio_socket`.
928
965
  *
966
+ * Accepted connection are automatically set to non-blocking mode and the
967
+ * O_CLOEXEC flag is set.
968
+ *
929
969
  * NOTE: this function does NOT attach the socket to the IO reactor - see
930
970
  * `fio_attach`.
931
971
  */
@@ -1237,17 +1277,6 @@ typedef struct fio_rw_hook_s {
1237
1277
  * deadlock might occur.
1238
1278
  */
1239
1279
  ssize_t (*write)(intptr_t uuid, void *udata, const void *buf, size_t count);
1240
- /**
1241
- * The `before_close` callback is called only once before closing the `uuid`.
1242
- *
1243
- * If the function returns a non-zero value, than closure will be delayed
1244
- * until the `flush` returns 0 (or less). This allows a closure signal to be
1245
- * sent by the read/write hook when such a signal is required.
1246
- *
1247
- * Note: facil.io library functions MUST NEVER be called by any r/w hook, or a
1248
- * deadlock might occur.
1249
- * */
1250
- ssize_t (*before_close)(intptr_t uuid, void *udata);
1251
1280
  /**
1252
1281
  * When implemented, this function will be called to flush any data remaining
1253
1282
  * in the internal buffer.
@@ -1259,6 +1288,18 @@ typedef struct fio_rw_hook_s {
1259
1288
  * deadlock might occur.
1260
1289
  */
1261
1290
  ssize_t (*flush)(intptr_t uuid, void *udata);
1291
+ /**
1292
+ * The `before_close` callback is called only once before closing the `uuid`
1293
+ * and it might not get called at all if an abnormal closure is detected.
1294
+ *
1295
+ * If the function returns a non-zero value, than closure will be delayed
1296
+ * until the `flush` returns 0 (or less). This allows a closure signal to be
1297
+ * sent by the read/write hook when such a signal is required.
1298
+ *
1299
+ * Note: facil.io library functions MUST NEVER be called by any r/w hook, or a
1300
+ * deadlock might occur.
1301
+ * */
1302
+ ssize_t (*before_close)(intptr_t uuid, void *udata);
1262
1303
  /**
1263
1304
  * Called to perform cleanup after the socket was closed or a new read/write
1264
1305
  * hook was set using `fio_rw_hook_set`.
@@ -1499,14 +1540,6 @@ fio_protocol_s *fio_protocol_try_lock(intptr_t uuid, enum fio_protocol_lock_e);
1499
1540
  * details. */
1500
1541
  void fio_protocol_unlock(fio_protocol_s *pr, enum fio_protocol_lock_e);
1501
1542
 
1502
- /**
1503
- Sets a socket to non blocking state.
1504
-
1505
- This function is called automatically for the new socket, when using
1506
- `fio_accept` or `fio_connect`.
1507
- */
1508
- int fio_set_non_block(int fd);
1509
-
1510
1543
  /* *****************************************************************************
1511
1544
  * Pub/Sub / Cluster Messages API
1512
1545
  *
@@ -2853,18 +2886,21 @@ Embeded Linked List Implementation
2853
2886
 
2854
2887
  /** Removes a node from the containing node. */
2855
2888
  FIO_FUNC inline fio_ls_embd_s *fio_ls_embd_remove(fio_ls_embd_s *node) {
2856
- if (node->next == node) {
2889
+ if (!node->next || node->next == node) {
2857
2890
  /* never remove the list's head */
2858
2891
  return NULL;
2859
2892
  }
2860
2893
  node->next->prev = node->prev;
2861
2894
  node->prev->next = node->next;
2895
+ node->prev = node->next = node;
2862
2896
  return node;
2863
2897
  }
2864
2898
 
2865
2899
  /** Adds a node to the list's head. */
2866
2900
  FIO_FUNC inline void fio_ls_embd_push(fio_ls_embd_s *dest,
2867
2901
  fio_ls_embd_s *node) {
2902
+ if (!dest || !node)
2903
+ return;
2868
2904
  node->prev = dest->prev;
2869
2905
  node->next = dest;
2870
2906
  dest->prev->next = node;
@@ -2907,7 +2943,7 @@ Independent Linked List Implementation
2907
2943
 
2908
2944
  /** Removes an object from the containing node. */
2909
2945
  FIO_FUNC inline void *fio_ls_remove(fio_ls_s *node) {
2910
- if (node->next == node) {
2946
+ if (!node || node->next == node) {
2911
2947
  /* never remove the list's head */
2912
2948
  return NULL;
2913
2949
  }
@@ -2920,6 +2956,8 @@ FIO_FUNC inline void *fio_ls_remove(fio_ls_s *node) {
2920
2956
 
2921
2957
  /** Adds an object to the list's head. */
2922
2958
  FIO_FUNC inline fio_ls_s *fio_ls_push(fio_ls_s *pos, const void *obj) {
2959
+ if (!pos)
2960
+ return NULL;
2923
2961
  /* prepare item */
2924
2962
  fio_ls_s *item = (fio_ls_s *)malloc(sizeof(*item));
2925
2963
  if (!item) {
@@ -40,6 +40,8 @@ typedef struct {
40
40
  int unnamed_max;
41
41
  int pos;
42
42
  int unnamed_count;
43
+ int argc;
44
+ char const **argv;
43
45
  char const *description;
44
46
  char const **names;
45
47
  } fio_cli_parser_data_s;
@@ -138,32 +140,29 @@ static void fio_cli_set_arg(cstr_s arg, char const *value, char const *line,
138
140
  char const *type = fio_cli_get_line_type(parser, line);
139
141
  switch ((size_t)type) {
140
142
  case /* FIO_CLI_TYPE_BOOL */ 0x2:
141
- if (value &&
142
- (value == arg.data + arg.len ||
143
- (value == arg.data + arg.len + 1 && arg.data[arg.len] == '='))) {
143
+ if (value && value != parser->argv[parser->pos + 1]) {
144
144
  goto error;
145
145
  }
146
146
  value = "1";
147
147
  break;
148
148
  case /* FIO_CLI_TYPE_INT */ 0x3: /* fallthrough */
149
- {
150
- if (!value)
151
- goto error;
152
- char const *tmp = value;
153
- if (*tmp == '-' || *tmp == '+') {
154
- ++tmp;
155
- }
156
- if (!*tmp) {
157
- goto error;
158
- }
159
- while (*tmp && *tmp >= '0' && *tmp <= '9') {
160
- ++tmp;
161
- }
162
- if (*tmp) {
163
- goto error;
149
+ if (value) {
150
+ char const *tmp = value;
151
+ if (*tmp == '-' || *tmp == '+') {
152
+ ++tmp;
153
+ }
154
+ while (*tmp && *tmp >= '0' && *tmp <= '9') {
155
+ ++tmp;
156
+ }
157
+ if (*tmp) {
158
+ goto error;
159
+ }
164
160
  }
165
- }
166
161
  case /* FIO_CLI_TYPE_STRING */ 0x1: /* fallthrough */
162
+ if (!value)
163
+ goto error;
164
+ if (!value[0])
165
+ goto finish;
167
166
  break;
168
167
  }
169
168
 
@@ -183,19 +182,19 @@ static void fio_cli_set_arg(cstr_s arg, char const *value, char const *line,
183
182
  }
184
183
  }
185
184
 
185
+ finish:
186
+
186
187
  /* handle additional argv progress (if value is on separate argv) */
187
- if (type != FIO_CLI_TYPE_BOOL && value && value != arg.data + arg.len &&
188
- !arg.data[arg.len]) {
189
- /* advance the position marker more than once? */
188
+ if (value && parser->pos < parser->argc &&
189
+ value == parser->argv[parser->pos + 1])
190
190
  ++parser->pos;
191
- }
192
191
  return;
193
192
 
194
193
  error: /* handle errors*/
195
194
  /* TODO! */
196
195
  fprintf(stderr, "\n\r\x1B[31mError:\x1B[0m unknown argument %.*s %s %s\n\n",
197
196
  (int)arg.len, arg.data, arg.len ? "with value" : "",
198
- value ? value : "(null)");
197
+ value ? (value[0] ? value : "(empty)") : "(null)");
199
198
  print_help:
200
199
  fprintf(stderr, "\n%s\n\n",
201
200
  parser->description ? parser->description
@@ -307,6 +306,8 @@ void fio_cli_start AVOID_MACRO(int argc, char const *argv[], int unnamed_min,
307
306
  .unnamed_min = unnamed_min,
308
307
  .unnamed_max = unnamed_max,
309
308
  .description = description,
309
+ .argc = argc,
310
+ .argv = argv,
310
311
  .names = names,
311
312
  .pos = 0,
312
313
  };
@@ -16,6 +16,10 @@ License: MIT
16
16
 
17
17
  #include <fio_siphash.h>
18
18
 
19
+ #ifdef H_FACIL_IO_H
20
+ #include <fiobj4fio.h>
21
+ #endif
22
+
19
23
  #if DEBUG
20
24
  FIO_INLINE void fiobj_test(void) {
21
25
  fprintf(stderr, "\n=== FIOBJ Tests ===\n\n");
File without changes
@@ -6,6 +6,14 @@
6
6
  #include <fiobj_mustache.h>
7
7
  #include <fiobj_str.h>
8
8
 
9
+ #ifndef FIO_IGNORE_MACRO
10
+ /**
11
+ * This is used internally to ignore macros that shadow functions (avoiding
12
+ * named arguments when required).
13
+ */
14
+ #define FIO_IGNORE_MACRO
15
+ #endif
16
+
9
17
  /**
10
18
  * Loads a mustache template, converting it into an opaque instruction array.
11
19
  *
@@ -20,6 +28,20 @@ mustache_s *fiobj_mustache_load(fio_str_info_s filename) {
20
28
  return mustache_load(.filename = filename.data, .filename_len = filename.len);
21
29
  }
22
30
 
31
+ /**
32
+ * Loads a mustache template, converting it into an opaque instruction array.
33
+ *
34
+ * Returns a pointer to the instruction array.
35
+ *
36
+ * The `folder` argument should contain the template's root folder which would
37
+ * also be used to search for any required partial templates.
38
+ *
39
+ * The `filename` argument should contain the template's file name.
40
+ */
41
+ mustache_s *fiobj_mustache_new FIO_IGNORE_MACRO(mustache_load_args_s args) {
42
+ return mustache_load FIO_IGNORE_MACRO(args);
43
+ }
44
+
23
45
  /** Free the mustache template */
24
46
  void fiobj_mustache_free(mustache_s *mustache) { mustache_free(mustache); }
25
47
 
@@ -52,8 +74,10 @@ Mustache Callbacks
52
74
  ***************************************************************************** */
53
75
 
54
76
  /** HTML ecape table, created using the following Ruby Script:
55
- a = []
56
- 256.times {|i| a[i] = "&\#x#{ i < 16 ? "0#{i.to_s(16)}" : i.to_s(16)};"}
77
+
78
+ a = (0..255).to_a.map {|i| i.chr }
79
+ # 100.times {|i| a[i] = "&\#x#{ i < 16 ? "0#{i.to_s(16)}" : i.to_s(16)};"}
80
+ 100.times {|i| a[i] = "&\##{i.to_s(10)};"}
57
81
  ('a'.ord..'z'.ord).each {|i| a[i] = i.chr }
58
82
  ('A'.ord..'Z'.ord).each {|i| a[i] = i.chr }
59
83
  ('0'.ord..'9'.ord).each {|i| a[i] = i.chr }
@@ -61,61 +85,58 @@ a['<'.ord] = "&lt;"
61
85
  a['>'.ord] = "&gt;"
62
86
  a['&'.ord] = "&amp;"
63
87
  a['"'.ord] = "&quot;"
88
+ a["\'".ord] = "&apos;"
89
+ a['|'.ord] = "&\##{'|'.ord.to_s(10)};"
64
90
 
65
91
  b = a.map {|s| s.length }
66
92
  puts "static char *html_escape_strs[] = {", a.to_s.slice(1..-2) ,"};",
67
93
  "static uint8_t html_escape_len[] = {", b.to_s.slice(1..-2),"};"
68
94
  */
69
- static const char *html_escape_strs[] = {
70
- "&#x00;", "&#x01;", "&#x02;", "&#x03;", "&#x04;", "&#x05;", "&#x06;",
71
- "&#x07;", "&#x08;", "&#x09;", "&#x0a;", "&#x0b;", "&#x0c;", "&#x0d;",
72
- "&#x0e;", "&#x0f;", "&#x10;", "&#x11;", "&#x12;", "&#x13;", "&#x14;",
73
- "&#x15;", "&#x16;", "&#x17;", "&#x18;", "&#x19;", "&#x1a;", "&#x1b;",
74
- "&#x1c;", "&#x1d;", "&#x1e;", "&#x1f;", "&#x20;", "&#x21;", "&quot;",
75
- "&#x23;", "&#x24;", "&#x25;", "&amp;", "&#x27;", "&#x28;", "&#x29;",
76
- "&#x2a;", "&#x2b;", "&#x2c;", "&#x2d;", "&#x2e;", "&#x2f;", "0",
77
- "1", "2", "3", "4", "5", "6", "7",
78
- "8", "9", "&#x3a;", "&#x3b;", "&lt;", "&#x3d;", "&gt;",
79
- "&#x3f;", "&#x40;", "A", "B", "C", "D", "E",
80
- "F", "G", "H", "I", "J", "K", "L",
81
- "M", "N", "O", "P", "Q", "R", "S",
82
- "T", "U", "V", "W", "X", "Y", "Z",
83
- "&#x5b;", "&#x5c;", "&#x5d;", "&#x5e;", "&#x5f;", "&#x60;", "a",
84
- "b", "c", "d", "e", "f", "g", "h",
85
- "i", "j", "k", "l", "m", "n", "o",
86
- "p", "q", "r", "s", "t", "u", "v",
87
- "w", "x", "y", "z", "&#x7b;", "&#x7c;", "&#x7d;",
88
- "&#x7e;", "&#x7f;", "&#x80;", "&#x81;", "&#x82;", "&#x83;", "&#x84;",
89
- "&#x85;", "&#x86;", "&#x87;", "&#x88;", "&#x89;", "&#x8a;", "&#x8b;",
90
- "&#x8c;", "&#x8d;", "&#x8e;", "&#x8f;", "&#x90;", "&#x91;", "&#x92;",
91
- "&#x93;", "&#x94;", "&#x95;", "&#x96;", "&#x97;", "&#x98;", "&#x99;",
92
- "&#x9a;", "&#x9b;", "&#x9c;", "&#x9d;", "&#x9e;", "&#x9f;", "&#xa0;",
93
- "&#xa1;", "&#xa2;", "&#xa3;", "&#xa4;", "&#xa5;", "&#xa6;", "&#xa7;",
94
- "&#xa8;", "&#xa9;", "&#xaa;", "&#xab;", "&#xac;", "&#xad;", "&#xae;",
95
- "&#xaf;", "&#xb0;", "&#xb1;", "&#xb2;", "&#xb3;", "&#xb4;", "&#xb5;",
96
- "&#xb6;", "&#xb7;", "&#xb8;", "&#xb9;", "&#xba;", "&#xbb;", "&#xbc;",
97
- "&#xbd;", "&#xbe;", "&#xbf;", "&#xc0;", "&#xc1;", "&#xc2;", "&#xc3;",
98
- "&#xc4;", "&#xc5;", "&#xc6;", "&#xc7;", "&#xc8;", "&#xc9;", "&#xca;",
99
- "&#xcb;", "&#xcc;", "&#xcd;", "&#xce;", "&#xcf;", "&#xd0;", "&#xd1;",
100
- "&#xd2;", "&#xd3;", "&#xd4;", "&#xd5;", "&#xd6;", "&#xd7;", "&#xd8;",
101
- "&#xd9;", "&#xda;", "&#xdb;", "&#xdc;", "&#xdd;", "&#xde;", "&#xdf;",
102
- "&#xe0;", "&#xe1;", "&#xe2;", "&#xe3;", "&#xe4;", "&#xe5;", "&#xe6;",
103
- "&#xe7;", "&#xe8;", "&#xe9;", "&#xea;", "&#xeb;", "&#xec;", "&#xed;",
104
- "&#xee;", "&#xef;", "&#xf0;", "&#xf1;", "&#xf2;", "&#xf3;", "&#xf4;",
105
- "&#xf5;", "&#xf6;", "&#xf7;", "&#xf8;", "&#xf9;", "&#xfa;", "&#xfb;",
106
- "&#xfc;", "&#xfd;", "&#xfe;", "&#xff;"};
95
+ static char *html_escape_strs[] = {
96
+ "&#0;", "&#1;", "&#2;", "&#3;", "&#4;", "&#5;", "&#6;", "&#7;",
97
+ "&#8;", "&#9;", "&#10;", "&#11;", "&#12;", "&#13;", "&#14;", "&#15;",
98
+ "&#16;", "&#17;", "&#18;", "&#19;", "&#20;", "&#21;", "&#22;", "&#23;",
99
+ "&#24;", "&#25;", "&#26;", "&#27;", "&#28;", "&#29;", "&#30;", "&#31;",
100
+ "&#32;", "&#33;", "&quot;", "&#35;", "&#36;", "&#37;", "&amp;", "&apos;",
101
+ "&#40;", "&#41;", "&#42;", "&#43;", "&#44;", "&#45;", "&#46;", "&#47;",
102
+ "0", "1", "2", "3", "4", "5", "6", "7",
103
+ "8", "9", "&#58;", "&#59;", "&lt;", "&#61;", "&gt;", "&#63;",
104
+ "&#64;", "A", "B", "C", "D", "E", "F", "G",
105
+ "H", "I", "J", "K", "L", "M", "N", "O",
106
+ "P", "Q", "R", "S", "T", "U", "V", "W",
107
+ "X", "Y", "Z", "&#91;", "&#92;", "&#93;", "&#94;", "&#95;",
108
+ "&#96;", "a", "b", "c", "d", "e", "f", "g",
109
+ "h", "i", "j", "k", "l", "m", "n", "o",
110
+ "p", "q", "r", "s", "t", "u", "v", "w",
111
+ "x", "y", "z", "{", "&#124;", "}", "~", "\x7F",
112
+ "\x80", "\x81", "\x82", "\x83", "\x84", "\x85", "\x86", "\x87",
113
+ "\x88", "\x89", "\x8A", "\x8B", "\x8C", "\x8D", "\x8E", "\x8F",
114
+ "\x90", "\x91", "\x92", "\x93", "\x94", "\x95", "\x96", "\x97",
115
+ "\x98", "\x99", "\x9A", "\x9B", "\x9C", "\x9D", "\x9E", "\x9F",
116
+ "\xA0", "\xA1", "\xA2", "\xA3", "\xA4", "\xA5", "\xA6", "\xA7",
117
+ "\xA8", "\xA9", "\xAA", "\xAB", "\xAC", "\xAD", "\xAE", "\xAF",
118
+ "\xB0", "\xB1", "\xB2", "\xB3", "\xB4", "\xB5", "\xB6", "\xB7",
119
+ "\xB8", "\xB9", "\xBA", "\xBB", "\xBC", "\xBD", "\xBE", "\xBF",
120
+ "\xC0", "\xC1", "\xC2", "\xC3", "\xC4", "\xC5", "\xC6", "\xC7",
121
+ "\xC8", "\xC9", "\xCA", "\xCB", "\xCC", "\xCD", "\xCE", "\xCF",
122
+ "\xD0", "\xD1", "\xD2", "\xD3", "\xD4", "\xD5", "\xD6", "\xD7",
123
+ "\xD8", "\xD9", "\xDA", "\xDB", "\xDC", "\xDD", "\xDE", "\xDF",
124
+ "\xE0", "\xE1", "\xE2", "\xE3", "\xE4", "\xE5", "\xE6", "\xE7",
125
+ "\xE8", "\xE9", "\xEA", "\xEB", "\xEC", "\xED", "\xEE", "\xEF",
126
+ "\xF0", "\xF1", "\xF2", "\xF3", "\xF4", "\xF5", "\xF6", "\xF7",
127
+ "\xF8", "\xF9", "\xFA", "\xFB", "\xFC", "\xFD", "\xFE", "\xFF"};
107
128
  static uint8_t html_escape_len[] = {
108
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
109
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6,
110
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 4, 6, 4, 6, 6, 1, 1, 1, 1, 1, 1, 1,
111
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 6,
112
- 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
113
- 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
114
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
115
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
116
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
117
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
118
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
129
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
130
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5,
131
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 4, 5, 4, 5, 5, 1, 1, 1, 1, 1, 1, 1,
132
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5,
133
+ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
134
+ 1, 1, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
135
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
136
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
137
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
138
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
139
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
119
140
 
120
141
  static inline FIOBJ fiobj_mustache_find_obj(mustache_section_s *section,
121
142
  const char *name,
@@ -127,7 +148,7 @@ static inline FIOBJ fiobj_mustache_find_obj(mustache_section_s *section,
127
148
  if (!FIOBJ_TYPE_IS((FIOBJ)section->udata2, FIOBJ_T_HASH))
128
149
  continue;
129
150
  o = fiobj_hash_get((FIOBJ)section->udata2, key);
130
- section = section->parent;
151
+ section = mustache_section_parent(section);
131
152
  } while (o == FIOBJ_INVALID && section);
132
153
  return o;
133
154
  }
@@ -201,13 +222,15 @@ static int mustache_on_text(mustache_section_s *section, const char *data,
201
222
  * Please note, this will handle both normal and inverted sections.
202
223
  */
203
224
  static int32_t mustache_on_section_test(mustache_section_s *section,
204
- const char *name, uint32_t name_len) {
225
+ const char *name, uint32_t name_len,
226
+ uint8_t callable) {
205
227
  FIOBJ o = fiobj_mustache_find_obj(section, name, name_len);
206
- if (!o)
228
+ if (!o || FIOBJ_TYPE_IS(o, FIOBJ_T_FALSE))
207
229
  return 0;
208
230
  if (FIOBJ_TYPE_IS(o, FIOBJ_T_ARRAY))
209
231
  return fiobj_ary_count(o);
210
232
  return 1;
233
+ (void)callable;
211
234
  }
212
235
 
213
236
  /**