ext/jsonnet/vm.c in jsonnet-0.3.0 vs ext/jsonnet/vm.c in jsonnet-0.4.0
- old
+ new
@@ -1,6 +1,9 @@
#include <libjsonnet.h>
+#ifdef HAVE_LIBJSONNET_FMT_H
+# include <libjsonnet_fmt.h>
+#endif
#include <ruby/ruby.h>
#include <ruby/intern.h>
#include "ruby_jsonnet.h"
@@ -18,12 +21,14 @@
/*
* Raised on evaluation errors in a Jsonnet VM.
*/
static VALUE eEvaluationError;
+static VALUE eFormatError;
static void raise_eval_error(struct JsonnetVm *vm, char *msg, rb_encoding *enc);
+static void raise_format_error(struct JsonnetVm *vm, char *msg, rb_encoding *enc);
static VALUE str_new_json(struct JsonnetVm *vm, char *json, rb_encoding *enc);
static VALUE fileset_new(struct JsonnetVm *vm, char *buf, rb_encoding *enc);
static void vm_free(void *ptr);
static void vm_mark(void *ptr);
@@ -253,43 +258,175 @@
struct jsonnet_vm_wrap *vm = rubyjsonnet_obj_to_vm(self);
jsonnet_max_trace(vm->vm, NUM2UINT(val));
return Qnil;
}
+static VALUE
+vm_set_fmt_indent(VALUE self, VALUE val)
+{
+ struct jsonnet_vm_wrap *vm = rubyjsonnet_obj_to_vm(self);
+ jsonnet_fmt_indent(vm->vm, NUM2INT(val));
+ return val;
+}
+
+static VALUE
+vm_set_fmt_max_blank_lines(VALUE self, VALUE val)
+{
+ struct jsonnet_vm_wrap *vm = rubyjsonnet_obj_to_vm(self);
+ jsonnet_fmt_max_blank_lines(vm->vm, NUM2INT(val));
+ return val;
+}
+
+static VALUE
+vm_set_fmt_string(VALUE self, VALUE str)
+{
+ const char *ptr;
+ struct jsonnet_vm_wrap *vm = rubyjsonnet_obj_to_vm(self);
+ StringValue(str);
+ if (RSTRING_LEN(str) != 1) {
+ rb_raise(rb_eArgError, "fmt_string must have a length of 1");
+ }
+ ptr = RSTRING_PTR(str);
+ switch (*ptr) {
+ case 'd':
+ case 's':
+ case 'l':
+ jsonnet_fmt_string(vm->vm, *ptr);
+ return str;
+ default:
+ rb_raise(rb_eArgError, "fmt_string only accepts 'd', 's', or 'l'");
+ }
+}
+
+static VALUE
+vm_set_fmt_comment(VALUE self, VALUE str)
+{
+ const char *ptr;
+ struct jsonnet_vm_wrap *vm = rubyjsonnet_obj_to_vm(self);
+ StringValue(str);
+ if (RSTRING_LEN(str) != 1) {
+ rb_raise(rb_eArgError, "fmt_comment must have a length of 1");
+ }
+ ptr = RSTRING_PTR(str);
+ switch (*ptr) {
+ case 'h':
+ case 's':
+ case 'l':
+ jsonnet_fmt_comment(vm->vm, *ptr);
+ return str;
+ default:
+ rb_raise(rb_eArgError, "fmt_comment only accepts 'h', 's', or 'l'");
+ }
+}
+
+static VALUE
+vm_set_fmt_pad_arrays(VALUE self, VALUE val)
+{
+ struct jsonnet_vm_wrap *vm = rubyjsonnet_obj_to_vm(self);
+ jsonnet_fmt_pad_objects(vm->vm, RTEST(val) ? 1 : 0);
+ return val;
+}
+
+static VALUE
+vm_set_fmt_pad_objects(VALUE self, VALUE val)
+{
+ struct jsonnet_vm_wrap *vm = rubyjsonnet_obj_to_vm(self);
+ jsonnet_fmt_pad_objects(vm->vm, RTEST(val) ? 1 : 0);
+ return val;
+}
+
+static VALUE
+vm_set_fmt_pretty_field_names(VALUE self, VALUE val)
+{
+ struct jsonnet_vm_wrap *vm = rubyjsonnet_obj_to_vm(self);
+ jsonnet_fmt_pretty_field_names(vm->vm, RTEST(val) ? 1 : 0);
+ return val;
+}
+
+static VALUE
+vm_set_fmt_sort_imports(VALUE self, VALUE val)
+{
+ struct jsonnet_vm_wrap *vm = rubyjsonnet_obj_to_vm(self);
+ jsonnet_fmt_sort_imports(vm->vm, RTEST(val) ? 1 : 0);
+ return val;
+}
+
+static VALUE
+vm_fmt_file(VALUE self, VALUE fname, VALUE encoding)
+{
+ int error;
+ char *result;
+ rb_encoding *const enc = rb_to_encoding(encoding);
+ struct jsonnet_vm_wrap *vm = rubyjsonnet_obj_to_vm(self);
+
+ FilePathValue(fname);
+ result = jsonnet_fmt_file(vm->vm, StringValueCStr(fname), &error);
+ if (error) {
+ raise_format_error(vm->vm, result, rb_enc_get(fname));
+ }
+ return str_new_json(vm->vm, result, enc);
+}
+
+static VALUE
+vm_fmt_snippet(VALUE self, VALUE snippet, VALUE fname)
+{
+ int error;
+ char *result;
+ struct jsonnet_vm_wrap *vm = rubyjsonnet_obj_to_vm(self);
+
+ rb_encoding *enc = rubyjsonnet_assert_asciicompat(StringValue(snippet));
+ FilePathValue(fname);
+ result = jsonnet_fmt_snippet(vm->vm, StringValueCStr(fname), StringValueCStr(snippet), &error);
+ if (error) {
+ raise_format_error(vm->vm, result, rb_enc_get(fname));
+ }
+ return str_new_json(vm->vm, result, enc);
+}
+
void
rubyjsonnet_init_vm(VALUE mJsonnet)
{
cVM = rb_define_class_under(mJsonnet, "VM", rb_cData);
rb_define_singleton_method(cVM, "new", vm_s_new, -1);
rb_define_private_method(cVM, "eval_file", vm_evaluate_file, 3);
rb_define_private_method(cVM, "eval_snippet", vm_evaluate, 3);
+ rb_define_private_method(cVM, "fmt_file", vm_fmt_file, 2);
+ rb_define_private_method(cVM, "fmt_snippet", vm_fmt_snippet, 2);
rb_define_method(cVM, "ext_var", vm_ext_var, 2);
rb_define_method(cVM, "ext_code", vm_ext_code, 2);
rb_define_method(cVM, "tla_var", vm_tla_var, 2);
rb_define_method(cVM, "tla_code", vm_tla_code, 2);
rb_define_method(cVM, "jpath_add", vm_jpath_add_m, -1);
rb_define_method(cVM, "max_stack=", vm_set_max_stack, 1);
rb_define_method(cVM, "gc_min_objects=", vm_set_gc_min_objects, 1);
rb_define_method(cVM, "gc_growth_trigger=", vm_set_gc_growth_trigger, 1);
rb_define_method(cVM, "string_output=", vm_set_string_output, 1);
rb_define_method(cVM, "max_trace=", vm_set_max_trace, 1);
+ rb_define_method(cVM, "fmt_indent=", vm_set_fmt_indent, 1);
+ rb_define_method(cVM, "fmt_max_blank_lines=", vm_set_fmt_max_blank_lines, 1);
+ rb_define_method(cVM, "fmt_string=", vm_set_fmt_string, 1);
+ rb_define_method(cVM, "fmt_comment=", vm_set_fmt_comment, 1);
+ rb_define_method(cVM, "fmt_pad_arrays=", vm_set_fmt_pad_arrays, 1);
+ rb_define_method(cVM, "fmt_pad_objects=", vm_set_fmt_pad_objects, 1);
+ rb_define_method(cVM, "fmt_pretty_field_names=", vm_set_fmt_pretty_field_names, 1);
+ rb_define_method(cVM, "fmt_sort_imports=", vm_set_fmt_sort_imports, 1);
+ rb_define_const(mJsonnet, "STRING_STYLE_DOUBLE", rb_str_new_cstr("d"));
+ rb_define_const(mJsonnet, "STRING_STYLE_SINGLE", rb_str_new_cstr("s"));
+ rb_define_const(mJsonnet, "STRING_STYLE_LEAVE", rb_str_new_cstr("l"));
+ rb_define_const(mJsonnet, "COMMENT_STYLE_HASH", rb_str_new_cstr("h"));
+ rb_define_const(mJsonnet, "COMMENT_STYLE_SLASH", rb_str_new_cstr("s"));
+ rb_define_const(mJsonnet, "COMMENT_STYLE_LEAVE", rb_str_new_cstr("l"));
+
rubyjsonnet_init_callbacks(cVM);
eEvaluationError = rb_define_class_under(mJsonnet, "EvaluationError", rb_eRuntimeError);
+ eFormatError = rb_define_class_under(mJsonnet, "FormatError", rb_eRuntimeError);
}
-/**
- * raises an EvaluationError whose message is \c msg.
- * @param[in] vm a JsonnetVM
- * @param[in] msg must be a NUL-terminated string returned by \c vm.
- * @return never returns
- * @throw EvaluationError
- * @sa rescue_callback
- */
static void
-raise_eval_error(struct JsonnetVm *vm, char *msg, rb_encoding *enc)
+raise_error(VALUE exception_class, struct JsonnetVm *vm, char *msg, rb_encoding *enc)
{
VALUE ex;
const int state = rubyjsonnet_jump_tag(msg);
if (state) {
/*
@@ -298,12 +435,32 @@
*/
jsonnet_realloc(vm, msg, 0);
rb_jump_tag(state);
}
- ex = rb_exc_new3(eEvaluationError, rb_enc_str_new_cstr(msg, enc));
+ ex = rb_exc_new3(exception_class, rb_enc_str_new_cstr(msg, enc));
jsonnet_realloc(vm, msg, 0);
rb_exc_raise(ex);
+}
+
+/**
+ * raises an EvaluationError whose message is \c msg.
+ * @param[in] vm a JsonnetVM
+ * @param[in] msg must be a NUL-terminated string returned by \c vm.
+ * @return never returns
+ * @throw EvaluationError
+ * @sa rescue_callback
+ */
+static void
+raise_eval_error(struct JsonnetVm *vm, char *msg, rb_encoding *enc)
+{
+ raise_error(eEvaluationError, vm, msg, enc);
+}
+
+static void
+raise_format_error(struct JsonnetVm *vm, char *msg, rb_encoding *enc)
+{
+ raise_error(eFormatError, vm, msg, enc);
}
/**
* Returns a String whose contents is equal to \c json.
* It automatically frees \c json just after constructing the return value.