1#!/usr/bin/perl 2eval 'exec /usr/bin/perl -S $0 ${1+"$@"}' 3 if $running_under_some_shell; 4 5# 6# Copyright (c) 1992, 1993 7# The Regents of the University of California. All rights reserved. 8# 9# Redistribution and use in source and binary forms, with or without 10# modification, are permitted provided that the following conditions 11# are met: 12# 1. Redistributions of source code must retain the above copyright 13# notice, this list of conditions and the following disclaimer. 14# 2. Redistributions in binary form must reproduce the above copyright 15# notice, this list of conditions and the following disclaimer in the 16# documentation and/or other materials provided with the distribution. 17# 3. All advertising materials mentioning features or use of this software 18# must display the following acknowledgement: 19# This product includes software developed by the University of 20# California, Berkeley and its contributors. 21# 4. Neither the name of the University nor the names of its contributors 22# may be used to endorse or promote products derived from this software 23# without specific prior written permission. 24# 25# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35# SUCH DAMAGE. 36# 37# @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93 38# $FreeBSD$ 39# 40# Script to produce VFS front-end sugar. 41# 42# usage: vnode_if.sh srcfile 43# (where srcfile is currently /sys/kern/vnode_if.src) 44# 45 46my %lockdata; 47 48 49if ($#ARGV != 0) { 50 print "usage: vnode_if.sh srcfile\n"; 51 exit(1); 52} 53 54# Name of the source file. 55$SRC=$ARGV[0]; 56 57# Names of the created files. 58$CFILE='vnode_if.c'; 59$HEADER='vnode_if.h'; 60 61open(HEADER, ">$HEADER") || die "Unable to create $HEADER"; 62open(CFILE, ">$CFILE") || die "Unable to create $CFILE"; 63open(SRC, "<$SRC") || die "Unable to open input file"; 64 65# Print out header information for vnode_if.h. 66print HEADER <<END_OF_LEADING_COMMENT 67/* 68 * This file is produced automatically. 69 * Do not modify anything in here by hand. 70 * 71 * Created from @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93 72 */ 73 74extern struct vnodeop_desc vop_default_desc; 75END_OF_LEADING_COMMENT 76 ; 77 78# Print out header information for vnode_if.c. 79print CFILE <<END_OF_LEADING_COMMENT 80/* 81 * This file is produced automatically. 82 * Do not modify anything in here by hand. 83 * 84 * Created from @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93 85 */ 86 87#include <sys/param.h> 88#include <sys/vnode.h> 89 90struct vnodeop_desc vop_default_desc = { 91 1, /* special case, vop_default => 1 */ 92 "default", 93 0, 94 NULL, 95 VDESC_NO_OFFSET, 96 VDESC_NO_OFFSET, 97 VDESC_NO_OFFSET, 98 VDESC_NO_OFFSET, 99 NULL, 100}; 101 102END_OF_LEADING_COMMENT 103 ; 104 105line: while (<SRC>) { 106 chop; # strip record separator 107 @Fld = split ' '; 108 if (@Fld == 0) { 109 next line; 110 } 111 if (/^#/) { 112 if (!/^#%\s+([a-z]+)\s+([a-z]+)\s+(.)\s(.)\s(.)/) { 113 next; 114 } 115 if (!defined($lockdata{"vop_$1"})) { 116 $lockdata{"vop_$1"} = {}; 117 } 118 $lockdata{"vop_$1"}->{$2} = { 119 'Entry' => $3, 120 'OK' => $4, 121 'Error' => $5, 122 }; 123 next; 124 } 125 126 # Get the function name. 127 $name = $Fld[0]; 128 $uname = uc($name); 129 130 # Get the function arguments. 131 for ($numargs = 0; ; ++$numargs) { 132 if ($ln = <SRC>) { 133 chomp; 134 } else { 135 die "Unable to read through the arguments for \"$name\""; 136 } 137 if ($ln =~ /^\};/) { 138 last; 139 } 140 # For the header file 141 $a{$numargs} = $ln; 142 143 # The rest of this loop is for the C file 144 # Delete comments, if any. 145 $ln =~ s/\/\*.*\*\///g; 146 147 # Delete leading/trailing space. 148 $ln =~ s/^\s*(.*?)\s*$/$1/; 149 150 # Pick off direction. 151 if ($ln =~ s/^INOUT\s+//) { 152 $dir = 'INOUT'; 153 } elsif ($ln =~ s/^IN\s+//) { 154 $dir = 'IN'; 155 } elsif ($ln =~ s/^OUT\s+//) { 156 $dir = 'OUT'; 157 } else { 158 die "No IN/OUT direction for \"$ln\"."; 159 } 160 if ($ln =~ s/^WILLRELE\s+//) { 161 $rele = 'WILLRELE'; 162 } else { 163 $rele = 'WONTRELE'; 164 } 165 166 # kill trailing ; 167 if ($ln !~ s/;$//) { 168 &bail("Missing end-of-line ; in \"$ln\"."); 169 } 170 171 # pick off variable name 172 if ($ln !~ s/([A-Za-z0-9_]+)$//) { 173 &bail("Missing var name \"a_foo\" in \"$ln\"."); 174 } 175 $arg = $1; 176 177 # what is left must be type 178 # (put clean it up some) 179 $type = $ln; 180 # condense whitespace 181 $type =~ s/\s+/ /g; 182 $type =~ s/^\s*(.*?)\s*$/$1/; 183 184 $dirs{$numargs} = $dir; 185 $reles{$numargs} = $rele; 186 $types{$numargs} = $type; 187 $args{$numargs} = $arg; 188 } 189 190 # Print out the vop_F_args structure. 191 print HEADER "struct ${name}_args {\n\tstruct vnodeop_desc *a_desc;\n"; 192 for ($c2 = 0; $c2 < $numargs; ++$c2) { 193 $a{$c2} =~ /^\s*(INOUT|OUT|IN)(\s+WILLRELE)?\s+(.*?)\s+(\**)(\S*\;)/; 194 print HEADER "\t$3 $4a_$5\n", 195 } 196 print HEADER "};\n"; 197 198 # Print out extern declaration. 199 print HEADER "extern struct vnodeop_desc ${name}_desc;\n"; 200 201 # Print out prototype. 202 print HEADER "static __inline int ${uname} __P((\n"; 203 for ($c2 = 0; $c2 < $numargs; ++$c2) { 204 $a{$c2} =~ /^\s*(INOUT|OUT|IN)(\s+WILLRELE)?\s+(.*?)\s+(\**\S*)\;/; 205 print HEADER "\t$3 $4" . 206 ($c2 < $numargs-1 ? "," : "));") . "\n"; 207 } 208 209 # Print out function. 210 print HEADER "static __inline int ${uname}("; 211 for ($c2 = 0; $c2 < $numargs; ++$c2) { 212 $a{$c2} =~ /\**([^;\s]*)\;[^\s]*$/; 213 print HEADER "$1" . ($c2 < $numargs - 1 ? ', ' : ")\n"); 214 } 215 for ($c2 = 0; $c2 < $numargs; ++$c2) { 216 $a{$c2} =~ /^\s*(INOUT|OUT|IN)(\s+WILLRELE)?\s+(.*?)\s+(\**\S*\;)/; 217 print HEADER "\t$3 $4\n"; 218 } 219 print HEADER "{\n\tstruct ${name}_args a;\n"; 220 print HEADER "\tint rc;\n"; 221 print HEADER "\ta.a_desc = VDESC(${name});\n"; 222 for ($c2 = 0; $c2 < $numargs; ++$c2) { 223 $a{$c2} =~ /(\**)([^;\s]*)([^\s]*)$/; 224 print HEADER "\ta.a_$2 = $2$3\n", 225 } 226 for ($c2 = 0; $c2 < $numargs; ++$c2) { 227 if (!exists($args{$c2})) { 228 die "Internal error"; 229 } 230 if (exists($lockdata{$name}) && 231 exists($lockdata{$name}->{$args{$c2}})) { 232 if ($ENV{'DEBUG_ALL_VFS_LOCKS'} =~ /yes/i) { 233 # Add assertions for locking 234 if ($lockdata{$name}->{$args{$c2}}->{Entry} eq "L") { 235 print HEADER 236 "\tASSERT_VOP_LOCKED($args{$c2}, \"$uname\");\n"; 237 } elsif ($lockdata{$name}->{$args{$c2}}->{Entry} eq "U") { 238 print HEADER 239 "\tASSERT_VOP_UNLOCKED($args{$c2}, \"$uname\");\n"; 240 } elsif (0) { 241 # XXX More checks! 242 } 243 } 244 } 245 } 246 $a{0} =~ /\s\**([^;\s]*);/; 247 print HEADER "\trc = VCALL($1, VOFFSET(${name}), &a);\n"; 248 print HEADER "\treturn (rc);\n"; 249 print HEADER "}\n"; 250 251 252 # Print out the vop_F_vp_offsets structure. This all depends 253 # on naming conventions and nothing else. 254 printf CFILE "static int %s_vp_offsets[] = {\n", $name; 255 # as a side effect, figure out the releflags 256 $releflags = ''; 257 $vpnum = 0; 258 for ($i = 0; $i < $numargs; $i++) { 259 if ($types{$i} eq 'struct vnode *') { 260 printf CFILE "\tVOPARG_OFFSETOF(struct %s_args,a_%s),\n", 261 $name, $args{$i}; 262 if ($reles{$i} eq 'WILLRELE') { 263 $releflags = $releflags . '|VDESC_VP' . $vpnum . '_WILLRELE'; 264 } 265 266 $vpnum++; 267 } 268 } 269 270 $releflags =~ s/^\|//; 271 print CFILE "\tVDESC_NO_OFFSET\n"; 272 print CFILE "};\n"; 273 274 # Print out the vnodeop_desc structure. 275 print CFILE "struct vnodeop_desc ${name}_desc = {\n"; 276 # offset 277 print CFILE "\t0,\n"; 278 # printable name 279 printf CFILE "\t\"%s\",\n", $name; 280 # flags 281 $vppwillrele = ''; 282 for ($i = 0; $i < $numargs; $i++) { 283 if ($types{$i} eq 'struct vnode **' && 284 ($reles{$i} eq 'WILLRELE')) { 285 $vppwillrele = '|VDESC_VPP_WILLRELE'; 286 } 287 } 288 289 if ($releflags eq '') { 290 printf CFILE "\t0%s,\n", $vppwillrele; 291 } 292 else { 293 printf CFILE "\t%s%s,\n", $releflags, $vppwillrele; 294 } 295 296 # vp offsets 297 printf CFILE "\t%s_vp_offsets,\n", $name; 298 # vpp (if any) 299 printf CFILE "\t%s,\n", &find_arg_with_type('struct vnode **'); 300 # cred (if any) 301 printf CFILE "\t%s,\n", &find_arg_with_type('struct ucred *'); 302 # proc (if any) 303 printf CFILE "\t%s,\n", &find_arg_with_type('struct proc *'); 304 # componentname 305 printf CFILE "\t%s,\n", &find_arg_with_type('struct componentname *'); 306 # transport layer information 307 print CFILE "\tNULL,\n};\n\n"; 308} 309 310close(HEADER) || die "Unable to close $HEADER"; 311close(CFILE) || die "Unable to close $CFILE"; 312close(SRC) || die; 313 314exit 0; 315 316sub find_arg_with_type { 317 my $type = shift; 318 my $i; 319 320 for ($i=0; $i < $numargs; $i++) { 321 if ($types{$i} eq $type) { 322 return "VOPARG_OFFSETOF(struct ${name}_args,a_" . $args{$i} . ")"; 323 } 324 } 325 326 return "VDESC_NO_OFFSET"; 327} 328