eolian: preliminary doc dependency detection for external files
authorDaniel Kolesa <d.kolesa@osg.samsung.com>
Wed, 23 Sep 2015 16:17:50 +0000 (17:17 +0100)
committerDaniel Kolesa <d.kolesa@osg.samsung.com>
Wed, 23 Sep 2015 16:17:50 +0000 (17:17 +0100)
This doesn't quite work yet as path sanitization needs to be done for it to
work correctly. For now this code path is disabled and will be enabled once
all paths are correctly sanitized.

src/lib/eolian/database_fill.c
src/lib/eolian/eo_lexer.c
src/lib/eolian/eolian_database.c
src/lib/eolian/eolian_database.h

index 2d43b6c..0371991 100644 (file)
@@ -217,6 +217,7 @@ eo_parser_database_fill(const char *filename, Eina_Bool eot)
    Eina_Iterator *itr;
    Eolian_Class *cl;
    Eo_Lexer *ls;
+   const char *dep;
 
    if (eina_hash_find(_parsedeos, filename))
      return EINA_TRUE;
@@ -257,6 +258,7 @@ eo_parser_database_fill(const char *filename, Eina_Bool eot)
           {
              fprintf(stderr, "eolian: unable to find function '%s'\n",
                      eolian_implement_full_name_get(impl));
+             eina_iterator_free(itr);
              goto error;
           }
         else if (eolian_function_is_constructor(impl->foo_id, impl->klass))
@@ -271,6 +273,7 @@ eo_parser_database_fill(const char *filename, Eina_Bool eot)
           {
              fprintf(stderr, "eolian: unable to find function '%s'\n",
                      eolian_constructor_full_name_get(ctor));
+             eina_iterator_free(itr);
              goto error;
           }
         else
@@ -278,6 +281,20 @@ eo_parser_database_fill(const char *filename, Eina_Bool eot)
      }
    eina_iterator_free(itr);
 
+   /* parse deferred eos (doc dependencies) */
+   itr = eina_hash_iterator_data_new(_defereos);
+   EINA_ITERATOR_FOREACH(itr, dep)
+     {
+        if (!eina_hash_find(_parsingeos, dep) && !eolian_file_parse(dep))
+          {
+             eina_iterator_free(itr);
+             eina_hash_free_buckets(_defereos);
+             goto error;
+          }
+     }
+   eina_iterator_free(itr);
+   eina_hash_free_buckets(_defereos);
+
 done:
    eina_hash_set(_parsedeos, filename, (void *)EINA_TRUE);
    eina_hash_set(_parsingeos, filename, (void *)EINA_FALSE);
index 456f0b1..ced0890 100644 (file)
@@ -253,6 +253,72 @@ enum Doc_Tokens {
     DOC_MANGLED = -2, DOC_UNFINISHED = -1, DOC_TEXT = 0, DOC_SINCE = 1
 };
 
+static void
+doc_ref_class(const char *cname)
+{
+   size_t clen = strlen(cname);
+   char *buf = alloca(clen + 4);
+   memcpy(buf, cname, clen);
+   buf[clen] = '\0';
+   for (char *p = buf; *p; ++p)
+     {
+        if (*p == '.')
+          *p = '_';
+        else
+          *p = tolower(*p);
+     }
+   memcpy(buf + clen, ".eo", sizeof(".eo"));
+   const char *eop = eina_hash_find(_filenames, buf);
+   if (!eop)
+     return;
+   eina_hash_set(_defereos, buf, eop);
+}
+
+static void
+doc_ref(Eo_Lexer *ls)
+{
+#if 0
+   const char *st = ls->stream, *ste = ls->stream_end;
+   size_t rlen = 0;
+   while ((st != ste) && ((*st == '.') || isalnum(*st)))
+     {
+        ++st;
+        ++rlen;
+     }
+   if ((rlen > 1) && (*(st - 1) == '.'))
+     --rlen;
+   if (!rlen)
+     return;
+   if (*ls->stream == '.')
+     return;
+
+   char *buf = alloca(rlen + 1);
+   memcpy(buf, ls->stream, rlen);
+   buf[rlen] = '\0';
+
+   /* actual full class name */
+   doc_ref_class(buf);
+
+   /* method name at the end */
+   char *end = strrchr(buf, '.');
+   if (!end)
+     return;
+   *end = '\0';
+   doc_ref_class(buf);
+
+   /* .get or .set at the end, handle possible property */
+   if (strcmp(end + 1, "get") && strcmp(end + 1, "set"))
+     return;
+   end = strrchr(buf, '.');
+   if (!end)
+     return;
+   *end = '\0';
+   doc_ref_class(buf);
+#else
+   (void)ls;
+#endif
+}
+
 static int
 doc_lex(Eo_Lexer *ls, Eina_Bool *term, Eina_Bool *since)
 {
@@ -324,6 +390,7 @@ doc_lex(Eo_Lexer *ls, Eina_Bool *term, Eina_Bool *since)
              tokret = DOC_TEXT;
              goto exit_with_token;
           }
+        doc_ref(ls);
         eina_strbuf_append_char(ls->buff, '@');
         next_char(ls);
         /* in-class references */
index a897f9d..6357c71 100644 (file)
@@ -27,6 +27,8 @@ Eina_Hash *_declsf     = NULL;
 Eina_Hash *_parsedeos  = NULL;
 Eina_Hash *_parsingeos = NULL;
 
+Eina_Hash *_defereos = NULL;
+
 static int _database_init_count = 0;
 
 static void
@@ -58,6 +60,7 @@ database_init()
    _declsf     = eina_hash_stringshared_new(_hashlist_free);
    _parsedeos  = eina_hash_string_small_new(NULL);
    _parsingeos = eina_hash_string_small_new(NULL);
+   _defereos   = eina_hash_string_small_new(NULL);
    return ++_database_init_count;
 }
 
@@ -91,6 +94,7 @@ database_shutdown()
         eina_hash_free(_declsf    ); _declsf     = NULL;
         eina_hash_free(_parsedeos ); _parsedeos  = NULL;
         eina_hash_free(_parsingeos); _parsingeos = NULL;
+        eina_hash_free(_defereos  ); _defereos   = NULL;
         eina_shutdown();
      }
    return _database_init_count;
index 40a5f62..dd530c7 100644 (file)
@@ -53,6 +53,9 @@ extern Eina_Hash *_decls;
 extern Eina_Hash *_parsedeos;
 extern Eina_Hash *_parsingeos;
 
+/* for deferred dependency parsing */
+extern Eina_Hash *_defereos;
+
 typedef struct _Eolian_Object
 {
    const char *file;