Line data Source code
1 : //
2 : // yaml2cjson.c
3 : // deployctl
4 : //
5 : // Created by Danny Goossen on 10/5/17.
6 : // Copyright (c) 2017 Danny Goossen. All rights reserved.
7 : //
8 :
9 :
10 : #include "deployd.h"
11 :
12 :
13 :
14 : // doesn't print styles.
15 87 : cJSON * yaml_node_json(yaml_document_t *document_p, yaml_node_t *node)
16 : {
17 : static int x = 0;
18 87 : x++;
19 87 : int node_n = x;
20 87 : cJSON * result=NULL;
21 : yaml_node_t *next_node_p;
22 :
23 87 : switch (node->type) {
24 : case YAML_NO_NODE:
25 0 : printf("Empty node(%d):\n", node_n);
26 0 : break;
27 : case YAML_SCALAR_NODE:
28 : {
29 69 : if (strcmp((const char*)node->tag,YAML_NULL_TAG)==0)
30 1 : result=cJSON_CreateNull();
31 68 : else if (strcmp((const char*)node->tag,YAML_STR_TAG)==0)
32 53 : result=cJSON_CreateString_n((const char* )node->data.scalar.value, node->data.scalar.length);
33 15 : else if (strcmp((const char*)node->tag,YAML_BOOL_TAG)==0)
34 : {
35 10 : upper_string_n((char*)node->data.scalar.value, node->data.scalar.length);
36 10 : if (node->data.scalar.length==4 && strncmp((const char *)node->data.scalar.value, "TRUE", 4)==0)
37 3 : result=cJSON_CreateTrue();
38 7 : else if (node->data.scalar.length==5 && strncmp((const char *)node->data.scalar.value, "FALSE", 5)==0)
39 1 : result=cJSON_CreateFalse();
40 6 : else if (node->data.scalar.length==3 && strncmp((const char *)node->data.scalar.value, "YES", 3)==0)
41 1 : result=cJSON_CreateTrue();
42 5 : else if (node->data.scalar.length==2 && strncmp((const char *)node->data.scalar.value, "NO", 2)==0)
43 1 : result=cJSON_CreateFalse();
44 4 : else if (node->data.scalar.length==2 && strncmp((const char *)node->data.scalar.value, "ON", 2)==0)
45 1 : result=cJSON_CreateTrue();
46 3 : else if (node->data.scalar.length==3 && strncmp((const char *)node->data.scalar.value, "OFF", 3)==0)
47 1 : result=cJSON_CreateFalse();
48 2 : else if (node->data.scalar.length==1 && strncmp((const char *)node->data.scalar.value, "Y", 1)==0)
49 1 : result=cJSON_CreateTrue();
50 1 : else if (node->data.scalar.length==1 && strncmp((const char *)node->data.scalar.value, "N", 1)==0)
51 0 : result=cJSON_CreateFalse();
52 1 : else if (node->data.scalar.length==1 && strncmp((const char *)node->data.scalar.value, "1", 1)==0)
53 0 : result=cJSON_CreateTrue();
54 1 : else if (node->data.scalar.length==1 && strncmp((const char *)node->data.scalar.value, "0", 1)==0)
55 0 : result=cJSON_CreateFalse();
56 : else
57 1 : result=cJSON_CreateString_n((const char*)node->data.scalar.value, node->data.scalar.length);
58 : }
59 5 : else if (strcmp((const char*)node->tag,YAML_INT_TAG)==0)
60 : {
61 : char * errCheck;
62 1 : char * buf=cJSON_strdup_n((const unsigned char*)node->data.scalar.value, node->data.scalar.length);
63 1 : int i = (int)strtol(buf, &errCheck,(10));
64 1 : free(buf);
65 1 : if(errCheck == buf)
66 0 : result=cJSON_CreateString_n((const char*)node->data.scalar.value, node->data.scalar.length);
67 : else
68 1 : result=cJSON_CreateNumber(i);
69 : }
70 4 : else if (strcmp((const char*)node->tag,YAML_FLOAT_TAG)==0)
71 : {
72 : char * errCheck;
73 2 : char * buf=cJSON_strdup_n((const unsigned char*)node->data.scalar.value, node->data.scalar.length);
74 2 : float f = strtod(buf, &errCheck);
75 2 : free(buf);
76 2 : if(errCheck == buf)
77 0 : result=cJSON_CreateString_n((const char*)node->data.scalar.value, node->data.scalar.length);
78 : else
79 2 : result=cJSON_CreateNumber(f);
80 : }
81 2 : else if (strcmp((const char*)node->tag,YAML_TIMESTAMP_TAG)==0)
82 0 : result=cJSON_CreateString_n((const char*)node->data.scalar.value, node->data.scalar.length);
83 : break;
84 : }
85 : case YAML_SEQUENCE_NODE:
86 : {
87 : yaml_node_item_t *i_node;
88 6 : cJSON * temp=NULL;
89 24 : for (i_node = node->data.sequence.items.start; i_node < node->data.sequence.items.top; i_node++) {
90 18 : next_node_p = yaml_document_get_node(document_p, *i_node);
91 18 : if (next_node_p)
92 : {
93 18 : temp=yaml_node_json(document_p, next_node_p);
94 18 : if (temp)
95 : {
96 18 : if (result==NULL ) result=cJSON_CreateArray();
97 18 : cJSON_AddItemToArray(result, temp);
98 : }
99 : }
100 : }
101 : break;
102 : }
103 : case YAML_MAPPING_NODE:
104 : {
105 : yaml_node_pair_t *i_node_p;
106 12 : cJSON * temp=NULL;
107 78 : for (i_node_p = node->data.mapping.pairs.start; i_node_p < node->data.mapping.pairs.top; i_node_p++) {
108 :
109 66 : next_node_p = yaml_document_get_node(document_p, i_node_p->value);
110 66 : if (next_node_p) {
111 66 : temp=yaml_node_json(document_p, next_node_p);
112 : }
113 66 : next_node_p = yaml_document_get_node(document_p, i_node_p->key);
114 66 : if (next_node_p && next_node_p->type==YAML_SCALAR_NODE)
115 : {
116 64 : if (result==NULL) result=cJSON_CreateObject();
117 64 : if (strncmp("<<", (const char*)next_node_p->data.scalar.value, next_node_p->data.scalar.length)==0)
118 : { // merge, deconstruct temp
119 2 : if (temp && temp->type==cJSON_Object)
120 : {
121 2 : cJSON * temp_item= temp->child;
122 2 : temp->child=NULL;
123 : cJSON * traverse;
124 : temp->child=NULL;
125 2 : if (result->child)
126 : {
127 : traverse=result->child;
128 0 : while ( traverse->next !=NULL) traverse=traverse->next;
129 0 : traverse->next=temp_item;
130 0 : temp_item->prev=traverse;
131 : }
132 : else
133 : {
134 2 : result->child=temp_item;
135 : }
136 0 : } else if (temp && temp->type==cJSON_Array)
137 : {
138 : // loop the array and add children to result
139 0 : cJSON * pos=NULL;
140 0 : int item=0;
141 : cJSON * traverse;
142 0 : cJSON_ArrayForEach(pos,temp)
143 : {
144 0 : if (result->child)
145 : {
146 : traverse=result->child;
147 0 : while ( traverse->next !=NULL) traverse=traverse->next;
148 0 : traverse->next=pos->child;
149 0 : pos->child=NULL;
150 : }
151 : else
152 : {
153 0 : result->child=pos->child;
154 0 : pos->child=NULL;
155 : }
156 0 : item ++;
157 : }
158 : }
159 : else
160 : {
161 0 : cJSON_AddItemToObject(result, "", temp);
162 : }
163 2 : cJSON_Delete(temp);
164 : }
165 : else
166 62 : cJSON_AddItemToObject_n(result, (const char*)next_node_p->data.scalar.value, next_node_p->data.scalar.length, temp);
167 2 : }else if (next_node_p)
168 : {
169 2 : cJSON * temp_key=yaml_node_json(document_p, next_node_p);
170 2 : if (temp_key){
171 2 : char * special_key=cJSON_PrintUnformatted(temp_key);
172 2 : char * print_key=calloc(1, strlen(special_key)+ 25);
173 : // TODO can maybe do something with raw
174 2 : sprintf(print_key,".error_unsupported_key: %s",special_key);
175 2 : cJSON_AddItemToObject(result,print_key,temp);
176 2 : if (special_key) free(special_key);
177 2 : if (print_key) free(print_key);
178 : }
179 : }
180 : }
181 : break;
182 : }
183 : default:
184 : break;
185 : }
186 87 : return result;
187 : }
188 :
189 1 : void yaml_document_2_cJSON(yaml_document_t *document_p, cJSON ** json_doc)
190 : {
191 1 : cJSON * result=NULL;
192 1 : result=yaml_node_json(document_p, yaml_document_get_root_node(document_p));
193 1 : if (result && *json_doc==NULL) *json_doc=cJSON_CreateArray();
194 1 : if (result) cJSON_AddItemToArray(*json_doc,result);
195 1 : }
196 :
197 1 : cJSON * yaml_sting_2_cJSON (void * opaque ,const char * yaml)
198 : {
199 1 : cJSON * result=NULL;
200 : yaml_parser_t parser;
201 : yaml_document_t document;
202 1 : yaml_parser_initialize(&parser);
203 1 : yaml_parser_set_input_string(&parser, (const unsigned char *) yaml, strlen(yaml));
204 :
205 1 : int done = 0;
206 4 : while (!done)
207 : {
208 2 : if (!yaml_parser_load(&parser, &document)) {
209 0 : debug( "Failed to load document \n");
210 : // todo feedback
211 0 : break;
212 : }
213 :
214 2 : done = (!yaml_document_get_root_node(&document));
215 :
216 2 : if (!done)
217 1 : yaml_document_2_cJSON(&document,&result);
218 :
219 2 : yaml_document_delete(&document);
220 : }
221 1 : yaml_parser_delete(&parser);
222 1 : return result;
223 : }
|