-
Notifications
You must be signed in to change notification settings - Fork 3
/
json_sem.h
180 lines (161 loc) · 7.66 KB
/
json_sem.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
* json_sem - JSON semantics support
*
* "Because grammar and syntax alone do not make a complete language." :-)
*
* This JSON parser was co-developed in 2022 by:
*
* @xexyl
* https://xexyl.net Cody Boone Ferguson
* https://ioccc.xexyl.net
* and:
* chongo (Landon Curt Noll, http://www.isthe.com/chongo/index.html) /\oo/\
*
* "Because sometimes even the IOCCC Judges need some help." :-)
*
* The concept of the JSON semantics tables was developed by Landon Curt Noll.
*
* "Share and Enjoy!"
* -- Sirius Cybernetics Corporation Complaints Division, JSON spec department. :-)
*/
#if !defined(INCLUDE_JSON_SEM_H)
# define INCLUDE_JSON_SEM_H
/*
* dbg - info, debug, warning, error, and usage message facility
*/
#if defined(INTERNAL_INCLUDE)
#include "../dbg/dbg.h"
#elif defined(INTERNAL_INCLUDE_2)
#include "dbg/dbg.h"
#else
#include <dbg.h>
#endif
/*
* util - common utility functions for the JSON parser
*/
#include "util.h"
/*
* json_parse - JSON parser support code
*/
#include "json_parse.h"
/*
* json_util - general JSON parser utility support functions
*/
#include "json_util.h"
/*
* definitions
*/
#define INF (0) /* special max value for no limit */
#define INF_DEPTH (UINT_MAX) /* no depth */
/*
* JSON semantic count error
*/
struct json_sem_count_err
{
struct json const *node; /* JSON parse node in question or NULL */
struct json_sem const *sem; /* semantic node in question or NULL (unknown_node == true) */
unsigned int count; /* number of times this JSON semantic was matched */
bool bad_min; /* true ==> JSON semantic node count under minimum */
bool bad_max; /* true ==> JSON semantic node count over maximum */
bool unknown_node; /* true ==> JSON node is not known to JSON semantics */
int sem_index; /* index of sem in JSON semantic table or -1 ==> not in table */
char *diagnostic; /* diagnostic message or NULL */
bool malloced; /* true ==> struct diagnostic malloced */
/* false ==> diagnostic is a non-malloced static string */
};
/*
* JSON semantic validation error
*
* When validate() returns false, that validating function
* records information about the validation error in this form.
*/
struct json_sem_val_err
{
struct json const *node; /* JSON parse node in question or NULL */
unsigned int depth; /* JSON parse tree node depth or UINT_MAX */
struct json_sem const *sem; /* semantic node in question or NULL */
int sem_index; /* index of sem in JSON semantic table or -1 ==> not in table */
char *diagnostic; /* diagnostic message or NULL */
bool malloced; /* true ==> struct diagnostic malloced */
/* false ==> diagnostic is a non-malloced static string */
};
/*
* JSON semantic node
*
* An array of JSON semantics describes what is required or allowed in a given
* valid JSON document.
*/
struct json_sem
{
unsigned int depth; /* JSON parse tree node depth */
enum item_type type; /* type of JSON node, JTYPE_UNSET ==> end of table */
unsigned int min; /* minimum allowed count */
unsigned int max; /* maximum allowed count, 0 ==> infinite */
unsigned int count; /* number of times this JSON semantic was matched */
int sem_index; /* index of sem in JSON semantic table or -1 ==> end of the table */
size_t name_len; /* if type == JTYPE_MEMBER length of name_str (not including final NUL) or 0 */
bool (* validate)(struct json const *node,
unsigned int depth, struct json_sem *sem, struct json_sem_val_err **val_err);
/* JSON parse tree node validator, or NULL */
char *name; /* if type == JTYPE_MEMBER, match decoded name or NULL */
};
/*
* str_or_null - report if a JSON JTYPE_MEMBER value is a valid JSON_STRING or a valid JSON_NULL
*
* Assuming valid == true, then if is_null == true, then str will be NULL else if is_null == false,
* then str will be non-NULL.
*
* When valid == false, then is_null and str have no meaning.
*/
struct str_or_null {
bool valid; /* true == JSON JTYPE_MEMBER value was is valid JSON_STRING or a valid JSON_NULL */
bool is_null; /* true ==> JTYPE_MEMBER value is valid JSON_NULL, false ==> is valid JSON_STRING */
char *str; /* decoded value string from JSON member or NULL */
};
/*
* external function declarations
*/
extern struct json_sem_val_err *werr_sem_val(int val_err, struct json const *node, unsigned int depth,
struct json_sem *sem, char const *name, char const *fmt, ...) \
__attribute__((format(printf, 6, 7))); /* 6=format 7=params */
extern struct json_sem_val_err *werrp_sem_val(int val_err, struct json const *node, unsigned int depth,
struct json_sem *sem, char const *name, char const *fmt, ...) \
__attribute__((format(printf, 6, 7))); /* 6=format 7=params */
extern bool sem_chk_null_args(struct json const *node, unsigned int depth, struct json_sem *sem,
char const *name, struct json_sem_val_err **val_err);
extern bool sem_node_valid(struct json const *node, unsigned int depth, struct json_sem *sem,
char const *name, struct json_sem_val_err **val_err);
extern struct json *sem_member_name(struct json const *node, unsigned int depth, struct json_sem *sem,
char const *name, struct json_sem_val_err **val_err);
extern struct json *sem_member_value(struct json const *node, unsigned int depth, struct json_sem *sem,
char const *name, struct json_sem_val_err **val_err);
extern char *sem_member_name_decoded_str(struct json const *node, unsigned int depth, struct json_sem *sem,
char const *name, struct json_sem_val_err **val_err);
extern char *sem_member_value_decoded_str(struct json const *node, unsigned int depth, struct json_sem *sem,
char const *name, struct json_sem_val_err **val_err);
extern bool *sem_member_value_bool(struct json const *node, unsigned int depth, struct json_sem *sem,
char const *name, struct json_sem_val_err **val_err);
extern struct str_or_null sem_member_value_str_or_null(struct json const *node, unsigned int depth,
struct json_sem *sem,
char const *name, struct json_sem_val_err **val_err);
extern int *sem_member_value_int(struct json const *node, unsigned int depth, struct json_sem *sem,
char const *name, struct json_sem_val_err **val_err);
extern size_t *sem_member_value_size_t(struct json const *node, unsigned int depth, struct json_sem *sem,
char const *name, struct json_sem_val_err **val_err);
extern time_t *sem_member_value_time_t(struct json const *node, unsigned int depth, struct json_sem *sem,
char const *name, struct json_sem_val_err **val_err);
extern struct json *sem_node_parent(struct json const *node, unsigned int depth, struct json_sem *sem,
char const *name, struct json_sem_val_err **val_err);
extern struct json *sem_object_find_name(struct json const *node, unsigned int depth, struct json_sem *sem,
char const *name, struct json_sem_val_err **val_err,
char const *memname);
extern void json_sem_zero_count(struct json_sem *sem);
extern int json_sem_find(struct json *node, unsigned int depth, struct json_sem *sem);
extern void json_sem_count_chk(struct json_sem *sem, struct dyn_array *count_err);
extern uintmax_t json_sem_check(struct json *node, unsigned int max_depth, struct json_sem *sem,
struct dyn_array **pcount_err, struct dyn_array **pval_err);
extern void free_count_err(struct dyn_array *count_err);
extern void free_val_err(struct dyn_array *val_err);
extern void fprint_count_err(FILE *stream, char const *prefix, struct json_sem_count_err *sem_count_err, char const *postfix);
extern void fprint_val_err(FILE *stream, char const *prefix, struct json_sem_val_err *sem_val_err, char const *postfix);
#endif /* INCLUDE_JSON_SEM_H */