summaryrefslogtreecommitdiff
path: root/tools/doxy2json
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-03-25 16:31:16 +0100
committerRobin Gareus <robin@gareus.org>2016-03-25 16:31:16 +0100
commitdd27620566cf83631c309f008a5bc6b4c28b9f07 (patch)
treeca0c9b342567865ddbd8b3eeb6ff4e4388858a9e /tools/doxy2json
parentc8b7d70ffab750535031836082e0103cad34da94 (diff)
filter declarations in C++, improve luadoc
Diffstat (limited to 'tools/doxy2json')
-rwxr-xr-xtools/doxy2json/ardourdoc.sh18
-rw-r--r--tools/doxy2json/doxy2json.cc142
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;
}