#!/bin/sh - copyright="\ /* * Copyright (c) 1992, 1993, 1994, 1995 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \`\`AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ " SCRIPT_ID='$NetBSD: vnode_if.sh,v 1.48 2008/01/02 11:48:57 ad Exp $' # Script to produce VFS front-end sugar. # # usage: vnode_if.sh srcfile # (where srcfile is currently /sys/kern/vnode_if.src) # if [ $# -ne 1 ] ; then echo 'usage: vnode_if.sh srcfile' exit 1 fi # Name and revision of the source file. src=$1 SRC_ID=`head -1 $src | sed -e 's/.*\$\(.*\)\$.*/\1/'` # Names of the created files. out_c=vnode_if.c out_h=../sys/vnode_if.h # Awk program (must support nawk extensions) # Use "awk" at Berkeley, "nawk" or "gawk" elsewhere. awk=${AWK:-awk} # Does this awk have a "toupper" function? (i.e. is it GNU awk) isgawk=`$awk 'BEGIN { print toupper("true"); exit; }' 2>/dev/null` # If this awk does not define "toupper" then define our own. if [ "$isgawk" = TRUE ] ; then # GNU awk provides it. toupper= else # Provide our own toupper() toupper=' function toupper(str) { _toupper_cmd = "echo "str" |tr a-z A-Z" _toupper_cmd | getline _toupper_str; close(_toupper_cmd); return _toupper_str; }' fi # # This is the common part of all awk programs that read $src # This parses the input for one function into the arrays: # argdir, argtype, argname, willrele # and calls "doit()" to generate output for the function. # # Input to this parser is pre-processed slightly by sed # so this awk parser doesn't have to work so hard. The # changes done by the sed pre-processing step are: # insert a space beween * and pointer name # replace semicolons with spaces # sed_prep='s:\*\([^\*/]\):\* \1:g s/;/ /' awk_parser=' # Comment line /^#/ { next; } # First line of description /^vop_/ { name=$1; argc=0; willmake=-1; next; } # Last line of description /^}/ { doit(); next; } # Middle lines of description { argdir[argc] = $1; i=2; if ($2 == "LOCKED=YES") { lockstate[argc] = 1; i++; } else if ($2 == "LOCKED=NO") { lockstate[argc] = 0; i++; } else lockstate[argc] = -1; if ($2 == "WILLRELE" || $3 == "WILLRELE") { willrele[argc] = 1; i++; } else if ($2 == "WILLUNLOCK" || $3 == "WILLUNLOCK") { willrele[argc] = 2; i++; } else if ($2 == "WILLPUT" || $3 == "WILLPUT") { willrele[argc] = 3; i++; } else willrele[argc] = 0; if ($2 == "WILLMAKE") { willmake=argc; i++; } argtype[argc] = $i; i++; while (i < NF) { argtype[argc] = argtype[argc]" "$i; i++; } argname[argc] = $i; argc++; next; } ' # This is put before the copyright on each generated file. warning="\ /* @NetBSD@ */ /* * Warning: DO NOT EDIT! This file is automatically generated! * (Modifications made here may easily be lost!) * * Created from the file: * ${SRC_ID} * by the script: * ${SCRIPT_ID} */ " # This is to satisfy McKusick (get rid of evil spaces 8^) anal_retentive='s:\([^/]\*\) :\1:g' # # Redirect stdout to the H file. # echo "$0: Creating $out_h" 1>&2 exec > $out_h # Begin stuff echo -n "$warning" | sed -e 's/\$//g;s/@/\$/g;s/ $//' echo "" echo -n "$copyright" echo '' echo '#ifndef _SYS_VNODE_IF_H_' echo '#define _SYS_VNODE_IF_H_' echo '' echo '#ifdef _KERNEL_OPT' echo '#include "opt_vnode_lockdebug.h"' echo '#endif /* _KERNEL_OPT */' echo ' extern const struct vnodeop_desc vop_default_desc; ' # Body stuff # This awk program needs toupper() so define it if necessary. sed -e "$sed_prep" $src | $awk "$toupper"' function doit() { # Declare arg struct, descriptor. printf("\n#define %s_DESCOFFSET %d\n", toupper(name), vop_offset++); printf("struct %s_args {\n", name); printf("\tconst struct vnodeop_desc * a_desc;\n"); for (i=0; i 77) { protoarg = ("\n " protoarg); arglen += 4; protolen = 0; } printf("%s", protoarg); protolen += arglen; } printf(");\n"); } BEGIN { arg0special=""; vop_offset = 1; # start at 1, to count the 'default' op printf("\n/* Special cases: */\n#include \n"); printf("#ifndef _KERNEL\n#include \n#endif\n\n"); argc=1; argtype[0]="struct buf *"; argname[0]="bp"; lockstate[0] = -1; arg0special="->b_vp"; name="vop_bwrite"; doit(); printf("/* End of special cases */\n"); } END { printf("\n#define VNODE_OPS_COUNT\t%d\n", vop_offset); } '"$awk_parser" | sed -e "$anal_retentive" # End stuff echo ' /* End of special cases. */' echo '' echo '#endif /* !_SYS_VNODE_IF_H_ */' # # Redirect stdout to the C file. # echo "$0: Creating $out_c" 1>&2 exec > $out_c # Begin stuff echo -n "$warning" | sed -e 's/\$//g;s/@/\$/g;s/ $//' echo "" echo -n "$copyright" echo " #include __KERNEL_RCSID(0, \"\$NetBSD\$\"); " echo ' #include "opt_vnode_lockdebug.h" #include "opt_multiprocessor.h"' echo ' #include #include #include #include #include const struct vnodeop_desc vop_default_desc = { 0, "default", 0, NULL, VDESC_NO_OFFSET, VDESC_NO_OFFSET, VDESC_NO_OFFSET, NULL, }; ' # Body stuff sed -e "$sed_prep" $src | $awk ' function do_offset(typematch) { for (i=0; iv_vflag & VV_LOCKSWORK) ? (VOP_ISLOCKED(%s) == LK_EXCLUSIVE) : %d;\n", argname[i], argname[i], argname[i], lockstate[i]); printf("\tif (islocked_%s != %d)\n", argname[i], lockstate[i]); printf("\t\tpanic(\"%s: %s: locked %%d, expected %%d\", islocked_%s, %d);\n", name, argname[i], argname[i], lockstate[i]); printf("#endif\n"); } } printf("\tmpsafe = (%s%s->v_vflag & VV_MPSAFE);\n", argname[0], arg0special); printf("\tif (!mpsafe) { KERNEL_LOCK(1, curlwp); }\n"); printf("\terror = (VCALL(%s%s, VOFFSET(%s), &a));\n", argname[0], arg0special, name); printf("\tif (!mpsafe) { KERNEL_UNLOCK_ONE(curlwp); }\n"); if (willmake != -1) { printf("#ifdef DIAGNOSTIC\n"); printf("\tif (error == 0)\n" \ "\t\tKASSERT((*%s)->v_size != VSIZENOTSET\n" \ "\t\t && (*%s)->v_writesize != VSIZENOTSET);\n", argname[willmake], argname[willmake]); printf("#endif /* DIAGNOSTIC */\n"); } printf("\treturn error;\n}\n"); } BEGIN { printf("\n/* Special cases: */\n"); # start from 1 (vop_default is at 0) argc=1; willmake=-1; argdir[0]="IN"; argtype[0]="struct buf *"; argname[0]="bp"; lockstate[0] = -1; arg0special="->b_vp"; willrele[0]=0; name="vop_bwrite"; doit(); printf("\n/* End of special cases */\n"); arg0special=""; } '"$awk_parser" | sed -e "$anal_retentive" # End stuff echo ' /* End of special cases. */' # Add the vfs_op_descs array to the C file. # Begin stuff echo ' const struct vnodeop_desc * const vfs_op_descs[] = { &vop_default_desc, /* MUST BE FIRST */ &vop_bwrite_desc, /* XXX: SPECIAL CASE */ ' # Body stuff sed -e "$sed_prep" $src | $awk ' function doit() { printf("\t&%s_desc,\n", name); } '"$awk_parser" # End stuff echo ' NULL }; ' exit 0 # Local Variables: # tab-width: 4 # End: