summaryrefslogtreecommitdiff
path: root/tools/defs_gen
diff options
context:
space:
mode:
authorJosé Alburquerque <jaalburqu@svn.gnome.org>2012-11-05 14:21:55 -0500
committerJosé Alburquerque <jaalburqu@svn.gnome.org>2012-11-05 14:21:55 -0500
commitf6b5fbc531137f76f0d8f418a03a2c3d53aad473 (patch)
tree90b4517c66b77871d2ea63344ee429b14ec9a597 /tools/defs_gen
parent386ab36df82d1c9ed60028c12b559af4b2aa7dd3 (diff)
downloadglibmm-f6b5fbc531137f76f0d8f418a03a2c3d53aad473.tar.gz
gmmproc: Make enum documentation possible.
* tools/defs_gen/docextract.py (enum_name_pattern): Add a new regular expression that recognizes gtk-doc enum comment blocks (though imperfectly because it also catches things such as structure comment blocks). (identifier_patterns): Append the new enum_name_pattern to the list of patterns used to test each gtk-doc block's identifier to see what type of block it is. (parse_file): Do not add a particular gtk-doc block if it has been marked as a block initially thought to be an enum comment block but later found not to be so. (skip_to_identifier): Mark the current comment block as an enum type if the enum_name_pattern matches the identifier. (process_params): Mark the current block as invalid if the block was recognized as an enum type but no parameters are found or if any of the parameter names are not all caps. (parse_dir): Include .h files for processing because gtk-doc enum comment blocks are included in those files. * tools/defs_gen/docextract_to_xml.py: Add an option to not print out enum docs. Assume that enum docs should be printed out by default. * tools/pm/DocsParser.pm (parse_on_start): (parse_on_end): Add logic to correctly parse an <enum> tag (which is just like the already existing <function> and <signal> tags. The only difference is in the name of the tags. The function name syntax is the same as a C function name, the signal name has the form 'CStructName::signal-name' while the enum name has the form 'CEnumName') (lookup_enum_description): Add this subroutine that gets the the description of the specified enum. (lookup_enum_value_documentation): Add this subroutine that gets the description of an enum value as a Doxygen block. (lookup_documentation): Use the new remove_example_code subroutine described below. (remove_example_code): Add this subroutine that removes example code from the specified text so that it can be used in other places. * tools/pm/Enum.pm (c_prefix): Add a new field to the class storing the enum's C prefix. This field is used when looking up an enum's value documentation. (parse_values): Modified to store the C prefix of the enum. (build_element_list): Modified to lookup the documentation of the values of the enum and insert the Doxygen block just before each value. This allows Doxygen to document each value of the enum. * tools/pm/Output.pm (output_wrap_enum): Modified to lookup the description of the enum previously parsed by the DocParser and merge it with an already passed in comment for the enum which is then passed as before to the _ENUM macro. * tools/m4/enum.m4: Whitespace correction. Bug #544694.
Diffstat (limited to 'tools/defs_gen')
-rw-r--r--tools/defs_gen/docextract.py45
-rwxr-xr-xtools/defs_gen/docextract_to_xml.py38
2 files changed, 58 insertions, 25 deletions
diff --git a/tools/defs_gen/docextract.py b/tools/defs_gen/docextract.py
index 13beeffb..19204dea 100644
--- a/tools/defs_gen/docextract.py
+++ b/tools/defs_gen/docextract.py
@@ -17,7 +17,8 @@ __all__ = ['extract']
class GtkDoc:
def __init__(self):
self.name = None
- self.block_type = '' # The block type ('function', 'signal', 'property')
+ # The block type ('function', 'signal', property', 'enum')
+ self.block_type = ''
self.params = []
self.annotations = []
self.description = ''
@@ -63,6 +64,7 @@ comment_empty_line_pattern = re.compile(r'^\s*\**\s*$')
function_name_pattern = re.compile(r'^([a-z]\w*)\s*:?(\s*\(.*\)\s*){0,2}\s*$')
signal_name_pattern = re.compile(r'^([A-Z]\w+::[a-z0-9-]+)\s*:?(\s*\(.*\)\s*){0,2}\s*$')
property_name_pattern = re.compile(r'^([A-Z]\w+:[a-z0-9-]+)\s*:?(\s*\(.*\)\s*){0,2}\s*$')
+enum_name_pattern = re.compile(r'^([A-Z]\w+)\s*:?(\s*\(.*\)\s*){0,2}\s*$')
return_pattern = re.compile(r'^@?(returns:|return\s+value:)(.*\n?)$', re.IGNORECASE)
deprecated_pattern = re.compile(r'^(deprecated\s*:\s*.*\n?)$', re.IGNORECASE)
rename_to_pattern = re.compile(r'^(rename\s+to)\s*:\s*(.*\n?)$', re.IGNORECASE)
@@ -77,7 +79,7 @@ annotation_lead_pattern = re.compile(r'^\s*\(\s*(.*?)\s*\)\s*')
# are grouped in a list for easy determination of block identifiers (in
# skip_to_identifier). The function_name_pattern should be tested for last
# because it always matches signal and property identifiers.
-identifier_patterns = [ signal_name_pattern, property_name_pattern, function_name_pattern ]
+identifier_patterns = [ signal_name_pattern, property_name_pattern, enum_name_pattern, function_name_pattern ]
# This pattern is to match return sections that forget to have a colon (':')
# after the initial 'Return' phrase. It is not included by default in the list
@@ -106,8 +108,14 @@ def parse_file(fp, doc_dict):
line = process_params(fp, line, cur_doc)
line = process_description(fp, line, cur_doc)
line = process_final_sections(fp, line, cur_doc)
- # Add the current doc block to the dictionary of doc blocks.
- doc_dict[cur_doc.name] = cur_doc
+
+ # Add the current doc block to the dictionary of doc blocks. If
+ # this block was initially recognized as an 'enum' block in
+ # skip_to_identifier(), the process_params() function will mark the
+ # block as invalid if enum members are not all caps. In that case
+ # do not add the block.
+ if cur_doc.get_type() != 'invalid':
+ doc_dict[cur_doc.name] = cur_doc
# Given a list of annotations as string of the form
# '(annotation1) (annotation2) ...' return a list of annotations of the form
@@ -153,9 +161,9 @@ def skip_to_nonblank(fp, line):
# Given the first line of a comment block (the '/**'), see if the next
# non-blank line is the identifier of the comment block. Stop processing if
# the end of the block or eof is reached. Store the identifier (if there is
-# one) and its type ('function', 'signal' or 'property') in the given GtkDoc.
-# Return the line where the identifier is found or the line that stops the
-# processing (if eof or the end of the comment block is found first).
+# one) and its type ('function', 'signal' or 'property', 'enum') in the given
+# GtkDoc. Return the line where the identifier is found or the line that stops
+# the processing (if eof or the end of the comment block is found first).
def skip_to_identifier(fp, line, cur_doc):
# Skip the initial comment block line ('/**') if not eof.
if line: line = fp.readline()
@@ -182,6 +190,8 @@ def skip_to_identifier(fp, line, cur_doc):
cur_doc.set_type('signal')
elif pattern == property_name_pattern:
cur_doc.set_type('property')
+ elif pattern == enum_name_pattern:
+ cur_doc.set_type('enum')
elif pattern == function_name_pattern:
cur_doc.set_type('function')
return line
@@ -198,6 +208,10 @@ def process_params(fp, line, cur_doc):
if line: line = fp.readline()
line = skip_to_nonblank(fp, line)
if not line or comment_end_pattern.match(line):
+ # If there are no parameters and this block has been recognized as an
+ # enum block, then mark it as invalid.
+ if cur_doc.get_type() == 'enum':
+ cur_doc.set_type('invalid')
return line
# Remove initial ' * ' in first non-empty comment block line.
@@ -207,9 +221,20 @@ def process_params(fp, line, cur_doc):
# param section is not reached (which could be triggered by anything that
# doesn't match a '@param:..." line, even the end of the comment block).
match = param_pattern.match(line)
+
+ # Mark the cur_doc type as invalid if no parameters are found.
+ if not match and cur_doc.get_type() == 'enum':
+ cur_doc.set_type('invalid')
+
while line and match:
+ name = match.group(1)
description = match.group(2)
+ # Set the cur_doc type as 'invalid' if the enum member names are not
+ # all caps.
+ if not name.isupper() and cur_doc.get_type() == 'enum':
+ cur_doc.set_type('invalid')
+
# First extract the annotations from the description and save them.
annotations = []
annotation_match = annotations_pattern.match(description)
@@ -224,12 +249,12 @@ def process_params(fp, line, cur_doc):
# See if the return has been included as part of the parameter
# section and make sure that lines are added to the GtkDoc return if
# so.
- if match.group(1).lower() == "returns":
+ if name.lower() == "returns":
cur_doc.add_return(description, annotations)
append_func = cur_doc.append_to_return
# If not, just add it as a regular parameter.
else:
- cur_doc.add_param(match.group(1), description, annotations)
+ cur_doc.add_param(name, description, annotations)
# Now read lines and append them until next parameter, beginning of
# description (an empty line), the end of the comment block or eof.
@@ -403,7 +428,7 @@ def parse_dir(dir, doc_dict):
path = os.path.join(dir, file)
if os.path.isdir(path):
parse_dir(path, doc_dict)
- if len(file) > 2 and file[-2:] == '.c':
+ if len(file) > 2 and (file[-2:] == '.c' or file[-2:] == '.h'):
sys.stderr.write("Processing " + path + '\n')
parse_file(open(path, 'r'), doc_dict)
diff --git a/tools/defs_gen/docextract_to_xml.py b/tools/defs_gen/docextract_to_xml.py
index d77ad6ec..c94c8574 100755
--- a/tools/defs_gen/docextract_to_xml.py
+++ b/tools/defs_gen/docextract_to_xml.py
@@ -17,7 +17,7 @@ def usage():
sys.stderr.write('usage: docextract_to_xml.py ' +
'[-s /src/dir | --source-dir=/src/dir] ' +
'[-a | --with-annotations] [-p | --with-properties] ' +
- '[-i | --no-signals ] [-n | --no-since]\n')
+ '[-n | --no-since] [-i | --no-signals ] [-e | --no-enums ]\n')
sys.exit(1)
# Translates special texts to &... HTML acceptable format. Also replace
@@ -61,10 +61,10 @@ def print_annotations(annotations):
if __name__ == '__main__':
try:
- opts, args = getopt.getopt(sys.argv[1:], "d:s:o:apin",
+ opts, args = getopt.getopt(sys.argv[1:], "d:s:o:apnie",
["source-dir=", "with-annotations",
- "with-properties", "no-signals",
- "no-since"])
+ "with-properties", "no-since",
+ "no-signals", "no-enums"])
except getopt.error, e:
sys.stderr.write('docextract_to_xml.py: %s\n' % e)
usage()
@@ -72,6 +72,7 @@ if __name__ == '__main__':
with_annotations = False
with_signals = True
with_properties = False
+ with_enums = True
for opt, arg in opts:
if opt in ('-s', '--source-dir'):
source_dirs.append(arg)
@@ -79,10 +80,12 @@ if __name__ == '__main__':
with_annotations = True
if opt in ('-p', '--with-properties'):
with_properties = True
- if opt in ('-i', '--no-signals'):
- with_signals = False
if opt in ('-n', '--no-since'):
docextract.no_since = True
+ if opt in ('-i', '--no-signals'):
+ with_signals = False
+ if opt in ('-e', '--no-enums'):
+ with_enums = False
if len(args) != 0:
usage()
@@ -106,6 +109,9 @@ if __name__ == '__main__':
# Likewise for properties.
elif block_type == 'property' and not with_properties:
continue
+ # Likewise for enums.
+ elif block_type == 'enum' and not with_enums:
+ continue
print "<" + block_type + " name=\"" + escape_text(name) + "\">"
@@ -127,15 +133,17 @@ if __name__ == '__main__':
print "</parameters>"
- # Show the return-type (also if not dealing with a property):
- if with_annotations:
- print "<return>"
- print "<return_description>" + escape_text(value.ret[0]) + \
- "</return_description>"
- print_annotations(value.ret[1])
- print "</return>"
- else:
- print "<return>" + escape_text(value.ret[0]) + "</return>"
+ if block_type != 'property' and block_type != 'enum':
+ # Show the return-type (also if not dealing with a property or
+ # enum):
+ if with_annotations:
+ print "<return>"
+ print "<return_description>" + escape_text(value.ret[0]) + \
+ "</return_description>"
+ print_annotations(value.ret[1])
+ print "</return>"
+ else:
+ print "<return>" + escape_text(value.ret[0]) + "</return>"
if with_annotations:
print_annotations(value.get_annotations())