mrb_value mrb_yaml_dump(mrb_state *mrb, mrb_value self) { yaml_emitter_t emitter; yaml_document_t document; mrb_value root; yaml_write_data_t write_data; /* Extract arguments */ mrb_get_args(mrb, "o", &root); /* Build the document */ yaml_document_initialize(&document, NULL, NULL, NULL, 0, 0); value_to_node(mrb, &document, root); /* Initialize the emitter */ yaml_emitter_initialize(&emitter); write_data.mrb = mrb; write_data.str = mrb_str_new(mrb, NULL, 0); yaml_emitter_set_output(&emitter, &yaml_write_handler, &write_data); /* Dump the document */ yaml_emitter_open(&emitter); yaml_emitter_dump(&emitter, &document); yaml_emitter_close(&emitter); /* Clean up */ yaml_emitter_delete(&emitter); yaml_document_delete(&document); return write_data.str; }
/* * COMMAND: <gda_report_expr> * * Creates a text node containing the evaluation of the textual contents of the node * * uses node's contents: yes * requested attributes: none */ static gboolean command_gda_report_eval_expr (GdaReportEngine *engine, xmlNodePtr node, GSList **created_nodes, RunContext *context, GError **error) { GValue *value; xmlNodePtr child; value = evaluate_expression (engine, context, (const gchar *) xmlNodeGetContent (node), error); if (!value) return FALSE; child = value_to_node (engine, context, value, NULL); *created_nodes = g_slist_prepend (NULL, child); return TRUE; }
/* * COMMAND: <gda_report_param_value> * * Creates a new text node containing the value of the parameter named from "param_name" * * uses node's contents: no * requested attributes: param_name * optional attributes: converter => use "richtext::docbook" */ static gboolean command_gda_report_param_value (GdaReportEngine *engine, xmlNodePtr node, GSList **created_nodes, RunContext *context, GError **error) { xmlChar *prop; prop = xmlGetProp (node, BAD_CAST "param_name"); if (prop) { GdaHolder *param; param = run_context_find_param (engine, context, prop); if (!param) { g_set_error (error, 0, 0, _("Unknown parameter '%s'"), prop); return FALSE; } else { /* Add a text node */ const GValue *value; xmlNodePtr child; GdaSet *options = NULL; xmlChar *cprop; cprop = xmlGetProp (node, BAD_CAST "converter"); if (cprop) { options = gda_set_new_inline (1, "converter", G_TYPE_STRING, (gchar*) cprop); xmlFree (cprop); } value = gda_holder_get_value (param); child = value_to_node (engine, context, value, options); if (options) g_object_unref (options); *created_nodes = g_slist_prepend (NULL, child); } xmlFree (prop); return TRUE; } else { g_set_error (error, 0, 0, "%s", _("Parameter name not specified")); return FALSE; } }
int value_to_node(mrb_state *mrb, yaml_document_t *document, mrb_value value) { int node; switch (mrb_type(value)) { case MRB_TT_ARRAY: { mrb_int len = mrb_ary_len(mrb, value); mrb_int i; int ai = mrb_gc_arena_save(mrb); node = yaml_document_add_sequence(document, NULL, YAML_ANY_SEQUENCE_STYLE); for (i = 0; i < len; i++) { mrb_value child = mrb_ary_ref(mrb, value, i); int child_node = value_to_node(mrb, document, child); /* Add the child to the sequence */ yaml_document_append_sequence_item(document, node, child_node); mrb_gc_arena_restore(mrb, ai); } break; } case MRB_TT_HASH: { /* Iterating a list of keys is slow, but it only * requires use of the interface defined in `hash.h`. */ mrb_value keys = mrb_hash_keys(mrb, value); mrb_int len = mrb_ary_len(mrb, keys); mrb_int i; int ai = mrb_gc_arena_save(mrb); node = yaml_document_add_mapping(document, NULL, YAML_ANY_MAPPING_STYLE); for (i = 0; i < len; i++) { mrb_value key = mrb_ary_ref(mrb, keys, i); mrb_value child = mrb_hash_get(mrb, value, key); int key_node = value_to_node(mrb, document, key); int child_node = value_to_node(mrb, document, child); /* Add the key/value pair to the mapping */ yaml_document_append_mapping_pair(document, node, key_node, child_node); mrb_gc_arena_restore(mrb, ai); } break; } default: { if (mrb_nil_p(value)) { /* http://yaml.org/type/null.html Canonical form */ value = mrb_str_new_lit(mrb, "~"); } else { /* Equivalent to `obj = obj#to_s` */ value = mrb_obj_as_string(mrb, value); } /* Fallthrough */ } case MRB_TT_STRING: { yaml_scalar_style_t style = YAML_ANY_SCALAR_STYLE; if (RSTRING_LEN(value) == 0) { /* If the String is empty, it may be reloaded as a nil instead of an * empty string, to avoid that place a quoted string instead */ style = YAML_SINGLE_QUOTED_SCALAR_STYLE; } yaml_char_t *value_chars = (unsigned char *) RSTRING_PTR(value); node = yaml_document_add_scalar(document, NULL, value_chars, RSTRING_LEN(value), style); break; } } return node; }