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