def json_value_generator(c_file, level, src, dst, ptx, typ): """ Description: json value generateor Interface: None History: 2019-06-17 """ if helpers.valid_basic_map_name(typ): c_file.write('%sstat = gen_%s(%s, %s, %s, err);\n' \ % (' ' * (level), helpers.make_basic_map_name(typ), dst, src, ptx)) c_file.write("%sif (yajl_gen_status_ok != stat)\n" % (' ' * (level))) c_file.write("%sGEN_SET_ERROR_AND_RETURN(stat, err);\n" % (' ' * (level + 1))) elif typ == 'string': c_file.write('%sstat = yajl_gen_string((yajl_gen)%s, \ (const unsigned char *)(%s), strlen(%s));\n' % (' ' * (level), dst, src, src)) c_file.write("%sif (yajl_gen_status_ok != stat)\n" % (' ' * (level))) c_file.write("%sGEN_SET_ERROR_AND_RETURN(stat, err);\n" % (' ' * (level + 1))) elif helpers.judge_data_type(typ): if typ == 'double': c_file.write('%sstat = yajl_gen_double((yajl_gen)%s, %s);\n' \ % (' ' * (level), dst, src)) elif typ.startswith("uint") or typ == 'GID' or typ == 'UID': c_file.write('%sstat = map_uint(%s, %s);\n' % (' ' * (level), dst, src)) else: c_file.write('%sstat = map_int(%s, %s);\n' % (' ' * (level), dst, src)) c_file.write("%sif (yajl_gen_status_ok != stat)\n" % (' ' * (level))) c_file.write("%sGEN_SET_ERROR_AND_RETURN(stat, err);\n" \ % (' ' * (level + 1))) elif typ == 'boolean': c_file.write('%sstat = yajl_gen_bool((yajl_gen)%s, (int)(%s));\n' \ % (' ' * (level), dst, src)) c_file.write("%sif (yajl_gen_status_ok != stat)\n" % (' ' * (level))) c_file.write("%sGEN_SET_ERROR_AND_RETURN(stat, err);\n" % (' ' * (level + 1)))
def parse_obj_arr_obj(obj, c_file, prefix, obj_typename): """ Description: generate c language for parse object or array object Interface: None History: 2019-06-17 """ nodes = obj.children if obj.typ == 'object' else obj.subtypobj required_to_check = [] for i in nodes or []: if obj.required and i.origname in obj.required and \ not helpers.judge_data_type(i.typ) and i.typ != 'boolean': required_to_check.append(i) parse_obj_type(i, c_file, prefix, obj_typename) for i in required_to_check: c_file.write(' if (ret->%s == NULL) {\n' % i.fixname) c_file.write(' if (asprintf(err, "Required field \'%%s\' not present", ' \ ' "%s") < 0)\n' % i.origname) c_file.write( ' *err = safe_strdup("error allocating memory");\n') c_file.write(" free_%s(ret);\n" % obj_typename) c_file.write(" return NULL;\n") c_file.write(' }\n') if obj.typ == 'object' and obj.children is not None: # O(n^2) complexity, but the objects should not really be big... condition = " &&\n ".join( \ ['strcmp(tree->u.object.keys[i], "%s")' % i.origname for i in obj.children]) c_file.write(""" if (tree->type == yajl_t_object && (ctx->options & OPT_PARSE_STRICT)) { size_t i; for (i = 0; i < tree->u.object.len; i++) if (%s) { if (ctx->stderr > 0) (void)fprintf(ctx->stderr, "WARNING: unknown key found: %%s\\n", tree->u.object.keys[i]); } } """ % condition)
def get_obj_arr_obj(obj, c_file, prefix): """ Description: c language generate object or array object Interface: None History: 2019-06-17 """ if obj.typ == 'string': c_file.write(' if ((ctx->options & OPT_GEN_KAY_VALUE) ||' \ ' (ptr != NULL && ptr->%s != NULL)) {\n' % obj.fixname) c_file.write(' char *str = "";\n') c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" if (ptr != NULL && ptr->%s != NULL) {\n" % obj.fixname) c_file.write(" str = ptr->%s;\n" % obj.fixname) c_file.write(" }\n") json_value_generator(c_file, 2, "str", 'g', 'ctx', obj.typ) c_file.write(" }\n") elif helpers.judge_data_type(obj.typ): c_file.write(' if ((ctx->options & OPT_GEN_KAY_VALUE) ||' \ ' (ptr != NULL && ptr->%s)) {\n' % obj.fixname) if obj.typ == 'double': numtyp = 'double' elif obj.typ.startswith( "uint") or obj.typ == 'GID' or obj.typ == 'UID': numtyp = 'long long unsigned int' else: numtyp = 'long long int' c_file.write(' %s num = 0;\n' % numtyp) c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" if (ptr != NULL && ptr->%s) {\n" % obj.fixname) c_file.write(" num = (%s)ptr->%s;\n" % (numtyp, obj.fixname)) c_file.write(" }\n") json_value_generator(c_file, 2, "num", 'g', 'ctx', obj.typ) c_file.write(" }\n") elif helpers.judge_data_pointer_type(obj.typ): c_file.write(' if ((ptr != NULL && ptr->%s != NULL)) {\n' % obj.fixname) numtyp = helpers.obtain_data_pointer_type(obj.typ) if numtyp == "": return c_file.write(' %s num = 0;\n' % helpers.get_map_c_types(numtyp)) c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" if (ptr != NULL && ptr->%s != NULL) {\n" % obj.fixname) c_file.write(" num = (%s)*(ptr->%s);\n" \ % (helpers.get_map_c_types(numtyp), obj.fixname)) c_file.write(" }\n") json_value_generator(c_file, 2, "num", 'g', 'ctx', numtyp) c_file.write(" }\n") elif obj.typ == 'boolean': c_file.write(' if ((ctx->options & OPT_GEN_KAY_VALUE) ||' \ ' (ptr != NULL && ptr->%s)) {\n' % obj.fixname) c_file.write(' bool b = false;\n') c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" if (ptr != NULL && ptr->%s) {\n" % obj.fixname) c_file.write(" b = ptr->%s;\n" % obj.fixname) c_file.write(" }\n") json_value_generator(c_file, 2, "b", 'g', 'ctx', obj.typ) c_file.write(" }\n") elif obj.typ == 'object' or obj.typ == 'mapStringObject': if obj.subtypname: typename = obj.subtypname else: typename = helpers.get_prefixe_name(obj.name, prefix) c_file.write(' if ((ctx->options & OPT_GEN_KAY_VALUE) ||' \ ' (ptr != NULL && ptr->%s != NULL)) {\n' % obj.fixname) c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(' stat = gen_%s(g, ptr != NULL ? ptr->%s : NULL, ctx, err);\n' \ % (typename, obj.fixname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" }\n") elif obj.typ == 'array' and (obj.subtypobj or obj.subtyp == 'object'): if obj.subtypname: typename = obj.subtypname else: typename = helpers.get_name_substr(obj.name, prefix) c_file.write(' if ((ctx->options & OPT_GEN_KAY_VALUE) || ' \ '(ptr != NULL && ptr->%s != NULL)) {\n' % obj.fixname) c_file.write(' size_t len = 0, i;\n') c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" if (ptr != NULL && ptr->%s != NULL) {\n" % obj.fixname) c_file.write(" len = ptr->%s_len;\n" % obj.fixname) c_file.write(" }\n") c_file.write( " if (!len && !(ctx->options & OPT_GEN_SIMPLIFY))\n") c_file.write(' yajl_gen_config(g, yajl_gen_beautify, 0);\n') c_file.write(' stat = yajl_gen_array_open((yajl_gen)g);\n') c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(' for (i = 0; i < len; i++) {\n') c_file.write(' stat = gen_%s(g, ptr->%s[i], ctx, err);\n' \ % (typename, obj.fixname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(' }\n') c_file.write(' stat = yajl_gen_array_close((yajl_gen)g);\n') c_file.write( " if (!len && !(ctx->options & OPT_GEN_SIMPLIFY))\n") c_file.write(' yajl_gen_config(g, yajl_gen_beautify, 1);\n') c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(' }\n') elif obj.typ == 'array' and obj.subtyp == 'byte': c_file.write(' if ((ctx->options & OPT_GEN_KAY_VALUE) ||' \ ' (ptr != NULL && ptr->%s != NULL && ptr->%s_len)) {\n' \ % (obj.fixname, obj.fixname)) c_file.write(' const char *str = "";\n') c_file.write(' size_t len = 0;\n') c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" if (ptr != NULL && ptr->%s != NULL) {\n" % obj.fixname) c_file.write(" str = (const char *)ptr->%s;\n" % obj.fixname) c_file.write(" len = ptr->%s_len;\n" % obj.fixname) c_file.write(" }\n") c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ (const unsigned char *)str, len);\n') c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" }\n") elif obj.typ == 'array': c_file.write(' if ((ctx->options & OPT_GEN_KAY_VALUE) || ' \ '(ptr != NULL && ptr->%s != NULL)) {\n' % obj.fixname) c_file.write(' size_t len = 0, i;\n') c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" if (ptr != NULL && ptr->%s != NULL) {\n" % obj.fixname) c_file.write(" len = ptr->%s_len;\n" % obj.fixname) c_file.write(" }\n") c_file.write( " if (!len && !(ctx->options & OPT_GEN_SIMPLIFY))\n") c_file.write(' yajl_gen_config(g, yajl_gen_beautify, 0);\n') c_file.write(' stat = yajl_gen_array_open((yajl_gen)g);\n') c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(' for (i = 0; i < len; i++) {\n') json_value_generator(c_file, 3, "ptr->%s[i]" % obj.fixname, 'g', 'ctx', obj.subtyp) c_file.write(' }\n') c_file.write(' stat = yajl_gen_array_close((yajl_gen)g);\n') c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write( " if (!len && !(ctx->options & OPT_GEN_SIMPLIFY))\n") c_file.write(' yajl_gen_config(g, yajl_gen_beautify, 1);\n') c_file.write(' }\n') elif helpers.valid_basic_map_name(obj.typ): c_file.write(' if ((ctx->options & OPT_GEN_KAY_VALUE) || ' \ '(ptr != NULL && ptr->%s != NULL)) {\n' % obj.fixname) c_file.write(' stat = yajl_gen_string((yajl_gen)g, \ (const unsigned char *)("%s"), strlen("%s"));\n' % (obj.origname, obj.origname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(' stat = gen_%s(g, ptr ? ptr->%s : NULL, ctx, err);\n' \ % (helpers.make_basic_map_name(obj.typ), obj.fixname)) c_file.write(" if (yajl_gen_status_ok != stat)\n") c_file.write(" GEN_SET_ERROR_AND_RETURN(stat, err);\n") c_file.write(" }\n")
def parse_obj_arr_obj(obj, c_file, prefix, obj_typename): """ Description: generate c language for parse object or array object Interface: None History: 2019-06-17 """ nodes = obj.children if obj.typ == 'object' else obj.subtypobj required_to_check = [] for i in nodes or []: if obj.required and i.origname in obj.required and \ not helpers.judge_data_type(i.typ) and i.typ != 'boolean': required_to_check.append(i) parse_obj_type(i, c_file, prefix, obj_typename) for i in required_to_check: c_file.write(' if (ret->%s == NULL) {\n' % i.fixname) c_file.write(' if (asprintf(err, "Required field \'%%s\' not present", ' \ ' "%s") < 0)\n' % i.origname) c_file.write(' *err = safe_strdup("error allocating memory");\n') c_file.write(" free_%s(ret);\n" % obj_typename) c_file.write(" return NULL;\n") c_file.write(' }\n') if obj.typ == 'object' and obj.children is not None: # O(n^2) complexity, but the objects should not really be big... condition = " &&\n ".join( \ ['strcmp(tree->u.object.keys[i], "%s")' % i.origname for i in obj.children]) c_file.write(""" if (tree->type == yajl_t_object) { size_t i; size_t j = 0; size_t cnt = tree->u.object.len; yajl_val resi = NULL; if (ctx->options & OPT_PARSE_FULLKEY) { resi = calloc (1, sizeof(*tree)); if (resi == NULL) { free_%s(ret); return NULL; } resi->type = yajl_t_object; resi->u.object.keys = calloc (cnt, sizeof (const char *)); if (resi->u.object.keys == NULL) { free_%s(ret); yajl_tree_free(resi); return NULL; } resi->u.object.values = calloc (cnt, sizeof (yajl_val)); if (resi->u.object.values == NULL) { free_%s(ret); yajl_tree_free(resi); return NULL; } } for (i = 0; i < tree->u.object.len; i++) { if (%s) { if (ctx->options & OPT_PARSE_FULLKEY) { resi->u.object.keys[j] = tree->u.object.keys[i]; tree->u.object.keys[i] = NULL; resi->u.object.values[j] = tree->u.object.values[i]; tree->u.object.values[i] = NULL; resi->u.object.len++; } j++; } } if (ctx->options & OPT_PARSE_STRICT) { if (j > 0 && ctx->stderr > 0) fprintf (ctx->stderr, "WARNING: unknown key found\\n"); } if (ctx->options & OPT_PARSE_FULLKEY) ret->_residual = resi; } """ % (obj_typename, obj_typename, obj_typename, condition))