diff options
-rw-r--r-- | src/genskel/CMakeLists.txt | 8 | ||||
-rw-r--r-- | src/genskel/json2c.c | 174 |
2 files changed, 182 insertions, 0 deletions
diff --git a/src/genskel/CMakeLists.txt b/src/genskel/CMakeLists.txt index ac1d1210..b1d63825 100644 --- a/src/genskel/CMakeLists.txt +++ b/src/genskel/CMakeLists.txt @@ -17,6 +17,14 @@ ########################################################################### ADD_EXECUTABLE(afb-genskel genskel.c) +ADD_EXECUTABLE(afb-exprefs exprefs.c) +ADD_EXECUTABLE(afb-json2c json2c.c) + TARGET_LINK_LIBRARIES(afb-genskel ${link_libraries}) +TARGET_LINK_LIBRARIES(afb-exprefs ${link_libraries}) +TARGET_LINK_LIBRARIES(afb-json2c ${link_libraries}) + INSTALL(TARGETS afb-genskel RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +INSTALL(TARGETS afb-exprefs RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +INSTALL(TARGETS afb-json2c RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/src/genskel/json2c.c b/src/genskel/json2c.c new file mode 100644 index 00000000..cb541bfd --- /dev/null +++ b/src/genskel/json2c.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2016, 2017 "IoT.bzh" + * Author José Bollo <jose.bollo@iot.bzh> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * This simple program expands the object { "$ref": "#/path/to/a/target" } + * + * For example: + * + * { + * "type":{ + * "a": "int", + * "b": { "$ref": "#/type/a" } + * } + * } + * + * will be exapanded to + * + * { + * "type":{ + * "a": "int", + * "b": "int" + * } + * } + * + * Invocation: program [file|-]... + * + * without arguments, it reads the input. + */ + +#define _GNU_SOURCE +#include <string.h> +#include <stdio.h> +#include <unistd.h> + +#include <json-c/json.h> + +#define oom(x) do{if(!(x)){fprintf(stderr,"out of memory\n");exit(1);}}while(0) + +/** + * root of the JSON being parsed + */ +struct json_object *root = NULL; + +char *make_desc(struct json_object *o) +{ + const char *a, *b; + char *desc, c, buf[3]; + size_t len; + int i, pos, e; + + a = b = json_object_to_json_string_ext(root, 0); + len = 1; + while((c = *b++)) { + len += 1 + ('"' == c); + } + + len += 7 * (1 + len / 72); + desc = malloc(len); + oom(desc); + + len = pos = 0; + b = a; + while((c = *b++)) { + if (c == '"') { + buf[0] = '\\'; + buf[1] = '"'; + buf[2] = 0; + } + else if (c == '\\') { + switch ((c = *b++)) { + case 0: + b--; + break; + case '/': + buf[0] = '/'; + buf[1] = 0; + break; + default: + buf[0] = '\\'; + buf[1] = c; + buf[2] = 0; + break; + } + } + else { + buf[0] = c; + buf[1] = 0; + } + i = e = 0; + while (buf[i]) { + if (pos >= 77 && !e) { + desc[len++] = '"'; + desc[len++] = '\n'; + pos = 0; + } + if (pos == 0) { + desc[len++] = ' '; + desc[len++] = ' '; + desc[len++] = ' '; + desc[len++] = ' '; + desc[len++] = '"'; + pos = 5; + } + c = buf[i++]; + desc[len++] = c; + e = !e && c == '\\'; + pos++; + } + } + desc[len++] = '"'; + desc[len++] = '\n'; + desc[len] = 0; + return desc; +} + +/** + * process a file and prints its expansion on stdout + */ +void process(char *filename) +{ + char *desc; + + /* translate - */ + if (!strcmp(filename, "-")) + filename = "/dev/stdin"; + + /* check access */ + if (access(filename, R_OK)) { + fprintf(stderr, "can't access file %s\n", filename); + exit(1); + } + + /* read the file */ + root = json_object_from_file(filename); + if (!root) { + fprintf(stderr, "reading file %s produced null\n", filename); + exit(1); + } + + /* create the description */ + desc = make_desc(root); + + printf("%s", desc); + + /* clean up */ + json_object_put(root); + free(desc); +} + +/** process the list of files or stdin if none */ +int main(int ac, char **av) +{ + if (!*++av) + process("-"); + else { + do { process(*av); } while(*++av); + } + return 0; +} + + |