You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2015/07/31 12:18:33 UTC

[2/5] celix git commit: CELIX-237: Small refactoring of descriptor. Added explicit header and annotation section

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 <pe...@gmail.com>
Authored: Thu Jul 30 13:18:11 2015 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
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);
     }