This patch fixes the compiler warnings caused by the invalid use of const.
It also provides a certain level of encapsulation when parsing the thread_event data. Some of the macros could be merged simplifying the code a bit more but I am not sure if it would make the code too obfuscated.
Introduced a function table to parse the event data. This also removes some of the unnecessary string comparisons and hopes to simplify maintenance via encapsulation (functions should tipically be open for extension but not modification) --- src/rt-app_parse_config.c | 366 ++++++++++++++++++++++++---------------------- 1 file changed, 194 insertions(+), 172 deletions(-)
diff --git a/src/rt-app_parse_config.c b/src/rt-app_parse_config.c index 96e5517..2dcb4a3 100644 --- a/src/rt-app_parse_config.c +++ b/src/rt-app_parse_config.c @@ -28,6 +28,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define PIN3 PIN2" " #define JSON_FILE_BUF_SIZE 4096
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) + + /* redefine foreach as in <json/json_object.h> but to be ANSI * compatible */ #define foreach(obj, entry, key, val, idx) \ @@ -306,199 +309,218 @@ static char* create_unique_name(char *tmp, int size, const char* ref, long tag) return tmp; }
-static void -parse_thread_event_data(char *name, struct json_object *obj, - event_data_t *data, rtapp_options_t *opts, long tag) -{ - rtapp_resource_t *rdata, *ddata; - char unique_name[22]; - const char *ref, *tmp; - int i; - - if (!strncmp(name, "run", strlen("run")) || - !strncmp(name, "sleep", strlen("sleep"))) { - - if (!json_object_is_type(obj, json_type_int)) - goto unknown_event; - - data->duration = json_object_get_int(obj); - - if (!strncmp(name, "sleep", strlen("sleep"))) - data->type = rtapp_sleep; - else - data->type = rtapp_run; - - log_info(PIN2 "type %d duration %d", data->type, data->duration); - return; - } - - if (!strncmp(name, "lock", strlen("lock")) || - !strncmp(name, "unlock", strlen("unlock"))) { - - if (!json_object_is_type(obj, json_type_string)) - goto unknown_event; - - ref = json_object_get_string(obj); - i = get_resource_index(ref, rtapp_mutex, opts); - - data->res = i; - - if (!strncmp(name, "lock", strlen("lock"))) - data->type = rtapp_lock; - else - data->type = rtapp_unlock; - - rdata = &(opts->resources[data->res]); - ddata = &(opts->resources[data->dep]); - - log_info(PIN2 "type %d target %s [%d]", data->type, rdata->name, rdata->index); - return; - } - - if (!strncmp(name, "signal", strlen("signal")) || - !strncmp(name, "broad", strlen("broad"))) { - - if (!strncmp(name, "signal", strlen("signal"))) - data->type = rtapp_signal; - else - data->type = rtapp_broadcast; - - if (!json_object_is_type(obj, json_type_string)) - goto unknown_event; - - ref = json_object_get_string(obj); - i = get_resource_index(ref, rtapp_wait, opts); - - data->res = i; - - rdata = &(opts->resources[data->res]); - ddata = &(opts->resources[data->dep]); - - log_info(PIN2 "type %d target %s [%d]", data->type, rdata->name, rdata->index); - return; - } - - if (!strncmp(name, "wait", strlen("wait")) || - !strncmp(name, "sync", strlen("sync"))) { - - if (!strncmp(name, "wait", strlen("wait"))) - data->type = rtapp_wait; - else - data->type = rtapp_sig_and_wait; - - ref = get_string_value_from(obj, "ref", TRUE, "unknown"); - i = get_resource_index(ref, rtapp_wait, opts); - /* - * get_string_value_from allocate the string so with have to free it - * once useless - */ - free(ref); - - data->res = i; - - ref = get_string_value_from(obj, "mutex", TRUE, "unknown"); - i = get_resource_index(ref, rtapp_mutex, opts); - /* - * get_string_value_from allocate the string so with have to free it - * once useless - */ - free(ref); - - data->dep = i; - - rdata = &(opts->resources[data->res]); - ddata = &(opts->resources[data->dep]); - - log_info(PIN2 "type %d target %s [%d] mutex %s [%d]", data->type, rdata->name, rdata->index, ddata->name, ddata->index); - return; - } - - if (!strncmp(name, "timer", strlen("timer"))) { - - tmp = get_string_value_from(obj, "ref", TRUE, "unknown"); - if (!strncmp(tmp, "unique", strlen("unique"))) - ref = create_unique_name(unique_name, sizeof(unique_name), tmp, tag); - else - ref = tmp; - - i = get_resource_index(ref, rtapp_timer, opts); - - /* - * get_string_value_from allocate the string so with have to free it - * once useless - */ - free(tmp); - - data->res = i; - - data->duration = get_int_value_from(obj, "period", TRUE, 0); - - data->type = rtapp_timer; - - rdata = &(opts->resources[data->res]); - ddata = &(opts->resources[data->dep]); - - log_info(PIN2 "type %d target %s [%d] period %d", data->type, rdata->name, rdata->index, data->duration); - return; - } - - if (!strncmp(name, "resume", strlen("resume"))) { - - data->type = rtapp_resume; - - if (!json_object_is_type(obj, json_type_string)) - goto unknown_event; - - ref = json_object_get_string(obj); - - i = get_resource_index(ref, rtapp_wait, opts); - - data->res = i; - - i = get_resource_index(ref, rtapp_mutex, opts); - - data->dep = i; +struct event_handler_data { + struct json_object *obj; + rtapp_options_t *opts; + event_data_t *data; + char *name; + long tag; +}; + +typedef int (*event_handler)(struct event_handler_data *data); + +struct event_handler { + event_handler exec; + const char *name; +}; + +#define handler_name(x, y) x##_handler_##y + +#define run_sleep_handler(__name) \ +static int handler_name(run_sleep, __name)(struct event_handler_data *p) \ +{ \ + if (!json_object_is_type(p->obj, json_type_int)) \ + return -1; \ + \ + p->data->type = rtapp_##__name; \ + p->data->duration = json_object_get_int(p->obj); \ + \ + log_info(PIN2 "type %d duration %d", p->data->type, p->data->duration); \ + \ + return 0; \ +}
- rdata = &(opts->resources[data->res]); - ddata = &(opts->resources[data->dep]); +#define lock_unlock_handler(__name) \ +static int handler_name(lock_unlock, __name)(struct event_handler_data *p) \ +{ \ + rtapp_resource_t *rdata, *ddata; \ + const char *cref; \ + \ + if (!json_object_is_type(p->obj, json_type_string)) \ + return -1; \ + \ + p->data->type = rtapp_##__name; \ + \ + cref = json_object_get_string(p->obj); \ + p->data->res = get_resource_index(cref, rtapp_mutex, p->opts); \ + rdata = &(p->opts->resources[p->data->res]); \ + ddata = &(p->opts->resources[p->data->dep]); \ + \ + log_info(PIN2 "type %d target %s [%d]", \ + p->data->type, rdata->name, rdata->index); \ + \ + return 0; \ +}
- log_info(PIN2 "type %d target %s [%d] mutex %s [%d]", data->type, rdata->name, rdata->index, ddata->name, ddata->index); - return; - } +#define signal_broad_handler(__name) \ +static int handler_name(signal_broad, __name)(struct event_handler_data *p) \ +{ \ + rtapp_resource_t *rdata, *ddata; \ + const char *cref; \ + \ + if (!json_object_is_type(p->obj, json_type_string)) \ + return -1; \ + \ + p->data->type = rtapp_##__name; \ + \ + cref = json_object_get_string(p->obj); \ + p->data->res = get_resource_index(cref, rtapp_wait, p->opts); \ + rdata = &(p->opts->resources[p->data->res]); \ + ddata = &(p->opts->resources[p->data->dep]); \ + \ + log_info(PIN2 "type %d target %s [%d]", \ + p->data->type, rdata->name, rdata->index); \ + \ + return 0; \ +}
- if (!strncmp(name, "suspend", strlen("suspend"))) { +#define suspend_resume_handler(__name) \ +static int handler_name(suspend_resume, __name)(struct event_handler_data *p) \ +{ \ + rtapp_resource_t *rdata, *ddata; \ + const char *cref; \ + \ + if (!json_object_is_type(p->obj, json_type_string)) \ + return -1; \ + \ + p->data->type = rtapp_##__name; \ + \ + cref = json_object_get_string(p->obj); \ + p->data->res = get_resource_index(cref, rtapp_wait, p->opts); \ + p->data->dep = get_resource_index(cref, rtapp_mutex, p->opts); \ + rdata = &(p->opts->resources[p->data->res]); \ + ddata = &(p->opts->resources[p->data->dep]); \ + \ + log_info(PIN2 "type %d target %s [%d] mutex %s [%d]", \ + p->data->type, rdata->name, rdata->index, ddata->name, ddata->index); \ + \ + return 0; \ +}
- data->type = rtapp_suspend; +#define wait_sync_handler(__name) \ +static int handler_name(wait_sync, __name)(struct event_handler_data *p) \ +{ \ + rtapp_resource_t *rdata, *ddata; \ + char *ref; \ + \ + p->data->type = rtapp_##__name; \ + \ + ref = get_string_value_from(p->obj, "ref", TRUE, "unknown"); \ + p->data->res = get_resource_index(ref, rtapp_wait, p->opts); \ + free(ref); \ + \ + ref = get_string_value_from(p->obj, "mutex", TRUE, "unknown"); \ + p->data->dep = get_resource_index(ref, rtapp_mutex, p->opts); \ + free(ref); \ + \ + rdata = &(p->opts->resources[p->data->res]); \ + ddata = &(p->opts->resources[p->data->dep]); \ + \ + log_info(PIN2 "type %d target %s [%d] mutex %s [%d]", \ + p->data->type, rdata->name, rdata->index, ddata->name, ddata->index); \ + \ + return 0; \ +}
- if (!json_object_is_type(obj, json_type_string)) - goto unknown_event; +static int timer_handler(struct event_handler_data *p) +{ + rtapp_resource_t *rdata, *ddata; + char unique_name[22]; + char *tmp, *ref;
- ref = json_object_get_string(obj); + tmp = get_string_value_from(p->obj, "ref", TRUE, "unknown"); + if (!strncmp(tmp, "unique", strlen("unique"))) + ref = create_unique_name(unique_name, sizeof(unique_name), tmp, p->tag); + else + ref = tmp;
- i = get_resource_index(ref, rtapp_wait, opts); + p->data->res = get_resource_index(ref, rtapp_timer, p->opts); + free(tmp);
- data->res = i; + p->data->duration = get_int_value_from(p->obj, "period", TRUE, 0); + p->data->type = rtapp_timer;
- i = get_resource_index(ref, rtapp_mutex, opts); + rdata = &(p->opts->resources[p->data->res]); + ddata = &(p->opts->resources[p->data->dep]);
- data->dep = i; + log_info(PIN2 "type %d target %s [%d] period %d", + p->data->type, rdata->name, rdata->index, p->data->duration);
- rdata = &(opts->resources[data->res]); - ddata = &(opts->resources[data->dep]); + return 0; +}
- log_info(PIN2 "type %d target %s [%d] mutex %s [%d]", data->type, rdata->name, rdata->index, ddata->name, ddata->index); - return; +/* + * actual definition of macro generated handlers + */ +#define handler_definition(x,y) x##_handler(y) +handler_definition(run_sleep, run) +handler_definition(run_sleep, sleep) +handler_definition(lock_unlock, lock) +handler_definition(lock_unlock, unlock) +handler_definition(signal_broad, signal) +handler_definition(signal_broad, broadcast) +handler_definition(wait_sync, wait) +handler_definition(wait_sync, sig_and_wait) +handler_definition(suspend_resume, suspend) +handler_definition(suspend_resume,resume) + +static struct event_handler events[] = { + { .name = "run", .exec = handler_name(run_sleep, run) }, + { .name = "sleep", .exec = handler_name(run_sleep, sleep) }, + { .name = "lock", .exec = handler_name(lock_unlock, lock) }, + { .name = "unlock", .exec = handler_name(lock_unlock, unlock) }, + { .name = "signal", .exec = handler_name(signal_broad, signal) }, + { .name = "broad", .exec = handler_name(signal_broad, broadcast) }, + { .name = "wait", .exec = handler_name(wait_sync, wait) }, + { .name = "sync", .exec = handler_name(wait_sync, sig_and_wait) }, + { .name = "timer", .exec = timer_handler }, + { .name = "resume", .exec = handler_name(suspend_resume, suspend) }, + { .name = "suspend", .exec = handler_name(suspend_resume, resume) }, +}; + +static void parse_thread_event_data(char *name, struct json_object *obj, + event_data_t *data, rtapp_options_t *opts, long tag) +{ + struct event_handler_data info = { + .name = name, + .obj = obj, + .data = data, + .opts = opts, + .tag = tag + }; + int len, i, ret; + const char *p; + + for (i = 0; i < ARRAY_SIZE(events); i++) { + len = strlen(events[i].name); + p = events[i].name; + + if (!strncmp(p, name, len)) { + ret = events[i].exec(&info); + if (ret < 0) + goto unknown_event; + return; + } }
unknown_resource: - log_error(PIN2 "Resource %s not found in the resource section !!!", ref); + log_error(PIN2 "Resource not found in the resource section !!!"); log_error(PIN2 "Please check the resource name or the resource section");
unknown_event: data->duration = 0; data->type = rtapp_run; log_error(PIN2 "Unknown or mismatch %s event type !!!", name); - }
static int