aboutsummaryrefslogtreecommitdiffstats
path: root/src/devtools/json2c.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/devtools/json2c.c')
-rw-r--r--src/devtools/json2c.c202
1 files changed, 105 insertions, 97 deletions
diff --git a/src/devtools/json2c.c b/src/devtools/json2c.c
index 9bb9e9bf..c26ef84a 100644
--- a/src/devtools/json2c.c
+++ b/src/devtools/json2c.c
@@ -42,133 +42,141 @@
#define _GNU_SOURCE
#include <string.h>
+#include <limits.h>
+#include <assert.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)
+static size_t s2c(const char *str, const char *prefix, int width, int lprf, char *out)
{
- const char *a, *b;
- char *desc, c, buf[3];
+ char c, buf[4];
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);
+ int i, pos;
+#define P(x) do{ if (out) out[len] = (x); len++; pos++; }while(0)
+ /* translate the string */
len = pos = 0;
- b = a;
- while((c = *b++)) {
- if (c == '"') {
+ for(;;) {
+ /* get the char to convert */
+ c = *str++;
+
+ /* set buf with next char */
+ switch(c) {
+ case '\\':
+ c = *str++;
+ if (c) {
+ if (c == '/') {
+ /* remove ugly \/ put by json-c */
+ buf[0] = '/';
+ buf[1] = 0;
+ } else {
+ buf[0] = '\\';
+ buf[1] = c;
+ buf[2] = 0;
+ }
+ break;
+ }
+ /*@fallthrough@*/
+ case 0:
+ if (!len) P('"');
+ if (!len || pos) {
+ P('"');
+ if (prefix) P('\n');
+ }
+ P(0);
+ return len;
+ case '"':
buf[0] = '\\';
buf[1] = '"';
buf[2] = 0;
- }
- else if (c == '\\') {
- switch ((c = *b++)) {
- case '/':
- buf[0] = '/';
- buf[1] = 0;
- break;
- case 0:
- b--;
- /*@fallthrough@*/
- default:
+ break;
+ case '\n':
+ buf[0] = '\\';
+ buf[1] = 'n';
+ buf[2] = 0;
+ break;
+ case '\t':
+ buf[0] = '\\';
+ buf[1] = 't';
+ buf[2] = 0;
+ break;
+ default:
+ if (0 < c && c < ' ') {
buf[0] = '\\';
- buf[1] = c;
- buf[2] = 0;
+ buf[1] = (char)('0' + ((c >> 3) & 7));
+ buf[2] = (char)('0' + ((c >> 0) & 7));
+ buf[3] = 0;
+ } else {
+ buf[0] = c;
+ buf[1] = 0;
break;
}
+ break;
}
- else {
- buf[0] = c;
- buf[1] = 0;
+ /* add the char in the output */
+ if (pos == 0) {
+ for(i = 0 ; i < lprf ; i++)
+ P(prefix[i]);
+ P('"');
}
- 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++;
+ for(i = 0 ; buf[i] ; i++)
+ P(buf[i]);
+ if (pos >= width - 1) {
+ P('"');
+ P('\n');
+ pos = 0;
}
}
- desc[len++] = '"';
- desc[len++] = '\n';
- desc[len] = 0;
- return desc;
+ while(c);
+#undef P
}
-/**
- * process a file and prints its expansion on stdout
- */
-void process(char *filename)
+char *str2c(const char *str, const char *prefix, int width)
{
- char *desc;
+ size_t len;
+ int lprf;
+ char *out;
- /* translate - */
- if (!strcmp(filename, "-"))
- filename = "/dev/stdin";
+ /* ensure defaults */
+ len = prefix ? strlen(prefix) : 0;
+ lprf = len > INT_MAX ? INT_MAX : (int)len;
+ width = width <= 0 || width - 2 <= lprf ? INT_MAX : width;
- /* check access */
- if (access(filename, R_OK)) {
- fprintf(stderr, "can't access file %s\n", filename);
- exit(1);
- }
+ /* compute final size*/
+ len = s2c(str, prefix, width, lprf, NULL);
- /* read the file */
- root = json_object_from_file(filename);
- if (!root) {
- fprintf(stderr, "reading file %s produced null\n", filename);
- exit(1);
- }
+ /* allocate the memory */
+ out = malloc(len);
+ if (!out)
+ return NULL;
- /* create the description */
- desc = make_desc(root);
+ /* make the output */
+ s2c(str, prefix, width, lprf, out);
+ return out;
+}
- printf("%s", desc);
+char *str2c_std(const char *str)
+{
+ return str2c(str, "\t", 71);
+}
- /* clean up */
- json_object_put(root);
- free(desc);
+char *str2c_inl(const char *str)
+{
+ return str2c(str, 0, 0);
}
-/** process the list of files or stdin if none */
-int main(int ac, char **av)
+char *json2c(struct json_object *object, const char *prefix, int width)
{
- if (!*++av)
- process("-");
- else {
- do { process(*av); } while(*++av);
- }
- return 0;
+ return str2c(json_object_to_json_string_ext(object, 0), prefix, width);
}
+char *json2c_std(struct json_object *object)
+{
+ return str2c_std(json_object_to_json_string_ext(object, 0));
+}
+char *json2c_inl(struct json_object *object)
+{
+ return str2c_inl(json_object_to_json_string_ext(object, 0));
+}