diff --git a/bindings/go/evmc/evmc.go b/bindings/go/evmc/evmc.go index b61cb6c..d15664f 100644 --- a/bindings/go/evmc/evmc.go +++ b/bindings/go/evmc/evmc.go @@ -15,9 +15,9 @@ package evmc #include #include -static inline int set_option(struct evmc_instance* instance, char* name, char* value) +static inline enum evmc_set_option_result set_option(struct evmc_instance* instance, char* name, char* value) { - int ret = evmc_set_option(instance, name, value); + enum evmc_set_option_result ret = evmc_set_option(instance, name, value); free(name); free(value); return ret; @@ -188,8 +188,12 @@ func (instance *Instance) Version() string { func (instance *Instance) SetOption(name string, value string) (err error) { r := C.set_option(instance.handle, C.CString(name), C.CString(value)) - if r != 1 { + switch r { + case C.EVMC_SET_OPTION_INVALID_NAME: err = fmt.Errorf("evmc: option '%s' not accepted", name) + case C.EVMC_SET_OPTION_INVALID_VALUE: + err = fmt.Errorf("evmc: option '%s' has invalid value", name) + case C.EVMC_SET_OPTION_SUCCESS: } return err } diff --git a/docs/EVMC.md b/docs/EVMC.md index 208ae6b..cd39011 100644 --- a/docs/EVMC.md +++ b/docs/EVMC.md @@ -16,7 +16,7 @@ to access Ethereum environment and state. – a collection of utility functions for easier integration with EVMC. - [EVM Instructions](@ref instructions) – the library with collection of metrics for EVM1 instruction set. -- [EMVC VM Tester](@ref vmtester) +- [EVMC VM Tester](@ref vmtester) – the EVMC-compatibility testing tool for VM implementations. diff --git a/examples/example_vm.c b/examples/example_vm.c index 39fd568..362e396 100644 --- a/examples/example_vm.c +++ b/examples/example_vm.c @@ -31,19 +31,21 @@ static void destroy(struct evmc_instance* evm) /// Example options. /// /// VMs are allowed to omit this function implementation. -static int set_option(struct evmc_instance* instance, char const* name, char const* value) +static enum evmc_set_option_result set_option(struct evmc_instance* instance, + char const* name, + char const* value) { struct example_vm* vm = (struct example_vm*)instance; if (strcmp(name, "verbose") == 0) { long int v = strtol(value, NULL, 0); if (v > INT_MAX || v < INT_MIN) - return 0; + return EVMC_SET_OPTION_INVALID_VALUE; vm->verbose = (int)v; - return 1; + return EVMC_SET_OPTION_SUCCESS; } - return 0; + return EVMC_SET_OPTION_INVALID_NAME; } static void release_result(struct evmc_result const* result) diff --git a/include/evmc/evmc.h b/include/evmc/evmc.h index 21e5e1e..50aa683 100644 --- a/include/evmc/evmc.h +++ b/include/evmc/evmc.h @@ -654,6 +654,15 @@ struct evmc_instance; */ typedef void (*evmc_destroy_fn)(struct evmc_instance* evm); +/** + * Possible outcomes of evmc_set_option. + */ +enum evmc_set_option_result +{ + EVMC_SET_OPTION_SUCCESS = 0, + EVMC_SET_OPTION_INVALID_NAME = 1, + EVMC_SET_OPTION_INVALID_VALUE = 2 +}; /** * Configures the EVM instance. @@ -666,9 +675,11 @@ typedef void (*evmc_destroy_fn)(struct evmc_instance* evm); * @param evm The EVM instance to be configured. * @param name The option name. NULL-terminated string. Cannot be NULL. * @param value The new option value. NULL-terminated string. Cannot be NULL. - * @return 1 if the option set successfully, 0 otherwise. + * @return The outcome of the operation. */ -typedef int (*evmc_set_option_fn)(struct evmc_instance* evm, char const* name, char const* value); +typedef enum evmc_set_option_result (*evmc_set_option_fn)(struct evmc_instance* evm, + char const* name, + char const* value); /** diff --git a/include/evmc/helpers.h b/include/evmc/helpers.h index 55fa0dc..a9ecd5f 100644 --- a/include/evmc/helpers.h +++ b/include/evmc/helpers.h @@ -56,13 +56,13 @@ static inline void evmc_destroy(struct evmc_instance* instance) * * @see evmc_set_option_fn */ -static inline int evmc_set_option(struct evmc_instance* instance, - char const* name, - char const* value) +static inline enum evmc_set_option_result evmc_set_option(struct evmc_instance* instance, + char const* name, + char const* value) { if (instance->set_option) return instance->set_option(instance, name, value); - return 0; + return EVMC_SET_OPTION_INVALID_NAME; } /** diff --git a/test/vmtester/tests.cpp b/test/vmtester/tests.cpp index 5d6b753..68c9805 100644 --- a/test/vmtester/tests.cpp +++ b/test/vmtester/tests.cpp @@ -64,10 +64,10 @@ TEST_F(evmc_vm_test, set_option_unknown) { if (vm->set_option) { - int r = vm->set_option(vm, "unknown_option_csk9twq", "v"); - EXPECT_EQ(r, 0); + enum evmc_set_option_result r = vm->set_option(vm, "unknown_option_csk9twq", "v"); + EXPECT_EQ(r, EVMC_SET_OPTION_INVALID_NAME); r = vm->set_option(vm, "unknown_option_csk9twq", "x"); - EXPECT_EQ(r, 0); + EXPECT_EQ(r, EVMC_SET_OPTION_INVALID_NAME); } } @@ -75,8 +75,8 @@ TEST_F(evmc_vm_test, set_option_empty_value) { if (vm->set_option) { - int r = vm->set_option(vm, "unknown_option_csk9twq", nullptr); - EXPECT_EQ(r, 0); + enum evmc_set_option_result r = vm->set_option(vm, "unknown_option_csk9twq", nullptr); + EXPECT_EQ(r, EVMC_SET_OPTION_INVALID_NAME); } }