]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - tools/tools/vop_table/vop_table.pl
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / tools / tools / vop_table / vop_table.pl
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`;
27 if ($?) {
28         print "Incapable of writing out the typedef file.\n";
29         exit(1);
30 }
31
32 # Eat the typedefs file into memory 
33 open TD, "vnode_if_typedef.h" || die "Unable to open typedef file: $!\n";
34 @vop_tdefs = <TD>;
35 close TD;
36 `rm -f vnode_if_typedef.h`;
37
38 # List of available vnode operations
39 @available_vn_ops = ();
40 push @available_vn_ops, "default";
41 foreach $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.
58 open OF, ">$outfile";
59 print OF "<HTML><HEAD><TITLE>File system vnode Operations</TITLE>";
60 print OF "</HEAD><BODY>\n";
61 print OF "<TABLE BORDER WIDTH=\"100%\" HEIGHT=\"100%\" >\n";
62 print 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";
63 print 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";
64 foreach $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 }
72 print 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.
78 open VT, $infile;
79 foreach $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 }
97 close VT;
98 `rm -f $infile`;
99 @fs_s = sort  @fs_s;
100 $m = 0;
101 foreach $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
111 sub 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.
164 for ($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
214 foreach $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
223 print OF "</TR></TABLE>\n";
224 print OF "<PRE>\n";
225 print OF "
226 C  vfs_cache_lookup
227 *  vop_defaultop
228 b  vop_ebadf
229 i  vop_einval
230 t  vop_enotty
231 *  vop_eopnotsupp
232 -  vop_null
233 !  vop_panic
234 F  _
235 V  vop_
236 N  vop_no
237 S  vop_std
238 L  _lookup
239 </PRE>";
240 print OF "</BODY></HTML>\n";
241 close OF;
242 exit 0;
243
244 sub 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 }