json2matlab.c
Go to the documentation of this file.
1 #include <assert.h>
2 #include <string.h>
3 #include "../csm/csm_all.h"
4 #include <options/options.h>
5 
6 #include <json-c/json.h>
8 
9 void jo_write_as_matlab(JO jo, FILE*out);
10 
11 void jo_write_as_matrix(JO jo, FILE*out);
12 void jo_write_as_column_vector(JO jo, FILE* out);
13 
14 void jo_write_as_cell_array(JO jo, FILE* out);
15 int jo_is_numeric_matrix(JO jo);
16 int jo_is_numeric_array(JO jo);
17 void jo_write_as_matlab_object(JO jo, FILE*out);
18 
19 
20 const char * banner =
21 "Converts JSON stream to Matlab file. \n"
22 "There are three usages: \n"
23 " 1) with only one parameter, \n"
24 " $ json2matlab dir/mydata.json \n"
25 " creates a Matlab function 'mydata' inside the file 'dir/mydata.m' \n"
26 " 2) with two parameters, \n"
27 " $ json2matlab dir/mydata.json dir/out.m \n"
28 " creates a Matlab function 'out' inside the file 'dir/out.m'. \n"
29 " 3) otherwise, use the options switches. \n"
30 " \n"
31 " By default it creates a complete script of the kind:\n"
32 " \n"
33 " function res = function_name()\n"
34 " res = \n"
35 " { ...}\n"
36 " \n"
37 " If complete_script is set to 0, it just outputs the meat: \n"
38 " \n"
39 " { ...}\n"
40 " \n";
41 
42 
43 int main(int argc, const char * argv[]) {
44  sm_set_program_name(argv[0]);
45 
46  const char * input_filename;
47  const char * out_filename;
48  const char * function;
49  int complete_script;
50  int debug;
51 
53 
54  struct option* ops = options_allocate(8);
55  options_string(ops, "in", &input_filename, "stdin", "input file (JSON)");
56  options_string(ops, "out", &out_filename, "stdout", "output file (MATLAB)");
57  options_string(ops, "function", &function, "", "Matlab function name (if empty, use basename of out)");
58  options_int(ops, "complete_script", &complete_script, 1, "Write complete script 'function res = ...'");
59  options_int(ops, "debug", &debug, 1, "Shows debug information");
60 
61  if(argc == 2 && (argv[1][0] != '-')) {
62  /* one parameter */
63  input_filename = argv[1]; int len = strlen(input_filename) + 4;
64  char base[len], no_suffix[len], out[len];
65  my_no_suffix(input_filename, no_suffix);
66  sprintf(out, "%s.m", no_suffix);
67  my_basename_no_suffix(input_filename, base);
68  out_filename = my_strdup(out);
69  function = my_strdup(base);
70  } else if(argc == 3 && (argv[1][0] != '-') && (argv[2][0] != '-')) {
71  input_filename = argv[1];
72  out_filename = argv[2];
73  } else {
74  /* FIXME help not shown */
75  if(!options_parse_args(ops, argc, argv))
76  return -1;
77  }
78 
79  sm_debug_write(debug);
80 
81  if(!strcmp(function,"")) {
82  int len = strlen(out_filename) + 4;
83  char base[len];
84  my_basename_no_suffix(out_filename, base);
85  function = my_strdup(base);
86  }
87 
88 
89  FILE * out = open_file_for_writing(out_filename);
90  if(!out) return -2;
91 
92  FILE * in = open_file_for_reading(input_filename);
93  if(!in) return -3;
94 
95  if(complete_script) {
96  fprintf(out, "function res = %s\n", function);
97  fprintf(out, " res = ... \n");
98  }
99  fprintf(out, " { ... \n\t");
100 
101  JO jo;
102  int i = 0;
103  while((jo = json_read_stream(in))) {
104  if(i>0) fprintf(out, ", ...\n\t");
105  jo_write_as_matlab(jo, out);
106  jo_free(jo);
107  i++;
108  }
109 
110  fprintf(out, "... \n }; \n");
111  return 0;
112 }
113 
114 
115 void jo_write_as_matlab(JO jo, FILE*out) {
116  if(!jo) { fprintf(out, "NaN"); return; }
117 
118  switch(json_object_get_type(jo)) {
119  case json_type_null:
120  fprintf(out, "NaN");
121  return;
122 
123  case json_type_boolean:
124  fprintf(out, json_object_get_boolean(jo) ? "true" : "false" );
125  return;
126 
127  case json_type_int:
128  fprintf(out, "%d", json_object_get_int(jo));
129  return;
130 
131  case json_type_double:
132  fprintf(out, "%lg", json_object_get_double(jo));
133  return;
134 
135  case json_type_object:
136  jo_write_as_matlab_object(jo, out);
137  return;
138 
139  case json_type_array:
140  if(jo_is_numeric_matrix(jo))
141  jo_write_as_matrix(jo, out);
142  else
143  if(jo_is_numeric_array(jo))
144  jo_write_as_column_vector(jo, out);
145  else
146  jo_write_as_cell_array(jo, out);
147  return;
148 
149  case json_type_string:
150  fprintf(out, "'");
151  const char* s = json_object_get_string(jo);
152  while(*s) {
153  if(*s==39)
154  fputc('"', out);
155  else
156  fputc(*s, out);
157  s++;
158  }
159 
160  fprintf(out, "'");
161  return;
162  }
163 
164 
165 }
166 
167 
168 
169 void jo_write_as_matlab_object(JO jo, FILE*out) {
170  int i=0;
171  struct json_object_iter iter;
172  fprintf(out, "struct(");
173 
174  json_object_object_foreachC(jo, iter) {
175  if(i) fprintf(out, ", ... \n\t ");
176  fprintf(out, "'%s', ", iter.key);
177 
178  enum json_type t = json_object_get_type(iter.val);
179  if( (t == json_type_array) && (!jo_is_numeric_matrix(iter.val)) && (!jo_is_numeric_array(iter.val))) {
180  fprintf(out, "{");
181  jo_write_as_matlab(iter.val, out);
182  fprintf(out, "}");
183  } else if(t == json_type_object) {
184  fprintf(out, "{ ");
185  jo_write_as_matlab(iter.val, out);
186  fprintf(out, " }");
187  } else jo_write_as_matlab(iter.val, out);
188 
189  i++;
190  }
191  fprintf(out, ")");
192 }
193 
194 
196  /* null is not a matrix */
197  if(!jo) return 0;
198  if(json_object_get_type(jo) != json_type_array) return 0;
199  int len = json_object_array_length(jo);
200  int ncolumns = -1;
201  for(int i=0;i<len;i++){
202  JO row = json_object_array_get_idx(jo, i);
203  if(!jo_is_numeric_array(row)) return 0;
204  if(i==0)
205  ncolumns = json_object_array_length(row);
206  else
207  if(ncolumns != json_object_array_length(row))
208  return 0;
209  }
210  if(ncolumns==0) return 0;
211  return 1;
212 }
213 
215  /* null is not an array */
216  if(!jo) return 0;
217  if(json_object_get_type(jo) != json_type_array) return 0;
218  int len = json_object_array_length(jo);
219  for(int i=0;i<len;i++){
220  JO elem = json_object_array_get_idx(jo, i);
221 
222  /* I consider null elements as numeric values because they can be
223  converted into NaN */
224  if(elem==0)
225  continue;
226 
227  switch(json_object_get_type(elem)) {
228  case json_type_null:
229  case json_type_boolean:
230  case json_type_int:
231  case json_type_double:
232  continue;
233  default:
234  return 0;
235  }
236  }
237  return 1;
238 }
239 
240 void jo_write_as_matrix(JO jo, FILE*out) {
241 // "[ " + map{|row| row.join(", ")}.join("; ... \n") + "]"
242  assert(json_object_get_type(jo) == json_type_array);
243  fprintf(out, "[");
244  int len = json_object_array_length(jo);
245  for(int i=0;i<len;i++){
246  if(i>0) fprintf(out, "; ");
247  JO row = json_object_array_get_idx(jo, i);
248  int n = json_object_array_length(row);
249  for(int j=0;j<n;j++) {
250  if(j>0) fprintf(out, ", ");
252  }
253  }
254  fprintf(out, "]");
255 }
256 
257 void jo_write_as_column_vector(JO jo, FILE* out) {
258 // "[ "+map{|x| x.to_matlab }.join("; ")+"]"
259  assert(json_object_get_type(jo) == json_type_array);
260  fprintf(out, "[");
261  int len = json_object_array_length(jo);
262  for(int i=0;i<len;i++){
263  if(i>0) fprintf(out, "; ");
264  JO elem = json_object_array_get_idx(jo, i);
265  jo_write_as_matlab(elem, out);
266  }
267  fprintf(out, "]");
268 }
269 
270 void jo_write_as_cell_array(JO jo, FILE* out) {
271  assert(json_object_get_type(jo) == json_type_array);
272  int len = json_object_array_length(jo);
273  if(len==0) {
274  fprintf(out, "{}");
275  return;
276  } else {
277  fprintf(out, "{ ");
278  for(int i=0;i<len;i++){
279  if(i>0) fprintf(out, ", ");
280  JO elem = json_object_array_get_idx(jo, i);
281  jo_write_as_matlab(elem, out);
282  }
283  fprintf(out, "}");
284  }
285 // "{ ... \n "+map{|x| x.to_matlab }.join(", ... \n")+"}"
286 }
char * json_object_get_string(struct json_object *this)
Definition: json_object.c:452
void options_banner(const char *message)
Definition: options.c:33
int json_object_array_length(struct json_object *this)
Definition: json_object.c:516
void jo_write_as_matlab_object(JO jo, FILE *out)
Definition: json2matlab.c:169
void jo_write_as_matrix(JO jo, FILE *out)
Definition: json2matlab.c:240
double json_object_get_double(struct json_object *this)
Definition: json_object.c:395
void sm_set_program_name(const char *name)
Definition: logging.c:21
int jo_is_numeric_array(JO jo)
Definition: json2matlab.c:214
enum json_type json_object_get_type(struct json_object *this)
Definition: json_object.c:190
struct option * ops
Definition: rb_sm.c:31
int json_object_get_int(struct json_object *this)
Definition: json_object.c:341
void my_basename_no_suffix(const char *file, char *dest)
Definition: utils.c:40
FILE * open_file_for_writing(const char *filename)
Definition: utils.c:25
void jo_write_as_cell_array(JO jo, FILE *out)
Definition: json2matlab.c:270
void jo_write_as_matlab(JO jo, FILE *out)
Definition: json2matlab.c:115
Definition: options.h:49
struct option * options_allocate(int n)
struct json_object * val
void options_int(struct option *, const char *name, int *p, int def_value, const char *desc)
void my_no_suffix(const char *file, char *dest)
Definition: utils.c:52
void sm_debug_write(int flag)
Definition: logging.c:16
#define json_object_object_foreachC(obj, iter)
Definition: json_object.h:165
int debug
Definition: sm2.c:20
json_type
Definition: json_object.h:37
FILE * open_file_for_reading(const char *filename)
Definition: utils.c:19
void jo_write_as_column_vector(JO jo, FILE *out)
Definition: json2matlab.c:257
int jo_is_numeric_matrix(JO jo)
Definition: json2matlab.c:195
int main(int argc, const char *argv[])
Definition: json2matlab.c:43
const char * banner
Definition: json2matlab.c:20
char * my_strdup(const char *s)
Definition: utils.c:61
void options_string(struct option *, const char *name, const char **p, const char *def_balue, const char *desc)
JO json_read_stream(FILE *f)
struct json_object * json_object_array_get_idx(struct json_object *this, int idx)
Definition: json_object.c:535
int options_parse_args(struct option *ops, int argc, const char *argv[])
Definition: options.c:66
boolean json_object_get_boolean(struct json_object *this)
Definition: json_object.c:306
#define jo_free


csm
Author(s): Andrea Censi
autogenerated on Tue May 11 2021 02:18:23