[gegl] docs: port gobj2dot to python for portability - remove ruby as build time dependency



commit 8e374539cd2408c9f9a68229fb059a084032ca26
Author: John Marshall <jtm home gmail com>
Date:   Wed Feb 10 15:37:07 2021 +0000

    docs: port gobj2dot to python for portability
    - remove ruby as build time dependency

 docs/build.txt.in               |   1 -
 docs/meson.build                |  25 ++++----
 docs/website/images/meson.build |   5 +-
 meson.build                     |   3 -
 tools/gobj2dot.py               | 137 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 151 insertions(+), 20 deletions(-)
---
diff --git a/docs/build.txt.in b/docs/build.txt.in
index 82ec497e5..987b1217c 100644
--- a/docs/build.txt.in
+++ b/docs/build.txt.in
@@ -82,7 +82,6 @@ other systems where glib and gtk+ work.
       * dot
       * gtkdoc_scan
       * rsvg_convert
-      * ruby
       * source-highlight
       * w3m
 
diff --git a/docs/meson.build b/docs/meson.build
index 81e4e7107..e657b06e4 100644
--- a/docs/meson.build
+++ b/docs/meson.build
@@ -106,18 +106,17 @@ website_asciidoc_files += [
 ]
 
 # Inheritance diagram
-if ruby.found()
-  gobj2dot = find_program(
-    project_source_root / 'tools' / 'gobj2dot.rb',
-    native: true,
-    required: true,
-  )
-  inheritance_txt = custom_target(
-    'inheritance_txt',
-    output: 'inheritance.txt',
-    command: [gobj2dot, project_source_root],
-    capture: true,
-  )
-endif
+inheritance_txt = custom_target(
+  'inheritance_txt',
+  output: 'inheritance.txt',
+  command: [
+    find_program(
+      project_source_root / 'tools' / 'gobj2dot.py', native: true
+    ),
+    '--output', '@OUTPUT@',
+    project_source_root
+  ],
+)
+
 
 subdir('website')
diff --git a/docs/website/images/meson.build b/docs/website/images/meson.build
index c69d2ffe6..333927f77 100644
--- a/docs/website/images/meson.build
+++ b/docs/website/images/meson.build
@@ -9,13 +9,12 @@ foreach _file : images
 endforeach
 
 # Inheritance diagram
-if is_variable('inheritance_txt') and dot.found()
+if dot.found()
   custom_target(
     'inheritance_png',
     input: inheritance_txt,
     output: 'inheritance.png',
-    command: [dot, '@INPUT@', '-Tpng'],
-    capture: true,
+    command: [dot, '-Tpng', '-o@OUTPUT@', '@INPUT@'],
     build_by_default: true,
   )
 endif
diff --git a/meson.build b/meson.build
index cff29267f..f2c45d6ca 100644
--- a/meson.build
+++ b/meson.build
@@ -215,8 +215,6 @@ gtkdoc_scan       = find_program('gtkdoc-scan',
                      required: false, native: true)
 rsvg_convert      = find_program('rsvg-convert',
                      required: false, native: true)
-ruby              = find_program('ruby',
-                     required: false, native: true)
 source_highlight  = find_program('source-highlight',
                      required: false, native: true)
 w3m               = find_program('w3m',
@@ -566,7 +564,6 @@ summary(
     'dot'               : dot.found(),
     'pygobject'         : pygobject3.found(),
     'rsvg-convert'      : rsvg_convert.found(),
-    'Ruby'              : ruby.found(),
     'source-highlight'  : source_highlight.found(),
     'w3m'               : w3m.found(),
   }, section: 'Optional build utilities'
diff --git a/tools/gobj2dot.py b/tools/gobj2dot.py
new file mode 100644
index 000000000..4805b7f60
--- /dev/null
+++ b/tools/gobj2dot.py
@@ -0,0 +1,137 @@
+#!/usr/bin/env python3
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
+#
+#
+# Utility script to re-implement gobj2dot.rb in python with extra
+# option to send the output to a new file.
+#
+# Copyright (C) 2009 Henrik Akesson
+# Copyright (C) 2021 John Marshall
+
+from __future__ import print_function
+
+import os
+import sys
+import argparse
+import glob
+import re
+
+header = '''digraph G {
+        rankdir = RL
+
+        fontname = "Bitstream Vera Sans"
+        fontsize = 8
+
+        node [ shape = "record" ]
+
+        edge [ arrowhead = empty ]'''
+
+footer = '}'
+
+re_def_type = re.compile(
+    r'G_DEFINE_TYPE\s*\(\s*\w+,\s*(\w+),\s*(\w+)\s*\)',
+    re.DOTALL
+)
+re_def_type_code = re.compile(
+    r'G_DEFINE_TYPE_WITH_CODE\s*\(\s*(\w+).*G_IMPLEMENT_INTERFACE\s*\s*\(\s*(\w+)',
+    re.DOTALL
+)
+re_interface = re.compile(
+    r'G_TYPE_INTERFACE\s*,\s*\"([^\"]+)\"',
+    re.DOTALL
+)
+
+
+class Args():
+    def __init__(self):
+        parser = argparse.ArgumentParser()
+        parser.add_argument(
+            '--output',
+            metavar='OUTPUT_FILE',
+            help='output file - otherwise output to STDOUT'
+        )
+        parser.add_argument(
+            'PATH',
+            help='search path'
+        )
+
+        self.path = os.path.realpath(parser.parse_args().PATH)
+        if parser.parse_args().output:
+            self.output = os.path.realpath(parser.parse_args().output)
+        else:
+            self.output = None
+
+def snake_to_camel(name):
+    return re.sub(r'(?:^|_)([a-z])', lambda x: x.group(1).upper(), name)
+
+def gegl_type_to_camel(name):
+    return snake_to_camel('_'.join(name.split('_TYPE_')).lower())
+
+
+def main():
+    args = Args()
+
+    if args.output:
+        try:
+            out_file = open(os.path.realpath(args.output), 'w')
+        except IOError:
+            print('cannot open output file %s' % args.output,
+                  sys.stderr)
+            sys.exit(1)
+    else:
+        out_file = sys.stdout
+
+    print(header, file = out_file)
+
+    for filename in glob.iglob(os.path.join(args.path, '**', '*.[ch]'),
+                               recursive = True):
+        f = open(filename, mode='r', encoding='utf-8')
+        content = f.read()
+        f.close()
+        match = re.search(re_def_type, content)
+        if match:
+            if match.groups()[1] != 'G_TYPE_OBJECT':
+                print(
+                    '\t' + snake_to_camel(match.groups()[0]) +
+                    ' -> ' + gegl_type_to_camel(match.groups()[1]),
+                    file = out_file
+                )
+        else:
+            match = re.search(re_def_type_code, content)
+            if match:
+                print(
+                    '\t' + match.groups()[0] +
+                    ' -> ' + gegl_type_to_camel(match.groups()[1]) +
+                    ' [ style = dashed ]',
+                    file = out_file
+                )
+            else:
+                match = re.search(re_interface, content)
+                if match:
+                    print(
+                    '\t' + match.groups()[0] +
+                    ' [ label = \"{\\<\\<interface\\>\\>\\l' +
+                    match.groups()[0] + '}\" ]',
+                    file = out_file
+                )
+
+
+    print(footer, file = out_file)
+
+    sys.exit(0)
+
+
+if __name__ == "__main__":
+  main()
\ No newline at end of file


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]