From f07e60916d938d0d3a6d0f074b3c4d06b56af822 Mon Sep 17 00:00:00 2001 From: rillig Date: Sat, 5 Jan 2008 17:55:48 +0000 Subject: Rewrote the help parser. You can get a list of all help topics by running "bmake help topic=:index" now. This change is in preparation of importing this help into the pkgsrc guide. There are still too many false positives to be useful. --- mk/help/help.awk | 90 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 29 deletions(-) (limited to 'mk') diff --git a/mk/help/help.awk b/mk/help/help.awk index ba20c582206..a953d111eaa 100644 --- a/mk/help/help.awk +++ b/mk/help/help.awk @@ -1,4 +1,4 @@ -# $NetBSD: help.awk,v 1.19 2008/01/05 17:01:23 rillig Exp $ +# $NetBSD: help.awk,v 1.20 2008/01/05 17:55:48 rillig Exp $ # # This program extracts the inline documentation from *.mk files. @@ -15,50 +15,67 @@ BEGIN { found_anything = no; # has some help text been found at all? last_fname = ""; - this_line_maybe_definition = yes; ignore_this_line = no; ignore_next_empty_line = no; + ignore_this_section = no; delete lines; # the collected lines nlines = 0; # the number of lines collected so far delete keywords; # the keywords for this paragraph + delete all_keywords; # all keywords that appear anywhere comment_lines = 0; # the number of comment lines so far print_noncomment_lines = yes; # for make targets, this isn't useful + print_index = (topic == ":index"); + # whether to print only the list of keywords } # Help topics are separated by either completely empty lines or by the # end of a file or by the end of all files. When there have been enough # comment lines, the topic is considered worth printing. # -function end_of_topic( kw, relevant) { - kw = ""; - for (i in keywords) { - kw = kw " " i; +function end_of_topic() { + + if (comment_lines <= 2 || ignore_this_section) { + cleanup(); + return; } + + for (k in keywords) + all_keywords[k]++; + relevant = (topic in keywords || lctopic in keywords || uctopic in keywords); - if (relevant && comment_lines > 2) { + if (relevant && !print_index) { + if (found_anything) print ""; found_anything = yes; + + kw = ""; + for (i in keywords) + kw = kw " " i; print "===> "last_fname " (keywords:" kw "):"; + for (i = 0; i < nlines; i++) { if (print_noncomment_lines || (lines[i] ~ /^#/)) print lines[i]; } } + cleanup(); +} +function cleanup() { ignore_next_empty_line = yes; delete lines; nlines = 0; delete keywords; comment_lines = 0; print_noncomment_lines = yes; + ignore_this_section = no; } always { ignore_this_line = (ignore_next_empty_line && $0 == "#") || $0 == ""; ignore_next_empty_line = no; - this_line_is_definition = no; } # There is no need to print the RCS Id, since the full pathname @@ -86,6 +103,10 @@ always { ignore_next_empty_line = no; } +$1 == "#" && $2 == "Copyright" { + ignore_this_section = yes; +} + # Don't show the user the definition of make targets, since they are # usually not interesting enough. This allows the comments to reach # until the line directly above the target definition. @@ -102,30 +123,38 @@ $1 ~ /:$/ && $2 == ".PHONY" { # be all-lowercase (make targets) or all-uppercase (variable names). # Everything else is assumed to belong to the explaining text. # -NF >= 1 { +NF >= 1 && !/^[\t.]/ && !/^#*$/ { + w = $1 == "#" ? $2 : $1; + # Reduce FOO. and FOO.${param} to FOO. - w1 = $1; sub(/\.[<$].*[>}]$/, "", w1); - w2 = $2; sub(/\.[<$].*[>}]$/, "", w2); - - # Convert all-lowercase words to all-uppercase. - w1 = (w1 == tolower(w1)) ? toupper(w1) : w1; - w2 = (w2 == tolower(w2)) ? toupper(w2) : w2; - - this_line_is_definition = (w1 == toupper($1)) && (w2 == toupper($2)); - - w = (w1 == "#") ? w2 : w1; - if ((w1 == uctopic"?=") || - (w1 == uctopic"=") || - (index(w1, "#"uctopic"=") == 1) || - (index(w1, "#"uctopic"?=") == 1) || - (this_line_maybe_definition && - (w == uctopic || w == uctopic":"))) { - keywords[w] = yes; + sub(/\.[<$].*[>}]$/, "", w); + + if (w ~ /\+=$/) { + # Appending to a variable is usually not a definition. + + } else if (!(w == toupper(w)) || (w == tolower(w) && w ~ /:$/)) { + # Automatic keywords must be either upper- or lower-case. + # Lower-case keywords (make targets) must end with a colon. + + } else if (w !~ /^[A-Za-z].*[0-9A-Za-z]$/) { + # Keywords must start with a letter and end with a letter + # or digit. + + } else if (w ~ /^(FIXME|TODO|XXX):?$/) { + # These are not keywords. + + } else { + sub(/^#[ \t]*/, "", w); + sub(/\??=.*$/, "", w); + sub(/:$/, "", w); + if (w != "") { + keywords[w] = yes; + } } } # Don't print the implementation of make targets. -$1 == uctopic":" { +$1 ~ /:$/ { print_noncomment_lines = no; } @@ -139,13 +168,16 @@ $1 == "#" { always { # Note: The first "this" actually means the next line. - this_line_maybe_definition = (/^#$/ || /^$/) || this_line_is_definition; last_fname = FILENAME; } END { end_of_topic(); - if (!found_anything) { + if (print_index) { + for (k in all_keywords) { + print all_keywords[k] "\t" k; + } + } else if (!found_anything) { print "No help found for "topic"."; } } -- cgit v1.2.3