ucl 0.1.4 → 0.2.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.
@@ -0,0 +1,668 @@
1
+ /* Copyright (c) 2013, Vsevolod Stakhov
2
+ * All rights reserved.
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without
5
+ * modification, are permitted provided that the following conditions are met:
6
+ * * Redistributions of source code must retain the above copyright
7
+ * notice, this list of conditions and the following disclaimer.
8
+ * * Redistributions in binary form must reproduce the above copyright
9
+ * notice, this list of conditions and the following disclaimer in the
10
+ * documentation and/or other materials provided with the distribution.
11
+ *
12
+ * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
13
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15
+ * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
16
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
+ */
23
+
24
+ #ifndef UCL_INTERNAL_H_
25
+ #define UCL_INTERNAL_H_
26
+
27
+ #ifdef HAVE_CONFIG_H
28
+ #include "config.h"
29
+ #else
30
+ /* Help embedded builds */
31
+ #define HAVE_SYS_TYPES_H
32
+ #define HAVE_SYS_MMAN_H
33
+ #define HAVE_SYS_STAT_H
34
+ #define HAVE_SYS_PARAM_H
35
+ #define HAVE_LIMITS_H
36
+ #define HAVE_FCNTL_H
37
+ #define HAVE_ERRNO_H
38
+ #define HAVE_UNISTD_H
39
+ #define HAVE_CTYPE_H
40
+ #define HAVE_STDIO_H
41
+ #define HAVE_STRING_H
42
+ #define HAVE_FLOAT_H
43
+ #define HAVE_LIBGEN_H
44
+ #define HAVE_MATH_H
45
+ #define HAVE_STDBOOL_H
46
+ #define HAVE_STDINT_H
47
+ #define HAVE_STDARG_H
48
+ #ifndef _WIN32
49
+ #define HAVE_REGEX_H
50
+ #endif
51
+ #endif
52
+
53
+ #ifdef HAVE_SYS_TYPES_H
54
+ #include <sys/types.h>
55
+ #endif
56
+
57
+ #ifdef HAVE_SYS_MMAN_H
58
+ #ifndef _WIN32
59
+ #include <sys/mman.h>
60
+ #endif
61
+ #endif
62
+ #ifdef HAVE_SYS_STAT_H
63
+ #include <sys/stat.h>
64
+ #endif
65
+ #ifdef HAVE_SYS_PARAM_H
66
+ #ifndef _WIN32
67
+ #include <sys/param.h>
68
+ #endif
69
+ #endif
70
+
71
+ #ifdef HAVE_LIMITS_H
72
+ #include <limits.h>
73
+ #endif
74
+ #ifdef HAVE_FCNTL_H
75
+ #include <fcntl.h>
76
+ #endif
77
+ #ifdef HAVE_ERRNO_H
78
+ #include <errno.h>
79
+ #endif
80
+ #ifdef HAVE_UNISTD_H
81
+ #ifndef _WIN32
82
+ #include <unistd.h>
83
+ #endif
84
+ #endif
85
+ #ifdef HAVE_CTYPE_H
86
+ #include <ctype.h>
87
+ #endif
88
+ #ifdef HAVE_STDIO_H
89
+ #include <stdio.h>
90
+ #endif
91
+ #ifdef HAVE_STRING_H
92
+ #include <string.h>
93
+ #endif
94
+ #ifdef HAVE_STRINGS_H
95
+ #include <strings.h>
96
+ #endif
97
+
98
+ #if defined(_MSC_VER)
99
+ /* Windows hacks */
100
+ #include <BaseTsd.h>
101
+ #include <inttypes.h>
102
+ typedef SSIZE_T ssize_t;
103
+ #define strdup _strdup
104
+ #define snprintf _snprintf
105
+ #define vsnprintf _vsnprintf
106
+ #define strcasecmp _stricmp
107
+ #define strncasecmp _strnicmp
108
+ #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
109
+ #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
110
+ #if _MSC_VER >= 1900
111
+ #include <../ucrt/stdlib.h>
112
+ #else
113
+ #include <../include/stdlib.h>
114
+ #endif
115
+ #ifndef PATH_MAX
116
+ #define PATH_MAX _MAX_PATH
117
+ #endif
118
+
119
+ /* Dirname, basename implementations */
120
+
121
+
122
+ #endif
123
+
124
+ #include "utlist.h"
125
+ #include "utstring.h"
126
+ #include "uthash.h"
127
+ #include "ucl.h"
128
+ #include "ucl_hash.h"
129
+
130
+ #ifdef HAVE_OPENSSL
131
+ #include <openssl/evp.h>
132
+ #endif
133
+
134
+ #ifndef __DECONST
135
+ #define __DECONST(type, var) ((type) (uintptr_t) (const void *) (var))
136
+ #endif
137
+
138
+ /**
139
+ * @file rcl_internal.h
140
+ * Internal structures and functions of UCL library
141
+ */
142
+
143
+ #define UCL_MAX_RECURSION 16
144
+ #define UCL_TRASH_KEY 0
145
+ #define UCL_TRASH_VALUE 1
146
+
147
+ enum ucl_parser_state {
148
+ UCL_STATE_INIT = 0,
149
+ UCL_STATE_OBJECT,
150
+ UCL_STATE_ARRAY,
151
+ UCL_STATE_KEY,
152
+ UCL_STATE_KEY_OBRACE,
153
+ UCL_STATE_VALUE,
154
+ UCL_STATE_AFTER_VALUE,
155
+ UCL_STATE_ARRAY_VALUE,
156
+ UCL_STATE_SCOMMENT,
157
+ UCL_STATE_MCOMMENT,
158
+ UCL_STATE_MACRO_NAME,
159
+ UCL_STATE_MACRO,
160
+ UCL_STATE_ERROR
161
+ };
162
+
163
+ enum ucl_character_type {
164
+ UCL_CHARACTER_DENIED = (1 << 0),
165
+ UCL_CHARACTER_KEY = (1 << 1),
166
+ UCL_CHARACTER_KEY_START = (1 << 2),
167
+ UCL_CHARACTER_WHITESPACE = (1 << 3),
168
+ UCL_CHARACTER_WHITESPACE_UNSAFE = (1 << 4),
169
+ UCL_CHARACTER_VALUE_END = (1 << 5),
170
+ UCL_CHARACTER_VALUE_STR = (1 << 6),
171
+ UCL_CHARACTER_VALUE_DIGIT = (1 << 7),
172
+ UCL_CHARACTER_VALUE_DIGIT_START = (1 << 8),
173
+ UCL_CHARACTER_ESCAPE = (1 << 9),
174
+ UCL_CHARACTER_KEY_SEP = (1 << 10),
175
+ UCL_CHARACTER_JSON_UNSAFE = (1 << 11),
176
+ UCL_CHARACTER_UCL_UNSAFE = (1 << 12)
177
+ };
178
+
179
+ struct ucl_macro {
180
+ char *name;
181
+ union _ucl_macro {
182
+ ucl_macro_handler handler;
183
+ ucl_context_macro_handler context_handler;
184
+ } h;
185
+ void *ud;
186
+ bool is_context;
187
+ UT_hash_handle hh;
188
+ };
189
+
190
+ enum ucl_stack_flags {
191
+ UCL_STACK_HAS_OBRACE = (1u << 0),
192
+ UCL_STACK_AUTOMATIC = (1u << 1),
193
+ UCL_STACK_MAX = (1u << 2),
194
+ };
195
+
196
+ struct ucl_stack {
197
+ ucl_object_t *obj;
198
+ struct ucl_stack *next;
199
+ union {
200
+ struct {
201
+ uint16_t level;
202
+ uint16_t flags;
203
+ uint32_t line;
204
+ } params;
205
+ uint64_t len;
206
+ } e;
207
+ struct ucl_chunk *chunk;
208
+ };
209
+
210
+ struct ucl_parser_special_handler_chain {
211
+ unsigned char *begin;
212
+ size_t len;
213
+ struct ucl_parser_special_handler *special_handler;
214
+ struct ucl_parser_special_handler_chain *next;
215
+ };
216
+
217
+ struct ucl_chunk {
218
+ const unsigned char *begin;
219
+ const unsigned char *end;
220
+ const unsigned char *pos;
221
+ char *fname;
222
+ size_t remain;
223
+ unsigned int line;
224
+ unsigned int column;
225
+ unsigned priority;
226
+ enum ucl_duplicate_strategy strategy;
227
+ enum ucl_parse_type parse_type;
228
+ struct ucl_parser_special_handler_chain *special_handlers;
229
+ struct ucl_chunk *next;
230
+ };
231
+
232
+ #ifdef HAVE_OPENSSL
233
+ struct ucl_pubkey {
234
+ EVP_PKEY *key;
235
+ struct ucl_pubkey *next;
236
+ };
237
+ #else
238
+ struct ucl_pubkey {
239
+ struct ucl_pubkey *next;
240
+ };
241
+ #endif
242
+
243
+ struct ucl_variable {
244
+ char *var;
245
+ char *value;
246
+ size_t var_len;
247
+ size_t value_len;
248
+ struct ucl_variable *prev, *next;
249
+ };
250
+
251
+ struct ucl_parser {
252
+ enum ucl_parser_state state;
253
+ enum ucl_parser_state prev_state;
254
+ unsigned int recursion;
255
+ int flags;
256
+ unsigned default_priority;
257
+ int err_code;
258
+ ucl_object_t *top_obj;
259
+ ucl_object_t *cur_obj;
260
+ ucl_object_t *trash_objs;
261
+ ucl_object_t *includepaths;
262
+ char *cur_file;
263
+ struct ucl_macro *macroes;
264
+ struct ucl_stack *stack;
265
+ struct ucl_chunk *chunks;
266
+ struct ucl_pubkey *keys;
267
+ struct ucl_parser_special_handler *special_handlers;
268
+ ucl_include_trace_func_t *include_trace_func;
269
+ void *include_trace_ud;
270
+ struct ucl_variable *variables;
271
+ ucl_variable_handler var_handler;
272
+ void *var_data;
273
+ ucl_object_t *comments;
274
+ ucl_object_t *last_comment;
275
+ UT_string *err;
276
+ };
277
+
278
+ struct ucl_object_userdata {
279
+ ucl_object_t obj;
280
+ ucl_userdata_dtor dtor;
281
+ ucl_userdata_emitter emitter;
282
+ };
283
+
284
+ /**
285
+ * Unescape json string inplace
286
+ * @param str
287
+ */
288
+ size_t ucl_unescape_json_string(char *str, size_t len);
289
+
290
+
291
+ /**
292
+ * Unescape single quoted string inplace
293
+ * @param str
294
+ */
295
+ size_t ucl_unescape_squoted_string(char *str, size_t len);
296
+
297
+ /**
298
+ * Handle include macro
299
+ * @param data include data
300
+ * @param len length of data
301
+ * @param args UCL object representing arguments to the macro
302
+ * @param ud user data
303
+ * @return
304
+ */
305
+ bool ucl_include_handler(const unsigned char *data, size_t len,
306
+ const ucl_object_t *args, void *ud);
307
+
308
+ /**
309
+ * Handle tryinclude macro
310
+ * @param data include data
311
+ * @param len length of data
312
+ * @param args UCL object representing arguments to the macro
313
+ * @param ud user data
314
+ * @return
315
+ */
316
+ bool ucl_try_include_handler(const unsigned char *data, size_t len,
317
+ const ucl_object_t *args, void *ud);
318
+
319
+ /**
320
+ * Handle includes macro
321
+ * @param data include data
322
+ * @param len length of data
323
+ * @param args UCL object representing arguments to the macro
324
+ * @param ud user data
325
+ * @return
326
+ */
327
+ bool ucl_includes_handler(const unsigned char *data, size_t len,
328
+ const ucl_object_t *args, void *ud);
329
+
330
+ /**
331
+ * Handle priority macro
332
+ * @param data include data
333
+ * @param len length of data
334
+ * @param args UCL object representing arguments to the macro
335
+ * @param ud user data
336
+ * @return
337
+ */
338
+ bool ucl_priority_handler(const unsigned char *data, size_t len,
339
+ const ucl_object_t *args, void *ud);
340
+
341
+ /**
342
+ * Handle load macro
343
+ * @param data include data
344
+ * @param len length of data
345
+ * @param args UCL object representing arguments to the macro
346
+ * @param ud user data
347
+ * @return
348
+ */
349
+ bool ucl_load_handler(const unsigned char *data, size_t len,
350
+ const ucl_object_t *args, void *ud);
351
+ /**
352
+ * Handle inherit macro
353
+ * @param data include data
354
+ * @param len length of data
355
+ * @param args UCL object representing arguments to the macro
356
+ * @param ctx the current context object
357
+ * @param ud user data
358
+ * @return
359
+ */
360
+ bool ucl_inherit_handler(const unsigned char *data, size_t len,
361
+ const ucl_object_t *args, const ucl_object_t *ctx, void *ud);
362
+
363
+ size_t ucl_strlcpy(char *dst, const char *src, size_t siz);
364
+ size_t ucl_strlcpy_unsafe(char *dst, const char *src, size_t siz);
365
+ size_t ucl_strlcpy_tolower(char *dst, const char *src, size_t siz);
366
+
367
+ char *ucl_strnstr(const char *s, const char *find, int len);
368
+ char *ucl_strncasestr(const char *s, const char *find, int len);
369
+
370
+ #ifdef __GNUC__
371
+ static inline void
372
+ ucl_create_err(UT_string **err, const char *fmt, ...)
373
+ __attribute__((format(printf, 2, 3)));
374
+ #endif
375
+
376
+ #undef UCL_FATAL_ERRORS
377
+
378
+ static inline void
379
+ ucl_create_err(UT_string **err, const char *fmt, ...)
380
+ {
381
+ if (*err == NULL) {
382
+ utstring_new(*err);
383
+ va_list ap;
384
+ va_start(ap, fmt);
385
+ utstring_printf_va(*err, fmt, ap);
386
+ va_end(ap);
387
+ }
388
+
389
+ #ifdef UCL_FATAL_ERRORS
390
+ assert(0);
391
+ #endif
392
+ }
393
+
394
+ /**
395
+ * Check whether a given string contains a boolean value
396
+ * @param obj object to set
397
+ * @param start start of a string
398
+ * @param len length of a string
399
+ * @return true if a string is a boolean value
400
+ */
401
+ static inline bool
402
+ ucl_maybe_parse_boolean(ucl_object_t *obj, const unsigned char *start, size_t len)
403
+ {
404
+ const char *p = (const char *) start;
405
+ bool ret = false, val = false;
406
+
407
+ if (len == 5) {
408
+ if ((p[0] == 'f' || p[0] == 'F') && strncasecmp(p, "false", 5) == 0) {
409
+ ret = true;
410
+ val = false;
411
+ }
412
+ }
413
+ else if (len == 4) {
414
+ if ((p[0] == 't' || p[0] == 'T') && strncasecmp(p, "true", 4) == 0) {
415
+ ret = true;
416
+ val = true;
417
+ }
418
+ }
419
+ else if (len == 3) {
420
+ if ((p[0] == 'y' || p[0] == 'Y') && strncasecmp(p, "yes", 3) == 0) {
421
+ ret = true;
422
+ val = true;
423
+ }
424
+ else if ((p[0] == 'o' || p[0] == 'O') && strncasecmp(p, "off", 3) == 0) {
425
+ ret = true;
426
+ val = false;
427
+ }
428
+ }
429
+ else if (len == 2) {
430
+ if ((p[0] == 'n' || p[0] == 'N') && strncasecmp(p, "no", 2) == 0) {
431
+ ret = true;
432
+ val = false;
433
+ }
434
+ else if ((p[0] == 'o' || p[0] == 'O') && strncasecmp(p, "on", 2) == 0) {
435
+ ret = true;
436
+ val = true;
437
+ }
438
+ }
439
+
440
+ if (ret && obj != NULL) {
441
+ obj->type = UCL_BOOLEAN;
442
+ obj->value.iv = val;
443
+ }
444
+
445
+ return ret;
446
+ }
447
+
448
+ /**
449
+ * Check numeric string
450
+ * @param obj object to set if a string is numeric
451
+ * @param start start of string
452
+ * @param end end of string
453
+ * @param pos position where parsing has stopped
454
+ * @param allow_double allow parsing of floating point values
455
+ * @return 0 if string is numeric and error code (EINVAL or ERANGE) in case of conversion error
456
+ */
457
+ int ucl_maybe_parse_number(ucl_object_t *obj,
458
+ const char *start, const char *end, const char **pos,
459
+ bool allow_double, bool number_bytes, bool allow_time);
460
+
461
+
462
+ static inline const ucl_object_t *
463
+ ucl_hash_search_obj(ucl_hash_t *hashlin, ucl_object_t *obj)
464
+ {
465
+ return (const ucl_object_t *) ucl_hash_search(hashlin, obj->key, obj->keylen);
466
+ }
467
+
468
+ static inline ucl_hash_t *ucl_hash_insert_object(ucl_hash_t *hashlin,
469
+ const ucl_object_t *obj,
470
+ bool ignore_case) UCL_WARN_UNUSED_RESULT;
471
+
472
+ static inline ucl_hash_t *
473
+ ucl_hash_insert_object(ucl_hash_t *hashlin,
474
+ const ucl_object_t *obj,
475
+ bool ignore_case)
476
+ {
477
+ ucl_hash_t *nhp;
478
+
479
+ if (hashlin == NULL) {
480
+ nhp = ucl_hash_create(ignore_case);
481
+ if (nhp == NULL) {
482
+ return NULL;
483
+ }
484
+ }
485
+ else {
486
+ nhp = hashlin;
487
+ }
488
+ if (!ucl_hash_insert(nhp, obj, obj->key, obj->keylen)) {
489
+ if (nhp != hashlin) {
490
+ ucl_hash_destroy(nhp, NULL);
491
+ }
492
+ return NULL;
493
+ }
494
+
495
+ return nhp;
496
+ }
497
+
498
+ /**
499
+ * Get standard emitter context for a specified emit_type
500
+ * @param emit_type type of emitter
501
+ * @return context or NULL if input is invalid
502
+ */
503
+ const struct ucl_emitter_context *
504
+ ucl_emit_get_standard_context(enum ucl_emitter emit_type);
505
+
506
+ /**
507
+ * Serialize string as JSON string
508
+ * @param str string to emit
509
+ * @param buf target buffer
510
+ */
511
+ void ucl_elt_string_write_json(const char *str, size_t size,
512
+ struct ucl_emitter_context *ctx);
513
+
514
+
515
+ /**
516
+ * Serialize string as single quoted string
517
+ * @param str string to emit
518
+ * @param buf target buffer
519
+ */
520
+ void ucl_elt_string_write_squoted(const char *str, size_t size,
521
+ struct ucl_emitter_context *ctx);
522
+
523
+ /**
524
+ * Write multiline string using `EOD` as string terminator
525
+ * @param str
526
+ * @param size
527
+ * @param ctx
528
+ */
529
+ void ucl_elt_string_write_multiline(const char *str, size_t size,
530
+ struct ucl_emitter_context *ctx);
531
+
532
+ /**
533
+ * Emit a single object to string
534
+ * @param obj
535
+ * @return
536
+ */
537
+ unsigned char *ucl_object_emit_single_json(const ucl_object_t *obj);
538
+
539
+ /**
540
+ * Check whether a specified string is long and should be likely printed in
541
+ * multiline mode
542
+ * @param obj
543
+ * @return
544
+ */
545
+ bool ucl_maybe_long_string(const ucl_object_t *obj);
546
+
547
+ /**
548
+ * Print integer to the msgpack output
549
+ * @param ctx
550
+ * @param val
551
+ */
552
+ void ucl_emitter_print_int_msgpack(struct ucl_emitter_context *ctx,
553
+ int64_t val);
554
+ /**
555
+ * Print integer to the msgpack output
556
+ * @param ctx
557
+ * @param val
558
+ */
559
+ void ucl_emitter_print_double_msgpack(struct ucl_emitter_context *ctx,
560
+ double val);
561
+ /**
562
+ * Print double to the msgpack output
563
+ * @param ctx
564
+ * @param val
565
+ */
566
+ void ucl_emitter_print_bool_msgpack(struct ucl_emitter_context *ctx,
567
+ bool val);
568
+ /**
569
+ * Print string to the msgpack output
570
+ * @param ctx
571
+ * @param s
572
+ * @param len
573
+ */
574
+ void ucl_emitter_print_string_msgpack(struct ucl_emitter_context *ctx,
575
+ const char *s, size_t len);
576
+
577
+ /**
578
+ * Print binary string to the msgpack output
579
+ * @param ctx
580
+ * @param s
581
+ * @param len
582
+ */
583
+ void ucl_emitter_print_binary_string_msgpack(struct ucl_emitter_context *ctx,
584
+ const char *s, size_t len);
585
+
586
+ /**
587
+ * Print array preamble for msgpack
588
+ * @param ctx
589
+ * @param len
590
+ */
591
+ void ucl_emitter_print_array_msgpack(struct ucl_emitter_context *ctx,
592
+ size_t len);
593
+
594
+ /**
595
+ * Print object preamble for msgpack
596
+ * @param ctx
597
+ * @param len
598
+ */
599
+ void ucl_emitter_print_object_msgpack(struct ucl_emitter_context *ctx,
600
+ size_t len);
601
+ /**
602
+ * Print NULL to the msgpack output
603
+ * @param ctx
604
+ */
605
+ void ucl_emitter_print_null_msgpack(struct ucl_emitter_context *ctx);
606
+ /**
607
+ * Print object's key if needed to the msgpack output
608
+ * @param print_key
609
+ * @param ctx
610
+ * @param obj
611
+ */
612
+ void ucl_emitter_print_key_msgpack(bool print_key,
613
+ struct ucl_emitter_context *ctx,
614
+ const ucl_object_t *obj);
615
+
616
+ /**
617
+ * Fetch URL into a buffer
618
+ * @param url url to fetch
619
+ * @param buf pointer to buffer (must be freed by callee)
620
+ * @param buflen pointer to buffer length
621
+ * @param err pointer to error argument
622
+ * @param must_exist fail if cannot find a url
623
+ */
624
+ bool ucl_fetch_url(const unsigned char *url,
625
+ unsigned char **buf,
626
+ size_t *buflen,
627
+ UT_string **err,
628
+ bool must_exist);
629
+
630
+ /**
631
+ * Fetch a file and save results to the memory buffer
632
+ * @param filename filename to fetch
633
+ * @param len length of filename
634
+ * @param buf target buffer
635
+ * @param buflen target length
636
+ * @return
637
+ */
638
+ bool ucl_fetch_file(const unsigned char *filename,
639
+ unsigned char **buf,
640
+ size_t *buflen,
641
+ UT_string **err,
642
+ bool must_exist);
643
+
644
+ /**
645
+ * Add new element to an object using the current merge strategy and priority
646
+ * @param parser
647
+ * @param nobj
648
+ * @return
649
+ */
650
+ bool ucl_parser_process_object_element(struct ucl_parser *parser,
651
+ ucl_object_t *nobj);
652
+
653
+ /**
654
+ * Parse msgpack chunk
655
+ * @param parser
656
+ * @return
657
+ */
658
+ bool ucl_parse_msgpack(struct ucl_parser *parser);
659
+
660
+ bool ucl_parse_csexp(struct ucl_parser *parser);
661
+
662
+ /**
663
+ * Free ucl chunk
664
+ * @param chunk
665
+ */
666
+ void ucl_chunk_free(struct ucl_chunk *chunk);
667
+
668
+ #endif /* UCL_INTERNAL_H_ */