Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
ex_json.c
Go to the documentation of this file.
1/*
2 * Nilorea Library
3 * Copyright (C) 2005-2026 Castagnier Mickael
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 *
17 * SPDX-License-Identifier: Apache-2.0
18 */
19
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <unistd.h>
31
32#include "nilorea/n_json.h"
33#include "nilorea/n_log.h"
34
35static int log_level = LOG_ERR;
36static int failures = 0;
37
38static int process_args(int argc, char** argv) {
39 int opt;
40 while ((opt = getopt(argc, argv, "V:")) != -1) {
41 switch (opt) {
42 case 'V':
43 if (!strcmp("LOG_NULL", optarg))
45 else if (!strcmp("LOG_NOTICE", optarg))
47 else if (!strcmp("LOG_INFO", optarg))
49 else if (!strcmp("LOG_ERR", optarg))
51 else if (!strcmp("LOG_DEBUG", optarg))
53 else
54 return -1;
55 break;
56 default:
57 return -1;
58 }
59 }
60 return 0;
61}
62
63static void expect_true(const char* label, int cond) {
64 if (!cond) {
65 n_log(LOG_ERR, "%s: condition false", label);
66 failures++;
67 }
68}
69
70int main(int argc, char** argv) {
72 if (process_args(argc, argv) != 0) {
73 fprintf(stderr, "Usage: %s [-V LOG_LEVEL]\n", argv[0]);
74 return 2;
75 }
77
78 /* invalid JSON yields NULL */
79 expect_true("invalid parse is NULL", n_json_parse("{ not json") == NULL);
80
81 {
82 const char* text =
83 "{ \"name\": \"scan\", \"depth\": 3, \"active\": true,"
84 " \"meta\": { \"host\": \"example.test\" },"
85 " \"tags\": [ \"a\", \"b\", \"c\" ] }";
86 N_JSON* root = n_json_parse(text);
87 N_JSON* meta;
88 N_JSON* tags;
89 char* dup;
90 expect_true("root parsed", root != NULL);
91 if (!root)
92 return 1;
93
94 /* typed getters with defaults */
95 expect_true("string", strcmp(n_json_string(root, "name", "?"), "scan") == 0);
96 expect_true("string default", strcmp(n_json_string(root, "missing", "def"), "def") == 0);
97 expect_true("int", n_json_int(root, "depth", -1) == 3);
98 expect_true("int default", n_json_int(root, "missing", 7) == 7);
99 expect_true("bool", n_json_bool(root, "active", 0) == 1);
100 expect_true("bool default", n_json_bool(root, "missing", 1) == 1);
101
102 /* string_dup returns an owned copy, NULL when absent */
103 dup = n_json_string_dup(root, "name");
104 expect_true("string_dup", dup && strcmp(dup, "scan") == 0);
105 free(dup);
106 expect_true("string_dup absent is NULL", n_json_string_dup(root, "missing") == NULL);
107
108 /* nested object */
109 meta = n_json_get(root, "meta");
110 expect_true("nested object", n_json_is_object(meta));
111 expect_true("nested string", strcmp(n_json_string(meta, "host", "?"), "example.test") == 0);
112
113 /* array */
114 tags = n_json_get(root, "tags");
115 expect_true("array", n_json_is_array(tags));
116 expect_true("array size", n_json_array_size(tags) == 3);
117 expect_true("array elem", strcmp(n_json_as_string(n_json_array_at(tags, 1), "?"), "b") == 0);
118 expect_true("array out of range", n_json_array_at(tags, 9) == NULL);
119
120 n_json_free(&root);
121 expect_true("free nulls", root == NULL);
122 }
123
124 /* parse a file */
125 {
126 const char* path = "ex_json_tmp.json";
127 FILE* fp = fopen(path, "w");
128 N_JSON* root;
129 if (fp) {
130 fputs("{ \"k\": \"v\", \"n\": 42 }", fp);
131 fclose(fp);
132 }
133 expect_true("temp file written", fp != NULL);
134 root = n_json_parse_file(path);
135 expect_true("file parsed", root != NULL);
136 if (root) {
137 expect_true("file string", strcmp(n_json_string(root, "k", "?"), "v") == 0);
138 expect_true("file int", n_json_int(root, "n", 0) == 42);
139 n_json_free(&root);
140 }
141 unlink(path);
142 expect_true("missing file is NULL", n_json_parse_file("ex_json_no_such.json") == NULL);
143 }
144
145 if (failures) {
146 n_log(LOG_ERR, "ex_json: %d failure(s)", failures);
147 return 1;
148 }
149 n_log(LOG_NOTICE, "ex_json: all checks passed");
150 return 0;
151}
static int failures
int main(void)
void process_args(int argc, char **argv)
Definition ex_common.c:48
int log_level
Definition ex_fluid.c:60
static void expect_true(const char *label, int cond)
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:89
#define LOG_DEBUG
debug-level messages
Definition n_log.h:84
#define LOG_ERR
error conditions
Definition n_log.h:76
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL )
Definition n_log.c:121
#define LOG_NOTICE
normal but significant condition
Definition n_log.h:80
#define LOG_NULL
no log output
Definition n_log.h:46
#define LOG_INFO
informational
Definition n_log.h:82
N_JSON * n_json_parse(const char *text)
Parse a JSON document from a NUL-terminated string.
Definition n_json.c:43
N_JSON * n_json_array_at(const N_JSON *arr, size_t i)
Get an array element by index.
Definition n_json.c:118
const char * n_json_as_string(const N_JSON *v, const char *dflt)
Get the string value of a node itself (e.g.
Definition n_json.c:124
char * n_json_string_dup(const N_JSON *obj, const char *key)
Duplicate a string member (caller frees), or NULL when absent.
Definition n_json.c:85
size_t n_json_array_size(const N_JSON *arr)
Number of elements in an array node.
Definition n_json.c:112
long n_json_int(const N_JSON *obj, const char *key, long dflt)
Get a numeric member as a long, or a default when absent/not a number.
Definition n_json.c:90
const char * n_json_string(const N_JSON *obj, const char *key, const char *dflt)
Get a string member, or a default when absent/not a string.
Definition n_json.c:78
int n_json_bool(const N_JSON *obj, const char *key, int dflt)
Get a boolean member, or a default when absent/not a boolean.
Definition n_json.c:97
int n_json_is_object(const N_JSON *v)
Report whether a node is a JSON object.
Definition n_json.c:108
void n_json_free(N_JSON **root)
Free a JSON tree and NULL the caller's pointer.
Definition n_json.c:65
struct N_JSON N_JSON
Opaque JSON node (a cJSON node under the hood).
Definition n_json.h:48
N_JSON * n_json_parse_file(const char *path)
Parse a JSON document from a file.
Definition n_json.c:49
int n_json_is_array(const N_JSON *v)
Report whether a node is a JSON array.
Definition n_json.c:104
N_JSON * n_json_get(const N_JSON *obj, const char *key)
Get a child member of an object by key (case-sensitive).
Definition n_json.c:72
Small public JSON helper, a thin wrapper over the vendored cJSON.
Generic log system.