diff options
author | Robin Gareus <robin@gareus.org> | 2016-03-25 16:31:16 +0100 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2016-03-25 16:31:16 +0100 |
commit | dd27620566cf83631c309f008a5bc6b4c28b9f07 (patch) | |
tree | ca0c9b342567865ddbd8b3eeb6ff4e4388858a9e /tools/doxy2json | |
parent | c8b7d70ffab750535031836082e0103cad34da94 (diff) |
filter declarations in C++, improve luadoc
Diffstat (limited to 'tools/doxy2json')
-rwxr-xr-x | tools/doxy2json/ardourdoc.sh | 18 | ||||
-rw-r--r-- | tools/doxy2json/doxy2json.cc | 142 |
2 files changed, 111 insertions, 49 deletions
diff --git a/tools/doxy2json/ardourdoc.sh b/tools/doxy2json/ardourdoc.sh index 478ae9326d..616e70343f 100755 --- a/tools/doxy2json/ardourdoc.sh +++ b/tools/doxy2json/ardourdoc.sh @@ -14,6 +14,8 @@ echo "# analyzing source.. -> $TMPFILE" $LLVMINCLUDE -I /usr/include/linux \ -I libs/ardour -I libs/pbd -I libs/lua -I gtk2_ardour -I libs/timecode \ -I libs/ltc -I libs/evoral \ + -X "_" -X "::" -X "sigc" -X "Atk::" -X "Gdk::" -X "Gtk::" -X "Gio::" \ + -X "Glib::" -X "Pango::" -X "luabridge::" \ libs/ardour/ardour/* libs/pbd/pbd/* \ gtk2_ardour/*.h \ /usr/include/cairomm-1.0/cairomm/context.h \ @@ -28,22 +30,12 @@ php << EOF \$api = array (); foreach (json_decode (\$json, true) as \$a) { if (!isset (\$a['decl'])) { continue; } - if (empty (\$a['decl'])) { continue; } - if (\$a['decl'] == '::') { continue; } - if (substr (\$a['decl'], 0, 1) == '_') { continue; } - if (substr (\$a['decl'], 0, 2) == '::') { continue; } - if (substr (\$a['decl'], 0, 4) == 'sigc') { continue; } - if (substr (\$a['decl'], 0, 5) == 'Atk::') { continue; } - if (substr (\$a['decl'], 0, 5) == 'Gdk::') { continue; } - if (substr (\$a['decl'], 0, 5) == 'Gtk::') { continue; } - if (substr (\$a['decl'], 0, 5) == 'Gio::') { continue; } - if (substr (\$a['decl'], 0, 6) == 'Glib::') { continue; } - if (substr (\$a['decl'], 0, 7) == 'Pango::') { continue; } - if (substr (\$a['decl'], 0, 11) == 'luabridge::') { continue; } \$a['decl'] = str_replace ('size_t', 'unsigned long', \$a['decl']); \$a['decl'] = str_replace ('uint32_t', 'unsigned int', \$a['decl']); + \$a['decl'] = str_replace ('int32_t', 'int', \$a['decl']); \$a['decl'] = str_replace ('framepos_t', 'long', \$a['decl']); + \$a['decl'] = str_replace ('framecnt_t', 'long', \$a['decl']); \$a['decl'] = str_replace ('frameoffset_t', 'long', \$a['decl']); \$a['decl'] = str_replace ('int64_t', 'long', \$a['decl']); \$a['decl'] = str_replace ('uint8_t', 'unsigned char', \$a['decl']); @@ -57,7 +49,7 @@ foreach (json_decode (\$json, true) as \$a) { \$a['decl'] = str_replace ('const unsigned long', 'unsigned long', \$a['decl']); \$canon = str_replace (' *', '*', \$a['decl']); \$api[\$canon] = \$a; - } +} \$jout = array (); foreach (\$api as \$k => \$a) { \$jout[] = \$a; diff --git a/tools/doxy2json/doxy2json.cc b/tools/doxy2json/doxy2json.cc index f8242d5d46..2f28257037 100644 --- a/tools/doxy2json/doxy2json.cc +++ b/tools/doxy2json/doxy2json.cc @@ -23,9 +23,49 @@ #include <cstring> #include <sstream> #include <iomanip> +#include <map> #include <clang-c/Index.h> #include <clang-c/Documentation.h> +struct dox2js { + dox2js () : clang_argc (2), clang_argv (0), excl_argc (0), excl_argv (0) + { + excl_argv = (char**) calloc (1, sizeof (char*)); + clang_argv = (char**) malloc (clang_argc * sizeof (char*)); + clang_argv[0] = strdup ("-x"); + clang_argv[1] = strdup ("c++"); + } + + ~dox2js () { + for (int i = 0; i < clang_argc; ++i) { + free (clang_argv[i]); + } + for (int i = 0; excl_argv[i]; ++i) { + free (excl_argv[i]); + } + free (clang_argv); + free (excl_argv); + } + + void add_clang_arg (const char *a) { + clang_argv = (char**) realloc (clang_argv, (clang_argc + 2) * sizeof (char*)); + clang_argv[clang_argc++] = strdup ("-I"); + clang_argv[clang_argc++] = strdup (a); + } + + void add_exclude (const char *a) { + excl_argv = (char**) realloc (excl_argv, (excl_argc + 2) * sizeof (char*)); + excl_argv[excl_argc++] = strdup (a); + excl_argv[excl_argc] = NULL; + } + + int clang_argc; + char** clang_argv; + int excl_argc; + char** excl_argv; + std::map <std::string, std::string> results; +}; + static const char* kind_to_txt (CXCursor cursor) { @@ -69,20 +109,37 @@ escape_json (const std::string &s) return o.str (); } -static void recurse_parents (CXCursor cr) { +static std::string +recurse_parents (CXCursor cr) { + std::string rv; CXCursor pc = clang_getCursorSemanticParent (cr); if (CXCursor_TranslationUnit == clang_getCursorKind (pc)) { - return; + return rv; } if (!clang_Cursor_isNull (pc)) { - recurse_parents (pc); - printf ("%s::", clang_getCString (clang_getCursorDisplayName (pc))); + rv += recurse_parents (pc); + rv += clang_getCString (clang_getCursorDisplayName (pc)); + rv += "::"; } + return rv; +} + +static bool +check_excludes (const std::string& decl, CXClientData d) { + struct dox2js* dj = (struct dox2js*) d; + char** excl = dj->excl_argv; + for (int i = 0; excl[i]; ++i) { + if (decl.compare (0, strlen (excl[i]), excl[i]) == 0) { + return true; + } + } + return false; } static enum CXChildVisitResult -traverse (CXCursor cr, CXCursor /*parent*/, CXClientData) +traverse (CXCursor cr, CXCursor /*parent*/, CXClientData d) { + struct dox2js* dj = (struct dox2js*) d; CXComment c = clang_Cursor_getParsedComment (cr); if (clang_Comment_getKind (c) != CXComment_Null @@ -90,45 +147,48 @@ traverse (CXCursor cr, CXCursor /*parent*/, CXClientData) && 0 != strlen (kind_to_txt (cr)) ) { - printf ("{ \"decl\" : \""); - recurse_parents (cr); - // TODO: resolve typedef enum { .. } name; // use clang_getCursorDefinition (clang_getCanonicalCursor (cr)) ?? - printf ("%s\",\n", clang_getCString (clang_getCursorDisplayName (cr))); + std::string decl = recurse_parents (cr); + decl += clang_getCString (clang_getCursorDisplayName (cr)); - if (clang_Cursor_isVariadic (cr)) { - printf (" \"variadic\" : true,\n"); + if (decl.empty () || check_excludes (decl, d)) { + return CXChildVisit_Recurse; } - printf (" \"kind\" : \"%s\",\n", kind_to_txt (cr)); + std::ostringstream o; + o << "{ \"decl\" : \"" << decl << "\",\n"; + + if (clang_Cursor_isVariadic (cr)) { + o << " \"variadic\" : true,\n"; + } CXSourceLocation loc = clang_getCursorLocation (cr); CXFile file; unsigned line, col, off; clang_getFileLocation (loc, &file, &line, &col, &off); - printf (" \"src\" : \"%s:%d\",\n", - clang_getCString (clang_getFileName (file)), line); + o << " \"kind\" : \"" << kind_to_txt (cr) << "\",\n" + << " \"src\" : \"" << clang_getCString (clang_getFileName (file)) << ":" << line << "\",\n" + << " \"doc\" : \"" << escape_json (clang_getCString (clang_FullComment_getAsHTML (c))) << "\"\n" + << "},\n"; - printf (" \"doc\" : \"%s\"\n", - escape_json (clang_getCString (clang_FullComment_getAsHTML (c))).c_str ()); - printf ("},\n"); + dj->results[decl] = o.str (); } return CXChildVisit_Recurse; } static void -process_file (int argc, char **args, const char *fn) +process_file (const char* fn, struct dox2js *dj) { CXIndex index = clang_createIndex (0, 0); - CXTranslationUnit tu = clang_createTranslationUnitFromSourceFile (index, fn, argc, args, 0, 0); + CXTranslationUnit tu = clang_createTranslationUnitFromSourceFile (index, fn, dj->clang_argc, dj->clang_argv, 0, 0); if (tu == NULL) { fprintf (stderr, "Cannot create translation unit for src: %s\n", fn); return; } - clang_visitChildren (clang_getTranslationUnitCursor (tu), traverse, 0); + clang_visitChildren (clang_getTranslationUnitCursor (tu), traverse, (CXClientData) dj); clang_disposeTranslationUnit (tu); clang_disposeIndex (index); @@ -138,23 +198,23 @@ static void usage (int status) { printf ("doxy2json - extract doxygen doc from C++ headers.\n\n"); - fprintf (stderr, "Usage: dox2json [-I path]* <filename> [filename]*\n"); + fprintf (stderr, "Usage: dox2json [-I path]* [-X exclude]* <filename> [filename]*\n"); exit (status); } -int main (int argc, char **argv) +int main (int argc, char** argv) { - int cnt = 2; - char **args = (char**) malloc (cnt * sizeof (char*)); - args[0] = strdup ("-x"); - args[1] = strdup ("c++"); + struct dox2js dj; + + bool report_progress = false; int c; - while (EOF != (c = getopt (argc, argv, "I:"))) { + while (EOF != (c = getopt (argc, argv, "I:X:"))) { switch (c) { case 'I': - args = (char**) realloc (args, (cnt + 2) * sizeof (char*)); - args[cnt++] = strdup ("-I"); - args[cnt++] = strdup (optarg); + dj.add_clang_arg (optarg); + break; + case 'X': + dj.add_exclude (optarg); break; case 'h': usage (0); @@ -168,16 +228,26 @@ int main (int argc, char **argv) usage (EXIT_FAILURE); } - printf ("[\n"); + const int total = (argc - optind); + if (total > 6) { + report_progress = true; + } + for (int i = optind; i < argc; ++i) { - process_file (cnt, args, argv[i]); + process_file (argv[i], &dj); + if (report_progress) { + fprintf (stderr, "progress: %4.1f%% [%4d / %4d] decl: %ld \r", + 100.f * (1.f + i - optind) / (float)total, i - optind, total, + dj.results.size ()); + fflush (stderr); + } } - printf ("{} ]\n"); - for (int i = 0; i < cnt; ++i) { - free (args[i]); + printf ("[\n"); + for (std::map <std::string, std::string>::const_iterator i = dj.results.begin (); i != dj.results.end (); ++i) { + printf ("%s\n", (*i).second.c_str ()); } - free (args); + printf ("{} ]\n"); return 0; } |