Make real number encoding and decoding work under all locales
[jansson.git] / test / bin / json_process.c
1 /*
2  * Copyright (c) 2009-2011 Petri Lehtinen <petri@digip.org>
3  *
4  * Jansson is free software; you can redistribute it and/or modify
5  * it under the terms of the MIT license. See LICENSE for details.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <ctype.h>
16 #include <jansson.h>
17
18 #if HAVE_LOCALE_H
19 #include <locale.h>
20 #endif
21
22 static int getenv_int(const char *name)
23 {
24     char *value, *end;
25     long result;
26
27     value = getenv(name);
28     if(!value)
29         return 0;
30
31     result = strtol(value, &end, 10);
32     if(*end != '\0')
33         return 0;
34
35     return (int)result;
36 }
37
38 /* Return a pointer to the first non-whitespace character of str.
39    Modifies str so that all trailing whitespace characters are
40    replaced by '\0'. */
41 static const char *strip(char *str)
42 {
43     size_t length;
44     char *result = str;
45     while(*result && isspace(*result))
46         result++;
47
48     length = strlen(result);
49     if(length == 0)
50         return result;
51
52     while(isspace(result[length - 1]))
53         result[--length] = '\0';
54
55     return result;
56 }
57
58 int main(int argc, char *argv[])
59 {
60     int indent = 0;
61     size_t flags = 0;
62
63     json_t *json;
64     json_error_t error;
65
66 #if HAVE_SETLOCALE
67     setlocale(LC_ALL, "");
68 #endif
69
70     if(argc != 1) {
71         fprintf(stderr, "usage: %s\n", argv[0]);
72         return 2;
73     }
74
75     indent = getenv_int("JSON_INDENT");
76     if(indent < 0 || indent > 255) {
77         fprintf(stderr, "invalid value for JSON_INDENT: %d\n", indent);
78         return 2;
79     }
80
81     if(indent > 0)
82         flags |= JSON_INDENT(indent);
83
84     if(getenv_int("JSON_COMPACT") > 0)
85         flags |= JSON_COMPACT;
86
87     if(getenv_int("JSON_ENSURE_ASCII"))
88         flags |= JSON_ENSURE_ASCII;
89
90     if(getenv_int("JSON_PRESERVE_ORDER"))
91         flags |= JSON_PRESERVE_ORDER;
92
93     if(getenv_int("JSON_SORT_KEYS"))
94         flags |= JSON_SORT_KEYS;
95
96     if(getenv_int("STRIP")) {
97         /* Load to memory, strip leading and trailing whitespace */
98         size_t size = 0, used = 0;
99         char *buffer = NULL;
100
101         while(1) {
102             int count;
103
104             size = (size == 0 ? 128 : size * 2);
105             buffer = realloc(buffer, size);
106             if(!buffer) {
107                 fprintf(stderr, "Unable to allocate %d bytes\n", (int)size);
108                 return 1;
109             }
110
111             count = fread(buffer + used, 1, size - used, stdin);
112             if(count < size - used) {
113                 buffer[used + count] = '\0';
114                 break;
115             }
116             used += count;
117         }
118
119         json = json_loads(strip(buffer), 0, &error);
120         free(buffer);
121     }
122     else
123         json = json_loadf(stdin, 0, &error);
124
125     if(!json) {
126         fprintf(stderr, "%d %d %d\n%s\n",
127                 error.line, error.column, error.position,
128                 error.text);
129         return 1;
130     }
131
132     json_dumpf(json, stdout, flags);
133     json_decref(json);
134
135     return 0;
136 }