summaryrefslogtreecommitdiff
path: root/src/bin/eolian
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@samsung.com>2019-06-30 20:26:51 +0200
committerDaniel Kolesa <d.kolesa@samsung.com>2019-07-08 16:06:42 +0200
commit2a1fa5d2aad8a9ceafc6ddef026b0f42c1518271 (patch)
treead873c9d89c69cefec7ca251717056cd8a0ae4fb /src/bin/eolian
parent47c5736ef9198c2b41d98ade601114f329b69b24 (diff)
eolian_gen: introduce C generation support for error types
ref T6890
Diffstat (limited to 'src/bin/eolian')
-rw-r--r--src/bin/eolian/types.c176
1 files changed, 142 insertions, 34 deletions
diff --git a/src/bin/eolian/types.c b/src/bin/eolian/types.c
index a932a7c..b55a89b 100644
--- a/src/bin/eolian/types.c
+++ b/src/bin/eolian/types.c
@@ -1,3 +1,5 @@
1#include <ctype.h>
2
1#include "main.h" 3#include "main.h"
2#include "headers.h" 4#include "headers.h"
3#include "docs.h" 5#include "docs.h"
@@ -214,6 +216,40 @@ _var_generate(const Eolian_State *state, const Eolian_Variable *vr)
214 return buf; 216 return buf;
215} 217}
216 218
219static Eina_Strbuf *
220_err_generate(const Eolian_State *state, const Eolian_Error *err)
221{
222 char *fn = strdup(eolian_error_name_get(err));
223 char *p = strrchr(fn, '.');
224 if (p) *p = '\0';
225 Eina_Strbuf *buf = eo_gen_docs_full_gen(state, eolian_error_documentation_get(err),
226 fn, 0);
227 if (p)
228 {
229 *p = '_';
230 while ((p = strchr(fn, '.')))
231 *p = '_';
232 }
233 eina_str_tolower(&fn);
234 if (!buf) buf = eina_strbuf_new();
235 else eina_strbuf_append_char(buf, '\n');
236
237 eina_strbuf_prepend_printf(buf, "EWAPI extern Eina_Error %s_get(void);\n\n", fn);
238
239 char *ufn = strdup(fn);
240 eina_str_toupper(&ufn);
241 eina_strbuf_append_printf(buf, "#define %s %s_get()", ufn, fn);
242 free(ufn);
243 free(fn);
244
245 if (eolian_error_is_beta(err))
246 {
247 eina_strbuf_prepend(buf, "#ifdef EFL_BETA_API_SUPPORT\n");
248 eina_strbuf_append(buf, "\n#endif /* EFL_BETA_API_SUPPORT */");
249 }
250 return buf;
251}
252
217void eo_gen_types_header_gen(const Eolian_State *state, 253void eo_gen_types_header_gen(const Eolian_State *state,
218 Eina_Iterator *itr, Eina_Strbuf *buf, 254 Eina_Iterator *itr, Eina_Strbuf *buf,
219 Eina_Bool full) 255 Eina_Bool full)
@@ -238,6 +274,21 @@ void eo_gen_types_header_gen(const Eolian_State *state,
238 } 274 }
239 continue; 275 continue;
240 } 276 }
277 else if (dt == EOLIAN_OBJECT_ERROR)
278 {
279 const Eolian_Error *err = (const Eolian_Error *)decl;
280 if (!err || eolian_error_is_extern(err))
281 continue;
282
283 Eina_Strbuf *ebuf = _err_generate(state, err);
284 if (ebuf)
285 {
286 eina_strbuf_append(buf, eina_strbuf_string_get(ebuf));
287 eina_strbuf_append(buf, "\n\n");
288 eina_strbuf_free(ebuf);
289 }
290 continue;
291 }
241 292
242 if (dt != EOLIAN_OBJECT_TYPEDECL) 293 if (dt != EOLIAN_OBJECT_TYPEDECL)
243 continue; 294 continue;
@@ -270,49 +321,106 @@ void eo_gen_types_header_gen(const Eolian_State *state,
270 eina_iterator_free(itr); 321 eina_iterator_free(itr);
271} 322}
272 323
273void eo_gen_types_source_gen(Eina_Iterator *itr, Eina_Strbuf *buf) 324static void
325_source_gen_error(Eina_Strbuf *buf, const Eolian_Error *err)
274{ 326{
275 const Eolian_Object *decl; 327 if (eolian_error_is_extern(err))
276 EINA_ITERATOR_FOREACH(itr, decl) 328 return;
277 {
278 Eolian_Object_Type dt = eolian_object_type_get(decl);
279 329
280 if (dt != EOLIAN_OBJECT_VARIABLE) 330 char *fn = strdup(eolian_error_name_get(err));
281 continue; 331 for (char *p = strchr(fn, '.'); p; p = strchr(p, '.'))
332 *p = '_';
333 eina_str_tolower(&fn);
282 334
283 const Eolian_Variable *vr = (const Eolian_Variable *)decl; 335 eina_strbuf_append_printf(buf, "EWAPI %s_get(void)\n{\n", fn);
284 if (eolian_variable_is_extern(vr)) 336 free(fn);
285 continue;
286 337
287 if (eolian_variable_type_get(vr) == EOLIAN_VAR_CONSTANT) 338 const char *msg = eolian_error_message_get(err);
288 continue; 339 eina_strbuf_append(buf, " static Eina_Error err = eina_error_msg_static_register(\"");
340 for (const char *p = msg; *p; ++p)
341 switch (*p)
342 {
343 case '\\':
344 case '\'':
345 case '\"':
346 {
347 eina_strbuf_append_char(buf, '\\');
348 eina_strbuf_append_char(buf, *p);
349 continue;
350 }
351 case '\n':
352 {
353 eina_strbuf_append_char(buf, '\\');
354 eina_strbuf_append_char(buf, 'n');
355 continue;
356 }
357 case '\t':
358 {
359 eina_strbuf_append_char(buf, '\\');
360 eina_strbuf_append_char(buf, 't');
361 continue;
362 }
363 default:
364 {
365 if (isprint(*p))
366 eina_strbuf_append_char(buf, *p);
367 else
368 eina_strbuf_append_printf(buf, "\\x%2X", (unsigned int)*p);
369 continue;
370 }
371 }
372 eina_strbuf_append(buf, "\");\n");
373 eina_strbuf_append(buf, " return err;\n}\n\n");
374}
289 375
290 const Eolian_Expression *vv = eolian_variable_value_get(vr); 376static void
291 if (!vv) 377_source_gen_var(Eina_Strbuf *buf, const Eolian_Variable *vr)
292 continue; 378{
379 if (eolian_variable_is_extern(vr))
380 return;
293 381
294 char *fn = strdup(eolian_variable_name_get(vr)); 382 if (eolian_variable_type_get(vr) == EOLIAN_VAR_CONSTANT)
295 for (char *p = strchr(fn, '.'); p; p = strchr(p, '.')) 383 return;
296 *p = '_';
297 eina_str_toupper(&fn);
298 384
299 const Eolian_Type *vt = eolian_variable_base_type_get(vr); 385 const Eolian_Expression *vv = eolian_variable_value_get(vr);
300 Eina_Stringshare *ct = eolian_type_c_type_get(vt, EOLIAN_C_TYPE_DEFAULT); 386 if (!vv)
301 eina_strbuf_append_printf(buf, "EWAPI %s %s = ", ct, fn); 387 return;
302 eina_stringshare_del(ct);
303 free(fn);
304 388
305 Eolian_Value val = eolian_expression_eval_type(vv, vt); 389 char *fn = strdup(eolian_variable_name_get(vr));
306 Eina_Stringshare *lit = eolian_expression_value_to_literal(&val); 390 for (char *p = strchr(fn, '.'); p; p = strchr(p, '.'))
307 eina_strbuf_append(buf, lit); 391 *p = '_';
308 eina_strbuf_append_char(buf, ';'); 392 eina_str_toupper(&fn);
309 Eina_Stringshare *exp = eolian_expression_serialize(vv); 393
310 if (exp && strcmp(lit, exp)) 394 const Eolian_Type *vt = eolian_variable_base_type_get(vr);
311 eina_strbuf_append_printf(buf, " /* %s */", exp); 395 Eina_Stringshare *ct = eolian_type_c_type_get(vt, EOLIAN_C_TYPE_DEFAULT);
312 eina_stringshare_del(lit); 396 eina_strbuf_append_printf(buf, "EWAPI %s %s = ", ct, fn);
313 eina_stringshare_del(exp); 397 eina_stringshare_del(ct);
398 free(fn);
399
400 Eolian_Value val = eolian_expression_eval_type(vv, vt);
401 Eina_Stringshare *lit = eolian_expression_value_to_literal(&val);
402 eina_strbuf_append(buf, lit);
403 eina_strbuf_append_char(buf, ';');
404 Eina_Stringshare *exp = eolian_expression_serialize(vv);
405 if (exp && strcmp(lit, exp))
406 eina_strbuf_append_printf(buf, " /* %s */", exp);
407 eina_stringshare_del(lit);
408 eina_stringshare_del(exp);
409
410 eina_strbuf_append(buf, "\n");
411}
412
413void eo_gen_types_source_gen(Eina_Iterator *itr, Eina_Strbuf *buf)
414{
415 const Eolian_Object *decl;
416 EINA_ITERATOR_FOREACH(itr, decl)
417 {
418 Eolian_Object_Type dt = eolian_object_type_get(decl);
314 419
315 eina_strbuf_append(buf, "\n"); 420 if (dt == EOLIAN_OBJECT_ERROR)
421 _source_gen_error(buf, (const Eolian_Error *)decl);
422 else if (dt == EOLIAN_OBJECT_VARIABLE)
423 _source_gen_var(buf, (const Eolian_Variable *)decl);
316 } 424 }
317 eina_iterator_free(itr); 425 eina_iterator_free(itr);
318} 426}