This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project gfxprim.git.
The branch, generate has been updated via 36c8c982d2d3a3f672a293664a04e7a0491a6a97 (commit) from a26eff704d1d896d04efccb273cab42593b9efde (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- http://repo.or.cz/w/gfxprim.git/commit/36c8c982d2d3a3f672a293664a04e7a0491a6...
commit 36c8c982d2d3a3f672a293664a04e7a0491a6a97 Author: Cyril Hrubis metan@ucw.cz Date: Thu Sep 29 01:14:00 2011 +0200
grinder: far better parameter checks and error messages.
diff --git a/demos/grinder/grinder.c b/demos/grinder/grinder.c index 73c2d4b..a4ef8c5 100644 --- a/demos/grinder/grinder.c +++ b/demos/grinder/grinder.c @@ -29,6 +29,33 @@
#include "params.h"
+static int param_err(const struct param *self, const char *val, void *priv) +{ + fprintf(stderr, "ERROR: %s: invalid %s parameter %s = '%s'", + (char *)priv, param_type_name(self->type), self->name, val); + + if (self->type == PARAM_ENUM) { + unsigned int i; + + fprintf(stderr, " is not in ["); + + for (i = 0; self->enum_table[i] != NULL; i++) + if (self->enum_table[i+1] == NULL) + fprintf(stderr, "'%s']", self->enum_table[i]); + else + fprintf(stderr, "'%s' | ", self->enum_table[i]); + } + + fprintf(stderr, "n"); + + return 1; +} + +static void print_error(const char *error) +{ + fprintf(stderr, "ERROR: %sn", error); +} + /* resize filter */
static const char *resize_algs[] = { @@ -37,10 +64,21 @@ static const char *resize_algs[] = { NULL };
+static int resize_check_ratio(const struct param *self __attribute__((unused)), + void *val) +{ + float f = *((float*)val); + + if (f <= 0) + return -1; + + return 0; +} + static struct param resize_params[] = { {"alg", PARAM_ENUM, resize_algs, NULL}, - {"ratio", PARAM_FLOAT, NULL, NULL}, - {NULL, 0, NULL, NULL} + {"ratio", PARAM_FLOAT, NULL, resize_check_ratio}, + {NULL, 0, NULL, NULL} };
static GP_RetCode resize(GP_Context **c, const char *params) @@ -48,10 +86,14 @@ static GP_RetCode resize(GP_Context **c, const char *params) int alg = 1; float ratio = -1;
- param_parse(params, resize_params, &alg, &ratio); + if (param_parse(params, resize_params, "resize", param_err, + &alg, &ratio)) + return GP_EINVAL;
- if (ratio == -1) + if (ratio == -1) { + print_error("resize: ratio parameter is missing"); return GP_EINVAL; + }
GP_Size w = ratio * (*c)->w; GP_Size h = ratio * (*c)->h; @@ -107,10 +149,14 @@ static GP_RetCode scale(GP_Context **c, const char *params) int w = -1; int h = -1;
- param_parse(params, scale_params, &alg, &w, &h); + if (param_parse(params, scale_params, "scale", param_err, + &alg, &w, &h)) + return GP_EINVAL;
- if (w == -1 || h == -1) + if (w == -1 || h == -1) { + print_error("scale: w and/or h missing"); return GP_EINVAL; + }
GP_Context *res = NULL;
@@ -149,10 +195,13 @@ static GP_RetCode rotate(GP_Context **c, const char *params) { int rot = -1;
- param_parse(params, rotate_params, &rot); + if (param_parse(params, rotate_params, "rotate", param_err, &rot)) + return GP_EINVAL;
- if (rot == -1) + if (rot == -1) { + print_error("rotate: rot parameter is missing"); return GP_EINVAL; + }
switch (rot) { case 0: @@ -160,6 +209,7 @@ static GP_RetCode rotate(GP_Context **c, const char *params) break; case 1: GP_MirrorV(*c); + GP_MirrorH(*c); break; case 2: GP_RotateCCW(*c); @@ -180,7 +230,13 @@ static GP_RetCode bright(GP_Context **c, const char *params) { int bright = 0;
- param_parse(params, bright_params, &bright); + if (param_parse(params, bright_params, "bright", param_err, &bright)) + return GP_EINVAL; + + if (bright == 0) { + print_error("bright: bright parameter is zero or missing"); + return GP_EINVAL; + }
GP_Context *res = GP_FilterBrightness(*c, bright);
diff --git a/demos/grinder/params.c b/demos/grinder/params.c index 405c8bd..1c02b7d 100644 --- a/demos/grinder/params.c +++ b/demos/grinder/params.c @@ -25,9 +25,26 @@ #include <ctype.h> #include <stdlib.h> #include <stdarg.h> +#include <errno.h>
#include "params.h"
+static const char *param_type_names[] = { + "bool", + "integer", + "float", + "string", + "enum", +}; + +const char *param_type_name(enum param_type type) +{ + if (type > PARAM_ENUM) + return NULL; + + return param_type_names[type]; +} + static unsigned int count_params(const char *params) { unsigned int ret = 1, i; @@ -97,16 +114,38 @@ int param_pos(char *names[], const char *name, unsigned int start, unsigned int
int set_int(int *res, char *val) { - //TODO: error checks - *res = atoi(val); + long l; + char *end; + + errno = 0; + l = strtol(val, &end, 0); + + if (*end != '0') + return 1; + + if (errno != 0) + return 1; + + *res = l;
return 0; }
int set_float(float *res, char *val) { - //TODO: error checks - *res = atof(val); + char *end; + float f; + + errno = 0; + f = strtof(val, &end); + + if (*end != '0') + return 1; + + if (errno != 0) + return 1; + + *res = f;
return 0; } @@ -124,11 +163,23 @@ int set_enum(int *res, char *val, const char *enums[]) return 1; }
-int param_parse(const char *params, const struct param *param_desc, ...) +#define CALL_ERR_CALLBACK(error, p, value, private) do { + if (error != NULL) + error(p, value, private); +} while (0) + +int param_parse(const char *params, const struct param *param_desc, void *priv, + int (*err)(const struct param *self, const char *val, void *priv), ...) { - char *par = strdup(params); + char *par; unsigned int n, i; va_list va; + int ret; + + if (params == NULL || *params == '0') + return 0; + + par = strdup(params);
if (par == NULL) { fprintf(stderr, "Malloc failed :(n"); @@ -143,43 +194,63 @@ int param_parse(const char *params, const struct param *param_desc, ...) split_params(par, names); split_values(names, values, n); - va_start(va, param_desc); + va_start(va, err);
for (i = 0; param_desc[i].name != NULL; i++) { void *arg = va_arg(va, void*); - int pos = 0, ret; + int pos = 0;
while ((pos = param_pos(names, param_desc[i].name, pos, n)) >= 0) { + + if (values[pos] == NULL || *values[pos] == '0') { + CALL_ERR_CALLBACK(err, ¶m_desc[i], "", priv); + goto err; + } + switch (param_desc[i].type) { case PARAM_BOOL: break; case PARAM_INT: - if ((ret = set_int(arg, values[pos]))) - return ret; + if ((ret = set_int(arg, values[pos]))) { + CALL_ERR_CALLBACK(err, ¶m_desc[i], + values[pos], priv); + goto err; + } break; case PARAM_FLOAT: - if ((ret = set_float(arg, values[pos]))) - return ret; + if ((ret = set_float(arg, values[pos]))) { + CALL_ERR_CALLBACK(err, ¶m_desc[i], + values[pos], priv); + goto err; + } break; case PARAM_STR: break; case PARAM_ENUM: if ((ret = set_enum(arg, values[pos], - param_desc[i].enum_table))) - return ret; + param_desc[i].enum_table))) { + CALL_ERR_CALLBACK(err, ¶m_desc[i], + values[pos], priv); + goto err; + } break; }
if (param_desc[i].check != NULL) - param_desc[i].check(¶m_desc[i], arg); + if ((ret = param_desc[i].check(¶m_desc[i], arg))) { + CALL_ERR_CALLBACK(err, ¶m_desc[i], + values[pos], priv); + goto err; + } pos++; } }
+ ret = 0; +err: va_end(va); free(par); - - return 0; + return ret; } diff --git a/demos/grinder/params.h b/demos/grinder/params.h index f397bb7..3efea7d 100644 --- a/demos/grinder/params.h +++ b/demos/grinder/params.h @@ -39,6 +39,9 @@ struct param { int (*check)(const struct param *self, void *val); };
-int param_parse(const char *params, const struct param *param_desc, ...); +const char *param_type_name(enum param_type type); + +int param_parse(const char *params, const struct param *param_desc, void *priv, + int (*err)(const struct param *self, const char *val, void *priv), ...);
#endif /* PARAMS_H */
-----------------------------------------------------------------------
Summary of changes: demos/grinder/grinder.c | 74 +++++++++++++++++++++++++++++---- demos/grinder/params.c | 105 +++++++++++++++++++++++++++++++++++++++-------- demos/grinder/params.h | 5 ++- 3 files changed, 157 insertions(+), 27 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos@gmail.com if you want to unsubscribe, or site admin admin@repo.or.cz if you receive no reply.