From 87e1be8ff3431ac81d721d5f647fc85d02e045dc Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Wed, 7 Dec 2011 18:37:44 -0800 Subject: [PATCH] generator: Add new return type to ABI: RLenValue RLenValue is similar to RLenType, though with one less argument. This required adding additional conversion functions for several languages' bindings. Signed-off-by: Alex Nelson --- generator/generator.ml | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/generator/generator.ml b/generator/generator.ml index dd13d6a..bc1ce44 100755 --- a/generator/generator.ml +++ b/generator/generator.ml @@ -51,6 +51,7 @@ and ret = | RNodeList (* Returns hive_node_h* or NULL. *) | RValue (* Returns hive_value_h or 0. *) | RValueList (* Returns hive_value_h* or NULL. *) + | RLenValue (* Returns offset and length of value. *) | RString (* Returns char* or NULL. *) | RStringList (* Returns char** or NULL. *) | RLenType (* See hivex_value_type. *) @@ -888,6 +889,7 @@ and generate_c_prototype ?(extern = false) name style = | RValueList -> pr "hive_value_h *" | RString -> pr "char *" | RStringList -> pr "char **" + | RLenValue -> pr "hive_value_h " | RLenType -> pr "int " | RLenTypeVal -> pr "char *" | RInt32 -> pr "int32_t " @@ -909,6 +911,7 @@ and generate_c_prototype ?(extern = false) name style = ) (snd style); (match fst style with | RLenType | RLenTypeVal -> pr ", hive_type *t, size_t *len" + | RLenValue -> pr ", size_t *len" | _ -> () ); pr ");\n" @@ -1111,6 +1114,10 @@ On error this returns NULL and sets errno.\n\n" pr "\ Returns 0 on success. On error this returns -1 and sets errno.\n\n" + | RLenValue -> + pr "\ +Returns a value handle. +On error this returns 0 and sets errno.\n\n" | RLenTypeVal -> pr "\ The value is returned as an array of bytes (of length C). @@ -1622,6 +1629,7 @@ and generate_ocaml_prototype ?(is_external = false) name style = | RString -> pr "string" | RStringList -> pr "string array" | RLenType -> pr "hive_type * int" + | RLenValue -> pr "int * value" | RLenTypeVal -> pr "hive_type * string" | RInt32 -> pr "int32" | RInt64 -> pr "int64" @@ -1685,6 +1693,7 @@ static hive_type HiveType_val (value); static value Val_hive_type (hive_type); static value copy_int_array (size_t *); static value copy_type_len (size_t, hive_type); +static value copy_len_value (size_t, hive_value_h); static value copy_type_value (const char *, size_t, hive_type); static void raise_error (const char *) Noreturn; static void raise_closed (const char *) Noreturn; @@ -1707,6 +1716,7 @@ static void raise_closed (const char *) Noreturn; let c_params = match fst style with | RLenType | RLenTypeVal -> c_params @ [["&t"; "&len"]] + | RLenValue -> c_params @ [["&len"]] | _ -> c_params in let c_params = List.concat c_params in @@ -1779,6 +1789,11 @@ static void raise_closed (const char *) Noreturn; pr " size_t len;\n"; pr " hive_type t;\n"; "-1" + | RLenValue -> + pr " errno = 0;"; + pr " hive_value_h r;\n"; + pr " size_t len;\n"; + "0 && errno != 0" | RLenTypeVal -> pr " char *r;\n"; pr " size_t len;\n"; @@ -1859,6 +1874,7 @@ static void raise_closed (const char *) Noreturn; pr " for (int i = 0; r[i] != NULL; ++i) free (r[i]);\n"; pr " free (r);\n" | RLenType -> pr " rv = copy_type_len (len, t);\n" + | RLenValue -> pr " rv = copy_len_value (len, r);\n" | RLenTypeVal -> pr " rv = copy_type_value (r, len, t);\n"; pr " free (r);\n" @@ -1981,6 +1997,20 @@ copy_type_len (size_t len, hive_type t) } static value +copy_len_value (size_t len, hive_value_h r) +{ + CAMLparam0 (); + CAMLlocal2 (v, rv); + + rv = caml_alloc (2, 0); + v = Val_int (len); + Store_field (rv, 0, v); + v = Val_int (r); + Store_field (rv, 1, v); + CAMLreturn (rv); +} + +static value copy_type_value (const char *r, size_t len, hive_type t) { CAMLparam0 (); @@ -2170,6 +2200,7 @@ sub open { | RString | RStringList | RLenType + | RLenValue | RLenTypeVal | RInt32 | RInt64 -> () @@ -2244,6 +2275,7 @@ and generate_perl_prototype name style = | RString -> pr "$string = " | RStringList -> pr "@strings = " | RLenType -> pr "($type, $len) = " + | RLenValue -> pr "($len, $value) = " | RLenTypeVal -> pr "($type, $data) = " | RInt32 -> pr "$int32 = " | RInt64 -> pr "$int64 = " @@ -2467,6 +2499,7 @@ DESTROY (h) | RValueList | RStringList | RLenType + | RLenValue | RLenTypeVal -> pr "void\n" | RInt32 -> pr "SV *\n" | RInt64 -> pr "SV *\n" @@ -2639,6 +2672,22 @@ DESTROY (h) pr " PUSHs (sv_2mortal (newSViv (type)));\n"; pr " PUSHs (sv_2mortal (newSViv (len)));\n"; + | RLenValue -> + pr "PREINIT:\n"; + pr " hive_value_h r;\n"; + pr " size_t len;\n"; + pr " PPCODE:\n"; + pr " errno = 0;\n"; + pr " r = hivex_%s (%s, &len);\n" + name (String.concat ", " c_params); + free_args (); + pr " if (r == 0 && errno)\n"; + pr " croak (\"%%s: \", \"%s\", strerror (errno));\n" + name; + pr " EXTEND (SP, 2);\n"; + pr " PUSHs (sv_2mortal (newSViv (len)));\n"; + pr " PUSHs (sv_2mortal (newSViv (r)));\n"; + | RLenTypeVal -> pr "PREINIT:\n"; pr " char *r;\n"; @@ -2886,6 +2935,15 @@ put_len_type (size_t len, hive_type t) } static PyObject * +put_len_val (size_t len, hive_value_h value) +{ + PyObject *r = PyTuple_New (2); + PyTuple_SetItem (r, 0, PyLong_FromLongLong ((long) len)); + PyTuple_SetItem (r, 1, PyLong_FromLongLong ((long) value)); + return r; +} + +static PyObject * put_val_type (char *val, size_t len, hive_type t) { PyObject *r = PyTuple_New (2); @@ -2929,6 +2987,11 @@ put_val_type (char *val, size_t len, hive_type t) pr " size_t len;\n"; pr " hive_type t;\n"; "-1" + | RLenValue -> + pr " errno = 0;\n"; + pr " int r;\n"; + pr " size_t len;\n"; + "0 && errno != 0" | RLenTypeVal -> pr " char *r;\n"; pr " size_t len;\n"; @@ -2953,6 +3016,7 @@ put_val_type (char *val, size_t len, hive_type t) let c_params = match fst style with | RLenType | RLenTypeVal -> c_params @ ["&t"; "&len"] + | RLenValue -> c_params @ ["&len"] | _ -> c_params in List.iter ( @@ -3101,6 +3165,8 @@ put_val_type (char *val, size_t len, hive_type t) pr " free_strings (r);\n" | RLenType -> pr " py_r = put_len_type (len, t);\n" + | RLenValue -> + pr " py_r = put_len_val (len, r);\n" | RLenTypeVal -> pr " py_r = put_val_type (r, len, t);\n"; pr " free (r);\n" @@ -3351,6 +3417,7 @@ get_values (VALUE valuesv, size_t *nr_values) | RString -> "string" | RStringList -> "list" | RLenType -> "hash" + | RLenValue -> "integer" | RLenTypeVal -> "hash" | RInt32 -> "integer" | RInt64 -> "integer" in @@ -3449,6 +3516,11 @@ get_values (VALUE valuesv, size_t *nr_values) pr " size_t len;\n"; pr " hive_type t;\n"; "-1" + | RLenValue -> + pr " errno = 0;\n"; + pr " hive_value_h r;\n"; + pr " size_t len;\n"; + "0 && errno != 0" | RLenTypeVal -> pr " char *r;\n"; pr " size_t len;\n"; @@ -3473,6 +3545,7 @@ get_values (VALUE valuesv, size_t *nr_values) let c_params = match ret with | RLenType | RLenTypeVal -> c_params @ [["&t"; "&len"]] + | RLenValue -> c_params @ [["&len"]] | _ -> c_params in let c_params = List.concat c_params in @@ -3554,6 +3627,11 @@ get_values (VALUE valuesv, size_t *nr_values) pr " rb_hash_aset (rv, ID2SYM (rb_intern (\"len\")), INT2NUM (len));\n"; pr " rb_hash_aset (rv, ID2SYM (rb_intern (\"type\")), INT2NUM (t));\n"; pr " return rv;\n" + | RLenValue -> + pr " VALUE rv = rb_hash_new ();\n"; + pr " rb_hash_aset (rv, ID2SYM (rb_intern (\"len\")), INT2NUM (len));\n"; + pr " rb_hash_aset (rv, ID2SYM (rb_intern (\"off\")), ULL2NUM (r));\n"; + pr " return rv;\n" | RLenTypeVal -> pr " VALUE rv = rb_hash_new ();\n"; pr " rb_hash_aset (rv, ID2SYM (rb_intern (\"len\")), INT2NUM (len));\n"; -- 1.8.3.1