q66 pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=c26134df7a43292e2dedee26da8aa62415528657

commit c26134df7a43292e2dedee26da8aa62415528657
Author: Daniel Kolesa <d.kol...@osg.samsung.com>
Date:   Tue Jun 23 15:28:46 2015 +0100

    eolian: new doc token lexer/parser
    
    This should allow us to more easily extend the format if desired
    and overall makes the doc syntax parsing more readable and simpler.
---
 src/lib/eolian/eo_lexer.c | 269 +++++++++++++++++++++-------------------------
 1 file changed, 124 insertions(+), 145 deletions(-)

diff --git a/src/lib/eolian/eo_lexer.c b/src/lib/eolian/eo_lexer.c
index ac59c6d..24d7080 100644
--- a/src/lib/eolian/eo_lexer.c
+++ b/src/lib/eolian/eo_lexer.c
@@ -252,185 +252,164 @@ cend:
    if (tok) tok->value.s = 
eina_stringshare_add(eina_strbuf_string_get(ls->buff));
 }
 
-void doc_error(Eo_Lexer *ls, const char *msg, Eolian_Documentation *doc, 
Eina_Strbuf *buf)
-{
-   eina_stringshare_del(doc->summary);
-   eina_stringshare_del(doc->description);
-   free(doc);
-   eina_strbuf_free(buf);
-   eo_lexer_lex_error(ls, msg, -1);
-}
+enum Doc_Tokens {
+    DOC_MANGLED = -2, DOC_UNFINISHED = -1, DOC_TEXT = 0, DOC_SINCE = 1
+};
 
-static void
-read_doc(Eo_Lexer *ls, Eo_Token *tok, int line, int column)
+static int
+doc_lex(Eo_Lexer *ls, Eina_Bool *term, Eina_Bool allow_since)
 {
-   Eolian_Documentation *doc = calloc(1, sizeof(Eolian_Documentation));
-   doc->base.file = ls->filename;
-   doc->base.line = line;
-   doc->base.column = column;
-
+   Eina_Bool contdoc = EINA_FALSE;
    eina_strbuf_reset(ls->buff);
-
-   skip_ws(ls);
-   while (is_newline(ls->current))
-     next_line_ws(ls);
-
-   for (;;)
+   for (;; contdoc = EINA_TRUE) switch (ls->current)
      {
-        if (!ls->current)
+      /* error case */
+      case '\0':
+        return DOC_UNFINISHED;
+      /* newline case: if two or more newlines are present, new paragraph
+       * if only one newline is present, append space to the text buffer
+       * when starting new paragraph, reset doc continutation
+       */
+      case '\n':
+      case '\r':
+        next_line(ls);
+        skip_ws(ls);
+        if (!is_newline(ls->current))
           {
-             doc_error(ls, "unfinished documentation", doc, NULL);
-             return; /* unreachable, for static analysis */
+             eina_strbuf_append_char(ls->buff, ' ');
+             continue;
           }
-        if (is_newline(ls->current))
+        while (is_newline(ls->current))
+          next_line_ws(ls);
+        eina_strbuf_trim(ls->buff);
+        return DOC_TEXT;
+      /* escape case: for any \X, output \X
+       * except for \\]], then output just ]]
+       */
+      case '\\':
+        next_char(ls);
+        if (ls->current == ']')
           {
-             next_line_ws(ls);
-             if (is_newline(ls->current))
+             next_char(ls);
+             if (ls->current == ']')
                {
-                  while (is_newline(ls->current))
-                    next_line_ws(ls);
-                  break;
+                  next_char(ls);
+                  eina_strbuf_append(ls->buff, "]]");
                }
              else
-               eina_strbuf_append_char(ls->buff, ' ');
+               eina_strbuf_append(ls->buff, "\\]");
           }
         else
+          eina_strbuf_append_char(ls->buff, '\\');
+        continue;
+      /* terminating case */
+      case ']':
+        next_char(ls);
+        if (ls->current == ']')
           {
-             if (ls->current == ']')
-               {
-                  next_char(ls);
-                  if (ls->current != ']')
-                    eina_strbuf_append_char(ls->buff, ']');
-                  else
-                    {
-                       next_char(ls);
-                       eina_strbuf_trim(ls->buff);
-                       doc->summary = eina_stringshare_add(
-                           eina_strbuf_string_get(ls->buff));
-                       tok->value.doc = doc;
-                       return;
-                    }
-               }
-             eina_strbuf_append_char(ls->buff, ls->current);
+             /* terminate doc */
              next_char(ls);
+             *term = EINA_TRUE;
+             eina_strbuf_trim(ls->buff);
+             return DOC_TEXT;
           }
-     }
-
-   eina_strbuf_trim(ls->buff);
-   doc->summary = eina_stringshare_add(eina_strbuf_string_get(ls->buff));
-
-   Eina_Strbuf *rbuf = eina_strbuf_new();
-   Eina_Bool had_nl = EINA_TRUE;
-
-   for (;;)
-     {
-        if (!ls->current)
+        eina_strbuf_append_char(ls->buff, ']');
+        continue;
+      /* @since case - only when starting a new paragraph */
+      case '@':
+        eina_strbuf_append_char(ls->buff, '@');
+        next_char(ls);
+        while (ls->current && isalpha(ls->current))
           {
-             doc_error(ls, "unfinished documentation", doc, rbuf);
-             return; /* unreachable, for static analysis */
+             eina_strbuf_append_char(ls->buff, ls->current);
+             next_char(ls);
           }
-
-        eina_strbuf_reset(ls->buff);
-
-        if (had_nl && ls->current == '@')
+        if (contdoc)
+          continue;
+        if (!strcmp(eina_strbuf_string_get(ls->buff), "@since"))
           {
-#define LEX_SINCE(c, failure) \
-        next_char(ls); \
-        if (ls->current != c) \
-          { \
-             eina_strbuf_append(ls->buff, failure); \
-             goto normal; \
-          }
-
-             LEX_SINCE('s', "@");
-             LEX_SINCE('i', "@s");
-             LEX_SINCE('n', "@si");
-             LEX_SINCE('c', "@sin");
-             LEX_SINCE('e', "@sinc");
-             LEX_SINCE(' ', "@since");
-
-#undef LEX_SINCE
-
+             /* since-token */
+             if (!allow_since)
+               return DOC_MANGLED;
+             *term = EINA_TRUE;
+             eina_strbuf_reset(ls->buff);
              skip_ws(ls);
-
-             /* gotta have a value */
-             if (!ls->current || is_newline(ls->current) || ls->current == ']')
-               goto docerr;
-
-             /* append the since string */
-             while (ls->current && ls->current != ']' && 
!is_newline(ls->current))
+             while (ls->current && (ls->current == '.' ||
+                                    ls->current == '_' ||
+                                    isalnum(ls->current)))
                {
                   eina_strbuf_append_char(ls->buff, ls->current);
                   next_char(ls);
                }
+             if (!eina_strbuf_length_get(ls->buff))
+               return DOC_UNFINISHED;
+             skip_ws(ls);
+             while (is_newline(ls->current))
+               next_line_ws(ls);
+             if (ls->current == ']')
+               next_char(ls);
+             if (ls->current != ']')
+               return DOC_MANGLED;
+             next_char(ls);
+             eina_strbuf_trim(ls->buff);
+             return DOC_SINCE;
+          }
+      /* default case - append character */
+      default:
+        eina_strbuf_append_char(ls->buff, ls->current);
+        next_char(ls);
+        continue;
+     }
+}
 
-             /* trigger "unfinished documentation" if things end early */
-             if (!ls->current)
-               continue;
-
-             /* strip final whitespace */
-             while (isspace(ls->current))
-               {
-                  if (is_newline(ls->current))
-                    next_line(ls);
-                  else
-                    next_char(ls);
-               }
+void doc_error(Eo_Lexer *ls, const char *msg, Eolian_Documentation *doc, 
Eina_Strbuf *buf)
+{
+   eina_stringshare_del(doc->summary);
+   eina_stringshare_del(doc->description);
+   free(doc);
+   eina_strbuf_free(buf);
+   eo_lexer_lex_error(ls, msg, -1);
+}
 
-             if (ls->current != ']') goto docerr;
-             next_char(ls);
-             if (ls->current != ']') goto docerr;
-             next_char(ls);
+static void
+read_doc(Eo_Lexer *ls, Eo_Token *tok, int line, int column)
+{
+   Eolian_Documentation *doc = calloc(1, sizeof(Eolian_Documentation));
+   doc->base.file = ls->filename;
+   doc->base.line = line;
+   doc->base.column = column;
 
-             eina_strbuf_trim(ls->buff);
-             doc->since = 
eina_stringshare_add(eina_strbuf_string_get(ls->buff));
+   Eina_Strbuf *rbuf = eina_strbuf_new();
 
-             goto done;
-docerr:
+   Eina_Bool term = EINA_FALSE;
+   while (!term)
+     {
+        int read = doc_lex(ls, &term, !!doc->summary);
+        switch (read)
+          {
+           case DOC_MANGLED:
              doc_error(ls, "mangled documentation", doc, rbuf);
              return;
-          }
-
-normal:
-        had_nl = EINA_FALSE;
-        while (ls->current && !is_newline(ls->current))
-          {
-             if (ls->current == ']')
+           case DOC_UNFINISHED:
+             doc_error(ls, "unfinished documentation", doc, rbuf);
+             return;
+           case DOC_TEXT:
+             if (!doc->summary)
+               doc->summary = 
eina_stringshare_add(eina_strbuf_string_get(ls->buff));
+             else
                {
-                  next_char(ls);
-                  if (ls->current != ']')
-                    eina_strbuf_append_char(ls->buff, ']');
-                  else
-                    {
-                       next_char(ls);
-                       eina_strbuf_trim(ls->buff);
-                       eina_strbuf_append(rbuf, 
eina_strbuf_string_get(ls->buff));
-                       goto done;
-                    }
+                  if (eina_strbuf_length_get(rbuf))
+                    eina_strbuf_append(rbuf, "\n\n");
+                  eina_strbuf_append(rbuf, eina_strbuf_string_get(ls->buff));
                }
-             eina_strbuf_append_char(ls->buff, ls->current);
-             next_char(ls);
-          }
-        eina_strbuf_trim(ls->buff);
-        eina_strbuf_append(rbuf, eina_strbuf_string_get(ls->buff));
-
-        if (is_newline(ls->current))
-          {
-             next_line_ws(ls);
-             /* new paragraph */
-             if (is_newline(ls->current))
-               eina_strbuf_append(rbuf, "\n\n");
-             else
-               eina_strbuf_append_char(rbuf, ' ');
-             while (is_newline(ls->current))
-               next_line_ws(ls);
-             had_nl = EINA_TRUE;
+             break;
+           case DOC_SINCE:
+             doc->since = 
eina_stringshare_add(eina_strbuf_string_get(ls->buff));
+             break;
           }
      }
 
-done:
-   eina_strbuf_trim(rbuf);
-   if (eina_strbuf_string_get(rbuf)[0])
+   if (eina_strbuf_length_get(rbuf))
      doc->description = eina_stringshare_add(eina_strbuf_string_get(rbuf));
    eina_strbuf_free(rbuf);
    tok->value.doc = doc;

-- 


Reply via email to