From 46a87a5d2bac598fed0870f0d3c926087f95d30f Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 14 Feb 2023 05:19:04 -0500 Subject: refactor(api): VALIDATE macros #22187 Problem: - API validation involves too much boilerplate. - API validation errors are not consistently worded. Solution: Introduce some macros. Currently these are clumsy, but they at least help with consistency and avoid some nesting. --- src/nvim/api/private/helpers.c | 30 ++++++++++++++++++ src/nvim/api/private/validate.h | 69 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 src/nvim/api/private/validate.h (limited to 'src/nvim/api/private') diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 519f2cc5bf..6beb3d8683 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -827,6 +827,36 @@ int object_to_hl_id(Object obj, const char *what, Error *err) } } +char *api_typename(ObjectType t) +{ + switch (t) { + case kObjectTypeNil: + return "nil"; + case kObjectTypeBoolean: + return "Boolean"; + case kObjectTypeInteger: + return "Integer"; + case kObjectTypeFloat: + return "Float"; + case kObjectTypeString: + return "String"; + case kObjectTypeArray: + return "Array"; + case kObjectTypeDictionary: + return "Dict"; + case kObjectTypeLuaRef: + return "Function"; + case kObjectTypeBuffer: + return "Buffer"; + case kObjectTypeWindow: + return "Window"; + case kObjectTypeTabpage: + return "Tabpage"; + default: + abort(); + } +} + HlMessage parse_hl_msg(Array chunks, Error *err) { HlMessage hl_msg = KV_INITIAL_VALUE; diff --git a/src/nvim/api/private/validate.h b/src/nvim/api/private/validate.h new file mode 100644 index 0000000000..8448b416be --- /dev/null +++ b/src/nvim/api/private/validate.h @@ -0,0 +1,69 @@ +#ifndef NVIM_API_PRIVATE_VALIDATE_H +#define NVIM_API_PRIVATE_VALIDATE_H + +#include "nvim/api/private/defs.h" +#include "nvim/api/private/helpers.h" + +#define VALIDATE_INT(cond, name, val_, code) \ + do { \ + if (!(cond)) { \ + api_set_error(err, kErrorTypeValidation, "Invalid " name ": %" PRId64, val_); \ + code; \ + } \ + } while (0) + +#define VALIDATE_S(cond, name, val_, code) \ + do { \ + if (!(cond)) { \ + if (strequal(val_, "")) { \ + api_set_error(err, kErrorTypeValidation, "Invalid " name); \ + } else { \ + api_set_error(err, kErrorTypeValidation, "Invalid " name ": '%s'", val_); \ + } \ + code; \ + } \ + } while (0) + +#define VALIDATE_R(cond, name, code) \ + do { \ + if (!(cond)) { \ + api_set_error(err, kErrorTypeValidation, "'" name "' is required"); \ + code; \ + } \ + } while (0) + +#define VALIDATE_EXP(cond, name, expected, actual, code) \ + do { \ + if (!(cond)) { \ + api_set_error(err, kErrorTypeValidation, "Invalid " name ": expected %s, got %s", \ + expected, actual); \ + code; \ + } \ + } while (0) + +#define VALIDATE_T(name, expected_t, actual_t, code) \ + do { \ + if (expected_t != actual_t) { \ + api_set_error(err, kErrorTypeValidation, "Invalid %s: expected %s, got %s", \ + name, api_typename(expected_t), api_typename(actual_t)); \ + code; \ + } \ + } while (0) + +#define VALIDATE(cond, msg_, code) \ + do { \ + if (!(cond)) { \ + api_set_error(err, kErrorTypeValidation, "%s", msg_); \ + code; \ + } \ + } while (0) + +#define VALIDATE_FMT(cond, fmt_, msg_, code) \ + do { \ + if (!(cond)) { \ + api_set_error(err, kErrorTypeValidation, fmt_, msg_); \ + code; \ + } \ + } while (0) + +#endif // NVIM_API_PRIVATE_VALIDATE_H -- cgit