diff --git a/json/json.c b/json/json.c
index beba289..e0ea300 100644
--- a/json/json.c
+++ b/json/json.c
@@ -13,27 +13,53 @@
#include <libkc3/kc3.h>
#include "json.h"
-/*s_tag * json_buf_parse_null (const s_buf *buf, s_tag *dest) {
+s_tag * json_buf_parse (s_buf *buf, s_tag *dest)
+{
character c;
sw r;
s_buf_save save;
+ s_tag tmp;
assert(buf);
assert(dest);
buf_save_init(buf, &save);
- if ((r = buf_read_1(buf, "void")) <= 0)
- goto clean;
- if (buf_peek_character_utf8(buf, &c) > 0 &&
- ! ident_character_is_reserved(c)) {
- r = 0;
- goto restore;
+ if ((r = buf_peek_character_utf8(buf, &c)) < 0)
+ return NULL;
+ switch (c) {
+ case '{':
+ return json_buf_parse_map(buf, dest);
+ case '"':
+ return json_buf_parse_str(buf, dest);
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ return json_buf_parse_number(buf, dest);
+ break;
+ case 't':
+ case 'f':
+ return json_buf_parse_bool(buf, dest);
+ break;
+ default:
+ return NULL;
}
- goto clean;
- restore:
- buf_save_restore_rpos(buf, &save);
- clean:
- buf_save_clean(buf, &save);
- return r;
-}*/
+ *dest = tmp;
+ return dest;
+}
+
+s_tag * json_buf_parse_bool (s_buf *buf, s_tag *dest)
+{
+ sw r;
+ if ((r = buf_parse_tag_bool(buf, dest)) <= 0)
+ return NULL;
+ return dest;
+}
s_tag * json_buf_parse_map (s_buf *buf, s_tag *dest)
{
@@ -45,13 +71,13 @@ s_tag * json_buf_parse_map (s_buf *buf, s_tag *dest)
s_list *values;
assert(buf);
assert(dest);
- buf_save_init(buf, &save);
- if ((r = buf_read_1(buf, "{")) <= 0)
- goto clean;
keys = NULL;
k = &keys;
values = NULL;
v = &values;
+ buf_save_init(buf, &save);
+ if ((r = buf_read_1(buf, "{")) <= 0)
+ goto clean;
while (1) {
if ((r = buf_ignore_spaces(buf)) <= 0)
goto restore;
@@ -59,14 +85,16 @@ s_tag * json_buf_parse_map (s_buf *buf, s_tag *dest)
goto restore;
if (r > 0)
break;
- buf_parse_tag_str(buf, &(*k)->tag);
- buf_parse_tag(buf, &(*v)->tag);
+ if ((r = buf_parse_tag_str(buf, &(*k)->tag)) <= 0)
+ goto restore;
+ if (! json_buf_parse(buf, &(*v)->tag))
+ goto restore;
}
- dest->type = TAG_MAP;
- if (! map_init_from_lists(&dest->data.map, keys, values))
+ if (! tag_init_map_from_lists(dest, keys, values))
goto restore;
list_delete_all(keys);
list_delete_all(values);
+ buf_save_clean(buf, &save);
return dest;
restore:
buf_save_restore_rpos(buf, &save);
@@ -77,58 +105,49 @@ s_tag * json_buf_parse_map (s_buf *buf, s_tag *dest)
return NULL;
}
-s_tag * json_buf_parse_numbers (s_buf *buf, s_tag *dest)
+s_tag * json_buf_parse_null (s_buf *buf, s_tag *dest)
{
+ character c;
+ sw r;
s_buf_save save;
assert(buf);
assert(dest);
buf_save_init(buf, &save);
- if (! buf_parse_tag_number(buf, dest)) {
- buf_save_restore_rpos(buf, &save);
- return NULL;
+ if ((r = buf_read_1(buf, "null")) <= 0)
+ goto clean;
+ if (buf_peek_character_utf8(buf, &c) > 0 &&
+ ! ident_character_is_reserved(c)) {
+ r = 0;
+ goto restore;
}
+ tag_init_void(dest);
+ buf_save_clean(buf, &save);
return dest;
+ restore:
+ buf_save_restore_rpos(buf, &save);
+ clean:
+ buf_save_clean(buf, &save);
+ return NULL;
}
-s_tag * json_buf_parse (s_buf *buf, s_tag *dest)
+s_tag * json_buf_parse_number (s_buf *buf, s_tag *dest)
{
- character c;
- sw r;
s_buf_save save;
- s_tag tmp;
assert(buf);
assert(dest);
buf_save_init(buf, &save);
- if ((r =buf_peek_character_utf8(buf, &c)) < 0)
+ if (! buf_parse_tag_number(buf, dest)) {
+ buf_save_restore_rpos(buf, &save);
return NULL;
- switch (c) {
- case '{':
- json_buf_parse_map(buf, &tmp);
- break;
- case '"':
- buf_parse_tag_str(buf, &tmp);
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '-':
- json_buf_parse_numbers(buf, &tmp);
- break;
- case 't':
- case 'f':
- buf_parse_tag_bool(buf, &tmp);
- break;
- default:
- return NULL;
}
- *dest = tmp;
+ return dest;
+}
+
+s_tag * json_buf_parse_str (s_buf *buf, s_tag *dest)
+{
+ sw r;
+ if ((r = buf_parse_tag_str(buf, dest)) <= 0)
+ return NULL;
return dest;
}
diff --git a/json/json.h b/json/json.h
index 27c83b4..809fb76 100644
--- a/json/json.h
+++ b/json/json.h
@@ -16,6 +16,11 @@
#include <libkc3/types.h>
s_tag * json_buf_parse (s_buf *buf, s_tag *dest);
+s_tag * json_buf_parse_bool (s_buf *buf, s_tag *dest);
+s_tag * json_buf_parse_map (s_buf *buf, s_tag *dest);
+s_tag * json_buf_parse_null (s_buf *buf, s_tag *dest);
+s_tag * json_buf_parse_number (s_buf *buf, s_tag *dest);
+s_tag * json_buf_parse_str (s_buf *buf, s_tag *dest);
s_tag * json_from_str (const s_str *src, s_tag *dest);
#endif /* KC3_JSON_H */
diff --git a/libkc3/list_init.c b/libkc3/list_init.c
index d5b2414..403ea6a 100644
--- a/libkc3/list_init.c
+++ b/libkc3/list_init.c
@@ -230,6 +230,18 @@ s_list * list_init_map_1 (s_list *list, const char *p, s_list *next)
return list;
}
+s_list * list_init_map_from_lists (s_list *list, const s_list *keys,
+ const s_list *values, s_list *next)
+{
+ s_list tmp = {0};
+ assert(list);
+ list_init(&tmp, next);
+ if (! tag_init_map_from_lists(&tmp.tag, keys, values))
+ return NULL;
+ *list = tmp;
+ return list;
+}
+
s_list * list_init_ptr (s_list *list, void *p, s_list *next)
{
s_list tmp = {0};
@@ -879,6 +891,20 @@ s_list * list_new_map_1 (const char *p, s_list *next)
return list;
}
+s_list * list_new_map_from_lists (const s_list *keys,
+ const s_list *values, s_list *next)
+{
+ s_list *list;
+ list = list_new(next);
+ if (! list)
+ return NULL;
+ if (! tag_init_map_from_lists(&list->tag, keys, values)) {
+ free(list);
+ return NULL;
+ }
+ return list;
+}
+
s_list * list_new_ptr (void *p, s_list *next)
{
s_list *list;
diff --git a/libkc3/list_init.h b/libkc3/list_init.h
index fb94a63..fa7c587 100644
--- a/libkc3/list_init.h
+++ b/libkc3/list_init.h
@@ -41,6 +41,8 @@ s_list * list_init_integer_zero (s_list *list, s_list *next);
s_list * list_init_map (s_list *list, uw count, s_list *next);
s_list * list_init_map_1 (s_list *list, const char *p, s_list *next);
+s_list * list_init_map_from_lists (s_list *list, const s_list *keys,
+ const s_list *values, s_list *next);
s_list * list_init_ptr (s_list *list, void *p, s_list *next);
s_list * list_init_ptr_free (s_list *list, void *p, s_list *next);
s_list * list_init_quote_copy (s_list *list, const s_quote *quote,
@@ -122,6 +124,8 @@ s_list * list_new_integer_zero (s_list *next);
s_list * list_new_map (uw count, s_list *next);
s_list * list_new_map_1 (const char *p, s_list *next);
+s_list * list_new_map_from_lists (const s_list *keys,
+ const s_list *values, s_list *next);
s_list * list_new_ptr (void *p, s_list *next);
s_list * list_new_ptr_free (void *p, s_list *next);
s_list * list_new_quote_copy (const s_quote *quote, s_list *next);
@@ -191,6 +195,8 @@ s_list * list_integer_zero (s_list *list);
s_list * list_map (s_list *list, uw count);
s_list * list_map_1 (s_list *list, const char *p);
+s_list * list_map_from_lists (s_list *list, const s_list *keys,
+ const s_list *values);
s_list * list_ptr (s_list *list, void *p);
s_list * list_ptr_free (s_list *list, void *p);
s_list * list_quote_copy (s_list *list, const s_quote *quote);
diff --git a/libkc3/tag_init.c b/libkc3/tag_init.c
index d0a95ee..5ebc612 100644
--- a/libkc3/tag_init.c
+++ b/libkc3/tag_init.c
@@ -232,6 +232,18 @@ s_tag * tag_init_map_1 (s_tag *tag, const char *p)
return tag;
}
+s_tag * tag_init_map_from_lists (s_tag *tag, const s_list *keys,
+ const s_list *values)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_MAP;
+ if (! map_init_from_lists(&tmp.data.map, keys, values))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
s_tag * tag_init_ptr (s_tag *tag, void *p)
{
s_tag tmp = {0};
@@ -861,6 +873,21 @@ s_tag * tag_new_map_1 (const char *p)
return tag;
}
+s_tag * tag_new_map_from_lists (const s_list *keys,
+ const s_list *values)
+{
+ s_tag *tag;
+ tag = alloc(sizeof(s_tag));
+ if (! tag)
+ return NULL;
+ tag->type = TAG_MAP;
+ if (! map_init_from_lists(&tag->data.map, keys, values)) {
+ free(tag);
+ return NULL;
+ }
+ return tag;
+}
+
s_tag * tag_new_ptr (void *p)
{
s_tag *tag;
@@ -1555,6 +1582,19 @@ s_tag * tag_map_1 (s_tag *tag, const char *p)
return tag;
}
+s_tag * tag_map_from_lists (s_tag *tag, const s_list *keys,
+ const s_list *values)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_MAP;
+ if (! map_init_from_lists(&tmp.data.map, keys, values))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
s_tag * tag_ptr (s_tag *tag, void *p)
{
s_tag tmp = {0};
diff --git a/libkc3/tag_init.h b/libkc3/tag_init.h
index a086916..7ff3bbf 100644
--- a/libkc3/tag_init.h
+++ b/libkc3/tag_init.h
@@ -36,6 +36,8 @@ s_tag * tag_init_integer_zero (s_tag *tag);
s_tag * tag_init_list (s_tag *tag, s_list *list);
s_tag * tag_init_map (s_tag *tag, uw count);
s_tag * tag_init_map_1 (s_tag *tag, const char *p);
+s_tag * tag_init_map_from_lists (s_tag *tag, const s_list *keys,
+ const s_list *values);
s_tag * tag_init_ptr (s_tag *tag, void *p);
s_tag * tag_init_ptr_free (s_tag *tag, void *p);
s_tag * tag_init_quote_copy (s_tag *tag, const s_quote *quote);
@@ -102,6 +104,8 @@ s_tag * tag_new_integer_zero (void);
s_tag * tag_new_list (s_list *list);
s_tag * tag_new_map (uw count);
s_tag * tag_new_map_1 (const char *p);
+s_tag * tag_new_map_from_lists (const s_list *keys,
+ const s_list *values);
s_tag * tag_new_ptr (void *p);
s_tag * tag_new_ptr_free (void *p);
s_tag * tag_new_quote_copy (const s_quote *quote);
@@ -164,6 +168,8 @@ s_tag * tag_integer_zero (s_tag *tag);
s_tag * tag_list (s_tag *tag, s_list *list);
s_tag * tag_map (s_tag *tag, uw count);
s_tag * tag_map_1 (s_tag *tag, const char *p);
+s_tag * tag_map_from_lists (s_tag *tag, const s_list *keys,
+ const s_list *values);
s_tag * tag_ptr (s_tag *tag, void *p);
s_tag * tag_ptr_free (s_tag *tag, void *p);
s_tag * tag_quote_copy (s_tag *tag, const s_quote *quote);
diff --git a/libkc3/tag_init.rb b/libkc3/tag_init.rb
index ccf62a9..4f88f33 100644
--- a/libkc3/tag_init.rb
+++ b/libkc3/tag_init.rb
@@ -339,6 +339,9 @@ class TagInitList
TagInit.new("map", "TAG_MAP", :init_mode_init,
[Arg.new("uw", "count")]),
TagInit1.new("map", "1", "TAG_MAP", :init_mode_init),
+ TagInit.new("map", "from_lists", "TAG_MAP", :init_mode_init,
+ [Arg.new("const s_list *", "keys"),
+ Arg.new("const s_list *", "values")]),
TagInit.new("ptr", "TAG_PTR", :init_mode_init,
[Arg.new("void *", "p")]),
TagInit.new("ptr_free", "TAG_PTR_FREE", :init_mode_init,