summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@osg.samsung.com>2015-06-08 15:55:02 +0100
committerDaniel Kolesa <d.kolesa@osg.samsung.com>2015-06-08 15:57:15 +0100
commit7a38f8ec2129a4ae7ca1c1f76fba47d0cd1f7052 (patch)
tree5c033391f8fa496b2d6e6986843569d4e6c6956c
parent15a64fdc86840e1a84e67abe113eb60d0f9545b5 (diff)
eolian: support for @since tag in new doc comments
This is kind of ugly, but I didn't see a better way to do it without turning this into a much more complicated parser. So this will have to do unless we find something else to add, in which case a new doc parser will be required. @feature
-rw-r--r--src/lib/eolian/Eolian.h13
-rw-r--r--src/lib/eolian/eo_lexer.c97
-rw-r--r--src/lib/eolian/eolian_database.c8
-rw-r--r--src/lib/eolian/eolian_database.h1
-rw-r--r--src/tests/eolian/data/docs.eo9
-rw-r--r--src/tests/eolian/eolian_parsing.c7
6 files changed, 121 insertions, 14 deletions
diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h
index 2ecb5821d2..cb6b97eb0f 100644
--- a/src/lib/eolian/Eolian.h
+++ b/src/lib/eolian/Eolian.h
@@ -2239,6 +2239,19 @@ EAPI Eina_Stringshare *eolian_documentation_summary_get(const Eolian_Documentati
2239 */ 2239 */
2240EAPI Eina_Stringshare *eolian_documentation_description_get(const Eolian_Documentation *doc); 2240EAPI Eina_Stringshare *eolian_documentation_description_get(const Eolian_Documentation *doc);
2241 2241
2242/*
2243 * @brief Get the "since" tag of the documentation.
2244 *
2245 * This can return NULL if the tag wasn't specified or
2246 * if the input is wrong.
2247 *
2248 * @param[in] doc the documentation
2249 * @return the description or NULL
2250 *
2251 * @ingroup Eolian
2252 */
2253EAPI Eina_Stringshare *eolian_documentation_since_get(const Eolian_Documentation *doc);
2254
2242#endif 2255#endif
2243 2256
2244/** 2257/**
diff --git a/src/lib/eolian/eo_lexer.c b/src/lib/eolian/eo_lexer.c
index b0c73904dc..3ed337ae64 100644
--- a/src/lib/eolian/eo_lexer.c
+++ b/src/lib/eolian/eo_lexer.c
@@ -252,6 +252,15 @@ cend:
252 if (tok) tok->value.s = eina_stringshare_add(eina_strbuf_string_get(ls->buff)); 252 if (tok) tok->value.s = eina_stringshare_add(eina_strbuf_string_get(ls->buff));
253} 253}
254 254
255void doc_error(Eo_Lexer *ls, const char *msg, Eolian_Documentation *doc, Eina_Strbuf *buf)
256{
257 eina_stringshare_del(doc->summary);
258 eina_stringshare_del(doc->description);
259 free(doc);
260 eina_strbuf_free(buf);
261 eo_lexer_lex_error(ls, msg, -1);
262}
263
255static void 264static void
256read_doc(Eo_Lexer *ls, Eo_Token *tok, int line, int column) 265read_doc(Eo_Lexer *ls, Eo_Token *tok, int line, int column)
257{ 266{
@@ -270,8 +279,7 @@ read_doc(Eo_Lexer *ls, Eo_Token *tok, int line, int column)
270 { 279 {
271 if (!ls->current) 280 if (!ls->current)
272 { 281 {
273 free(doc); 282 doc_error(ls, "unfinished documentation", doc, NULL);
274 eo_lexer_lex_error(ls, "unfinished documentation", -1);
275 return; /* unreachable, for static analysis */ 283 return; /* unreachable, for static analysis */
276 } 284 }
277 if (is_newline(ls->current)) 285 if (is_newline(ls->current))
@@ -312,18 +320,79 @@ read_doc(Eo_Lexer *ls, Eo_Token *tok, int line, int column)
312 doc->summary = eina_stringshare_add(eina_strbuf_string_get(ls->buff)); 320 doc->summary = eina_stringshare_add(eina_strbuf_string_get(ls->buff));
313 321
314 Eina_Strbuf *rbuf = eina_strbuf_new(); 322 Eina_Strbuf *rbuf = eina_strbuf_new();
323 Eina_Bool had_nl = EINA_TRUE;
324
315 for (;;) 325 for (;;)
316 { 326 {
317 if (!ls->current) 327 if (!ls->current)
318 { 328 {
319 eina_stringshare_del(doc->summary); 329 doc_error(ls, "unfinished documentation", doc, NULL);
320 free(doc);
321 eina_strbuf_free(rbuf);
322 eo_lexer_lex_error(ls, "unfinished documentation", -1);
323 return; /* unreachable, for static analysis */ 330 return; /* unreachable, for static analysis */
324 } 331 }
325 332
326 eina_strbuf_reset(ls->buff); 333 eina_strbuf_reset(ls->buff);
334
335 if (had_nl && ls->current == '@')
336 {
337#define LEX_SINCE(c, failure) \
338 next_char(ls); \
339 if (ls->current != c) \
340 { \
341 eina_strbuf_append(ls->buff, failure); \
342 goto normal; \
343 }
344
345 LEX_SINCE('s', "@");
346 LEX_SINCE('i', "@s");
347 LEX_SINCE('n', "@si");
348 LEX_SINCE('c', "@sin");
349 LEX_SINCE('e', "@sinc");
350 LEX_SINCE(' ', "@since");
351
352#undef LEX_SINCE
353
354 skip_ws(ls);
355
356 /* gotta have a value */
357 if (!ls->current || is_newline(ls->current) || ls->current == ']')
358 goto docerr;
359
360 /* append the since string */
361 while (ls->current && ls->current != ']' && !is_newline(ls->current))
362 {
363 eina_strbuf_append_char(ls->buff, ls->current);
364 next_char(ls);
365 }
366
367 /* trigger "unfinished documentation" if things end early */
368 if (!ls->current)
369 continue;
370
371 /* strip final whitespace */
372 while (isspace(ls->current))
373 {
374 if (is_newline(ls->current))
375 next_line(ls);
376 else
377 next_char(ls);
378 }
379
380 if (ls->current != ']') goto docerr;
381 next_char(ls);
382 if (ls->current != ']') goto docerr;
383 next_char(ls);
384
385 eina_strbuf_trim(ls->buff);
386 doc->since = eina_stringshare_add(eina_strbuf_string_get(ls->buff));
387
388 goto done;
389docerr:
390 doc_error(ls, "mangled documentation", doc, rbuf);
391 return;
392 }
393
394normal:
395 had_nl = EINA_FALSE;
327 while (ls->current && !is_newline(ls->current)) 396 while (ls->current && !is_newline(ls->current))
328 { 397 {
329 if (ls->current == ']') 398 if (ls->current == ']')
@@ -336,13 +405,7 @@ read_doc(Eo_Lexer *ls, Eo_Token *tok, int line, int column)
336 next_char(ls); 405 next_char(ls);
337 eina_strbuf_trim(ls->buff); 406 eina_strbuf_trim(ls->buff);
338 eina_strbuf_append(rbuf, eina_strbuf_string_get(ls->buff)); 407 eina_strbuf_append(rbuf, eina_strbuf_string_get(ls->buff));
339 eina_strbuf_trim(rbuf); 408 goto done;
340 if (eina_strbuf_string_get(rbuf)[0])
341 doc->description = eina_stringshare_add(
342 eina_strbuf_string_get(rbuf));
343 eina_strbuf_free(rbuf);
344 tok->value.doc = doc;
345 return;
346 } 409 }
347 } 410 }
348 eina_strbuf_append_char(ls->buff, ls->current); 411 eina_strbuf_append_char(ls->buff, ls->current);
@@ -361,8 +424,16 @@ read_doc(Eo_Lexer *ls, Eo_Token *tok, int line, int column)
361 eina_strbuf_append_char(rbuf, ' '); 424 eina_strbuf_append_char(rbuf, ' ');
362 while (is_newline(ls->current)) 425 while (is_newline(ls->current))
363 next_line_ws(ls); 426 next_line_ws(ls);
427 had_nl = EINA_TRUE;
364 } 428 }
365 } 429 }
430
431done:
432 eina_strbuf_trim(rbuf);
433 if (eina_strbuf_string_get(rbuf)[0])
434 doc->description = eina_stringshare_add(eina_strbuf_string_get(rbuf));
435 eina_strbuf_free(rbuf);
436 tok->value.doc = doc;
366} 437}
367 438
368static void 439static void
diff --git a/src/lib/eolian/eolian_database.c b/src/lib/eolian/eolian_database.c
index cc23f87d6b..4ebc9785a7 100644
--- a/src/lib/eolian/eolian_database.c
+++ b/src/lib/eolian/eolian_database.c
@@ -166,6 +166,7 @@ void database_doc_del(Eolian_Documentation *doc)
166 if (!doc) return; 166 if (!doc) return;
167 eina_stringshare_del(doc->summary); 167 eina_stringshare_del(doc->summary);
168 eina_stringshare_del(doc->description); 168 eina_stringshare_del(doc->description);
169 eina_stringshare_del(doc->since);
169 free(doc); 170 free(doc);
170} 171}
171 172
@@ -183,6 +184,13 @@ eolian_documentation_description_get(const Eolian_Documentation *doc)
183 return doc->description; 184 return doc->description;
184} 185}
185 186
187EAPI Eina_Stringshare *
188eolian_documentation_since_get(const Eolian_Documentation *doc)
189{
190 EINA_SAFETY_ON_NULL_RETURN_VAL(doc, NULL);
191 return doc->since;
192}
193
186#define EO_SUFFIX ".eo" 194#define EO_SUFFIX ".eo"
187#define EOT_SUFFIX ".eot" 195#define EOT_SUFFIX ".eot"
188 196
diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h
index c3a7a55b30..91b12f78c1 100644
--- a/src/lib/eolian/eolian_database.h
+++ b/src/lib/eolian/eolian_database.h
@@ -65,6 +65,7 @@ struct _Eolian_Documentation
65 Eolian_Object base; 65 Eolian_Object base;
66 Eina_Stringshare *summary; 66 Eina_Stringshare *summary;
67 Eina_Stringshare *description; 67 Eina_Stringshare *description;
68 Eina_Stringshare *since;
68}; 69};
69 70
70struct _Eolian_Declaration 71struct _Eolian_Declaration
diff --git a/src/tests/eolian/data/docs.eo b/src/tests/eolian/data/docs.eo
index eb89c929f6..c7c8622fe7 100644
--- a/src/tests/eolian/data/docs.eo
+++ b/src/tests/eolian/data/docs.eo
@@ -5,6 +5,8 @@ struct Foo {
5 This is a longer description for struct Foo. 5 This is a longer description for struct Foo.
6 6
7 This is another paragraph. 7 This is another paragraph.
8
9 @since 1.66
8 ]] 10 ]]
9 field1: int; [[Field documentation.]] 11 field1: int; [[Field documentation.]]
10 field2: float; 12 field2: float;
@@ -22,6 +24,8 @@ type Alias: Bar; [[Docs for typedef.
22 24
23 More docs for typedef. 25 More docs for typedef.
24 See @Bar. 26 See @Bar.
27
28 @since 2.0
25 ]] 29 ]]
26 30
27var pants: int = 150; [[Docs for var.]] 31var pants: int = 150; [[Docs for var.]]
@@ -48,7 +52,10 @@ class Docs {
48 return: int; [[Return documentation.]] 52 return: int; [[Return documentation.]]
49 } 53 }
50 @property prop { 54 @property prop {
51 [[Property common documentation.]] 55 [[Property common documentation.
56
57 @since 1.18
58 ]]
52 get { 59 get {
53 [[Get documentation.]] 60 [[Get documentation.]]
54 } 61 }
diff --git a/src/tests/eolian/eolian_parsing.c b/src/tests/eolian/eolian_parsing.c
index ed0626a9eb..f5e441ba85 100644
--- a/src/tests/eolian/eolian_parsing.c
+++ b/src/tests/eolian/eolian_parsing.c
@@ -1125,6 +1125,8 @@ START_TEST(eolian_docs)
1125 fail_if(strcmp(eolian_documentation_description_get(doc), 1125 fail_if(strcmp(eolian_documentation_description_get(doc),
1126 "This is a longer description for struct Foo.\n\n" 1126 "This is a longer description for struct Foo.\n\n"
1127 "This is another paragraph.")); 1127 "This is another paragraph."));
1128 fail_if(strcmp(eolian_documentation_since_get(doc),
1129 "1.66"));
1128 1130
1129 fail_if(!(sfl = eolian_type_struct_field_get(type, "field1"))); 1131 fail_if(!(sfl = eolian_type_struct_field_get(type, "field1")));
1130 fail_if(!(doc = eolian_type_struct_field_documentation_get(sfl))); 1132 fail_if(!(doc = eolian_type_struct_field_documentation_get(sfl)));
@@ -1146,6 +1148,7 @@ START_TEST(eolian_docs)
1146 fail_if(strcmp(eolian_documentation_summary_get(doc), 1148 fail_if(strcmp(eolian_documentation_summary_get(doc),
1147 "Docs for enum Bar.")); 1149 "Docs for enum Bar."));
1148 fail_if(eolian_documentation_description_get(doc)); 1150 fail_if(eolian_documentation_description_get(doc));
1151 fail_if(eolian_documentation_since_get(doc));
1149 1152
1150 fail_if(!(efl = eolian_type_enum_field_get(type, "blah"))); 1153 fail_if(!(efl = eolian_type_enum_field_get(type, "blah")));
1151 fail_if(eolian_type_enum_field_documentation_get(efl)); 1154 fail_if(eolian_type_enum_field_documentation_get(efl));
@@ -1168,6 +1171,8 @@ START_TEST(eolian_docs)
1168 "Docs for typedef.")); 1171 "Docs for typedef."));
1169 fail_if(strcmp(eolian_documentation_description_get(doc), 1172 fail_if(strcmp(eolian_documentation_description_get(doc),
1170 "More docs for typedef. See @Bar.")); 1173 "More docs for typedef. See @Bar."));
1174 fail_if(strcmp(eolian_documentation_since_get(doc),
1175 "2.0"));
1171 1176
1172 fail_if(!(var = eolian_variable_global_get_by_name("pants"))); 1177 fail_if(!(var = eolian_variable_global_get_by_name("pants")));
1173 fail_if(!(doc = eolian_variable_documentation_get(var))); 1178 fail_if(!(doc = eolian_variable_documentation_get(var)));
@@ -1224,6 +1229,8 @@ START_TEST(eolian_docs)
1224 fail_if(strcmp(eolian_documentation_summary_get(doc), 1229 fail_if(strcmp(eolian_documentation_summary_get(doc),
1225 "Property common documentation.")); 1230 "Property common documentation."));
1226 fail_if(eolian_documentation_description_get(doc)); 1231 fail_if(eolian_documentation_description_get(doc));
1232 fail_if(strcmp(eolian_documentation_since_get(doc),
1233 "1.18"));
1227 fail_if(!(doc = eolian_function_documentation_get(fid, EOLIAN_PROP_GET))); 1234 fail_if(!(doc = eolian_function_documentation_get(fid, EOLIAN_PROP_GET)));
1228 fail_if(strcmp(eolian_documentation_summary_get(doc), 1235 fail_if(strcmp(eolian_documentation_summary_get(doc),
1229 "Get documentation.")); 1236 "Get documentation."));