File: libdoc.awk

package info (click to toggle)
unixcw 2.0-6
  • links: PTS
  • area: main
  • in suites: woody
  • size: 764 kB
  • ctags: 645
  • sloc: ansic: 5,693; cpp: 1,736; makefile: 333; sh: 213; awk: 209
file content (172 lines) | stat: -rw-r--r-- 4,654 bytes parent folder | download
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/bin/awk -f
#
# UnixCW - Unix CW (Morse code) training program
# Copyright (C) 2001  Simon Baldwin (simonb@caldera.com)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
#
# Simple AWK script to produce documentation suitable for processing into
# man pages from a C source file.
#

# Initialize the states, arrays, and indices.
BEGIN {
	IDLE			= 0
	DOCUMENTATION		= 1
	FUNCTION_TYPE		= 2
	SPECIFICATION		= 3
	FUNCTION_BODY		= 4
	state			= IDLE

	GLOBAL_TAG		= "G"
	STATIC_TAG		= "S"
	DOCUMENTATION_TAG	= "D"
	FUNCTION_TYPE_TAG	= "T"
	SPECIFICATION_TAG	= "S"
	static			= 0

#	delete output
	output_line		= 0
    }

# Ignore all blank lines in the file
/^[[:space:]]*$/ {
	next
    }

# Handle every other line in the file according to the state.
    {
	# Ignore everything seen while idle.
	if (state == IDLE)
	    {
		# Move to documentation state on seeing '/**'.  Read and
		# discard the two lines that follow, up to '^ *$'.
		if ($0 ~ /^\/\*\*/)
		    {
			static = 0
			state = DOCUMENTATION
			output_line = 0
			while ($0 !~ /^ \* *$/)
				if (getline == 0)
					break;
			next
	    	    }
		next
	    }

	# Catch documentation lines, stopping on ' */'.
	if (state == DOCUMENTATION)
	    {
		# Check for end of the documentation.
		if ($0 ~ /^ \*\//)
		    {
			# Now expecting the function specification, starting
			# with a one-line return type.
			state = FUNCTION_TYPE
		    }
		else
		    {
			# Remove any " * ", and save the line as documentation.
			sub (/^ \* /," *")
			sub (/^ \*/,"")
			output[ output_line++ ] = DOCUMENTATION_TAG" "$0
		    }
		next
	    }

	# Catch the function type, one line after the documentation.
	if (state == FUNCTION_TYPE)
	    {
		output[ output_line++ ] = FUNCTION_TYPE_TAG" "$0
		static = ($0 ~ /static/)
		state = SPECIFICATION
		next
	    }

	# Catch all specification lines, stopping on '{'.
	if (state == SPECIFICATION)
	    {
		# Check for end of the specification.
		if ($0 ~ /^\{/)
			# Now expecting some form of function body.
			state = FUNCTION_BODY
		else
			# Save this line as specification, prepending the
			# function type if we have one.
			output[ output_line++ ] = SPECIFICATION_TAG" "$0
		next
	    }

	# Ignore function lines, but at the end, check for 'run-on'
	# functions.  If any are found, go back to storing specifications,
	# otherwise drop through, since we have something to report.
	if (state == FUNCTION_BODY)
	    {
		# Check for the closing '}' of the function.
		if ($0 ~ /^\}/)
		    {
			# Assume we are going to idle for now.
			state = IDLE

			# Look at the next line, to see if it is a blank
			# line.  If it's not, there is another specification
			# coming.
			if (getline != 0)
				if ($0 !~ /^[[:space:]]*$/)
				    {
					# Set the new state, catch the read
					# specification line, and continue.
					output[ output_line++ ] \
						= FUNCTION_TYPE_TAG" "$0
					static = ($0 ~ /static/)
					state = SPECIFICATION
					next
				    }
		    }
		else
			# Not a closing '}', so still in the function body.
			next
	    }

	# Print out the specification and documentation lines we have found,
	# reordering so that documentation lines come after the function
	# signatures.
	for (i = 0; i < output_line; i++)
		if (index (output[ i ], DOCUMENTATION_TAG) == 0)
			print (static?STATIC_TAG:GLOBAL_TAG)output[ i ]
	for (i = 0; i < output_line; i++)
		if (index (output[ i ], DOCUMENTATION_TAG) != 0)
			print (static?STATIC_TAG:GLOBAL_TAG)output[ i ]
	print (static?STATIC_TAG:GLOBAL_TAG)END_TAG

	# Reset variables and state for the next section.
	state = IDLE

#	delete output
	output_line		= 0
    }

# Simply dump anything we have so far on end of file.
END {
	for (i = 0; i < output_line; i++)
		if (index (output[ i ], DOCUMENTATION_TAG) == 0)
			print (static?STATIC_TAG:GLOBAL_TAG)output[ i ]
	for (i = 0; i < output_line; i++)
		if (index (output[ i ], DOCUMENTATION_TAG) != 0)
			print (static?STATIC_TAG:GLOBAL_TAG)output[ i ]
	if (i > 0)
		print (static?STATIC_TAG:GLOBAL_TAG)END_TAG
}