1106Svbart@nginx.com
2106Svbart@nginx.com /*
3106Svbart@nginx.com * Copyright (C) Igor Sysoev
4106Svbart@nginx.com * Copyright (C) Valentin V. Bartenev
5106Svbart@nginx.com * Copyright (C) NGINX, Inc.
6106Svbart@nginx.com */
7106Svbart@nginx.com
8106Svbart@nginx.com #include <nxt_main.h>
9106Svbart@nginx.com #include <nxt_conf.h>
101439Svbart@nginx.com
111439Svbart@nginx.com #include <float.h>
12106Svbart@nginx.com #include <math.h>
13106Svbart@nginx.com
14106Svbart@nginx.com
15106Svbart@nginx.com #define NXT_CONF_MAX_SHORT_STRING 14
161439Svbart@nginx.com #define NXT_CONF_MAX_NUMBER_LEN 14
17172Svbart@nginx.com #define NXT_CONF_MAX_STRING NXT_INT32_T_MAX
18106Svbart@nginx.com
191174Svbart@nginx.com #define NXT_CONF_MAX_TOKEN_LEN 256
201174Svbart@nginx.com
21106Svbart@nginx.com
22106Svbart@nginx.com typedef enum {
23116Svbart@nginx.com NXT_CONF_VALUE_NULL = 0,
24116Svbart@nginx.com NXT_CONF_VALUE_BOOLEAN,
25116Svbart@nginx.com NXT_CONF_VALUE_INTEGER,
26116Svbart@nginx.com NXT_CONF_VALUE_NUMBER,
27116Svbart@nginx.com NXT_CONF_VALUE_SHORT_STRING,
28116Svbart@nginx.com NXT_CONF_VALUE_STRING,
29116Svbart@nginx.com NXT_CONF_VALUE_ARRAY,
30116Svbart@nginx.com NXT_CONF_VALUE_OBJECT,
31116Svbart@nginx.com } nxt_conf_value_type_t;
32106Svbart@nginx.com
33106Svbart@nginx.com
34106Svbart@nginx.com typedef enum {
35106Svbart@nginx.com NXT_CONF_OP_PASS = 0,
36106Svbart@nginx.com NXT_CONF_OP_CREATE,
37106Svbart@nginx.com NXT_CONF_OP_REPLACE,
38106Svbart@nginx.com NXT_CONF_OP_DELETE,
39106Svbart@nginx.com } nxt_conf_op_action_t;
40106Svbart@nginx.com
41106Svbart@nginx.com
42106Svbart@nginx.com typedef struct nxt_conf_array_s nxt_conf_array_t;
43106Svbart@nginx.com typedef struct nxt_conf_object_s nxt_conf_object_t;
44106Svbart@nginx.com
45106Svbart@nginx.com
46180Smax.romanov@nginx.com struct nxt_conf_value_s {
47187Smax.romanov@nginx.com union {
48171Svbart@nginx.com uint8_t boolean; /* 1 bit. */
491439Svbart@nginx.com u_char number[NXT_CONF_MAX_NUMBER_LEN + 1];;
50173Svbart@nginx.com
51173Svbart@nginx.com struct {
52208Svbart@nginx.com u_char start[NXT_CONF_MAX_SHORT_STRING];
53173Svbart@nginx.com uint8_t length;
54173Svbart@nginx.com } str;
55172Svbart@nginx.com
56187Smax.romanov@nginx.com struct {
57172Svbart@nginx.com u_char *start;
58172Svbart@nginx.com uint32_t length;
59187Smax.romanov@nginx.com } nxt_packed string;
60172Svbart@nginx.com
61106Svbart@nginx.com nxt_conf_array_t *array;
62106Svbart@nginx.com nxt_conf_object_t *object;
63187Smax.romanov@nginx.com } nxt_packed u;
64106Svbart@nginx.com
65171Svbart@nginx.com uint8_t type; /* 3 bits. */
66180Smax.romanov@nginx.com } nxt_aligned(8);
67106Svbart@nginx.com
68106Svbart@nginx.com
69106Svbart@nginx.com struct nxt_conf_array_s {
70106Svbart@nginx.com nxt_uint_t count;
71106Svbart@nginx.com nxt_conf_value_t elements[];
72106Svbart@nginx.com };
73106Svbart@nginx.com
74106Svbart@nginx.com
75106Svbart@nginx.com typedef struct {
76106Svbart@nginx.com nxt_conf_value_t name;
77106Svbart@nginx.com nxt_conf_value_t value;
78106Svbart@nginx.com } nxt_conf_object_member_t;
79106Svbart@nginx.com
80106Svbart@nginx.com
81106Svbart@nginx.com struct nxt_conf_object_s {
82106Svbart@nginx.com nxt_uint_t count;
83106Svbart@nginx.com nxt_conf_object_member_t members[];
84106Svbart@nginx.com };
85106Svbart@nginx.com
86106Svbart@nginx.com
87106Svbart@nginx.com struct nxt_conf_op_s {
88106Svbart@nginx.com uint32_t index;
89106Svbart@nginx.com uint32_t action; /* nxt_conf_op_action_t */
90106Svbart@nginx.com void *ctx;
91106Svbart@nginx.com };
92106Svbart@nginx.com
93106Svbart@nginx.com
941174Svbart@nginx.com typedef struct {
951174Svbart@nginx.com u_char *start;
961174Svbart@nginx.com u_char *end;
971174Svbart@nginx.com nxt_bool_t last;
981174Svbart@nginx.com u_char buf[NXT_CONF_MAX_TOKEN_LEN];
991174Svbart@nginx.com } nxt_conf_path_parse_t;
1001174Svbart@nginx.com
1011174Svbart@nginx.com
1021174Svbart@nginx.com static nxt_int_t nxt_conf_path_next_token(nxt_conf_path_parse_t *parse,
1031174Svbart@nginx.com nxt_str_t *token);
1041174Svbart@nginx.com
105*2139Sandrew@digital-domain.net static u_char *nxt_conf_json_skip_space(u_char *start, const u_char *end);
106106Svbart@nginx.com static u_char *nxt_conf_json_parse_value(nxt_mp_t *mp, nxt_conf_value_t *value,
107208Svbart@nginx.com u_char *start, u_char *end, nxt_conf_json_error_t *error);
108106Svbart@nginx.com static u_char *nxt_conf_json_parse_object(nxt_mp_t *mp, nxt_conf_value_t *value,
109208Svbart@nginx.com u_char *start, u_char *end, nxt_conf_json_error_t *error);
110106Svbart@nginx.com static nxt_int_t nxt_conf_object_hash_add(nxt_mp_t *mp,
111106Svbart@nginx.com nxt_lvlhsh_t *lvlhsh, nxt_conf_object_member_t *member);
112106Svbart@nginx.com static nxt_int_t nxt_conf_object_hash_test(nxt_lvlhsh_query_t *lhq,
113106Svbart@nginx.com void *data);
114106Svbart@nginx.com static void *nxt_conf_object_hash_alloc(void *data, size_t size);
115106Svbart@nginx.com static void nxt_conf_object_hash_free(void *data, void *p);
116106Svbart@nginx.com static u_char *nxt_conf_json_parse_array(nxt_mp_t *mp, nxt_conf_value_t *value,
117208Svbart@nginx.com u_char *start, u_char *end, nxt_conf_json_error_t *error);
118106Svbart@nginx.com static u_char *nxt_conf_json_parse_string(nxt_mp_t *mp, nxt_conf_value_t *value,
119208Svbart@nginx.com u_char *start, u_char *end, nxt_conf_json_error_t *error);
120106Svbart@nginx.com static u_char *nxt_conf_json_parse_number(nxt_mp_t *mp, nxt_conf_value_t *value,
121208Svbart@nginx.com u_char *start, u_char *end, nxt_conf_json_error_t *error);
122208Svbart@nginx.com static void nxt_conf_json_parse_error(nxt_conf_json_error_t *error, u_char *pos,
123208Svbart@nginx.com const char *detail);
124106Svbart@nginx.com
125106Svbart@nginx.com static nxt_int_t nxt_conf_copy_value(nxt_mp_t *mp, nxt_conf_op_t *op,
126106Svbart@nginx.com nxt_conf_value_t *dst, nxt_conf_value_t *src);
1271048Svbart@nginx.com static nxt_int_t nxt_conf_copy_array(nxt_mp_t *mp, nxt_conf_op_t *op,
1281048Svbart@nginx.com nxt_conf_value_t *dst, nxt_conf_value_t *src);
129106Svbart@nginx.com static nxt_int_t nxt_conf_copy_object(nxt_mp_t *mp, nxt_conf_op_t *op,
130106Svbart@nginx.com nxt_conf_value_t *dst, nxt_conf_value_t *src);
131106Svbart@nginx.com
132106Svbart@nginx.com static size_t nxt_conf_json_string_length(nxt_conf_value_t *value);
133106Svbart@nginx.com static u_char *nxt_conf_json_print_string(u_char *p, nxt_conf_value_t *value);
134106Svbart@nginx.com static size_t nxt_conf_json_array_length(nxt_conf_value_t *value,
135106Svbart@nginx.com nxt_conf_json_pretty_t *pretty);
136106Svbart@nginx.com static u_char *nxt_conf_json_print_array(u_char *p, nxt_conf_value_t *value,
137106Svbart@nginx.com nxt_conf_json_pretty_t *pretty);
138106Svbart@nginx.com static size_t nxt_conf_json_object_length(nxt_conf_value_t *value,
139106Svbart@nginx.com nxt_conf_json_pretty_t *pretty);
140106Svbart@nginx.com static u_char *nxt_conf_json_print_object(u_char *p, nxt_conf_value_t *value,
141106Svbart@nginx.com nxt_conf_json_pretty_t *pretty);
142106Svbart@nginx.com
143106Svbart@nginx.com static size_t nxt_conf_json_escape_length(u_char *p, size_t size);
144106Svbart@nginx.com static u_char *nxt_conf_json_escape(u_char *dst, u_char *src, size_t size);
145106Svbart@nginx.com
146106Svbart@nginx.com
147106Svbart@nginx.com #define nxt_conf_json_newline(p) \
148106Svbart@nginx.com ((p)[0] = '\r', (p)[1] = '\n', (p) + 2)
149106Svbart@nginx.com
150106Svbart@nginx.com
151106Svbart@nginx.com nxt_inline u_char *
nxt_conf_json_indentation(u_char * p,uint32_t level)152106Svbart@nginx.com nxt_conf_json_indentation(u_char *p, uint32_t level)
153106Svbart@nginx.com {
154106Svbart@nginx.com while (level) {
155106Svbart@nginx.com *p++ = '\t';
156106Svbart@nginx.com level--;
157106Svbart@nginx.com }
158106Svbart@nginx.com
159106Svbart@nginx.com return p;
160106Svbart@nginx.com }
161106Svbart@nginx.com
162106Svbart@nginx.com
163121Svbart@nginx.com void
nxt_conf_get_string(nxt_conf_value_t * value,nxt_str_t * str)164106Svbart@nginx.com nxt_conf_get_string(nxt_conf_value_t *value, nxt_str_t *str)
165106Svbart@nginx.com {
166116Svbart@nginx.com if (value->type == NXT_CONF_VALUE_SHORT_STRING) {
167173Svbart@nginx.com str->length = value->u.str.length;
168173Svbart@nginx.com str->start = value->u.str.start;
169106Svbart@nginx.com
170106Svbart@nginx.com } else {
171172Svbart@nginx.com str->length = value->u.string.length;
172172Svbart@nginx.com str->start = value->u.string.start;
173106Svbart@nginx.com }
174106Svbart@nginx.com }
175106Svbart@nginx.com
176106Svbart@nginx.com
177773Svbart@nginx.com void
nxt_conf_set_string(nxt_conf_value_t * value,nxt_str_t * str)178773Svbart@nginx.com nxt_conf_set_string(nxt_conf_value_t *value, nxt_str_t *str)
179773Svbart@nginx.com {
180773Svbart@nginx.com if (str->length > NXT_CONF_MAX_SHORT_STRING) {
181773Svbart@nginx.com value->type = NXT_CONF_VALUE_STRING;
182773Svbart@nginx.com value->u.string.length = str->length;
183773Svbart@nginx.com value->u.string.start = str->start;
184773Svbart@nginx.com
185773Svbart@nginx.com } else {
186773Svbart@nginx.com value->type = NXT_CONF_VALUE_SHORT_STRING;
187773Svbart@nginx.com value->u.str.length = str->length;
188773Svbart@nginx.com
189773Svbart@nginx.com nxt_memcpy(value->u.str.start, str->start, str->length);
190773Svbart@nginx.com }
191773Svbart@nginx.com }
192773Svbart@nginx.com
193773Svbart@nginx.com
194774Svbart@nginx.com nxt_int_t
nxt_conf_set_string_dup(nxt_conf_value_t * value,nxt_mp_t * mp,const nxt_str_t * str)1952075Salx.manpages@gmail.com nxt_conf_set_string_dup(nxt_conf_value_t *value, nxt_mp_t *mp,
1962075Salx.manpages@gmail.com const nxt_str_t *str)
197774Svbart@nginx.com {
198774Svbart@nginx.com nxt_str_t tmp, *ptr;
199774Svbart@nginx.com
200774Svbart@nginx.com if (str->length > NXT_CONF_MAX_SHORT_STRING) {
201774Svbart@nginx.com value->type = NXT_CONF_VALUE_STRING;
202774Svbart@nginx.com
203774Svbart@nginx.com ptr = nxt_str_dup(mp, &tmp, str);
204774Svbart@nginx.com if (nxt_slow_path(ptr == NULL)) {
205774Svbart@nginx.com return NXT_ERROR;
206774Svbart@nginx.com }
207774Svbart@nginx.com
208774Svbart@nginx.com value->u.string.length = tmp.length;
209774Svbart@nginx.com value->u.string.start = tmp.start;
210774Svbart@nginx.com
211774Svbart@nginx.com } else {
212774Svbart@nginx.com value->type = NXT_CONF_VALUE_SHORT_STRING;
213774Svbart@nginx.com value->u.str.length = str->length;
214774Svbart@nginx.com
215774Svbart@nginx.com nxt_memcpy(value->u.str.start, str->start, str->length);
216774Svbart@nginx.com }
217774Svbart@nginx.com
218774Svbart@nginx.com return NXT_OK;
219774Svbart@nginx.com }
220774Svbart@nginx.com
221774Svbart@nginx.com
2221439Svbart@nginx.com double
nxt_conf_get_number(nxt_conf_value_t * value)2231439Svbart@nginx.com nxt_conf_get_number(nxt_conf_value_t *value)
224507Smax.romanov@nginx.com {
2251439Svbart@nginx.com return nxt_strtod(value->u.number, NULL);
226507Smax.romanov@nginx.com }
227507Smax.romanov@nginx.com
228507Smax.romanov@nginx.com
2291236St.nateldemoura@f5.com uint8_t
nxt_conf_get_boolean(nxt_conf_value_t * value)2301236St.nateldemoura@f5.com nxt_conf_get_boolean(nxt_conf_value_t *value)
2311236St.nateldemoura@f5.com {
2321236St.nateldemoura@f5.com return value->u.boolean;
2331236St.nateldemoura@f5.com }
2341236St.nateldemoura@f5.com
2351236St.nateldemoura@f5.com
236116Svbart@nginx.com nxt_uint_t
nxt_conf_object_members_count(nxt_conf_value_t * value)237121Svbart@nginx.com nxt_conf_object_members_count(nxt_conf_value_t *value)
238121Svbart@nginx.com {
239121Svbart@nginx.com return value->u.object->count;
240121Svbart@nginx.com }
241121Svbart@nginx.com
242121Svbart@nginx.com
243121Svbart@nginx.com nxt_conf_value_t *
nxt_conf_create_object(nxt_mp_t * mp,nxt_uint_t count)244121Svbart@nginx.com nxt_conf_create_object(nxt_mp_t *mp, nxt_uint_t count)
245121Svbart@nginx.com {
246121Svbart@nginx.com size_t size;
247121Svbart@nginx.com nxt_conf_value_t *value;
248121Svbart@nginx.com
249121Svbart@nginx.com size = sizeof(nxt_conf_value_t)
250121Svbart@nginx.com + sizeof(nxt_conf_object_t)
251121Svbart@nginx.com + count * sizeof(nxt_conf_object_member_t);
252121Svbart@nginx.com
253121Svbart@nginx.com value = nxt_mp_get(mp, size);
254121Svbart@nginx.com if (nxt_slow_path(value == NULL)) {
255121Svbart@nginx.com return NULL;
256121Svbart@nginx.com }
257121Svbart@nginx.com
258121Svbart@nginx.com value->u.object = nxt_pointer_to(value, sizeof(nxt_conf_value_t));
259121Svbart@nginx.com value->u.object->count = count;
260121Svbart@nginx.com
261121Svbart@nginx.com value->type = NXT_CONF_VALUE_OBJECT;
262121Svbart@nginx.com
263121Svbart@nginx.com return value;
264121Svbart@nginx.com }
265121Svbart@nginx.com
266121Svbart@nginx.com
267208Svbart@nginx.com void
nxt_conf_set_member(nxt_conf_value_t * object,nxt_str_t * name,const nxt_conf_value_t * value,uint32_t index)268208Svbart@nginx.com nxt_conf_set_member(nxt_conf_value_t *object, nxt_str_t *name,
269*2139Sandrew@digital-domain.net const nxt_conf_value_t *value, uint32_t index)
270121Svbart@nginx.com {
271121Svbart@nginx.com nxt_conf_object_member_t *member;
272121Svbart@nginx.com
273121Svbart@nginx.com member = &object->u.object->members[index];
274773Svbart@nginx.com
275773Svbart@nginx.com nxt_conf_set_string(&member->name, name);
276121Svbart@nginx.com
277121Svbart@nginx.com member->value = *value;
278208Svbart@nginx.com }
279208Svbart@nginx.com
280208Svbart@nginx.com
281208Svbart@nginx.com void
nxt_conf_set_member_string(nxt_conf_value_t * object,nxt_str_t * name,nxt_str_t * value,uint32_t index)282208Svbart@nginx.com nxt_conf_set_member_string(nxt_conf_value_t *object, nxt_str_t *name,
283208Svbart@nginx.com nxt_str_t *value, uint32_t index)
284208Svbart@nginx.com {
285208Svbart@nginx.com nxt_conf_object_member_t *member;
286208Svbart@nginx.com
287208Svbart@nginx.com member = &object->u.object->members[index];
288773Svbart@nginx.com
289773Svbart@nginx.com nxt_conf_set_string(&member->name, name);
290773Svbart@nginx.com
291773Svbart@nginx.com nxt_conf_set_string(&member->value, value);
292208Svbart@nginx.com }
293208Svbart@nginx.com
294208Svbart@nginx.com
295774Svbart@nginx.com nxt_int_t
nxt_conf_set_member_string_dup(nxt_conf_value_t * object,nxt_mp_t * mp,nxt_str_t * name,nxt_str_t * value,uint32_t index)296774Svbart@nginx.com nxt_conf_set_member_string_dup(nxt_conf_value_t *object, nxt_mp_t *mp,
297774Svbart@nginx.com nxt_str_t *name, nxt_str_t *value, uint32_t index)
298774Svbart@nginx.com {
299774Svbart@nginx.com nxt_conf_object_member_t *member;
300774Svbart@nginx.com
301774Svbart@nginx.com member = &object->u.object->members[index];
302774Svbart@nginx.com
303774Svbart@nginx.com nxt_conf_set_string(&member->name, name);
304774Svbart@nginx.com
305774Svbart@nginx.com return nxt_conf_set_string_dup(&member->value, mp, value);
306774Svbart@nginx.com }
307774Svbart@nginx.com
308774Svbart@nginx.com
309208Svbart@nginx.com void
nxt_conf_set_member_integer(nxt_conf_value_t * object,nxt_str_t * name,int64_t value,uint32_t index)310208Svbart@nginx.com nxt_conf_set_member_integer(nxt_conf_value_t *object, nxt_str_t *name,
311208Svbart@nginx.com int64_t value, uint32_t index)
312208Svbart@nginx.com {
3131439Svbart@nginx.com u_char *p, *end;
314208Svbart@nginx.com nxt_conf_object_member_t *member;
315208Svbart@nginx.com
316208Svbart@nginx.com member = &object->u.object->members[index];
317773Svbart@nginx.com
318773Svbart@nginx.com nxt_conf_set_string(&member->name, name);
319208Svbart@nginx.com
3201439Svbart@nginx.com p = member->value.u.number;
3211439Svbart@nginx.com end = p + NXT_CONF_MAX_NUMBER_LEN;
3221439Svbart@nginx.com
3231439Svbart@nginx.com end = nxt_sprintf(p, end, "%L", value);
3241439Svbart@nginx.com *end = '\0';
3251439Svbart@nginx.com
326208Svbart@nginx.com member->value.type = NXT_CONF_VALUE_INTEGER;
327121Svbart@nginx.com }
328121Svbart@nginx.com
329121Svbart@nginx.com
330774Svbart@nginx.com void
nxt_conf_set_member_null(nxt_conf_value_t * object,nxt_str_t * name,uint32_t index)331774Svbart@nginx.com nxt_conf_set_member_null(nxt_conf_value_t *object, nxt_str_t *name,
332774Svbart@nginx.com uint32_t index)
333774Svbart@nginx.com {
334774Svbart@nginx.com nxt_conf_object_member_t *member;
335774Svbart@nginx.com
336774Svbart@nginx.com member = &object->u.object->members[index];
337774Svbart@nginx.com
338774Svbart@nginx.com nxt_conf_set_string(&member->name, name);
339774Svbart@nginx.com
340774Svbart@nginx.com member->value.type = NXT_CONF_VALUE_NULL;
341774Svbart@nginx.com }
342774Svbart@nginx.com
343774Svbart@nginx.com
344774Svbart@nginx.com nxt_conf_value_t *
nxt_conf_create_array(nxt_mp_t * mp,nxt_uint_t count)345774Svbart@nginx.com nxt_conf_create_array(nxt_mp_t *mp, nxt_uint_t count)
346774Svbart@nginx.com {
347774Svbart@nginx.com size_t size;
348774Svbart@nginx.com nxt_conf_value_t *value;
349774Svbart@nginx.com
350774Svbart@nginx.com size = sizeof(nxt_conf_value_t)
351774Svbart@nginx.com + sizeof(nxt_conf_array_t)
352774Svbart@nginx.com + count * sizeof(nxt_conf_value_t);
353774Svbart@nginx.com
354774Svbart@nginx.com value = nxt_mp_get(mp, size);
355774Svbart@nginx.com if (nxt_slow_path(value == NULL)) {
356774Svbart@nginx.com return NULL;
357774Svbart@nginx.com }
358774Svbart@nginx.com
359774Svbart@nginx.com value->u.array = nxt_pointer_to(value, sizeof(nxt_conf_value_t));
360774Svbart@nginx.com value->u.array->count = count;
361774Svbart@nginx.com
362774Svbart@nginx.com value->type = NXT_CONF_VALUE_ARRAY;
363774Svbart@nginx.com
364774Svbart@nginx.com return value;
365774Svbart@nginx.com }
366774Svbart@nginx.com
367774Svbart@nginx.com
368774Svbart@nginx.com void
nxt_conf_set_element(nxt_conf_value_t * array,nxt_uint_t index,const nxt_conf_value_t * value)369774Svbart@nginx.com nxt_conf_set_element(nxt_conf_value_t *array, nxt_uint_t index,
370*2139Sandrew@digital-domain.net const nxt_conf_value_t *value)
371774Svbart@nginx.com {
372774Svbart@nginx.com array->u.array->elements[index] = *value;
373774Svbart@nginx.com }
374774Svbart@nginx.com
375774Svbart@nginx.com
376774Svbart@nginx.com nxt_int_t
nxt_conf_set_element_string_dup(nxt_conf_value_t * array,nxt_mp_t * mp,nxt_uint_t index,nxt_str_t * value)377774Svbart@nginx.com nxt_conf_set_element_string_dup(nxt_conf_value_t *array, nxt_mp_t *mp,
378774Svbart@nginx.com nxt_uint_t index, nxt_str_t *value)
379774Svbart@nginx.com {
380774Svbart@nginx.com nxt_conf_value_t *element;
381774Svbart@nginx.com
382774Svbart@nginx.com element = &array->u.array->elements[index];
383774Svbart@nginx.com
384774Svbart@nginx.com return nxt_conf_set_string_dup(element, mp, value);
385774Svbart@nginx.com }
386774Svbart@nginx.com
387774Svbart@nginx.com
388121Svbart@nginx.com nxt_uint_t
nxt_conf_array_elements_count(nxt_conf_value_t * value)389961Sigor@sysoev.ru nxt_conf_array_elements_count(nxt_conf_value_t *value)
390961Sigor@sysoev.ru {
391961Sigor@sysoev.ru return value->u.array->count;
392961Sigor@sysoev.ru }
393961Sigor@sysoev.ru
394961Sigor@sysoev.ru
395961Sigor@sysoev.ru nxt_uint_t
nxt_conf_array_elements_count_or_1(nxt_conf_value_t * value)3962076Salx.manpages@gmail.com nxt_conf_array_elements_count_or_1(nxt_conf_value_t *value)
3972076Salx.manpages@gmail.com {
3982076Salx.manpages@gmail.com return (value->type == NXT_CONF_VALUE_ARRAY) ? value->u.array->count : 1;
3992076Salx.manpages@gmail.com }
4002076Salx.manpages@gmail.com
4012076Salx.manpages@gmail.com
4022076Salx.manpages@gmail.com nxt_uint_t
nxt_conf_type(nxt_conf_value_t * value)403116Svbart@nginx.com nxt_conf_type(nxt_conf_value_t *value)
404116Svbart@nginx.com {
405116Svbart@nginx.com switch (value->type) {
406116Svbart@nginx.com
407116Svbart@nginx.com case NXT_CONF_VALUE_NULL:
408116Svbart@nginx.com return NXT_CONF_NULL;
409116Svbart@nginx.com
410116Svbart@nginx.com case NXT_CONF_VALUE_BOOLEAN:
411116Svbart@nginx.com return NXT_CONF_BOOLEAN;
412116Svbart@nginx.com
413116Svbart@nginx.com case NXT_CONF_VALUE_INTEGER:
414116Svbart@nginx.com return NXT_CONF_INTEGER;
415116Svbart@nginx.com
416116Svbart@nginx.com case NXT_CONF_VALUE_NUMBER:
417116Svbart@nginx.com return NXT_CONF_NUMBER;
418116Svbart@nginx.com
419116Svbart@nginx.com case NXT_CONF_VALUE_SHORT_STRING:
420116Svbart@nginx.com case NXT_CONF_VALUE_STRING:
421116Svbart@nginx.com return NXT_CONF_STRING;
422116Svbart@nginx.com
423116Svbart@nginx.com case NXT_CONF_VALUE_ARRAY:
424116Svbart@nginx.com return NXT_CONF_ARRAY;
425116Svbart@nginx.com
426116Svbart@nginx.com case NXT_CONF_VALUE_OBJECT:
427116Svbart@nginx.com return NXT_CONF_OBJECT;
428116Svbart@nginx.com }
429116Svbart@nginx.com
430116Svbart@nginx.com nxt_unreachable();
431116Svbart@nginx.com
432116Svbart@nginx.com return 0;
433116Svbart@nginx.com }
434116Svbart@nginx.com
435116Svbart@nginx.com
436106Svbart@nginx.com nxt_conf_value_t *
nxt_conf_get_path(nxt_conf_value_t * value,nxt_str_t * path)437106Svbart@nginx.com nxt_conf_get_path(nxt_conf_value_t *value, nxt_str_t *path)
438106Svbart@nginx.com {
439106Svbart@nginx.com nxt_str_t token;
4401174Svbart@nginx.com nxt_int_t ret, index;
441106Svbart@nginx.com nxt_conf_path_parse_t parse;
442106Svbart@nginx.com
443106Svbart@nginx.com parse.start = path->start;
444106Svbart@nginx.com parse.end = path->start + path->length;
445106Svbart@nginx.com parse.last = 0;
446106Svbart@nginx.com
447106Svbart@nginx.com do {
4481174Svbart@nginx.com ret = nxt_conf_path_next_token(&parse, &token);
4491174Svbart@nginx.com if (nxt_slow_path(ret != NXT_OK)) {
4501174Svbart@nginx.com return NULL;
4511174Svbart@nginx.com }
452106Svbart@nginx.com
453106Svbart@nginx.com if (token.length == 0) {
454106Svbart@nginx.com
455106Svbart@nginx.com if (parse.last) {
456106Svbart@nginx.com break;
457106Svbart@nginx.com }
458106Svbart@nginx.com
459106Svbart@nginx.com return NULL;
460106Svbart@nginx.com }
461106Svbart@nginx.com
462775Svbart@nginx.com switch (value->type) {
463775Svbart@nginx.com
464775Svbart@nginx.com case NXT_CONF_VALUE_OBJECT:
465775Svbart@nginx.com value = nxt_conf_get_object_member(value, &token, NULL);
466775Svbart@nginx.com break;
467775Svbart@nginx.com
468775Svbart@nginx.com case NXT_CONF_VALUE_ARRAY:
469775Svbart@nginx.com index = nxt_int_parse(token.start, token.length);
470775Svbart@nginx.com
471775Svbart@nginx.com if (index < 0 || index > NXT_INT32_T_MAX) {
472775Svbart@nginx.com return NULL;
473775Svbart@nginx.com }
474775Svbart@nginx.com
475775Svbart@nginx.com value = nxt_conf_get_array_element(value, index);
476775Svbart@nginx.com break;
477775Svbart@nginx.com
478775Svbart@nginx.com default:
479775Svbart@nginx.com return NULL;
480775Svbart@nginx.com }
481106Svbart@nginx.com
482106Svbart@nginx.com if (value == NULL) {
483106Svbart@nginx.com return NULL;
484106Svbart@nginx.com }
485106Svbart@nginx.com
486106Svbart@nginx.com } while (parse.last == 0);
487106Svbart@nginx.com
488106Svbart@nginx.com return value;
489106Svbart@nginx.com }
490106Svbart@nginx.com
491106Svbart@nginx.com
4921174Svbart@nginx.com static nxt_int_t
nxt_conf_path_next_token(nxt_conf_path_parse_t * parse,nxt_str_t * token)493106Svbart@nginx.com nxt_conf_path_next_token(nxt_conf_path_parse_t *parse, nxt_str_t *token)
494106Svbart@nginx.com {
4951174Svbart@nginx.com u_char *p, *start, *end;
4961174Svbart@nginx.com size_t length;
4971174Svbart@nginx.com
4981174Svbart@nginx.com start = parse->start + 1;
4991174Svbart@nginx.com
5001174Svbart@nginx.com p = start;
5011174Svbart@nginx.com
5021174Svbart@nginx.com while (p < parse->end && *p != '/') {
503106Svbart@nginx.com p++;
504106Svbart@nginx.com }
505106Svbart@nginx.com
506106Svbart@nginx.com parse->start = p;
5071174Svbart@nginx.com parse->last = (p >= parse->end);
5081174Svbart@nginx.com
5091174Svbart@nginx.com length = p - start;
5101174Svbart@nginx.com
5111174Svbart@nginx.com if (nxt_slow_path(length > NXT_CONF_MAX_TOKEN_LEN)) {
5121174Svbart@nginx.com return NXT_ERROR;
5131174Svbart@nginx.com }
5141174Svbart@nginx.com
5151174Svbart@nginx.com end = nxt_decode_uri(parse->buf, start, length);
5161174Svbart@nginx.com if (nxt_slow_path(end == NULL)) {
5171174Svbart@nginx.com return NXT_ERROR;
5181174Svbart@nginx.com }
5191174Svbart@nginx.com
5201174Svbart@nginx.com token->length = end - parse->buf;
5211174Svbart@nginx.com token->start = parse->buf;
5221174Svbart@nginx.com
5231174Svbart@nginx.com return NXT_OK;
524106Svbart@nginx.com }
525106Svbart@nginx.com
526106Svbart@nginx.com
527106Svbart@nginx.com nxt_conf_value_t *
nxt_conf_get_object_member(nxt_conf_value_t * value,nxt_str_t * name,uint32_t * index)528106Svbart@nginx.com nxt_conf_get_object_member(nxt_conf_value_t *value, nxt_str_t *name,
529106Svbart@nginx.com uint32_t *index)
530106Svbart@nginx.com {
531106Svbart@nginx.com nxt_str_t str;
532106Svbart@nginx.com nxt_uint_t n;
533106Svbart@nginx.com nxt_conf_object_t *object;
534106Svbart@nginx.com nxt_conf_object_member_t *member;
535106Svbart@nginx.com
536116Svbart@nginx.com if (value->type != NXT_CONF_VALUE_OBJECT) {
537106Svbart@nginx.com return NULL;
538106Svbart@nginx.com }
539106Svbart@nginx.com
540106Svbart@nginx.com object = value->u.object;
541106Svbart@nginx.com
542106Svbart@nginx.com for (n = 0; n < object->count; n++) {
543106Svbart@nginx.com member = &object->members[n];
544106Svbart@nginx.com
545106Svbart@nginx.com nxt_conf_get_string(&member->name, &str);
546106Svbart@nginx.com
547106Svbart@nginx.com if (nxt_strstr_eq(&str, name)) {
548106Svbart@nginx.com
549106Svbart@nginx.com if (index != NULL) {
550106Svbart@nginx.com *index = n;
551106Svbart@nginx.com }
552106Svbart@nginx.com
553106Svbart@nginx.com return &member->value;
554106Svbart@nginx.com }
555106Svbart@nginx.com }
556106Svbart@nginx.com
557106Svbart@nginx.com return NULL;
558106Svbart@nginx.com }
559106Svbart@nginx.com
560106Svbart@nginx.com
561106Svbart@nginx.com nxt_int_t
nxt_conf_map_object(nxt_mp_t * mp,nxt_conf_value_t * value,nxt_conf_map_t * map,nxt_uint_t n,void * data)562213Svbart@nginx.com nxt_conf_map_object(nxt_mp_t *mp, nxt_conf_value_t *value, nxt_conf_map_t *map,
563213Svbart@nginx.com nxt_uint_t n, void *data)
564106Svbart@nginx.com {
5651439Svbart@nginx.com double num;
566213Svbart@nginx.com nxt_str_t str, *s;
567106Svbart@nginx.com nxt_uint_t i;
568106Svbart@nginx.com nxt_conf_value_t *v;
569106Svbart@nginx.com
570106Svbart@nginx.com union {
571111Sigor@sysoev.ru uint8_t ui8;
572111Sigor@sysoev.ru int32_t i32;
573111Sigor@sysoev.ru int64_t i64;
574839Svbart@nginx.com int i;
575111Sigor@sysoev.ru ssize_t size;
576111Sigor@sysoev.ru off_t off;
577111Sigor@sysoev.ru nxt_msec_t msec;
578111Sigor@sysoev.ru double dbl;
579111Sigor@sysoev.ru nxt_str_t str;
580213Svbart@nginx.com char *cstrz;
581111Sigor@sysoev.ru void *v;
582106Svbart@nginx.com } *ptr;
583106Svbart@nginx.com
584136Svbart@nginx.com for (i = 0; i < n; i++) {
585106Svbart@nginx.com
586106Svbart@nginx.com v = nxt_conf_get_object_member(value, &map[i].name, NULL);
587106Svbart@nginx.com
588116Svbart@nginx.com if (v == NULL || v->type == NXT_CONF_VALUE_NULL) {
589106Svbart@nginx.com continue;
590106Svbart@nginx.com }
591106Svbart@nginx.com
592106Svbart@nginx.com ptr = nxt_pointer_to(data, map[i].offset);
593106Svbart@nginx.com
594106Svbart@nginx.com switch (map[i].type) {
595106Svbart@nginx.com
596106Svbart@nginx.com case NXT_CONF_MAP_INT8:
597106Svbart@nginx.com
598136Svbart@nginx.com if (v->type == NXT_CONF_VALUE_BOOLEAN) {
599136Svbart@nginx.com ptr->ui8 = v->u.boolean;
600106Svbart@nginx.com }
601106Svbart@nginx.com
602106Svbart@nginx.com break;
603106Svbart@nginx.com
604106Svbart@nginx.com case NXT_CONF_MAP_INT32:
605106Svbart@nginx.com case NXT_CONF_MAP_INT64:
606106Svbart@nginx.com case NXT_CONF_MAP_INT:
607106Svbart@nginx.com case NXT_CONF_MAP_SIZE:
608106Svbart@nginx.com case NXT_CONF_MAP_OFF:
609111Sigor@sysoev.ru case NXT_CONF_MAP_MSEC:
610106Svbart@nginx.com
611116Svbart@nginx.com if (v->type != NXT_CONF_VALUE_INTEGER) {
612136Svbart@nginx.com break;
613106Svbart@nginx.com }
614106Svbart@nginx.com
6151439Svbart@nginx.com num = nxt_strtod(v->u.number, NULL);
6161439Svbart@nginx.com
617106Svbart@nginx.com switch (map[i].type) {
618106Svbart@nginx.com
619106Svbart@nginx.com case NXT_CONF_MAP_INT32:
6201439Svbart@nginx.com ptr->i32 = num;
621106Svbart@nginx.com break;
622106Svbart@nginx.com
623106Svbart@nginx.com case NXT_CONF_MAP_INT64:
6241439Svbart@nginx.com ptr->i64 = num;
625106Svbart@nginx.com break;
626106Svbart@nginx.com
627106Svbart@nginx.com case NXT_CONF_MAP_INT:
6281439Svbart@nginx.com ptr->i = num;
629106Svbart@nginx.com break;
630106Svbart@nginx.com
631106Svbart@nginx.com case NXT_CONF_MAP_SIZE:
6321439Svbart@nginx.com ptr->size = num;
633106Svbart@nginx.com break;
634106Svbart@nginx.com
635106Svbart@nginx.com case NXT_CONF_MAP_OFF:
6361439Svbart@nginx.com ptr->off = num;
637106Svbart@nginx.com break;
638106Svbart@nginx.com
639111Sigor@sysoev.ru case NXT_CONF_MAP_MSEC:
6401439Svbart@nginx.com ptr->msec = (nxt_msec_t) num * 1000;
641111Sigor@sysoev.ru break;
642111Sigor@sysoev.ru
643106Svbart@nginx.com default:
644106Svbart@nginx.com nxt_unreachable();
645106Svbart@nginx.com }
646106Svbart@nginx.com
647106Svbart@nginx.com break;
648106Svbart@nginx.com
649106Svbart@nginx.com case NXT_CONF_MAP_DOUBLE:
650106Svbart@nginx.com
651116Svbart@nginx.com if (v->type == NXT_CONF_VALUE_NUMBER) {
6521439Svbart@nginx.com ptr->dbl = nxt_strtod(v->u.number, NULL);
653106Svbart@nginx.com }
654106Svbart@nginx.com
655106Svbart@nginx.com break;
656106Svbart@nginx.com
657106Svbart@nginx.com case NXT_CONF_MAP_STR:
658213Svbart@nginx.com case NXT_CONF_MAP_STR_COPY:
659213Svbart@nginx.com case NXT_CONF_MAP_CSTRZ:
660213Svbart@nginx.com
661213Svbart@nginx.com if (v->type != NXT_CONF_VALUE_SHORT_STRING
662213Svbart@nginx.com && v->type != NXT_CONF_VALUE_STRING)
663106Svbart@nginx.com {
664213Svbart@nginx.com break;
665213Svbart@nginx.com }
666213Svbart@nginx.com
667213Svbart@nginx.com nxt_conf_get_string(v, &str);
668213Svbart@nginx.com
669213Svbart@nginx.com switch (map[i].type) {
670213Svbart@nginx.com
671213Svbart@nginx.com case NXT_CONF_MAP_STR:
672213Svbart@nginx.com ptr->str = str;
673213Svbart@nginx.com break;
674213Svbart@nginx.com
675213Svbart@nginx.com case NXT_CONF_MAP_STR_COPY:
676213Svbart@nginx.com
677213Svbart@nginx.com s = nxt_str_dup(mp, &ptr->str, &str);
678213Svbart@nginx.com
679213Svbart@nginx.com if (nxt_slow_path(s == NULL)) {
680213Svbart@nginx.com return NXT_ERROR;
681213Svbart@nginx.com }
682213Svbart@nginx.com
683213Svbart@nginx.com break;
684213Svbart@nginx.com
685213Svbart@nginx.com case NXT_CONF_MAP_CSTRZ:
686213Svbart@nginx.com
687213Svbart@nginx.com ptr->cstrz = nxt_str_cstrz(mp, &str);
688213Svbart@nginx.com
689213Svbart@nginx.com if (nxt_slow_path(ptr->cstrz == NULL)) {
690213Svbart@nginx.com return NXT_ERROR;
691213Svbart@nginx.com }
692213Svbart@nginx.com
693213Svbart@nginx.com break;
694213Svbart@nginx.com
695213Svbart@nginx.com default:
696213Svbart@nginx.com nxt_unreachable();
697106Svbart@nginx.com }
698106Svbart@nginx.com
699106Svbart@nginx.com break;
700106Svbart@nginx.com
701106Svbart@nginx.com case NXT_CONF_MAP_PTR:
702106Svbart@nginx.com
703106Svbart@nginx.com ptr->v = v;
704106Svbart@nginx.com
705106Svbart@nginx.com break;
706106Svbart@nginx.com }
707106Svbart@nginx.com }
708106Svbart@nginx.com
709106Svbart@nginx.com return NXT_OK;
710106Svbart@nginx.com }
711106Svbart@nginx.com
712106Svbart@nginx.com
713106Svbart@nginx.com nxt_conf_value_t *
nxt_conf_next_object_member(nxt_conf_value_t * value,nxt_str_t * name,uint32_t * next)714106Svbart@nginx.com nxt_conf_next_object_member(nxt_conf_value_t *value, nxt_str_t *name,
715106Svbart@nginx.com uint32_t *next)
716106Svbart@nginx.com {
717106Svbart@nginx.com uint32_t n;
718106Svbart@nginx.com nxt_conf_object_t *object;
719106Svbart@nginx.com nxt_conf_object_member_t *member;
720106Svbart@nginx.com
721116Svbart@nginx.com if (value->type != NXT_CONF_VALUE_OBJECT) {
722106Svbart@nginx.com return NULL;
723106Svbart@nginx.com }
724106Svbart@nginx.com
725106Svbart@nginx.com n = *next;
726106Svbart@nginx.com object = value->u.object;
727106Svbart@nginx.com
728106Svbart@nginx.com if (n >= object->count) {
729106Svbart@nginx.com return NULL;
730106Svbart@nginx.com }
731106Svbart@nginx.com
732106Svbart@nginx.com member = &object->members[n];
733106Svbart@nginx.com *next = n + 1;
734106Svbart@nginx.com
735106Svbart@nginx.com nxt_conf_get_string(&member->name, name);
736106Svbart@nginx.com
737106Svbart@nginx.com return &member->value;
738106Svbart@nginx.com }
739106Svbart@nginx.com
740106Svbart@nginx.com
741214Svbart@nginx.com nxt_conf_value_t *
nxt_conf_get_array_element(nxt_conf_value_t * value,uint32_t index)742214Svbart@nginx.com nxt_conf_get_array_element(nxt_conf_value_t *value, uint32_t index)
743214Svbart@nginx.com {
744214Svbart@nginx.com nxt_conf_array_t *array;
745214Svbart@nginx.com
746214Svbart@nginx.com if (value->type != NXT_CONF_VALUE_ARRAY) {
747214Svbart@nginx.com return NULL;
748214Svbart@nginx.com }
749214Svbart@nginx.com
750214Svbart@nginx.com array = value->u.array;
751214Svbart@nginx.com
752214Svbart@nginx.com if (index >= array->count) {
753214Svbart@nginx.com return NULL;
754214Svbart@nginx.com }
755214Svbart@nginx.com
756214Svbart@nginx.com return &array->elements[index];
757214Svbart@nginx.com }
758214Svbart@nginx.com
759214Svbart@nginx.com
7602076Salx.manpages@gmail.com nxt_conf_value_t *
nxt_conf_get_array_element_or_itself(nxt_conf_value_t * value,uint32_t index)7612076Salx.manpages@gmail.com nxt_conf_get_array_element_or_itself(nxt_conf_value_t *value, uint32_t index)
7622076Salx.manpages@gmail.com {
7632076Salx.manpages@gmail.com nxt_conf_array_t *array;
7642076Salx.manpages@gmail.com
7652076Salx.manpages@gmail.com if (value->type != NXT_CONF_VALUE_ARRAY) {
7662076Salx.manpages@gmail.com return (index == 0) ? value : NULL;
7672076Salx.manpages@gmail.com }
7682076Salx.manpages@gmail.com
7692076Salx.manpages@gmail.com array = value->u.array;
7702076Salx.manpages@gmail.com
7712076Salx.manpages@gmail.com if (index >= array->count) {
7722076Salx.manpages@gmail.com return NULL;
7732076Salx.manpages@gmail.com }
7742076Salx.manpages@gmail.com
7752076Salx.manpages@gmail.com return &array->elements[index];
7762076Salx.manpages@gmail.com }
7772076Salx.manpages@gmail.com
7782076Salx.manpages@gmail.com
779962Sigor@sysoev.ru void
nxt_conf_array_qsort(nxt_conf_value_t * value,int (* compare)(const void *,const void *))780962Sigor@sysoev.ru nxt_conf_array_qsort(nxt_conf_value_t *value,
781962Sigor@sysoev.ru int (*compare)(const void *, const void *))
782962Sigor@sysoev.ru {
783962Sigor@sysoev.ru nxt_conf_array_t *array;
784962Sigor@sysoev.ru
785962Sigor@sysoev.ru if (value->type != NXT_CONF_VALUE_ARRAY) {
786962Sigor@sysoev.ru return;
787962Sigor@sysoev.ru }
788962Sigor@sysoev.ru
789962Sigor@sysoev.ru array = value->u.array;
790962Sigor@sysoev.ru
791962Sigor@sysoev.ru nxt_qsort(array->elements, array->count, sizeof(nxt_conf_value_t), compare);
792962Sigor@sysoev.ru }
793962Sigor@sysoev.ru
794962Sigor@sysoev.ru
7951049Svbart@nginx.com nxt_conf_op_ret_t
nxt_conf_op_compile(nxt_mp_t * mp,nxt_conf_op_t ** ops,nxt_conf_value_t * root,nxt_str_t * path,nxt_conf_value_t * value,nxt_bool_t add)796106Svbart@nginx.com nxt_conf_op_compile(nxt_mp_t *mp, nxt_conf_op_t **ops, nxt_conf_value_t *root,
7971049Svbart@nginx.com nxt_str_t *path, nxt_conf_value_t *value, nxt_bool_t add)
798106Svbart@nginx.com {
799106Svbart@nginx.com nxt_str_t token;
8001174Svbart@nginx.com nxt_int_t ret, index;
801106Svbart@nginx.com nxt_conf_op_t *op, **parent;
8021047Svbart@nginx.com nxt_conf_value_t *node;
803106Svbart@nginx.com nxt_conf_path_parse_t parse;
804106Svbart@nginx.com nxt_conf_object_member_t *member;
805106Svbart@nginx.com
806106Svbart@nginx.com parse.start = path->start;
807106Svbart@nginx.com parse.end = path->start + path->length;
808106Svbart@nginx.com parse.last = 0;
809106Svbart@nginx.com
810106Svbart@nginx.com parent = ops;
811106Svbart@nginx.com
812106Svbart@nginx.com for ( ;; ) {
813106Svbart@nginx.com op = nxt_mp_zget(mp, sizeof(nxt_conf_op_t));
814106Svbart@nginx.com if (nxt_slow_path(op == NULL)) {
8151049Svbart@nginx.com return NXT_CONF_OP_ERROR;
816106Svbart@nginx.com }
817106Svbart@nginx.com
818106Svbart@nginx.com *parent = op;
819106Svbart@nginx.com parent = (nxt_conf_op_t **) &op->ctx;
820106Svbart@nginx.com
8211174Svbart@nginx.com ret = nxt_conf_path_next_token(&parse, &token);
8221174Svbart@nginx.com if (nxt_slow_path(ret != NXT_OK)) {
8231174Svbart@nginx.com return NXT_CONF_OP_ERROR;
8241174Svbart@nginx.com }
825106Svbart@nginx.com
8261048Svbart@nginx.com switch (root->type) {
8271048Svbart@nginx.com
8281048Svbart@nginx.com case NXT_CONF_VALUE_OBJECT:
8291048Svbart@nginx.com node = nxt_conf_get_object_member(root, &token, &op->index);
8301048Svbart@nginx.com break;
8311048Svbart@nginx.com
8321048Svbart@nginx.com case NXT_CONF_VALUE_ARRAY:
8331048Svbart@nginx.com index = nxt_int_parse(token.start, token.length);
8341048Svbart@nginx.com
8351048Svbart@nginx.com if (index < 0 || index > NXT_INT32_T_MAX) {
8361049Svbart@nginx.com return NXT_CONF_OP_NOT_FOUND;
8371048Svbart@nginx.com }
8381048Svbart@nginx.com
8391048Svbart@nginx.com op->index = index;
8401048Svbart@nginx.com
8411048Svbart@nginx.com node = nxt_conf_get_array_element(root, index);
8421048Svbart@nginx.com break;
8431048Svbart@nginx.com
8441048Svbart@nginx.com default:
8451048Svbart@nginx.com node = NULL;
8461048Svbart@nginx.com }
847106Svbart@nginx.com
848106Svbart@nginx.com if (parse.last) {
849106Svbart@nginx.com break;
850106Svbart@nginx.com }
851106Svbart@nginx.com
8521047Svbart@nginx.com if (node == NULL) {
8531049Svbart@nginx.com return NXT_CONF_OP_NOT_FOUND;
854106Svbart@nginx.com }
855106Svbart@nginx.com
856106Svbart@nginx.com op->action = NXT_CONF_OP_PASS;
8571047Svbart@nginx.com root = node;
858106Svbart@nginx.com }
859106Svbart@nginx.com
860106Svbart@nginx.com if (value == NULL) {
861106Svbart@nginx.com
8621047Svbart@nginx.com if (node == NULL) {
8631049Svbart@nginx.com return NXT_CONF_OP_NOT_FOUND;
864106Svbart@nginx.com }
865106Svbart@nginx.com
866106Svbart@nginx.com op->action = NXT_CONF_OP_DELETE;
867106Svbart@nginx.com
8681049Svbart@nginx.com return NXT_CONF_OP_OK;
8691049Svbart@nginx.com }
8701049Svbart@nginx.com
8711049Svbart@nginx.com if (add) {
8721049Svbart@nginx.com if (node == NULL) {
8731049Svbart@nginx.com return NXT_CONF_OP_NOT_FOUND;
8741049Svbart@nginx.com }
8751049Svbart@nginx.com
8761049Svbart@nginx.com if (node->type != NXT_CONF_VALUE_ARRAY) {
8771049Svbart@nginx.com return NXT_CONF_OP_NOT_ALLOWED;
8781049Svbart@nginx.com }
8791049Svbart@nginx.com
8801049Svbart@nginx.com op->action = NXT_CONF_OP_PASS;
8811049Svbart@nginx.com
8821049Svbart@nginx.com op = nxt_mp_zget(mp, sizeof(nxt_conf_op_t));
8831049Svbart@nginx.com if (nxt_slow_path(op == NULL)) {
8841049Svbart@nginx.com return NXT_CONF_OP_ERROR;
8851049Svbart@nginx.com }
8861049Svbart@nginx.com
8871049Svbart@nginx.com *parent = op;
8881049Svbart@nginx.com
8891049Svbart@nginx.com op->index = node->u.array->count;
8901049Svbart@nginx.com op->action = NXT_CONF_OP_CREATE;
8911049Svbart@nginx.com op->ctx = value;
8921049Svbart@nginx.com
8931049Svbart@nginx.com return NXT_CONF_OP_OK;
894106Svbart@nginx.com }
895106Svbart@nginx.com
8961048Svbart@nginx.com if (node != NULL) {
8971048Svbart@nginx.com op->action = NXT_CONF_OP_REPLACE;
8981048Svbart@nginx.com op->ctx = value;
8991048Svbart@nginx.com
9001049Svbart@nginx.com return NXT_CONF_OP_OK;
9011048Svbart@nginx.com }
9021048Svbart@nginx.com
9031048Svbart@nginx.com op->action = NXT_CONF_OP_CREATE;
9041048Svbart@nginx.com
9051048Svbart@nginx.com if (root->type == NXT_CONF_VALUE_ARRAY) {
9061048Svbart@nginx.com if (op->index > root->u.array->count) {
9071049Svbart@nginx.com return NXT_CONF_OP_NOT_FOUND;
9081048Svbart@nginx.com }
9091048Svbart@nginx.com
9101048Svbart@nginx.com op->ctx = value;
9111048Svbart@nginx.com
9121048Svbart@nginx.com } else {
913106Svbart@nginx.com member = nxt_mp_zget(mp, sizeof(nxt_conf_object_member_t));
914106Svbart@nginx.com if (nxt_slow_path(member == NULL)) {
9151049Svbart@nginx.com return NXT_CONF_OP_ERROR;
916106Svbart@nginx.com }
917106Svbart@nginx.com
9181174Svbart@nginx.com ret = nxt_conf_set_string_dup(&member->name, mp, &token);
9191174Svbart@nginx.com if (nxt_slow_path(ret != NXT_OK)) {
9201174Svbart@nginx.com return NXT_CONF_OP_ERROR;
9211174Svbart@nginx.com }
922106Svbart@nginx.com
923106Svbart@nginx.com member->value = *value;
924106Svbart@nginx.com
9251047Svbart@nginx.com op->index = root->u.object->count;
926106Svbart@nginx.com op->ctx = member;
927106Svbart@nginx.com }
928106Svbart@nginx.com
9291049Svbart@nginx.com return NXT_CONF_OP_OK;
930106Svbart@nginx.com }
931106Svbart@nginx.com
932106Svbart@nginx.com
933106Svbart@nginx.com nxt_conf_value_t *
nxt_conf_clone(nxt_mp_t * mp,nxt_conf_op_t * op,nxt_conf_value_t * value)934106Svbart@nginx.com nxt_conf_clone(nxt_mp_t *mp, nxt_conf_op_t *op, nxt_conf_value_t *value)
935106Svbart@nginx.com {
936106Svbart@nginx.com nxt_int_t rc;
937106Svbart@nginx.com nxt_conf_value_t *copy;
938106Svbart@nginx.com
939106Svbart@nginx.com copy = nxt_mp_get(mp, sizeof(nxt_conf_value_t));
940106Svbart@nginx.com if (nxt_slow_path(copy == NULL)) {
941106Svbart@nginx.com return NULL;
942106Svbart@nginx.com }
943106Svbart@nginx.com
944106Svbart@nginx.com rc = nxt_conf_copy_value(mp, op, copy, value);
945106Svbart@nginx.com
946106Svbart@nginx.com if (nxt_slow_path(rc != NXT_OK)) {
947106Svbart@nginx.com return NULL;
948106Svbart@nginx.com }
949106Svbart@nginx.com
950106Svbart@nginx.com return copy;
951106Svbart@nginx.com }
952106Svbart@nginx.com
953106Svbart@nginx.com
954106Svbart@nginx.com static nxt_int_t
nxt_conf_copy_value(nxt_mp_t * mp,nxt_conf_op_t * op,nxt_conf_value_t * dst,nxt_conf_value_t * src)955106Svbart@nginx.com nxt_conf_copy_value(nxt_mp_t *mp, nxt_conf_op_t *op, nxt_conf_value_t *dst,
956106Svbart@nginx.com nxt_conf_value_t *src)
957106Svbart@nginx.com {
9581048Svbart@nginx.com if (op != NULL
9591048Svbart@nginx.com && src->type != NXT_CONF_VALUE_ARRAY
9601048Svbart@nginx.com && src->type != NXT_CONF_VALUE_OBJECT)
9611048Svbart@nginx.com {
962106Svbart@nginx.com return NXT_ERROR;
963106Svbart@nginx.com }
964106Svbart@nginx.com
965106Svbart@nginx.com switch (src->type) {
966106Svbart@nginx.com
967116Svbart@nginx.com case NXT_CONF_VALUE_STRING:
968106Svbart@nginx.com
969172Svbart@nginx.com dst->u.string.start = nxt_mp_nget(mp, src->u.string.length);
970172Svbart@nginx.com if (nxt_slow_path(dst->u.string.start == NULL)) {
971106Svbart@nginx.com return NXT_ERROR;
972106Svbart@nginx.com }
973106Svbart@nginx.com
974172Svbart@nginx.com nxt_memcpy(dst->u.string.start, src->u.string.start,
975172Svbart@nginx.com src->u.string.length);
976