| @@ -1,4 +1,4 @@ | |||
| # Doxyfile 1.8.9.1 | |||
| # Doxyfile 1.8.10 | |||
| # This file describes the settings to be used by the documentation system | |||
| # doxygen (www.doxygen.org) for a project. | |||
| @@ -343,6 +343,13 @@ IDL_PROPERTY_SUPPORT = YES | |||
| DISTRIBUTE_GROUP_DOC = NO | |||
| # If one adds a struct or class to a group and this option is enabled, then also | |||
| # any nested class or struct is added to the same group. By default this option | |||
| # is disabled and one has to add nested compounds explicitly via \ingroup. | |||
| # The default value is: NO. | |||
| GROUP_NESTED_COMPOUNDS = NO | |||
| # Set the SUBGROUPING tag to YES to allow class member groups of the same type | |||
| # (for instance a group of public functions) to be put as a subgroup of that | |||
| # type (e.g. under the Public Functions section). Set it to NO to prevent | |||
| @@ -758,7 +765,7 @@ WARN_LOGFILE = | |||
| # spaces. | |||
| # Note: If this tag is empty the current directory is searched. | |||
| INPUT = ../modules | |||
| INPUT = build | |||
| # This tag can be used to specify the character encoding of the source files | |||
| # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses | |||
| @@ -771,12 +778,17 @@ INPUT_ENCODING = UTF-8 | |||
| # If the value of the INPUT tag contains directories, you can use the | |||
| # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and | |||
| # *.h) to filter out the source-files in the directories. If left blank the | |||
| # following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, | |||
| # *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, | |||
| # *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, | |||
| # *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, | |||
| # *.qsf, *.as and *.js. | |||
| # *.h) to filter out the source-files in the directories. | |||
| # | |||
| # Note that for custom extensions or not directly supported extensions you also | |||
| # need to set EXTENSION_MAPPING for the extension otherwise the files are not | |||
| # read by doxygen. | |||
| # | |||
| # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, | |||
| # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, | |||
| # *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, | |||
| # *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, | |||
| # *.vhdl, *.ucf, *.qsf, *.as and *.js. | |||
| FILE_PATTERNS = juce_*.h \ | |||
| juce_*.dox | |||
| @@ -794,53 +806,21 @@ RECURSIVE = YES | |||
| # Note that relative paths are relative to the directory from which doxygen is | |||
| # run. | |||
| EXCLUDE = ../modules/juce_graphics/image_formats \ | |||
| ../modules/juce_core/zip/zlib \ | |||
| ../modules/juce_audio_formats/codecs/flac \ | |||
| ../modules/juce_audio_formats/codecs/oggvorbis \ | |||
| ../modules/juce_audio_basics/juce_audio_basics.h \ | |||
| ../modules/juce_audio_basics/juce_audio_basics.cpp \ | |||
| ../modules/juce_audio_devices/juce_audio_devices.h \ | |||
| ../modules/juce_audio_devices/juce_audio_devices.cpp \ | |||
| ../modules/juce_audio_devices/native \ | |||
| ../modules/juce_audio_formats/juce_audio_formats.h \ | |||
| ../modules/juce_audio_formats/juce_audio_formats.cpp \ | |||
| ../modules/juce_audio_plugin_client/juce_audio_plugin_client.h \ | |||
| ../modules/juce_audio_plugin_client/AU/CoreAudioUtilityClasses \ | |||
| ../modules/juce_audio_processors/juce_audio_processors.h \ | |||
| ../modules/juce_audio_processors/juce_audio_processors.cpp \ | |||
| ../modules/juce_audio_utils/juce_audio_utils.h \ | |||
| ../modules/juce_audio_utils/juce_audio_utils.cpp \ | |||
| ../modules/juce_browser_plugin_client/juce_browser_plugin.h \ | |||
| ../modules/juce_browser_plugin_client/juce_browser_plugin.cpp \ | |||
| ../modules/juce_core/juce_core.h \ | |||
| ../modules/juce_core/juce_core.cpp \ | |||
| ../modules/juce_core/native \ | |||
| ../modules/juce_cryptography/juce_cryptography.h \ | |||
| ../modules/juce_cryptography/juce_cryptography.cpp \ | |||
| ../modules/juce_data_structures/juce_data_structures.h \ | |||
| ../modules/juce_data_structures/juce_data_structures.cpp \ | |||
| ../modules/juce_events/juce_events.h \ | |||
| ../modules/juce_events/juce_events.cpp \ | |||
| ../modules/juce_events/native \ | |||
| ../modules/juce_graphics/juce_graphics.h \ | |||
| ../modules/juce_graphics/juce_graphics.cpp \ | |||
| ../modules/juce_graphics/native \ | |||
| ../modules/juce_gui_basics/juce_gui_basics.h \ | |||
| ../modules/juce_gui_basics/juce_gui_basics.cpp \ | |||
| ../modules/juce_gui_basics/native \ | |||
| ../modules/juce_gui_extra/juce_gui_extra.h \ | |||
| ../modules/juce_gui_extra/juce_gui_extra.cpp \ | |||
| ../modules/juce_gui_extra/native \ | |||
| ../modules/juce_opengl/juce_opengl.h \ | |||
| ../modules/juce_opengl/juce_opengl.cpp \ | |||
| ../modules/juce_opengl/native \ | |||
| ../modules/juce_tracktion_marketplace/juce_tracktion_marketplace.h \ | |||
| ../modules/juce_video/juce_video.h \ | |||
| ../modules/juce_video/juce_video.cpp \ | |||
| ../modules/juce_video/native \ | |||
| ../modules/juce_dsp/juce_dsp.h \ | |||
| ../modules/juce_dsp/juce_dsp.cpp | |||
| EXCLUDE = build/juce_graphics/image_formats \ | |||
| build/juce_core/zip/zlib \ | |||
| build/juce_audio_formats/codecs/flac \ | |||
| build/juce_audio_formats/codecs/oggvorbis \ | |||
| build/juce_audio_devices/native \ | |||
| build/juce_audio_plugin_client/AU/CoreAudioUtilityClasses \ | |||
| build/juce_browser_plugin_client/juce_browser_plugin.h \ | |||
| build/juce_core/native \ | |||
| build/juce_events/native \ | |||
| build/juce_graphics/native \ | |||
| build/juce_gui_basics/native \ | |||
| build/juce_gui_extra/native \ | |||
| build/juce_opengl/native \ | |||
| build/juce_video/native \ | |||
| build/juce_dsp/native | |||
| # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or | |||
| # directories that are symbolic links (a Unix file system feature) are excluded | |||
| @@ -1129,7 +1109,7 @@ HTML_HEADER = | |||
| # that doxygen normally uses. | |||
| # This tag requires that the tag GENERATE_HTML is set to YES. | |||
| HTML_FOOTER = footer.html | |||
| HTML_FOOTER = | |||
| # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style | |||
| # sheet that is used by each HTML page. It can be used to fine-tune the look of | |||
| @@ -1198,8 +1178,9 @@ HTML_COLORSTYLE_GAMMA = 80 | |||
| # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML | |||
| # page will contain the date and time when the page was generated. Setting this | |||
| # to NO can help when comparing the output of multiple runs. | |||
| # The default value is: YES. | |||
| # to YES can help to show when doxygen was last run and thus if the | |||
| # documentation is up to date. | |||
| # The default value is: NO. | |||
| # This tag requires that the tag GENERATE_HTML is set to YES. | |||
| HTML_TIMESTAMP = YES | |||
| @@ -1673,9 +1654,12 @@ COMPACT_LATEX = NO | |||
| PAPER_TYPE = a4wide | |||
| # The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names | |||
| # that should be included in the LaTeX output. To get the times font for | |||
| # instance you can specify | |||
| # EXTRA_PACKAGES=times | |||
| # that should be included in the LaTeX output. The package can be specified just | |||
| # by its name or with the correct syntax as to be used with the LaTeX | |||
| # \usepackage command. To get the times font for instance you can specify : | |||
| # EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} | |||
| # To use the option intlimits with the amsmath package you can specify: | |||
| # EXTRA_PACKAGES=[intlimits]{amsmath} | |||
| # If left blank no extra packages will be included. | |||
| # This tag requires that the tag GENERATE_LATEX is set to YES. | |||
| @@ -2057,9 +2041,12 @@ PREDEFINED = WIN32=1 \ | |||
| JUCE_LINUX=1 \ | |||
| DOXYGEN=1 \ | |||
| JUCE_COMPILER_SUPPORTS_NOEXCEPT=1 \ | |||
| JUCE_COMPILER_SUPPORTS_NULLPTR=1 \ | |||
| JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS=1 \ | |||
| JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS=1 \ | |||
| JUCE_COMPILER_SUPPORTS_VARIADIC_TEMPLATES=1 \ | |||
| JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL=1 \ | |||
| JUCE_COMPILER_SUPPORTS_LAMBDAS=1 \ | |||
| JUCE_MODAL_LOOPS_PERMITTED=1 | |||
| # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this | |||
| @@ -2175,7 +2162,7 @@ HIDE_UNDOC_RELATIONS = YES | |||
| # set to NO | |||
| # The default value is: NO. | |||
| HAVE_DOT = NO | |||
| HAVE_DOT = YES | |||
| # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed | |||
| # to run in parallel. When set to 0 doxygen will base this on the number of | |||
| @@ -2287,7 +2274,8 @@ INCLUDED_BY_GRAPH = NO | |||
| # | |||
| # Note that enabling this option will significantly increase the time of a run. | |||
| # So in most cases it will be better to enable call graphs for selected | |||
| # functions only using the \callgraph command. | |||
| # functions only using the \callgraph command. Disabling a call graph can be | |||
| # accomplished by means of the command \hidecallgraph. | |||
| # The default value is: NO. | |||
| # This tag requires that the tag HAVE_DOT is set to YES. | |||
| @@ -2298,7 +2286,8 @@ CALL_GRAPH = NO | |||
| # | |||
| # Note that enabling this option will significantly increase the time of a run. | |||
| # So in most cases it will be better to enable caller graphs for selected | |||
| # functions only using the \callergraph command. | |||
| # functions only using the \callergraph command. Disabling a caller graph can be | |||
| # accomplished by means of the command \hidecallergraph. | |||
| # The default value is: NO. | |||
| # This tag requires that the tag HAVE_DOT is set to YES. | |||
| @@ -2321,15 +2310,19 @@ GRAPHICAL_HIERARCHY = NO | |||
| DIRECTORY_GRAPH = NO | |||
| # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images | |||
| # generated by dot. | |||
| # generated by dot. For an explanation of the image formats see the section | |||
| # output formats in the documentation of the dot tool (Graphviz (see: | |||
| # http://www.graphviz.org/)). | |||
| # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order | |||
| # to make the SVG files visible in IE 9+ (other browsers do not have this | |||
| # requirement). | |||
| # Possible values are: png, jpg, gif and svg. | |||
| # Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, | |||
| # png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and | |||
| # png:gdiplus:gdiplus. | |||
| # The default value is: png. | |||
| # This tag requires that the tag HAVE_DOT is set to YES. | |||
| DOT_IMAGE_FORMAT = png | |||
| DOT_IMAGE_FORMAT = svg | |||
| # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to | |||
| # enable generation of interactive SVG images that allow zooming and panning. | |||
| @@ -2347,7 +2340,7 @@ INTERACTIVE_SVG = NO | |||
| # found. If left blank, it is assumed the dot tool can be found in the path. | |||
| # This tag requires that the tag HAVE_DOT is set to YES. | |||
| DOT_PATH = | |||
| DOT_PATH = | |||
| # The DOTFILE_DIRS tag can be used to specify one or more directories that | |||
| # contain dot files that are included in the documentation (see the \dotfile | |||
| @@ -2415,7 +2408,7 @@ MAX_DOT_GRAPH_DEPTH = 0 | |||
| # The default value is: NO. | |||
| # This tag requires that the tag HAVE_DOT is set to YES. | |||
| DOT_TRANSPARENT = NO | |||
| DOT_TRANSPARENT = YES | |||
| # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output | |||
| # files in one run (i.e. multiple -o and -T options on the command line). This | |||
| @@ -2432,7 +2425,7 @@ DOT_MULTI_TARGETS = NO | |||
| # The default value is: YES. | |||
| # This tag requires that the tag HAVE_DOT is set to YES. | |||
| GENERATE_LEGEND = YES | |||
| GENERATE_LEGEND = NO | |||
| # If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot | |||
| # files that are used to generate the various graphs. | |||
| @@ -0,0 +1,16 @@ | |||
| SHELL := /bin/bash | |||
| SOURCE_FILES := $(shell find ../modules -type f -name "juce_*.h" -or -name "juce_*.dox" | sed 's/ /\\ /g') | |||
| .PHONEY: clean | |||
| doc/index.html: build/juce_modules.dox Doxyfile | |||
| doxygen | |||
| build/juce_modules.dox: process_source_files.py $(SOURCE_FILES) | |||
| rm -rf build | |||
| python $< ../modules build | |||
| clean: | |||
| rm -rf build doc | |||
| @@ -6,5 +6,5 @@ How to: | |||
| 1. install doxygen | |||
| 2. cd into this directory on the command line | |||
| 3. run doxygen (no additional arguments needed) | |||
| 4. doxygen will create a new subfolder "doc". Open doc/index.html in your browser to access the generated HTML documentation. | |||
| 3. run `make` | |||
| 4. doxygen will create a new subfolder "doc" - open doc/index.html in your browser to access the generated HTML documentation | |||
| @@ -1,14 +0,0 @@ | |||
| <hr class="footer"/> | |||
| <address class="footer"><small>All content © ROLI Ltd.</small></address><br/> | |||
| <script type="text/javascript"> | |||
| var _gaq = _gaq || []; | |||
| _gaq.push(['_setAccount', 'UA-19759318-1']); | |||
| _gaq.push(['_trackPageview']); | |||
| (function() { | |||
| var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; | |||
| ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; | |||
| var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); | |||
| })(); | |||
| </script> | |||
| </body> | |||
| </html> | |||
| @@ -0,0 +1,174 @@ | |||
| #!/usr/bin/env python | |||
| import os | |||
| import shutil | |||
| import re | |||
| import argparse | |||
| def get_curly_brace_scope_end(string, start_pos): | |||
| """Given a string and the position of an opening curly brace, find the | |||
| position of the closing brace. | |||
| """ | |||
| if string[start_pos] != "{": | |||
| raise ValueError("string must have \"{\" at start pos") | |||
| string_end = len(string) | |||
| bracket_counter = 1 | |||
| start_pos += 1 | |||
| while start_pos < string_end: | |||
| if string[start_pos] == "{": | |||
| bracket_counter += 1 | |||
| elif string[start_pos] == "}": | |||
| bracket_counter -= 1 | |||
| if bracket_counter == 0: | |||
| return start_pos | |||
| start_pos += 1 | |||
| return -1 | |||
| def add_doxygen_group(path, group_name): | |||
| """Add a Doxygen group to the file at 'path'. | |||
| Namespaces cause all kinds of problems, and we need to ensure that if | |||
| the classes in a source file are contained within a namespace then we | |||
| also put the @weakgroup inside the namespace. | |||
| """ | |||
| filename = os.path.basename(path) | |||
| if re.match(r"^juce_.*\.(h|dox)", filename): | |||
| group_definition_start = ("\r\n/** @weakgroup " | |||
| + group_name | |||
| + "\r\n * @{\r\n */\r\n") | |||
| group_definition_end = "\r\n/** @}*/\r\n" | |||
| with open(path, "r") as f: | |||
| content = f.read() | |||
| # Put the group definitions inside all namespaces. | |||
| namespace_regex = re.compile(r"\s+namespace\s+\S+\s+{") | |||
| match = namespace_regex.search(content) | |||
| while (match is not None): | |||
| namespace_end = get_curly_brace_scope_end(content, match.end() - 1) | |||
| if namespace_end == -1: | |||
| raise ValueError("error finding end of namespace " | |||
| + match.group() | |||
| + " in " | |||
| + path) | |||
| content = (content[:match.end()] | |||
| + group_definition_start | |||
| + content[match.end():namespace_end] | |||
| + group_definition_end | |||
| + content[namespace_end:]) | |||
| search_start = (namespace_end | |||
| + len(group_definition_start) | |||
| + len(group_definition_end)) | |||
| match = namespace_regex.search(content, search_start) | |||
| with open(path, "w") as f: | |||
| f.write(group_definition_start) | |||
| f.write(content) | |||
| f.write(group_definition_end) | |||
| ############################################################################### | |||
| if __name__ == "__main__": | |||
| parser = argparse.ArgumentParser() | |||
| parser.add_argument("source_dir", | |||
| help="the directory to search for source files") | |||
| parser.add_argument("dest_dir", | |||
| help="the directory in which to place processed files") | |||
| parser.add_argument("--subdirs", | |||
| help="if specified, only include these comma separated" | |||
| "subdirectories") | |||
| args = parser.parse_args() | |||
| # Get the list of JUCE modules to include. | |||
| if args.subdirs: | |||
| juce_modules = args.subdirs.split(",") | |||
| else: | |||
| juce_modules = [] | |||
| for item in os.listdir(args.source_dir): | |||
| if os.path.isdir(os.path.join(args.source_dir, item)): | |||
| juce_modules.append(item) | |||
| # Copy the JUCE modules to the temporary directory, and process the source | |||
| # files. | |||
| module_definitions = [] | |||
| for module_name in juce_modules: | |||
| # Copy the required modules. | |||
| original_module_dir = os.path.join(args.source_dir, module_name) | |||
| module_path = os.path.join(args.dest_dir, module_name) | |||
| shutil.copytree(original_module_dir, module_path) | |||
| # Parse the module header to get module information. | |||
| module_header = os.path.join(module_path, module_name + ".h") | |||
| with open(module_header, "r") as f: | |||
| content = f.read() | |||
| block_info_result = re.match(r".*BEGIN_JUCE_MODULE_DECLARATION" | |||
| "(.*)" | |||
| "END_JUCE_MODULE_DECLARATION.*", | |||
| content, | |||
| re.DOTALL) | |||
| detail_lines = [] | |||
| for line in block_info_result.group(1).split("\n"): | |||
| stripped_line = line.strip() | |||
| if stripped_line: | |||
| result = re.match(r"^.*?description:\s*(.*)$", stripped_line) | |||
| if result: | |||
| short_description = result.group(1) | |||
| else: | |||
| detail_lines.append(stripped_line) | |||
| # The module header causes problems for Doxygen, so delete it. | |||
| os.remove(module_header) | |||
| # Create a Doxygen group definition for the module. | |||
| module_definiton = [] | |||
| module_definiton.append("/** @defgroup {n} {n}".format(n=module_name)) | |||
| module_definiton.append(" {d}".format(d=short_description)) | |||
| module_definiton.append("") | |||
| for line in detail_lines: | |||
| module_definiton.append(" - {l}".format(l=line)) | |||
| module_definiton.append("") | |||
| module_definiton.append(" @{") | |||
| module_definiton.append("*/") | |||
| # Create a list of the directories in the module that we can use as | |||
| # subgroups and create the Doxygen group hierarchy string. | |||
| dir_contents = os.listdir(module_path) | |||
| subdirs = [x for x in dir_contents | |||
| if os.path.isdir(os.path.join(module_path, x))] | |||
| module_groups = {} | |||
| for subdir in subdirs: | |||
| subgroup_name = "{n}-{s}".format(n=module_name, s=subdir) | |||
| module_groups[subgroup_name] = os.path.join(module_path, subdir) | |||
| module_definiton.append("") | |||
| module_definiton.append( | |||
| "/** @defgroup {tag} {n} */".format(tag=subgroup_name, n=subdir) | |||
| ) | |||
| module_definiton.append("") | |||
| module_definiton.append("/** @} */") | |||
| module_definitions.append("\r\n".join(module_definiton)) | |||
| # Put the top level files into the main group. | |||
| for filename in (set(dir_contents) - set(subdirs)): | |||
| add_doxygen_group(os.path.join(module_path, filename), module_name) | |||
| # Put subdirectory files into their respective groups. | |||
| for group_name in module_groups: | |||
| for dirpath, dirnames, filenames in os.walk(module_groups[group_name]): | |||
| for filename in filenames: | |||
| try: | |||
| add_doxygen_group(os.path.join(dirpath, filename), group_name) | |||
| except: | |||
| print("Error preprocessing " + filename) | |||
| continue | |||
| # Create an extra header file containing the module hierarchy. | |||
| with open(os.path.join(args.dest_dir, "juce_modules.dox"), "w") as f: | |||
| f.write("\r\n\r\n".join(module_definitions)) | |||
| @@ -1,6 +1,8 @@ | |||
| SHELL := /bin/bash | |||
| SOURCE_FILES := $(shell find ../../../modules -type f -name "juce_*.h" | sed 's/ /\\ /g') | |||
| INCLUDED_MODULES := juce_audio_basics,juce_audio_devices,juce_blocks_basics,juce_core,juce_events | |||
| SOURCE_FILES := $(shell find ../../../modules -type f -name "juce_*.h" -or -name "juce_*.dox"| sed 's/ /\\ /g') | |||
| EXAMPLE_DIRS := ../standalone_sdk/examples ../../../examples/BLOCKS | |||
| EXAMPLE_SOURCE_FILES := $(foreach DIR,$(EXAMPLE_DIRS),$(shell find $(DIR) -type f -name "*.h" -or -name "*.cpp" | sed 's/ /\\ /g')) | |||
| DOCUMENTATION_FILES := $(shell find pages -type f -name "*.dox" | sed 's/ /\\ /g') | |||
| @@ -11,8 +13,9 @@ IMAGES := $(shell find images -type f | sed 's/ /\\ /g') | |||
| doc/index.html: build/juce_modules.dox Doxyfile DoxygenLayout.xml footer.html header.html stylesheet.css $(DOCUMENTATION_FILES) $(EXAMPLE_SOURCE_FILES) $(IMAGES) | |||
| doxygen | |||
| build/juce_modules.dox: process_source_files.py $(SOURCE_FILES) | |||
| python $< | |||
| build/juce_modules.dox: ../../../doxygen/process_source_files.py $(SOURCE_FILES) | |||
| rm -rf build | |||
| python $< ../../../modules build --subdirs=$(INCLUDED_MODULES) | |||
| clean: | |||
| rm -rf build doc | |||
| @@ -1,163 +0,0 @@ | |||
| import os | |||
| import shutil | |||
| import re | |||
| def get_curly_brace_scope_end(string, start_pos): | |||
| """Given a string and the position of an opening curly brace, find the | |||
| position of the closing brace. | |||
| """ | |||
| if string[start_pos] != "{": | |||
| raise ValueError("string must have \"{\" at start pos") | |||
| string_end = len(string) | |||
| bracket_counter = 1 | |||
| start_pos += 1 | |||
| while start_pos < string_end: | |||
| if string[start_pos] == "{": | |||
| bracket_counter += 1 | |||
| elif string[start_pos] == "}": | |||
| bracket_counter -= 1 | |||
| if bracket_counter == 0: | |||
| return start_pos | |||
| start_pos += 1 | |||
| return -1 | |||
| def add_doxygen_group(path, group_name): | |||
| """Add a Doxygen group to the file at 'path'. | |||
| Namespaces cause all kinds of problems, and we need to ensure that if | |||
| the classes in a source file are contained within a namespace then we | |||
| also put the @weakgroup inside. | |||
| """ | |||
| filename = os.path.basename(path) | |||
| if filename.startswith("juce_") and filename.endswith(".h"): | |||
| group_definition_start = ("\r\n/** @weakgroup " | |||
| + group_name | |||
| + "\r\n * @{\r\n */\r\n") | |||
| group_definition_end = "\r\n/** @}*/\r\n" | |||
| with open(path, "r") as f: | |||
| content = f.read() | |||
| # Put the group definitions inside all namespaces. | |||
| namespace_regex = re.compile(r"\s+namespace\s+\S+\s+{") | |||
| match = namespace_regex.search(content) | |||
| while (match is not None): | |||
| namespace_end = get_curly_brace_scope_end(content, match.end() - 1) | |||
| if namespace_end == -1: | |||
| raise ValueError("error finding end of namespace " | |||
| + match.group() | |||
| + " in " | |||
| + path) | |||
| content = (content[:match.end()] | |||
| + group_definition_start | |||
| + content[match.end():namespace_end] | |||
| + group_definition_end | |||
| + content[namespace_end:]) | |||
| search_start = (namespace_end | |||
| + len(group_definition_start) | |||
| + len(group_definition_end)) | |||
| match = namespace_regex.search(content, search_start) | |||
| with open(path, "w") as f: | |||
| f.write(group_definition_start) | |||
| f.write(content) | |||
| f.write(group_definition_end) | |||
| ############################################################################### | |||
| # Get the list of JUCE modules to include. | |||
| juce_modules = ("juce_audio_basics", "juce_audio_devices", | |||
| "juce_blocks_basics", "juce_core", "juce_events") | |||
| # A temporary directory to hold our preprocessed source files. | |||
| build_directory = "build" | |||
| # Make sure we have a clean temporary directory. | |||
| try: | |||
| shutil.rmtree(build_directory) | |||
| except OSError as e: | |||
| if e.errno != 2: | |||
| # An errno of 2 indicates that the directory does not exist, which is | |||
| # fine! | |||
| raise e | |||
| # Copy the JUCE modules to the temporary directory, and process the source | |||
| # files. | |||
| module_definitions = [] | |||
| for module_name in juce_modules: | |||
| # Copy the required modules. | |||
| original_module_dir = os.path.join("..", "..", "..", "modules", | |||
| module_name) | |||
| module_path = os.path.join(build_directory, module_name) | |||
| shutil.copytree(original_module_dir, module_path) | |||
| # Parse the module header to get module information. | |||
| module_header = os.path.join(module_path, module_name + ".h") | |||
| with open(module_header, "r") as f: | |||
| content = f.read() | |||
| block_info_result = re.match(r".*BEGIN_JUCE_MODULE_DECLARATION" | |||
| "(.*)" | |||
| "END_JUCE_MODULE_DECLARATION.*", | |||
| content, | |||
| re.DOTALL) | |||
| detail_lines = [] | |||
| for line in block_info_result.group(1).split("\n"): | |||
| stripped_line = line.strip() | |||
| if stripped_line: | |||
| result = re.match(r"^.*?description:\s*(.*)$", stripped_line) | |||
| if result: | |||
| short_description = result.group(1) | |||
| else: | |||
| detail_lines.append(stripped_line) | |||
| # The module header causes problems for Doxygen, so delete it. | |||
| os.remove(module_header) | |||
| # Create a Doxygen group definition for the module. | |||
| module_definiton = [] | |||
| module_definiton.append("/** @defgroup {n} {n}".format(n=module_name)) | |||
| module_definiton.append(" {d}".format(d=short_description)) | |||
| module_definiton.append("") | |||
| for line in detail_lines: | |||
| module_definiton.append(" - {l}".format(l=line)) | |||
| module_definiton.append("") | |||
| module_definiton.append(" @{") | |||
| module_definiton.append("*/") | |||
| # Create a list of internal directories we can use as subgroups and create | |||
| # the Doxygen group hierarchy string. | |||
| dir_contents = os.listdir(module_path) | |||
| subdirs = [x for x in dir_contents | |||
| if os.path.isdir(os.path.join(module_path, x))] | |||
| module_groups = {} | |||
| for subdir in subdirs: | |||
| subgroup_name = "{n}-{s}".format(n=module_name, s=subdir) | |||
| module_groups[subgroup_name] = os.path.join(module_path, subdir) | |||
| module_definiton.append("") | |||
| module_definiton.append( | |||
| "/** @defgroup {tag} {n} */".format(tag=subgroup_name, n=subdir) | |||
| ) | |||
| module_definiton.append("") | |||
| module_definiton.append("/** @} */") | |||
| module_definitions.append("\r\n".join(module_definiton)) | |||
| # Put the top level files into the main group. | |||
| for filename in (set(dir_contents) - set(subdirs)): | |||
| add_doxygen_group(os.path.join(module_path, filename), module_name) | |||
| # Put subdirectory files into their respective groups. | |||
| for group_name in module_groups: | |||
| for dirpath, dirnames, filenames in os.walk(module_groups[group_name]): | |||
| for filename in filenames: | |||
| add_doxygen_group(os.path.join(dirpath, filename), group_name) | |||
| # Create an extra header file containing the module hierarchy. | |||
| with open(os.path.join(build_directory, "juce_modules.dox"), "w") as f: | |||
| f.write("\r\n\r\n".join(module_definitions)) | |||