xref: /freebsd/tools/tools/vop_table/vop_table.pl (revision 7bd6fde3)
1#!/usr/bin/perl
2#
3# Attempt to generate a similar HTML file akin to vop_table.tcl output.
4# This is all fairly poor perl code... but whatever, will be cleaned up
5# in the near future.
6#
7# (c) 2004 Andrew R. Reiter <arr@watson.org>
8# All Rights Reserved.
9#
10# $FreeBSD$
11
12# XXX todo: Make $src_dir modificationable
13
14$src_dir = "/usr/src";
15$srcsys_dir = $src_dir."/sys";
16$vnode_if_awk = $srcsys_dir."/tools/vnode_if.awk";
17$vnode_if_src = $srcsys_dir."/kern/vnode_if.src";
18
19# Temporary input file... generated by a find(1) based command.
20$infile = "/tmp/vt.$$";
21
22# Output HTML
23$outfile = "vop_vectors.html";
24
25# Get a bunch of the vop_ routines out of this file.
26`awk -f $vnode_if_awk $vnode_if_src -q`;
27if ($?) {
28	print "Incapable of writing out the typedef file.\n";
29	exit(1);
30}
31
32# Eat the typedefs file into memory
33open TD, "vnode_if_typedef.h" || die "Unable to open typedef file: $!\n";
34@vop_tdefs = <TD>;
35close TD;
36`rm -f vnode_if_typedef.h`;
37
38# List of available vnode operations
39@available_vn_ops = ();
40push @available_vn_ops, "default";
41foreach $vt (@vop_tdefs) {
42	if ($vt =~ m/typedef\s+(\S+)\s+vop_(\S+)_t\(/) {
43		push @available_vn_ops, $2;
44	}
45}
46# Alpha sort.
47@available_vn_ops = sort(@available_vn_ops);
48
49# Array of { file , fs }
50@fs = ();
51$#fs = 0;
52
53# Array of available vops for a given fs
54@fsvnops = ();
55$#fsvnops = 0;
56
57#Begin output.
58open OF, ">$outfile";
59print OF "<HTML><HEAD><TITLE>File system vnode Operations</TITLE>";
60print OF "</HEAD><BODY>\n";
61print OF "<TABLE BORDER WIDTH=\"100%\" HEIGHT=\"100%\" >\n";
62print OF "<TR><TH><font size=-1>F<br>i<br>l<br>e<br><br>S<br>y<br>s<br>t<br>e<br>m<br></font>\n";
63print OF "<TH><font size=-1>V<br>e<br>c<br>t<br>o<br>r<br><br>V<br>a<br>r<br>i<br>a<br>b<br>l<br>e<br></font>\n";
64foreach $avops (@available_vn_ops) {
65	@ao = split //,$avops;
66	print OF "<TH><font size=-1> ";
67	foreach $aoz (@ao) {
68		print OF "$aoz<br>\n";
69	}
70	print OF "</font>\n";
71}
72print OF "</TR></font>\n";
73
74#Generate $infile; sketchy
75`find /usr/src/sys -type f -iname *.c -print | xargs grep 'vnodeops =' > $infile`;
76
77# Read in the file we find(1) generated.
78open VT, $infile;
79foreach $l (<VT>) {
80	chomp($l);
81
82	# Attempt to find all the files holding vop_vector declarations
83
84	##
85	# Need to sort based on $fs[]->{fs}
86	if ($l =~ m/^(\S+):.*vop_vector ((\S+)_vnodeops) =/) {
87		# Eh, I suck at perl; forgot some syntax, so hack.
88		$sz = $#fs;
89		$#fs++;
90		$fs[$sz]->{file} = $1;
91		$fs[$sz]->{fs} = $3;	# file system
92		$fs[$sz]->{fsvar} = $2;	# fs vop vector variable
93		push @fs_s, $3;
94		next;
95	}
96}
97close VT;
98`rm -f $infile`;
99@fs_s = sort  @fs_s;
100$m = 0;
101foreach $fss (@fs_s) {
102	for ($l = 0; $l < $#fs; $l++) {
103		if ($fs_s[$m] eq $fs[$l]->{fs}) {
104			$fs[$l]->{fsi} = $m;
105			$m++;
106			last;
107		}
108	}
109}
110
111sub vop_fn_val {
112	($vfn) = @_;
113	$ret = "<TD BGCOLOR=\"#00ddd0\"> ";
114
115	if ($vfn eq "VOP_EBADF") {
116		$ret .= "b";
117		return $ret;
118	}
119	if ($vfn eq "VOP_PANIC") {
120		$ret .= "!";
121		return $ret;
122	}
123	if ($vfn eq "VOP_NULL") {
124		$ret .= "-";
125		return $ret;
126	}
127	if ($vfn =~ m/vop_std/) {
128		$ret .= "S";
129		return $ret;
130	}
131	if ($vfn eq "vop_cache_lookup") {
132		$ret .= "C";
133		return $ret;
134	}
135	if ($vfn =~ m/vop_no/) {
136		$ret .= "N";
137		return $ret;
138	}
139	if ($vfn =~ m/vop_/) {
140		$ret .= "V";
141		return $ret;
142	}
143	if ($vfn eq "VOP_EINVAL") {
144		$ret .= "i";
145		return $ret;
146	}
147	if ($vfn eq "VOP_ENOTTY") {
148		$ret .= "t";
149		return $ret;
150	}
151	if ($vfn eq "VOP_ENOTOPSUPP") {
152		$ret .= "*";
153		return $ret;
154	}
155	if ($vfn =~ m/_lookup/) {
156		$ret .= "L";
157		return $ret;
158	}
159	$ret .= "F";
160	return $ret;
161}
162
163# Loop through files that define vop_vectors.
164for ($j = 0; $j < $#fs; $j++) {
165
166	# Open the file containing the vop_vector decl.
167	open V, $fs[$j]->{file};
168	@VF = <V>;
169	close V;
170
171	# Zero out array; is there an easier way to do this in perl?
172	for ($z = 0; $z < $#fsvnops; $z++) {
173		$fsvnops[$z] = "<td bgcolor=\"d0d0d0\">";
174	}
175
176	$opz = 0;
177	foreach $v (@VF) {
178		chomp($v);
179
180		if ($v =~ m/vop_vector (\S+_vnodeops) =/) {
181			$opz = 1;
182			next;
183		}
184
185		next if ($opz == 0);
186
187		# Ehhh...	hax
188		if ($v =~ m/;/) {
189			$opz = 0;
190			next;
191		}
192
193		# ... Generate a vop_vector under each @fs entry?
194		#  vop_LABEL = <func>
195		if ($v =~ m/\.vop_(\S+)\s+=\s+(\S+),/) {
196			$iz = get_vop_fn_index($1);
197			if ($iz == -1) {
198				print "Unknown vnop routine: $1:$2 \n";
199				exit 1;
200			}
201			$fsvnops[$iz] = vop_fn_val($2);
202		}
203	}
204	#
205	$fs[$j]->{out} = " <TD> $fs[$j]->{fsvar}";
206
207	# Print out based on fsvnops
208	foreach $z (@fsvnops) {
209		$fs[$j]->{out} .= $z;
210	}
211	$fs[$j]->{out} .= "</TR>\n";
212}
213
214foreach $s (@fs_s) {
215	for ($b = 0; $b < $#fs; $b++) {
216		if ($s eq $fs[$b]->{fs}) {
217			print OF "<TD> $s ".$fs[$b]->{out};
218		}
219	}
220}
221
222
223print OF "</TR></TABLE>\n";
224print OF "<PRE>\n";
225print OF "
226C  vfs_cache_lookup
227*  vop_defaultop
228b  vop_ebadf
229i  vop_einval
230t  vop_enotty
231*  vop_eopnotsupp
232-  vop_null
233!  vop_panic
234F  _
235V  vop_
236N  vop_no
237S  vop_std
238L  _lookup
239</PRE>";
240print OF "</BODY></HTML>\n";
241close OF;
242exit 0;
243
244sub get_vop_fn_index {
245	($vop_fn) = @_;
246	$r = 0;
247
248	foreach $y (@available_vn_ops) {
249		if ($y eq $vop_fn) {
250			return $r;
251		}
252		$r++;
253	}
254	return -1;
255}
256