diff options
author | José Alburquerque <jaalburqu@svn.gnome.org> | 2012-11-05 14:21:55 -0500 |
---|---|---|
committer | José Alburquerque <jaalburqu@svn.gnome.org> | 2012-11-05 14:21:55 -0500 |
commit | f6b5fbc531137f76f0d8f418a03a2c3d53aad473 (patch) | |
tree | 90b4517c66b77871d2ea63344ee429b14ec9a597 /tools/defs_gen | |
parent | 386ab36df82d1c9ed60028c12b559af4b2aa7dd3 (diff) | |
download | glibmm-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.py | 45 | ||||
-rwxr-xr-x | tools/defs_gen/docextract_to_xml.py | 38 |
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()) |