summaryrefslogtreecommitdiff
path: root/mk/help/help.awk
blob: 4cb5f97b676aa2733a657efca5116cbdb71e9842 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# $NetBSD: help.awk,v 1.10 2007/01/14 16:42:37 rillig Exp $
#

# This program extracts the inline documentation from *.mk files.
#
# usage: env TOPIC="topic" awk help.awk file...
#

BEGIN {
	no = 0; yes = 1; always = 1;

	topic = ENVIRON["TOPIC"];
	uctopic = toupper(topic);
	lctopic = tolower(topic);

	found_anything = no;	# has some help text been found at all?
	last_fname = "";
	last_line_was_empty = yes;
	ignore_this_line = no;
	ignore_next_empty_line = no;

	delete lines;		# the collected lines
	relevant = no;		# are the current lines relevant?
	nlines = 0;		# the number of lines collected so far
	comment_lines = 0;	# the number of comment lines so far
	print_noncomment_lines = yes; # for make targets, this isn't useful
}

# Help topics are separated by either completely empty lines or by the
# end of a file or by the end of all files. When here have been enough
# comment lines, the topic is considered worth printing.
#
function end_of_topic() {
	if (relevant && comment_lines > 2) {
		found_anything = yes;
		print "===> "last_fname":";
		for (i = 0; i < nlines; i++) {
			if (print_noncomment_lines || (lines[i] ~ /^#/))
				print lines[i];
		}
	}

	ignore_next_empty_line = yes;
	delete lines;
	relevant = no;
	nlines = 0;
	comment_lines = 0;
	print_noncomment_lines = yes;
}

always {
	ignore_this_line = (ignore_next_empty_line && $0 == "#") || $0 == "";
	ignore_next_empty_line = no;
}

# There is no need to print the RCS Id, since the full pathname
# is prefixed to the file contents.
/^#.*\$.*\$$/ {
	ignore_this_line = yes;
	ignore_next_empty_line = yes;
}

# The lines containing the keywords should also not appear in
# the output for now. This decision is not final since it may
# be helpful for the user to know by which keywords a topic
# can be reached.
($1 == "#" && $2 == "Keywords:") {
	for (i = 3; i <= NF; i++) {
		w = ($i == toupper($i)) ? tolower($i) : $i;
		if (w == lctopic) {
			relevant = yes;
		}
	}
	ignore_this_line = yes;
	ignore_next_empty_line = yes;
}

($0 == "#") {
	ignore_next_empty_line = no;
}

(!ignore_this_line) {
	lines[nlines++] = $0;
}

# Check whether the current line contains a keyword. Such a keyword must
# be all-lowercase (make targets) or all-uppercase (variable names).
# Everything else is assumed to belong to the explaining text.
#
NF >= 2 {
	w1 = ($1 == tolower($1)) ? toupper($1) : $1;
	w2 = ($2 == tolower($2)) ? toupper($2) : $2;

	if ((w1 == uctopic"?=") ||
	    (w1 == uctopic"=") ||
	    (index(w1, "#"uctopic"=") == 1) ||
	    (index(w1, "#"uctopic"?=") == 1) ||
	    (last_line_was_empty && w1 == "#" && (w2 == uctopic ||
						  w2 == uctopic":"))) {
		relevant = yes;
	}
}

# Don't print the implementation of make targets.
$1 == uctopic":" {
	print_noncomment_lines = no;
}

$1 == "#" {
	comment_lines++;
}

/^$/ || last_fname != FILENAME {
	end_of_topic();
}

always {
	last_line_was_empty = (/^#$/ || /^$/);
	last_fname = FILENAME;
}

END {
	end_of_topic();
	if (!found_anything) {
		print "No help found for "topic".";
	}
}