ISC DHCP 4.4.3-P1
A reference DHCPv4 and DHCPv6 implementation
 
Loading...
Searching...
No Matches
json.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2017-2022 Internet Systems Consortium, Inc. ("ISC")
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
14 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 *
16 * Internet Systems Consortium, Inc.
17 * PO Box 360
18 * Newmarket, NH 03857 USA
19 * <info@isc.org>
20 * https://www.isc.org/
21 *
22 */
23
24/* From Kea src/lib/cc/data.cc fromJSON() */
25
26#include "keama.h"
27
28#include <stdlib.h>
29#include <string.h>
30
31struct element *
32json_parse(struct parse *cfile)
33{
34 struct element *elem;
35 const char *val;
36 enum dhcp_token token;
37
38 elem = create();
39 stackPush(cfile, elem);
40 cfile->stack[0] = elem;
41 cfile->stack_top = 0;
42
43 token = next_token(&val, NULL, cfile);
44 switch (token) {
45 case NUMBER:
46 elem = createInt(atoll(val));
47 TAILQ_CONCAT(&elem->comments, &cfile->comments);
48 break;
49 case STRING:
50 elem = createString(makeString(-1, val));
51 TAILQ_CONCAT(&elem->comments, &cfile->comments);
52 break;
53 case NAME:
54 if (strcmp(val, "null") == 0)
55 elem = createNull();
56 else if (strcmp(val, "true") == 0)
57 elem = createBool(ISC_TRUE);
58 else if (strcmp(val, "false") == 0) {
59 elem = createBool(ISC_FALSE);
60 elem->skip = ISC_TRUE;
61 } else
62 parse_error(cfile, "unknown name %s", val);
63 TAILQ_CONCAT(&elem->comments, &cfile->comments);
64 break;
65 case LBRACKET:
66 elem = json_list_parse(cfile);
67 break;
68 case LBRACE:
69 elem = json_map_parse(cfile);
70 break;
71 case END_OF_FILE:
72 parse_error(cfile, "unexpected end of file");
73 default:
74 parse_error(cfile, "unexpected %s", val);
75 }
76 return elem;
77}
78
79struct element *
80json_list_parse(struct parse *cfile)
81{
82 struct element *list;
83 struct element *item;
84 const char *val;
85 enum dhcp_token token;
87
88 list = createList();
89 TAILQ_CONCAT(&list->comments, &cfile->comments);
90 stackPush(cfile, list);
91 do {
92 token = peek_token(&val, NULL, cfile);
93 switch (token) {
94 case RBRACKET:
95 done = ISC_TRUE;
96 break;
97 case END_OF_FILE:
98 parse_error(cfile, "unexpected end of file");
99 case COMMA:
100 skip_token(&val, NULL, cfile);
101 if (listSize(list) == 0)
102 parse_error(cfile, "unexpected ','");
103 item = json_parse(cfile);
104 listPush(list, item);
105 break;
106 default:
107 if (listSize(list) > 0)
108 parse_error(cfile, "expected ','");
109 item = json_parse(cfile);
110 listPush(list, item);
111 break;
112 }
113 } while (!done);
114 skip_token(&val, NULL, cfile);
115 cfile->stack_top--;
116 return list;
117}
118
119struct element *
120json_map_parse(struct parse *cfile)
121{
122 struct element *map;
123 struct element *item;
124 const char *val;
125 const char *key;
126 enum dhcp_token token;
128
129 map = createMap();
130 TAILQ_CONCAT(&map->comments, &cfile->comments);
131 stackPush(cfile, map);
132 do {
133 token = peek_token(&val, NULL, cfile);
134 switch (token) {
135 case RBRACE:
136 done = ISC_TRUE;
137 break;
138 case END_OF_FILE:
139 parse_error(cfile, "unexpected end of file");
140 case COMMA:
141 skip_token(&val, NULL, cfile);
142 if (mapSize(map) == 0)
143 parse_error(cfile, "unexpected ','");
144 token = next_token(&val, NULL, cfile);
145 if (token != STRING)
146 parse_error(cfile, "unexpected %s, "
147 "expected \"key\":value", val);
148 key = strdup(val);
149 token = next_token(&val, NULL, cfile);
150 if (token != COLON)
151 parse_error(cfile, "unexpected %s, "
152 "expected ':'", val);
153 item = json_parse(cfile);
154 mapSet(map, item, key);
155 break;
156 case STRING:
157 skip_token(&val, NULL, cfile);
158 if (mapSize(map) > 0)
159 parse_error(cfile, "unexpected \"%s\", "
160 "expected ','", val);
161 key = strdup(val);
162 token = next_token(&val, NULL, cfile);
163 if (token != COLON)
164 parse_error(cfile, "unexpected %s, "
165 "expected ':'", val);
166 item = json_parse(cfile);
167 mapSet(map, item, key);
168 break;
169 default:
170 if (mapSize(map) == 0)
171 parse_error(cfile, "unexpected %s, "
172 "expected \"key\":value or '}'",
173 val);
174 else
175 parse_error(cfile, "unexpected %s, "
176 "expected ',' or '}'", val);
177 }
178 } while (!done);
179 skip_token(&val, NULL, cfile);
180 cfile->stack_top--;
181 return map;
182}
enum dhcp_token peek_token(const char **rval, unsigned *rlen, struct parse *cfile)
Definition conflex.c:443
enum dhcp_token next_token(const char **rval, unsigned *rlen, struct parse *cfile)
Definition conflex.c:369
void listPush(struct element *l, struct element *e)
Definition data.c:697
struct string * makeString(int l, const char *s)
Definition data.c:44
struct element * createList(void)
Definition data.c:504
struct element * createBool(isc_boolean_t b)
Definition data.c:469
size_t mapSize(const struct element *m)
Definition data.c:829
struct element * createNull(void)
Definition data.c:481
struct element * create(void)
Definition data.c:432
struct element * createInt(int64_t i)
Definition data.c:445
void mapSet(struct element *m, struct element *e, const char *k)
Definition data.c:777
size_t listSize(const struct element *l)
Definition data.c:730
struct element * createMap(void)
Definition data.c:516
struct element * createString(const struct string *s)
Definition data.c:492
#define TAILQ_CONCAT(head1, head2)
Definition data.h:49
isc_boolean_t
Definition data.h:150
#define ISC_TRUE
Definition data.h:153
#define ISC_FALSE
Definition data.h:152
#define skip_token(a, b, c)
Definition dhcpd.h:2192
dhcp_token
Definition dhctoken.h:34
@ LBRACE
Definition dhctoken.h:40
@ LBRACKET
Definition dhctoken.h:42
@ NUMBER
Definition dhctoken.h:67
@ COLON
Definition dhctoken.h:37
@ NAME
Definition dhctoken.h:69
@ END_OF_FILE
Definition dhctoken.h:307
@ RBRACE
Definition dhctoken.h:41
@ RBRACKET
Definition dhctoken.h:43
@ STRING
Definition dhctoken.h:66
@ COMMA
Definition dhctoken.h:38
struct element * json_map_parse(struct parse *cfile)
Definition json.c:120
struct element * json_parse(struct parse *cfile)
Definition json.c:32
struct element * json_list_parse(struct parse *cfile)
Definition json.c:80
void parse_error(struct parse *cfile, const char *fmt,...)
Definition keama.c:197
void stackPush(struct parse *pc, struct element *elem)
Definition keama.c:181
isc_boolean_t skip
Definition data.h:219
char * key
Definition data.h:220
struct comments comments
Definition data.h:222
Definition dhcpd.h:288
struct comments comments
Definition keama.h:116
size_t stack_top
Definition keama.h:112
struct element ** stack
Definition keama.h:110