CELIX-237: Small refactoring of descriptor. Added explicit header and annotation section
Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/794f7971 Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/794f7971 Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/794f7971 Branch: refs/heads/feature/CELIX-237_rsa-ffi Commit: 794f7971a1c2db96bafb2cebabd8d70cde919435 Parents: d4b2ce6 Author: Pepijn Noltes <[email protected]> Authored: Thu Jul 30 13:18:11 2015 +0200 Committer: Pepijn Noltes <[email protected]> Committed: Thu Jul 30 13:18:11 2015 +0200 ---------------------------------------------------------------------- .../descriptors/example1.descriptor | 8 +- .../dynamic_function_interface/dyn_common.c | 8 +- .../dynamic_function_interface/dyn_common.h | 1 - .../dynamic_function_interface/dyn_interface.c | 91 ++++++++++++++++---- .../dynamic_function_interface/dyn_interface.h | 16 ++-- .../tst/dyn_interface_tests.cpp | 12 ++- 6 files changed, 107 insertions(+), 29 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/794f7971/remote_services/dynamic_function_interface/descriptors/example1.descriptor ---------------------------------------------------------------------- diff --git a/remote_services/dynamic_function_interface/descriptors/example1.descriptor b/remote_services/dynamic_function_interface/descriptors/example1.descriptor index a0eacfa..97b1df8 100644 --- a/remote_services/dynamic_function_interface/descriptors/example1.descriptor +++ b/remote_services/dynamic_function_interface/descriptors/example1.descriptor @@ -1,9 +1,9 @@ -:annotations +:header type=interface name=calculator -major_version=1 -minor_version=0 -micro_version=0 +version=1.0.0 +:annotations +classname=org.example.Calculator :types StatsResult={DDD[D average min max input} :methods http://git-wip-us.apache.org/repos/asf/celix/blob/794f7971/remote_services/dynamic_function_interface/dyn_common.c ---------------------------------------------------------------------- diff --git a/remote_services/dynamic_function_interface/dyn_common.c b/remote_services/dynamic_function_interface/dyn_common.c index 5ee1a5a..057ddcf 100644 --- a/remote_services/dynamic_function_interface/dyn_common.c +++ b/remote_services/dynamic_function_interface/dyn_common.c @@ -67,13 +67,14 @@ int dynCommon_parseNameValue(FILE *stream, char **outName, char **outValue) { int status = OK; char *name = NULL; char *value = NULL; + const char *valueAcceptedChars = ".<>{}[]?;:~!@#$%^&*()_+-=,./\\'\""; status = dynCommon_parseName(stream, &name); if (status == OK) { status = dynCommon_eatChar(stream, '='); } if (status == OK) { - status = dynCommon_parseName(stream, &value); //TODO use different more lenient function? + status = dynCommon_parseNameAlsoAccept(stream, valueAcceptedChars, &value); //NOTE use different more lenient function e.g. only stop at '\n' ? } if (status == OK) { @@ -90,12 +91,13 @@ int dynCommon_parseNameValue(FILE *stream, char **outName, char **outValue) { return status; } -inline int dynCommon_eatChar(FILE *stream, int expected) { +int dynCommon_eatChar(FILE *stream, int expected) { int status = OK; + long loc = ftell(stream); int c = fgetc(stream); if (c != expected) { status = ERROR; - LOG_ERROR("Error parsing, expected token '%c' got '%c'", expected, c); + LOG_ERROR("Error parsing, expected token '%c' got '%c' at position %li", expected, loc); } return status; } http://git-wip-us.apache.org/repos/asf/celix/blob/794f7971/remote_services/dynamic_function_interface/dyn_common.h ---------------------------------------------------------------------- diff --git a/remote_services/dynamic_function_interface/dyn_common.h b/remote_services/dynamic_function_interface/dyn_common.h index 163bafc..308b75a 100644 --- a/remote_services/dynamic_function_interface/dyn_common.h +++ b/remote_services/dynamic_function_interface/dyn_common.h @@ -30,5 +30,4 @@ int dynCommon_parseNameAlsoAccept(FILE *stream, const char *acceptedChars, char int dynCommon_parseNameValue(FILE *stream, char **name, char **value); int dynCommon_eatChar(FILE *stream, int c); - #endif http://git-wip-us.apache.org/repos/asf/celix/blob/794f7971/remote_services/dynamic_function_interface/dyn_interface.c ---------------------------------------------------------------------- diff --git a/remote_services/dynamic_function_interface/dyn_interface.c b/remote_services/dynamic_function_interface/dyn_interface.c index bc07a47..d411232 100644 --- a/remote_services/dynamic_function_interface/dyn_interface.c +++ b/remote_services/dynamic_function_interface/dyn_interface.c @@ -19,12 +19,17 @@ static int dynInterface_parseSection(dyn_interface_type *intf, FILE *stream); static int dynInterface_parseAnnotations(dyn_interface_type *intf, FILE *stream); static int dynInterface_parseTypes(dyn_interface_type *intf, FILE *stream); static int dynInterface_parseMethods(dyn_interface_type *intf, FILE *stream); +static int dynInterface_parseHeader(dyn_interface_type *intf, FILE *stream); +static int dynInterface_parseNameValueSection(dyn_interface_type *intf, FILE *stream, struct namvals_head *head); +static int dynInterface_checkInterface(dyn_interface_type *intf); +static int dynInterface_getEntryForHead(struct namvals_head *head, const char *name, char **value); int dynInterface_parse(FILE *descriptor, dyn_interface_type **out) { int status = OK; dyn_interface_type *intf = calloc(1, sizeof(*intf)); if (intf != NULL) { + TAILQ_INIT(&intf->header); TAILQ_INIT(&intf->annotations); TAILQ_INIT(&intf->types); TAILQ_INIT(&intf->methods); @@ -43,6 +48,10 @@ int dynInterface_parse(FILE *descriptor, dyn_interface_type **out) { if (status == OK) { status = dynCommon_eatChar(descriptor, EOF); } + + if (status == OK) { + status = dynInterface_checkInterface(intf); + } } else { status = ERROR; LOG_ERROR("Error allocating memory for dynamic interface\n"); @@ -56,6 +65,34 @@ int dynInterface_parse(FILE *descriptor, dyn_interface_type **out) { return status; } +static int dynInterface_checkInterface(dyn_interface_type *intf) { + int status = OK; + + //check header section + if (status == OK) { + bool foundType = false; + bool foundVersion = false; + bool foundName = false; + struct namval_entry *entry = NULL; + TAILQ_FOREACH(entry, &intf->header, entries) { + if (strcmp(entry->name, "type") == 0) { + foundType = true; + } else if (strcmp(entry->name, "version") == 0) { + foundVersion = true; + } else if (strcmp(entry->name, "name") == 0) { + foundName = true; + } + } + + if (!foundType || !foundVersion || !foundName) { + status = ERROR; + LOG_ERROR("Parse Error. There must be a header section with a type, version and name entry"); + } + } + + return status; +} + static int dynInterface_parseSection(dyn_interface_type *intf, FILE *stream) { int status = OK; char *sectionName = NULL; @@ -71,12 +108,14 @@ static int dynInterface_parseSection(dyn_interface_type *intf, FILE *stream) { } if (status == OK) { - if (strcmp("annotations", sectionName) ==0) { - status = dynInterface_parseAnnotations(intf, stream); + if (strcmp("header", sectionName) == 0) { + status = dynInterface_parseHeader(intf, stream); + } else if (strcmp("annotations", sectionName) ==0) { + status = dynInterface_parseAnnotations(intf, stream); } else if (strcmp("types", sectionName) == 0) { - status =dynInterface_parseTypes(intf, stream); + status =dynInterface_parseTypes(intf, stream); } else if (strcmp("methods", sectionName) == 0) { - status =dynInterface_parseMethods(intf, stream); + status =dynInterface_parseMethods(intf, stream); } else { status = ERROR; LOG_ERROR("unsupported section '%s'", sectionName); @@ -86,7 +125,15 @@ static int dynInterface_parseSection(dyn_interface_type *intf, FILE *stream) { return status; } +static int dynInterface_parseHeader(dyn_interface_type *intf, FILE *stream) { + return dynInterface_parseNameValueSection(intf, stream, &intf->header); +} + static int dynInterface_parseAnnotations(dyn_interface_type *intf, FILE *stream) { + return dynInterface_parseNameValueSection(intf, stream, &intf->annotations); +} + +static int dynInterface_parseNameValueSection(dyn_interface_type *intf, FILE *stream, struct namvals_head *head) { int status = OK; int peek = fgetc(stream); @@ -107,7 +154,7 @@ static int dynInterface_parseAnnotations(dyn_interface_type *intf, FILE *stream) if (entry != NULL) { entry->name = name; entry->value = value; - TAILQ_INSERT_TAIL(&intf->annotations, entry, entries); + TAILQ_INSERT_TAIL(head, entry, entries); } else { status = ERROR; LOG_ERROR("Error allocating memory for namval entry"); @@ -129,7 +176,7 @@ static int dynInterface_parseAnnotations(dyn_interface_type *intf, FILE *stream) peek = fgetc(stream); } ungetc(peek, stream); - + return status; } @@ -295,23 +342,37 @@ void dynInterface_destroy(dyn_interface_type *intf) { } } -//TODO refactor using a dynInterface_findAnnotation method int dynInterface_getName(dyn_interface_type *intf, char **out) { + return dynInterface_getEntryForHead(&intf->header, "name", out); +} + +int dynInterface_getVersion(dyn_interface_type *intf, char **version) { + return dynInterface_getEntryForHead(&intf->header, "version", version); +} + +int dynInterface_getHeaderEntry(dyn_interface_type *intf, const char *name, char **value) { + return dynInterface_getEntryForHead(&intf->header, name, value); +} + +int dynInterface_getAnnotationEntry(dyn_interface_type *intf, const char *name, char **value) { + return dynInterface_getEntryForHead(&intf->annotations, name, value); +} + +static int dynInterface_getEntryForHead(struct namvals_head *head, const char *name, char **out) { int status = OK; - char *name = NULL; + char *value = NULL; struct namval_entry *entry = NULL; - TAILQ_FOREACH(entry, &intf->annotations, entries) { - if (strcmp("name", entry->name) == 0) { - name = entry->value; + TAILQ_FOREACH(entry, head, entries) { + if (strcmp(name, entry->name) == 0) { + value = entry->value; break; } } - - if (name != NULL) { - *out = name; + if (value != NULL) { + *out = value; } else { status = ERROR; - LOG_WARNING("Cannot find 'name' in dyn interface annotations"); + LOG_WARNING("Cannot find '%s' in list", name); } return status; } http://git-wip-us.apache.org/repos/asf/celix/blob/794f7971/remote_services/dynamic_function_interface/dyn_interface.h ---------------------------------------------------------------------- diff --git a/remote_services/dynamic_function_interface/dyn_interface.h b/remote_services/dynamic_function_interface/dyn_interface.h index 84badc4..6b7f9ce 100644 --- a/remote_services/dynamic_function_interface/dyn_interface.h +++ b/remote_services/dynamic_function_interface/dyn_interface.h @@ -12,12 +12,14 @@ DFI_SETUP_LOG_HEADER(dynInterface); /* Description string * - * Descriptor = [Section]* - * Section = SecionHeader | Body - * SectionHeader = ':' (Name) - * SectionBody = subDescriptor '\n\ + * Descriptor (interface) = HeaderSection AnnotationSection TypesSection MethodsSection + * + * HeaderSection= + * ':header\n' [NameValue]* + * ':annotations\n' [NameValue]* + * ':types\n' [TypeIdValue]* + * ':methods\n' [MethodIdValue] * - * expected sections: header, types & mehods */ TAILQ_HEAD(namvals_head, namval_entry); @@ -27,6 +29,7 @@ TAILQ_HEAD(methods_head, method_entry); typedef struct _dyn_interface_type dyn_interface_type; struct _dyn_interface_type { + struct namvals_head header; struct namvals_head annotations; struct reference_types_head types; struct methods_head methods; @@ -53,6 +56,9 @@ int dynInterface_parse(FILE *descriptor, dyn_interface_type **out); void dynInterface_destroy(dyn_interface_type *intf); int dynInterface_getName(dyn_interface_type *intf, char **name); +int dynInterface_getVersion(dyn_interface_type *intf, char **version); +int dynInterface_getHeaderEntry(dyn_interface_type *intf, const char *name, char **value); +int dynInterface_getAnnotationEntry(dyn_interface_type *intf, const char *name, char **value); #endif http://git-wip-us.apache.org/repos/asf/celix/blob/794f7971/remote_services/dynamic_function_interface/tst/dyn_interface_tests.cpp ---------------------------------------------------------------------- diff --git a/remote_services/dynamic_function_interface/tst/dyn_interface_tests.cpp b/remote_services/dynamic_function_interface/tst/dyn_interface_tests.cpp index f22c540..18bdb33 100644 --- a/remote_services/dynamic_function_interface/tst/dyn_interface_tests.cpp +++ b/remote_services/dynamic_function_interface/tst/dyn_interface_tests.cpp @@ -40,7 +40,17 @@ extern "C" { char *name = NULL; status = dynInterface_getName(dynIntf, &name); CHECK_EQUAL(0, status); - STRCMP_EQUAL("calculator", name); + STRCMP_EQUAL("calculator", name); + + char *version = NULL; + status = dynInterface_getVersion(dynIntf, &version); + CHECK_EQUAL(0, status); + STRCMP_EQUAL("1.0.0", version); + + char *annVal = NULL; + status = dynInterface_getAnnotationEntry(dynIntf, "classname", &annVal); + CHECK_EQUAL(0, status); + STRCMP_EQUAL("org.example.Calculator", annVal); dynInterface_destroy(dynIntf); }
