Print this page
    
XXX Remove nawk(1)
    
      
        | Split | Close | 
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/mdb/tools/scripts/hdr2map.sh
          +++ new/usr/src/cmd/mdb/tools/scripts/hdr2map.sh
   1    1  #!/bin/ksh
   2    2  #
   3    3  # CDDL HEADER START
   4    4  #
   5    5  # The contents of this file are subject to the terms of the
   6    6  # Common Development and Distribution License (the "License").
   7    7  # You may not use this file except in compliance with the License.
   8    8  #
   9    9  # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10   10  # or http://www.opensolaris.org/os/licensing.
  11   11  # See the License for the specific language governing permissions
  12   12  # and limitations under the License.
  13   13  #
  14   14  # When distributing Covered Code, include this CDDL HEADER in each
  15   15  # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  
    | ↓ open down ↓ | 15 lines elided | ↑ open up ↑ | 
  16   16  # If applicable, add the following below this CDDL HEADER, with the
  17   17  # fields enclosed by brackets "[]" replaced with your own identifying
  18   18  # information: Portions Copyright [yyyy] [name of copyright owner]
  19   19  #
  20   20  # CDDL HEADER END
  21   21  #
  22   22  #
  23   23  # Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  24   24  # Use is subject to license terms.
  25   25  #
  26      -#ident  "%Z%%M% %I%     %E% SMI"
  27      -#
  28   26  
  29   27  #
  30   28  # Given a header file, extract function prototypes and global variable
  31   29  # declarations in a form that can be used in a mapfile.  The list of extracted
  32   30  # functions and variables will be combined with a user-specified template to
  33   31  # create a complete mapfile.
  34   32  #
  35   33  # Template
  36   34  # --------
  37   35  #
  38   36  # The template contains two sections - the prologue, and the epilogue.  These
  39   37  # sections are used, verbatim, as the beginning and the end of the mapfile.
  40   38  # Sections begin and end with single-line comments whose sole contents are
  41   39  # "/* BEGIN $section */" and "/* END $section */".
  42   40  #
  43   41  # Template example:
  44   42  #
  45   43  # /* BEGIN PROLOGUE */
  46   44  # [ ... prologue goes here ... ]
  47   45  # /* END PROLOGUE */
  48   46  # /* BEGIN EPILOGUE */
  49   47  # [ ... epilogue goes here ... ]
  50   48  # /* END EPILOGUE */
  51   49  #
  52   50  # Selective Exportation
  53   51  # ---------------------
  54   52  #
  55   53  # Some header files will have a public/private interface mix that is strongly
  56   54  # biased towards private interfaces.  That is, of the interfaces declared by
  57   55  # a given header file, the majority of them are private.  Only a small subset
  58   56  # of interfaces are to be exported publicly.  Using Selective Exportation, a
  59   57  # special comment is included in the header file, declaring to this script that
  60   58  # only a subset of interfaces - those with a marking declared in the comment -
  61   59  # should be included in the mapfile.  The marking is itself a special comment,
  62   60  # whose format is declared using a directive like this:
  63   61  #
  64   62  #       MAPFILE: export "Driver OK"
  65   63  #
  66   64  # Using the above directive, only those function prototypes and variable
  67   65  # declarations with "/* Driver OK */" comments included in the mapfile.  Note
  68   66  # that the comment must be at the end of the first line.  If the declaration
  69   67  # spans multiple lines, the exportation comment must appear on the first line.
  70   68  #
  71   69  # Examples of functions selected for exportation:
  72   70  #
  73   71  # MAPFILE: export "Driver OK"
  74   72  #
  75   73  # extern int foo(int);          /* Driver OK */
  76   74  # extern void bar(int, int,     /* Driver OK */
  77   75  #     int, void *);
  78   76  #
  79   77  # Selective Exportation may not be used in the same file as Selective Exclusion.
  80   78  #
  81   79  # Selective Exclusion
  82   80  # -------------------
  83   81  #
  84   82  # Selective Exclusion is to be used in cases where the public/private interface
  85   83  # mix is reversed - where public interfaces greatly outnumber the private ones.
  86   84  # In this case, we want to be able to mark the private ones, thus telling this
  87   85  # script that the marked interfaces are to be excluded from the mapfile.
  88   86  # Marking is accomplished via a process similar to that used for Selective
  89   87  # Exportation.  A directive is included in a comment, and is formatted like
  90   88  # this:
  91   89  #
  92   90  #       MAPFILE: exclude "Internal"
  93   91  #
  94   92  # Using the above directive, function prototypes and variable declarations with
  95   93  # "/* Internal */" comments would be excluded.  Note that the comment must be at
  96   94  # the end of the first line.  If the declaration spans multiple lines, the
  97   95  # exclusion comment must appear on the first line.
  98   96  #
  99   97  # Examples of functions excluded from exportation:
 100   98  #
 101   99  # MAPFILE: exclude "Internal"
 102  100  #
 103  101  # extern int foo(int);          /* Internal */
 104  102  # extern void bar(int, int,     /* Internal */
  
    | ↓ open down ↓ | 67 lines elided | ↑ open up ↑ | 
 105  103  #       int, void *);
 106  104  #
 107  105  # Selective Exclusion may not be used in the same file as Selective Exportation.
 108  106  #
 109  107  
 110  108  function extract_prototypes
 111  109  {
 112  110          typeset header="$1"
 113  111          typeset prefix="$2"
 114  112  
 115      -        nawk -v prefix="$prefix" <$header '
      113 +        /usr/xpg4/bin/awk -v prefix="$prefix" <$header '
 116  114                  /^.*MAPFILE: export \"[^\"]*\"$/ {
 117  115                          if (protoexclude) {
 118  116                                  print "ERROR: export after exclude\n";
 119  117                                  exit(1);
 120  118                          }
 121  119                  
 122  120                          sub(/^[^\"]*\"/, "");
 123  121                          sub(/\"$/, "");
 124  122  
 125  123                          exportmark=sprintf("/* %s */", $0);
 126  124                          next;
 127  125                  }
 128  126  
 129  127                  /^.*MAPFILE: exclude \"[^\"]*\"$/ {
 130  128                          if (protomatch) {
 131  129                                  print "ERROR: exclude after export";
 132  130                                  exit(1);
 133  131                          }
 134  132  
 135  133                          sub(/^[^\"]*\"/, "");
 136  134                          sub(/\"$/, "");
 137  135  
 138  136                          excludemark=sprintf("/* %s */", $0);
 139  137                          next;
 140  138                  }
 141  139  
 142  140                  exportmark {
 143  141                          # Selective Exportation has been selected (exportmark is
 144  142                          # set), so exclude this line if it does not have the
 145  143                          # magic export mark.
 146  144                          if (length($0) < length(exportmark) ||
 147  145                              substr($0, length($0) - length(exportmark) + 1) != \
 148  146                              exportmark)
 149  147                                  next;
 150  148                  }
 151  149  
 152  150                  excludemark {
 153  151                          # Selective Exclusion has been selected (excludemark is
 154  152                          # set), so exclude this line only if it has the magic
 155  153                          # exclude mark.
 156  154                          if (length($0) > length(excludemark) &&
 157  155                              substr($0, \
 158  156                              length($0) - length(excludemark) + 1) == \
 159  157                              excludemark)
 160  158                                  next;
 161  159                  }
 162  160  
 163  161                  # Functions
 164  162                  /^extern.*\(/ {
 165  163                          for (i = 1; i <= NF; i++) {
 166  164                                  if (sub(/\(.*$/, "", $i)) {
 167  165                                          sub(/^\*/, "", $i);
 168  166                                          if (!seenfn[$i]) {
 169  167                                                  printf("%s%s;\n", prefix, $i);
 170  168                                                  seenfn[$i] = 1;
 171  169                                          }
 172  170                                          break;
 173  171                                  }
 174  172                          }
 175  173                          next;
 176  174                  }
 177  175  
 178  176                  # Global variables
 179  177                  /^extern[^\(\)]*;/ {
 180  178                          for (i = 1; i <= NF; i++) {
 181  179                                  if (match($i, /;$/)) {
 182  180                                          printf("%s%s; /* variable */\n", prefix,
 183  181                                              substr($i, 1, length($i) - 1));
 184  182                                          break;
 185  183                                  }
 186  184                          }
  
    | ↓ open down ↓ | 61 lines elided | ↑ open up ↑ | 
 187  185                          next;
 188  186                  }
 189  187          ' || die "Extraction failed"
 190  188  }
 191  189  
 192  190  function extract_section
 193  191  {
 194  192          typeset skel="$1"
 195  193          typeset secname="$2"
 196  194  
 197      -        nawk <$skel -v name=$secname -v skel=$skel '
      195 +        /usr/xpg4/bin/awk <$skel -v name=$secname -v skel=$skel '
 198  196              /\/\* [^ ]* [^ ]* \*\// && $3 == name {
 199  197                  if ($2 == "BEGIN") {
 200  198                          printing = 1;
 201  199                  } else {
 202  200                          printing = 0;
 203  201                  }
 204  202                  next;
 205  203              }
 206  204  
 207  205              printing != 0 { print; }
 208  206          '
 209  207  }
 210  208  
 211  209  function die
 212  210  {
 213  211          echo "$PROGNAME: $@" >&2
 214  212          exit 1
 215  213  }
 216  214  
 217  215  function usage
 218  216  {
 219  217          echo "Usage: $PROGNAME -t tmplfile header [header ...]" >&2
 220  218          exit 2
 221  219  }
 222  220  
 223  221  PROGNAME=$(basename "$0")
 224  222  
 225  223  while getopts t: c ; do
 226  224          case $c in
 227  225              t)
 228  226                  mapfile_skel=$OPTARG
 229  227                  ;;
 230  228              ?)
 231  229                  usage
 232  230          esac
 233  231  done
 234  232  
 235  233  [[ -z "$mapfile_skel" ]] && usage
 236  234  [[ ! -f $mapfile_skel ]] && die "Couldn't open template $tmplfile"
 237  235  
 238  236  shift $(($OPTIND - 1))
 239  237  
 240  238  [[ $# -lt 1 ]] && usage
 241  239  
 242  240  for file in $@ ; do
 243  241          [[ ! -f $file ]] && die "Can't open input file $file"
 244  242  done
 245  243  
 246  244  extract_section $mapfile_skel PROLOGUE
 247  245  
 248  246  for file in $@ ; do
 249  247          echo "\t\t/*"
 250  248          echo "\t\t * Exported functions and variables from:"
 251  249          echo "\t\t *  $file"
 252  250          echo "\t\t */"
 253  251          extract_prototypes $file "\t\t"
 254  252          echo
 255  253  done
 256  254  
 257  255  extract_section $mapfile_skel EPILOGUE
  
    | ↓ open down ↓ | 50 lines elided | ↑ open up ↑ | 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX