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