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