diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-07-22 19:03:25 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-07-22 19:03:25 +0200 |
commit | f754082176ba202596cedaec98ee06c2ca2e48e4 (patch) | |
tree | 773974ed787cecb8a74e4a8b24f4bdb5a7741fc1 /src | |
parent | 1a90ef262d8e60630d5b79135c2eefe78b1341d4 (diff) | |
download | gnunet-f754082176ba202596cedaec98ee06c2ca2e48e4.tar.gz gnunet-f754082176ba202596cedaec98ee06c2ca2e48e4.zip |
introduce GNUNET_JSON_spec_mark_optional
Diffstat (limited to 'src')
-rw-r--r-- | src/include/gnunet_json_lib.h | 15 | ||||
-rw-r--r-- | src/json/json.c | 64 |
2 files changed, 51 insertions, 28 deletions
diff --git a/src/include/gnunet_json_lib.h b/src/include/gnunet_json_lib.h index 32de2208a..72d2c4ebe 100644 --- a/src/include/gnunet_json_lib.h +++ b/src/include/gnunet_json_lib.h | |||
@@ -104,6 +104,11 @@ struct GNUNET_JSON_Specification | |||
104 | * Where should we store the final size of @e ptr. | 104 | * Where should we store the final size of @e ptr. |
105 | */ | 105 | */ |
106 | size_t *size_ptr; | 106 | size_t *size_ptr; |
107 | |||
108 | /** | ||
109 | * Set to #GNUNET_YES if this component is optional. | ||
110 | */ | ||
111 | int is_optional; | ||
107 | }; | 112 | }; |
108 | 113 | ||
109 | 114 | ||
@@ -148,6 +153,16 @@ GNUNET_JSON_spec_end (void); | |||
148 | 153 | ||
149 | 154 | ||
150 | /** | 155 | /** |
156 | * Set the "optional" flag for a parser specification entry. | ||
157 | * | ||
158 | * @param spec specification to modify | ||
159 | * @return spec copy of @a spec with optional bit set | ||
160 | */ | ||
161 | struct GNUNET_JSON_Specification | ||
162 | GNUNET_JSON_spec_mark_optional (struct GNUNET_JSON_Specification spec); | ||
163 | |||
164 | |||
165 | /** | ||
151 | * Variable size object (in network byte order, encoded using Crockford | 166 | * Variable size object (in network byte order, encoded using Crockford |
152 | * Base32hex encoding). | 167 | * Base32hex encoding). |
153 | * | 168 | * |
diff --git a/src/json/json.c b/src/json/json.c index fdce30488..068214f4e 100644 --- a/src/json/json.c +++ b/src/json/json.c | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
@@ -47,23 +47,20 @@ GNUNET_JSON_parse (const json_t *root, | |||
47 | const char **error_json_name, | 47 | const char **error_json_name, |
48 | unsigned int *error_line) | 48 | unsigned int *error_line) |
49 | { | 49 | { |
50 | unsigned int i; | ||
51 | json_t *pos; | ||
52 | |||
53 | if (NULL == root) | 50 | if (NULL == root) |
54 | return GNUNET_SYSERR; | 51 | return GNUNET_SYSERR; |
55 | for (i=0;NULL != spec[i].parser;i++) | 52 | for (unsigned int i = 0; NULL != spec[i].parser; i++) |
56 | { | 53 | { |
54 | json_t *pos; | ||
55 | |||
57 | if (NULL == spec[i].field) | 56 | if (NULL == spec[i].field) |
58 | pos = (json_t *) root; | 57 | pos = (json_t *) root; |
59 | else | 58 | else |
60 | pos = json_object_get (root, | 59 | pos = json_object_get (root, spec[i].field); |
61 | spec[i].field); | 60 | if ((NULL == pos) && (spec[i].is_optional)) |
62 | if ( (NULL == pos) || | 61 | continue; |
63 | (GNUNET_OK != | 62 | if ((NULL == pos) || |
64 | spec[i].parser (spec[i].cls, | 63 | (GNUNET_OK != spec[i].parser (spec[i].cls, pos, &spec[i]))) |
65 | pos, | ||
66 | &spec[i])) ) | ||
67 | { | 64 | { |
68 | if (NULL != error_json_name) | 65 | if (NULL != error_json_name) |
69 | *error_json_name = spec[i].field; | 66 | *error_json_name = spec[i].field; |
@@ -78,6 +75,22 @@ GNUNET_JSON_parse (const json_t *root, | |||
78 | 75 | ||
79 | 76 | ||
80 | /** | 77 | /** |
78 | * Set the "optional" flag for a parser specification entry. | ||
79 | * | ||
80 | * @param spec specification to modify | ||
81 | * @return spec copy of @a spec with optional bit set | ||
82 | */ | ||
83 | struct GNUNET_JSON_Specification | ||
84 | GNUNET_JSON_spec_mark_optional (struct GNUNET_JSON_Specification spec) | ||
85 | { | ||
86 | struct GNUNET_JSON_Specification ret = spec; | ||
87 | |||
88 | ret.is_optional = GNUNET_YES; | ||
89 | return ret; | ||
90 | } | ||
91 | |||
92 | |||
93 | /** | ||
81 | * Frees all elements allocated during a #GNUNET_JSON_parse() | 94 | * Frees all elements allocated during a #GNUNET_JSON_parse() |
82 | * operation. | 95 | * operation. |
83 | * | 96 | * |
@@ -86,10 +99,9 @@ GNUNET_JSON_parse (const json_t *root, | |||
86 | void | 99 | void |
87 | GNUNET_JSON_parse_free (struct GNUNET_JSON_Specification *spec) | 100 | GNUNET_JSON_parse_free (struct GNUNET_JSON_Specification *spec) |
88 | { | 101 | { |
89 | for (unsigned int i=0;NULL != spec[i].parser;i++) | 102 | for (unsigned int i = 0; NULL != spec[i].parser; i++) |
90 | if (NULL != spec[i].cleaner) | 103 | if (NULL != spec[i].cleaner) |
91 | spec[i].cleaner (spec[i].cls, | 104 | spec[i].cleaner (spec[i].cls, &spec[i]); |
92 | &spec[i]); | ||
93 | } | 105 | } |
94 | 106 | ||
95 | 107 | ||
@@ -114,13 +126,11 @@ set_json (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | |||
114 | json_t **json = scls; | 126 | json_t **json = scls; |
115 | json_error_t error; | 127 | json_error_t error; |
116 | 128 | ||
117 | *json = json_loads (value, | 129 | *json = json_loads (value, JSON_REJECT_DUPLICATES, &error); |
118 | JSON_REJECT_DUPLICATES, | ||
119 | &error); | ||
120 | if (NULL == *json) | 130 | if (NULL == *json) |
121 | { | 131 | { |
122 | FPRINTF (stderr, | 132 | FPRINTF (stderr, |
123 | _("Failed to parse JSON in option `%s': %s (%s)\n"), | 133 | _ ("Failed to parse JSON in option `%s': %s (%s)\n"), |
124 | option, | 134 | option, |
125 | error.text, | 135 | error.text, |
126 | error.source); | 136 | error.source); |
@@ -146,15 +156,13 @@ GNUNET_JSON_getopt (char shortName, | |||
146 | const char *description, | 156 | const char *description, |
147 | json_t **json) | 157 | json_t **json) |
148 | { | 158 | { |
149 | struct GNUNET_GETOPT_CommandLineOption clo = { | 159 | struct GNUNET_GETOPT_CommandLineOption clo = {.shortName = shortName, |
150 | .shortName = shortName, | 160 | .name = name, |
151 | .name = name, | 161 | .argumentHelp = argumentHelp, |
152 | .argumentHelp = argumentHelp, | 162 | .description = description, |
153 | .description = description, | 163 | .require_argument = 1, |
154 | .require_argument = 1, | 164 | .processor = &set_json, |
155 | .processor = &set_json, | 165 | .scls = (void *) json}; |
156 | .scls = (void *) json | ||
157 | }; | ||
158 | 166 | ||
159 | return clo; | 167 | return clo; |
160 | } | 168 | } |