Man Linux: Main Page and Category List

NAME

       metaconfig - a Configure script generator

SYNOPSIS

       metaconfig [ -dhkmostvwGMV ] [ -L dir ]

DESCRIPTION

       Metaconfig  is a program that generates Configure scripts. If you don’t
       know what a Configure script is, please skip to the TUTORIAL section of
       this manual page. If you want a full (formal) description of the way to
       use metaconfig and its units, please look at the REFERENCE section. The
       following  is  a  quick  introduction  and  reference for knowledgeable
       users.

       Metaconfig operates from set of  units  which  define  everything  that
       metaconfig  knows  about portability.  Each unit is self-contained, and
       does not have to be registered anywhere  other  than  by  inclusion  in
       either the public U directory or your private U directory.  If the dist
       package (of which metaconfig is a part) is installed in LIB,  then  the
       public  U  directory  is  LIB/dist/mcon/U.  On  this  machine,  the LIB
       directory is /usr/share/dist.  Your private U directory,  if  you  have
       one, is in the top level directory of your package.  Before you can run
       metaconfig you must do a several things:

       ·    Create a .package file in the package’s  top  level  directory  by
            running  packinit.   This  program will ask you about your package
            and remember what you tell it so that all the dist programs can be
            smart.

       ·    Consult  the  Glossary  (in  LIB/dist/mcon)  and  write your shell
            scripts and C programs in terms of  the  symbols  that  metaconfig
            knows  how  to  define.   You  don’t need to tell metaconfig which
            symbols you used, since metaconfig will figure that out for you.

       ·    Generate any .SH  scripts  needed  to  write  Makefiles  or  shell
            scripts that will depend on values defined by Configure.  There is
            a program called makeSH that will help you convert a plain  script
            into  a  script.SH  template;  some  editing will still need to be
            performed  on  the  resulting  .SH  file  to  move  the   variable
            configuration  part  in  the  top  part  of the script (see inline
            comments generated by makeSH within your .SH file).

       ·    Create a MANIFEST.new file in your top level directory that  lists
            all  the  files in your package. This file will remain private and
            will not be part of the final distribution. (As a convenience, the
            MANIFEST   file  will  be  used  by  metaconfig  if  there  is  no
            MANIFEST.new file yet.)  The filename should be the first field on
            each  line.   After  some  whitespace  you can add a short comment
            describing your file.  Only  source  files  should  be  listed  in
            there.  The  special  file  patchlevel.h  (which  is  handled  and
            maintained by the patching tools -- see pat(1)) should be part  of
            the  MANIFEST.new file, but may be silently ignored by some tools.
            As a rule of thumb, only files maintained by RCS should be  listed
            in there, the patchlevel.h file being one important exception.

       ·    Optionally,  you may wish to create a MANIFEST file, which will be
            an exported version of your MANIFEST.new. That file must  be  made
            part  of  the  release,  i.e. listed in both your MANIFEST.new and
            MANIFEST itself.  One of the metaconfig  units  knows  about  this
            file and will force Configure to perform a release check, ensuring
            all the files listed there  are  part  of  the  distribution.  The
            MANIFEST and MANIFEST.new files should be distinct, not links.

       ·    Copy  any  .U  files  that  you  want  to modify to your private U
            directory.  Any .U files in your private U directory will be  used
            in  preference to the one in the public U directory.  For example,
            one way to force inclusion of any unit is to copy the  End.U  file
            to  your  .U  directory and add the name of the unit you want as a
            dependency on the end of the ?MAKE: line.  Certain units can  ONLY
            be  forced  in  this  way,  namely  those of the form Warn_*.U and
            Chk_*.U.   You  can  also  customize  certain  default   Configure
            variables   by  copying  Myinit.U  to  your  package’s  private  U
            directory and setting the variables in that unit.

       Now you are ready to run metaconfig. That will create a Configure file,
       and  optionally  a  config_h.SH file (if your sources make any use of C
       symbols).  The generated files will  automatically  be  added  to  your
       MANIFEST.new  if  necessary. Do not forget to update your MANIFEST file
       though.

       In order to create new units, do the following:

       ·    Copy a similar unit to a new .U file.  The name you choose  should
            be  the name of a variable generated by the unit, although this is
            only a convenience for you, not a requirement.  It should be 12 or
            less characters to prevent filename chopping.  Actually, it should
            probably be 10 or less so that those who want to use RCS can  have
            a  .U,v  on the end without chopping.  Metaconfig uses the case of
            the first letter to determine if any variable is actually produced
            by this unit, so don’t Capitalize your unit name if it is supposed
            to produce a shell variable.

       ·    Edit the new .U file to do what you want.  The first  ?MAKE:  line
            indicates  the  dependencies;  before the final list colon all the
            variables this unit defines, and after the  final  colon  all  the
            variables (or other units) on which this unit depends.  It is very
            important that  these  lists  be  accurate.  If  a  dependency  is
            optional  and  a  default value can be used, you should prefix the
            dependency with a ’+’ sign. The corresponding  unit  will  not  be
            loaded  to  compute  the symbol, unless really required by another
            unit.

       ·    To the extent possible, parameterize  your  unit  based  on  shell
            variable  defined  on  ?INIT:  lines.  This will move the variable
            definitions up to the Init.U unit, where they can be overridden by
            definitions in Myinit.U, which is included after Init.U.

       ·    Add  the definition of any C symbols desired as ?H: lines.  A line
            beginning with ?H:?%<: in  the  .U  file  will  be  added  to  the
            eventual config.h file if and only if metaconfig decides that this
            unit is needed.  The %< stands for the unit’s name, which  happens
            to  be  the  name of the file too (without .U) if you followed the
            convention.  Always put a comment on each ?H: line in case one  of
            the  variable  substitutions  earlier on the line starts a comment
            without finishing it.  Any shell variable starting with d_ may  do
            this,  so beware.  If you ommit the ?%<:, then metaconfig will try
            to  intuit  the  symbol  whose  definition  is  needed  prior  any
            inclusion in config.h.

       ·    Add  glossary definitions as ?S: lines for shell variables and ?C:
            lines for C  preprocessor  variables.   See  a  current  unit  for
            examples.   It  is  VERY important to start each entry with a left
            justified symbol name, and end each entry  with  a  ?C:.  or  ?S:.
            line.  The algorithm that translates C preprocessor symbol entries
            for the Glossary into comments for config.h depends on this.

       ·    Make sure the order of all your ? lines  is  right.   The  correct
            order is:

                 ?RCS: and ?X:  basically just comments
                 ?MAKE:         metaconfig dependencies
                 ?Y:            unit layout directive
                 ?S:            glossary shell definitions
                 ?C:            glossary C definitions
                 ?H:            config.h definitions
                 ?M:            confmagic.h definitions
                 ?W:            wanted symbols
                 ?V:            visible symbols
                 ?F:            files created by this unit
                 ?T:            temporary shell symbols used
                 ?D:            optional dependencies default value
                 ?O:            used to mark obsolete units
                 ?LINT:         metalint hints
                 ?INIT:         shell symbols initializations

       Here  is  an  example to show the ordering of the lines and the various
       formats allowed:

            ?RCS: $RCS-Id$
            ?RCS: Copyright information
            ?RCS: $RCS-Log$
            ?X:
            ?X: A contrived example
            ?X:
            ?MAKE:d_one two: three +four Five
            ?MAKE:    -pick add $@ %<
            ?Y:DEFAULT
            ?S:d_one:
            ?S:  First shell symbol, conditionally defines ONE.
            ?S:.
            ?S:two:
            ?S:  Second shell symbol, value for TWO.
            ?S:.
            ?C:ONE:
            ?C:  First C symbol.
            ?C:.
            ?C:TWO:
            ?C:  Second C symbol.
            ?C:.
            ?H:#$d_one ONE /**/
            ?H:#define TWO "$two"
            ?H:#$d_one ONE_TWO "$two"
            ?H:.
            ?M:flip: HAS_FLIP
            ?M:#ifndef HAS_FLIP
            ?M:#define flip(x) flop(x)
            ?M:#endif
            ?M:.
            ?W:%<:one_two
            ?V:p_one p_two:p_three
            ?F:file ./ftest !tmp
            ?T:tmp var
            ?D:two=’undef’
            ?LINT:change three
            ?INIT:two_init=’2’
            : shell code implementing the unit follows
            p_one=’one’
            p_two=’two’
            p_three=""

       Let me state it one more time: the above unit definition is a fake  one
       to  only  show  the  different  possibilities.  Such a unit would serve
       little purpose anyway... Some more advanced features are not  described
       here.   Please  refer  to  the  REFERENCE  section  for  more  complete
       information.

       ·      Put  the  unit  into  the  public  or  private  U  directory  as
              appropriate.

       ·      Rerun metaconfig.

       ·      Send  your  unit to ram@acri.fr (Raphael Manfredi) for inclusion
              in the master copy, if you think it’s of general interest.

       In order to add a new program to be located:

       ·      Edit Loc.U, and add the name of the program both to  the  ?MAKE:
              line  (between  the two colons) and to either loclist or trylist
              (depending on whether the program is mandatory or not).

       ·      Rerun metaconfig.

       ·      Send your unit to me for inclusion in the master  copy,  if  you
              think it’s of general interest.

       Notes for writing .U files:

       *    Always  use  "rm  -f"  because  there  are  systems  where  rm  is
            interactive by default.

       *    Do not use "set -- ..." because ’--’  does  not  work  with  every
            shell. Use "set x ...; shift".

       *    Do  not  use  "unset  ENV" since unset is not fully portable.  Say
            "ENV=’’" instead.

       *    Always use echo " " (with a space) because of Eunice systems.

       *    Only use test with -r, -w, -f or  -d  since  those  are  the  only
            portable switches. In particular, avoid "test -x".

       *    Use only programs that came with V7, so that you know everyone has
            them.

       *    Use $contains when you want to grep conditionally, since  not  all
            greps  return a reasonable status.  Be sure to redirect the output
            to /dev/null, by using ’>/dev/null 2>&1’.

       *    Use "if test" rather than "if [...]" since not every sh knows  the
            latter construct.

       *    Use the myread script for inputs so that they can do shell escapes
            and default evaluation.  The general form is

                 case "$grimble" in
                 ’’) dflt=452;;
                 *) dflt="$grimble";;
                 esac
                 rp=’How many grimbles do you have?’
                 . ./myread
                 grimble="$ans"

       *    Use the getfile script when asking for a file pathname in order to
            have optional ~name expansion and sanity checks. See the Getfile.U
            unit for a full decription.

       *    Always put a

                      $startsh

            at the top of every generated script that is going to be  launched
            or sourced by Configure.

       *    Never  assume  common  UNIX-isms like the fact that an object file
            ends with a .o and that a library name ends with .a.  Use the  $_o
            and $_a variables instead (see Unix.U).

       *    When doing a compile-link-execute test, always write it like this:

                 $cc $ccflags $ldflags try.c -o try $libs

            because some systems  require  that  linking  flags  be  specified
            before the compiled target (with the exception of trailing linking
            libraries).

       *    Issue important messages on file descriptor #4, by using ’>&4’  to
            redirect  output.  Only  those  messages  will  appear when the -s
            switch is given to Configure on the command line (silent mode).

       *    Always try to determine whether a feature is present in  the  most
            specific  way--don’t  say  "if bsd" when you can grep libc.  There
            are many hybrid systems out there, and each feature  should  stand
            or fall by itself.

       *    Always  try  to determine whether a feature is present in the most
            general way, so that other packages can use your unit.

       *    When in doubt, set a default and ask.  Don’t assume anything.

       *    If you think the user is wrong, allow for the fact that he may  be
            right.  For instance, he could be running Configure on a different
            system than he is going to use the final product on.

       Metaconfig reserves the following names in your directory, and  if  you
       use such a name it may get clobbered or have other unforeseen effects:

             .MT/*
            Configure
            Wanted
            Obsolete
            configure
            config_h.SH
            confmagic.h
            U/*
            MANIFEST.new

       Additionally,  Configure may clobber these names in the directory it is
       run in:

            UU/*
            config.sh
            config.h

OPTIONS

       The following options are recognized by metaconfig:

       -d             Turn on debug mode. Not really  useful  unless  you  are
                      debugging metaconfig itself.

       -h             Print help message and exit.

       -k             Keep  temporary  directory,  so that you may examine the
                      working files used by metaconfig to build your Configure
                      script. Useful only when debugging the units.

       -m             Assume lots of memory and swap space. This will speed up
                      symbol lookup in source files by a significant amount of
                      time, at the expense of memory consumption...

       -o             Map obsolete symbols on new ones. Use this switch if you
                      still have some obsolete symbols in your source code and
                      do  not  want  (or  cannot)  remove  them  for  now. The
                      obsolete symbols are otherwise  ignored,  although  that
                      will give you a warning from metaconfig.

       -s             Turn silent mode on.

       -t             Trace symbols as they are found.

       -v             Turn verbose mode on.

       -w             Assume  Wanted  file  is  up-to-date. This will skip the
                      time and memory consuming phase of source code scanning,
                      looking  for  known  symbols.  Use it only when you know
                      your source file have not changed with  respect  to  the
                      pool of metaconfig symbols used.

       -G             Also  provide  a  GNU  configure-like  front  end to the
                      generated  Configure  script,  to  be  included  in  the
                      distribution  as well. This is only a wrapper around the
                      Configure script naturally, but it lets people  familiar
                      with  the  GNU  tool  to  not  be lost when facing a new
                      distribution.

       -L dir         Override default library location. Normally only  useful
                      for  metaconfig  maintainers  to  locally  use the units
                      being developped instead of the publicly available ones.
                      The  dir  specified  is  the  one containing the units U
                      directory.

       -M             Allow production of a confmagic.h file to  automagically
                      remap some well-known symbols to some other alternative,
                      like bcopy() being remapped  transparently  to  memcpy()
                      when   not   available.   This   option   is  turned  on
                      automatically when a confmagic.h file exists in the top-
                      level  directory. Simply remove that file if you wish to
                      disable this option permanently.

       -V             Print version number and exit.

TUTORIAL

       This (long) section is an introduction to metaconfig, in which we  will
       learn  all  the  basics. If you already know how to use metaconfig, you
       may safely skip to the next section.

   Overview
       Usually when you want to get some source package to compile on a  given
       platform  you  have to edit the main Makefile (assuming there is one!),
       choose a C compiler, make sure you have the proper libraries, and  then
       fire  the  make  command. If the package is reasonably well written, it
       will compile (without a warning being an option  :-).  In  itself,  the
       last  sentence  is  a real performance, since given the variety of UNIX
       platforms available today and the diversity of flavours, that means the
       author  of  the  package  has  gone into deep trouble to figure out the
       right choices given some standard trial, guessing  and  messing  around
       with system includes and types.

       However,  despite  all his talent, the author cannot possibly know that
       some system has a broken system call,  or  that  some  sytem  structure
       lacks  one  otherwise  standard field, or simply wheter a given include
       file exists or not. And I’m not considering the  implicit  assumptions,
       like  the type returned by the malloc() function or the presence of the
       rename() system call to name a few. But that knowledge is necessary  to
       achieve real portability.

       Now  let’s not abuse ourselves. Using that information requires greater
       skills, yet it can lead to more portable  programs  since  it  is  then
       written  in  a  system-independant  fashion and relies only on the fact
       that some assumption is true or false  on  a  particular  system,  each
       assumption  being  unrelated with each other. That is to say, we do not
       say: We’re on a BSD system or we are on a USG system. That’s too  fuzzy
       anyway  nowadays.   No,  we want to say to the source code: this system
       does not have the rename() system call and malloc() returns a (void  *)
       value.

       Metaconfig  is  a  tool  that  will  let  you  do  just  that, with the
       additional benefit of not having to hand-edit the Makefile if all  goes
       well. By running metaconfig, you create a shell script named Configure.
       Lots of efforts have been devoted to the Configure script internals  to
       ensure  it  will run on 99% of the existing shells available as of this
       writing.  Configure will probe the target system, asking questions when
       in  doubt and gather all the answers in one single shell file, which in
       turn can be used to automatically generate configured Makefiles  and  C
       include files.

       There  is only a limited (but quite large) set of symbols available for
       your shell scripts and C programs.  They  are  all  documented  in  the
       Glossary  file.  All you need to do is learn about them and start using
       them to  address  portability  and  configuration  problems.  Then,  by
       running  metaconfig,  a suitable Configure script will be generated for
       your package.

       The Configure script is built out several units (more than  300),  each
       unit  being  responsible  for defining a small number of shell and/or C
       symbols. Units are assembled together at the final stage, honoring  the
       dependency  graph  (one unit may need the result of several other units
       which are then placed before in the script).

   Symbols
       Symbols are the most important thing in the metaconfig world. They  are
       the  smallest  recognized  entity, usually a word, and can be granted a
       value at the end of the Configure execution. For instance, the  C  pre-
       processor symbol HAS_RENAME is a metaconfig symbol that is guranteed to
       be defined if, and only  if,  the  rename()  system  call  is  present.
       Likewise,  the  $ranlib  shell  variable  will  be set to either ’:’ or
       ’ranlib’ depending on whether the call to the ranlib program is  needed
       to  order a library file. How this works is not important for now, what
       is important is to understand that those symbols are given a life (i.e.
       a value) upon Configure execution.

       Using  symbols  is  relatively straightforward. In a C source file, you
       simply use the symbol value, as a pre-processor directive (for instance
       an: #ifdef HAS_RENAME) or, if the symbol value is a string, directly as
       you would use a macro in C. And in a shell file or a Makefile, you  may
       reference a shell symbol directly.

       Actually,  I’m  lying,  because  that’s  not completely as magic as the
       previous paragraph could sound. In a C file, you need  to  include  the
       Configure-produced  config.h  file, and you must wrap your shell script
       or Makefile in a .SH file and you may reference the shell  symbol  only
       in the variable substitution part of that .SH file. More on this later.

   Source Files
       Symbols may only appear in a  limited  set  of  source  files,  because
       metaconfig  will only scan those when looking for known symbols, trying
       to figure out which units it will need. You may  use  C  symbols  in  C
       source  files,  i.e. files with a .c, .h, .y or .l extension, and shell
       symbols are looked for only in .SH files.

       In order to get the value of a symbol, a C file needs  to  include  the
       special  config.h  file,  which is produced by Configure when C symbols
       are present. And .SH files are run through a  shell,  producing  a  new
       file.   However,  in  the  top  section  of  the  .SH file, the special
       config.sh file (also produced by running  Configure)  is  sourced,  and
       variable substitutions apply. Actually, config.h is produced by running
       the  metaconfig-produced  config_h.SH  file,   again   using   variable
       substitution.  So  we’re  going  to  look at that a little more closely
       since this is the heart of the whole configuration scheme...

   Variable Substitution
       There is shell construct called here document which enables  a  command
       to  take  an  input  specified  within the script itself. That input is
       interpreted by the shell as a double-quoted string or a  single  quoted
       string depending on the form of the here document specification.

       To  specify  a  here  document,  the  ’<<’ token is used, followed by a
       single identifier. From then on, the remaining script  lines  form  the
       input  for  the  command, until the here document is found on a line by
       itself.  Shell substitution (including shell variable substitutions) is
       done  unless  the  identifier  is  surrounded  by  single  quotes.  For
       instance:

            var=’first’
            tar=’second’
            echo "--> first here document:"
            cat <<EOM
            var=’$var’
            tar=’$tar’
            EOM
            echo "--> second here document:"
            cat <<’EOM’
            echo $var
            echo $tar
            EOM
            echo "--> end."

       will produce, when run through a shell:

            --> first here document:
            var=’first’
            tar=’second’
            --> second here document:
            echo $var
            echo $tar
            --> end.

       The first here document has its content interpreted whilst  the  second
       one  is  output as-is. Both are useful in a .SH script, as we are about
       to see.

   Using .SH Scripts
       A .SH script is usually produced by running the MakeSH script other  an
       existing  file,  transforming  file into a file.SH. Let’s take a single
       example. Here is a little script (let’s call it intsize) which prints a
       single  message,  the size of the int datatype in C.  Unfortunately, it
       has the value hardwired in it, thusly:

            #!/bin/sh
            intsize=’4’
            echo "On this machine, the int type is $intsize bytes"

       Let’s run makeSH on it by typing ’makeSH  intsize’.  We  get  a  single
       intsize.SH file that looks like this:

            case $CONFIG in
            ’’)
                 if test -f config.sh; then TOP=.;
                 elif test -f ../config.sh; then TOP=..;
                 elif test -f ../../config.sh; then TOP=../..;
                 elif test -f ../../../config.sh; then TOP=../../..;
                 elif test -f ../../../../config.sh; then TOP=../../../..;
                 else
                      echo "Can’t find config.sh."; exit 1
                 fi
                 . $TOP/config.sh
                 ;;
            esac
            : This forces SH files to create target in same directory as SH file.
            : This is so that make depend always knows where to find SH derivatives.
            case "$0" in
            */*) cd ‘expr X$0 : ’X\(.*\)/’‘ ;;
            esac
            echo "Extracting intsize (with variable substitutions)"
            : This section of the file will have variable substitutions done on it.
            : Move anything that needs config subs from !NO!SUBS! section to !GROK!THIS!.
            : Protect any dollar signs and backticks that you do not want interpreted
            : by putting a backslash in front.  You may delete these comments.
            $spitshell >intsize <<!GROK!THIS!
            $startsh
            !GROK!THIS!

            : In the following dollars and backticks do not need the extra backslash.
            $spitshell >>intsize <<’!NO!SUBS!’
            intsize=’4’
            echo "On this machine, the int type is $intsize bytes"
            !NO!SUBS!
            chmod 755 intsize
            $eunicefix intsize

       The  first  part  of  this  script (in the case statement) is trying to
       locate the config.sh file, in order to source it. The $CONFIG  variable
       is  false  by  default, by true when config.sh has been sourced already
       (which would be  the  case  if  this  file  was  executed  from  within
       Configure itself, but let’s not confuse the issue here).

       Once the config.sh file has been sources, all the shell symbols defined
       by Configure are set. We know reach a second case  statement,  used  to
       change  the  current  directory  should  a  path  be used to reach this
       program (for instance if we said ’sh ../scripts/intsize.SH’,  we  would
       first  run ’cd ../scripts’ before continuing). If you do not understand
       this, don’t worry about it.

       Here comes the  intersting  stuff.  This  script  uses  the  $spitshell
       variable,  and  it’s  not  something  we  know about...yet. If you look
       through the Glossary file, you will see that this is a  variable  known
       by  metaconfig.  If  you  make  this file part of your distribution (by
       including it in the MANIFEST.new file, we’ll come back  to  that  later
       on)  and  run  metaconfig,  then  the Configure script will determine a
       suitable value for this variable and it will be set in config.sh.  Same
       goes  for  $startsh  and  the  mysterious  $eunicefix  at the end. On a
       reasonable system, the relevant part of config.sh would look like this:

            spitshell=’cat’
            startsh=’#!/bin/sh’
            eunicefix=’:’

       Ah!  We’re  getting there. Now it looks familiar. We’re facing a single
       cat  command  whose  input  comes  from  a  variable-interpolated  here
       document  and  whose output is redirected to intsize. The value will be
       that of $startsh, i.e. ’#!/bin/sh’. Fine so far.

       Then we reach the second here document expansion, to get the  remaining
       of  the  script.  This  time, the here document symbol is surrounded by
       single quotes so the contents will be appended verbatim to the  intsize
       file.  So, by running ’sh intsize.SH’, we get the following output:

            Extracting intsize (with variable substitutions)

       and by looking at the produced intsize file, we see:

            #!/bin/sh
            intsize=’4’
            echo "On this machine, the int type is $intsize bytes"

       which  is  exactly  what  we  had  at the beginning. So far, it’s a no-
       operation  procedure...  But,  how  marvelous!  It  so  happens   (pure
       coincidence, trust me!), that metaconfig knows about the $intsize shell
       symbol. By moving  the  initialization  of  intsize  to  the  variable-
       interpolated  area  of  the  .SH  script  and  initializing it with the
       Configure-computed value, and removing the now useless  comments  added
       by makeSH, we get:

            case $CONFIG in
            ’’)
                 if test -f config.sh; then TOP=.;
                 elif test -f ../config.sh; then TOP=..;
                 elif test -f ../../config.sh; then TOP=../..;
                 elif test -f ../../../config.sh; then TOP=../../..;
                 elif test -f ../../../../config.sh; then TOP=../../../..;
                 else
                      echo "Can’t find config.sh."; exit 1
                 fi
                 . $TOP/config.sh
                 ;;
            esac
            case "$0" in
            */*) cd ‘expr X$0 : ’X\(.*\)/’‘ ;;
            esac
            echo "Extracting intsize (with variable substitutions)"
            $spitshell >intsize <<!GROK!THIS!
            $startsh
            intsize=’$intsize’
            !GROK!THIS!

            $spitshell >>intsize <<’!NO!SUBS!’
            echo "On this machine, the int type is $intsize bytes"
            !NO!SUBS!
            chmod 755 intsize
            $eunicefix intsize

       Of  course,  running  this script through a shell will again output the
       same script. But if we run Configure on  a  machine  where  an  int  is
       stored  as  a 64 bits quantity, config.sh will set intsize to 8 and the
       intsize script will bear the right value and print:

            On this machine, the int type is 8 bytes

       which is correct. Congratulations! We  have  just  configured  a  shell
       script!!

   Producing config.h
       We  can  now  have  a  look  at  the  way  config.h  is produced out of
       config_h.SH. We know that running Configure produces a config.sh script
       (how  exactly  this  is done is not strictly relevant here, but for the
       curious, it’s  another  here  document  substitution  within  Configure
       itself). The config_h.SH itself is built by metaconfig at the same time
       Configure is, provided you make use of at least  one  C  symbol  within
       your sources.

       Let’s  have  a  look at some random config_h.SH file to see what really
       happens:

            case $CONFIG in
            ’’)
                 if test -f config.sh; then TOP=.;
                 elif test -f ../config.sh; then TOP=..;
                 elif test -f ../../config.sh; then TOP=../..;
                 elif test -f ../../../config.sh; then TOP=../../..;
                 elif test -f ../../../../config.sh; then TOP=../../../..;
                 else
                      echo "Can’t find config.sh."; exit 1
                 fi
                 . $TOP/config.sh
                 ;;
            esac
            case "$0" in
            */*) cd ‘expr X$0 : ’X\(.*\)/’‘ ;;
            esac
            echo "Extracting config.h (with variable substitutions)"
            sed <<!GROK!THIS! >config.h -e ’s!^#undef!/define!’ -e ’s!^#un-def!#undef!’
            /*
             * This file was produced by running the config_h.SH script, which
             * gets its values from config.sh, which is generally produced by
             * running Configure.
             *
             * Feel free to modify any of this as the need arises.  Note, however,
             * that running config.h.SH again will wipe out any changes you’ve made.
             * For a more permanent change edit config.sh and rerun config.h.SH.
             */

            /* Configuration time: $cf_time
             * Configured by: $cf_by
             * Target system: $myuname
             */

            #ifndef _config_h_
            #define _config_h_

            /* bcopy:
             *   This symbol is maped to memcpy if the bcopy() routine is not
             *   available to copy strings.
             */
            /* HAS_BCOPY:
             *   This symbol is defined if the bcopy() routine is available to
             *   copy blocks of memory. You should not use this symbol under
             *   normal circumstances and use bcopy() directly instead, which
             *   will get mapped to memcpy() if bcopy is not available.
             */
            #$d_bcopy HAS_BCOPY /**/
            #ifndef HAS_BCOPY
            #ifdef bcopy
            #un-def bcopy
            #endif
            #define bcopy(s,d,l) memcpy((d),(s),(l))          /* mapped to memcpy */
            #endif

            /* HAS_DUP2:
             *   This symbol, if defined, indicates that the dup2 routine is
             *   available to duplicate file descriptors.
             */
            #$d_dup2 HAS_DUP2   /**/

            /* I_STRING:
             *   This symbol, if defined, indicates to the C program that it should
             *   include <string.h> (USG systems) instead of <strings.h> (BSD systems).
             */
            #$i_string I_STRING      /**/

            #endif
            !GROK!THIS!

       At the top of the file, we recognize the standard .SH construct that we
       have  already  studied in detail. Next comes the extraction of the file
       itself, via a here document with variable substitutions. However,  here
       we  do  not use a plain cat but a sed instead, since we need to do some
       further editing on-the-fly. We’ll see why later  on,  so  let’s  forget
       about it right now.

       We  now  reach  the  leading  comment,  and the file is tagged with the
       configuration time, the target system, etc... (those  variables  coming
       from  the  sourced config.sh file have been set up by Configure).  That
       comment header is followed by a ’#ifndef’ protection to  guard  against
       multiple inclusions of this file. Then comes the heart of the file...

       It  helps  to  know  that  $d_*  and  $i_*  variables are set to either
       ’define’ or ’undef’ by Configure, depending on wether a function or  an
       include file is present on the system or not.  That means the:

            #$d_bcopy HAS_BCOPY /**/

       line will be expanded to either:

            #define HAS_BCOPY /**/

       if the $d_bcopy variable is set to ’define’ or:

            #undef HAS_BCOPY /**/

       if  $d_bcopy  was  set  to  ’undef’, because the feature was not there.
       However, that’s not what gets written in the config.h file  because  of
       the  sed  filter  we have already seen, which will transform the second
       form into:

            /*#define HAS_BCOPY /**/

       That’s a handy form for later editing of config.h because you only need
       to  remove the leading ’/*’ if you want to override Configure’s choice.
       Likewise, you may add a single ’/*’ at the  beginning  of  a  ’#define’
       line  to  avoid the definition of a particular symbol. This is why each
       symbol definition is protected by  a  trailing  ’/**/’,  to  close  the
       leading comment opened by ’/*’ (comments are not nested in C).

       Now  transforming  ’#undef’ into ’/*#define’ is nice, but if we want to
       actually write a ’#undef’, we’re stuck... unless we write it  as  ’#un-
       def’  and  let sed fix that to ’#undef’ while producing config.h, which
       is what is actually done here.

       The same kind of reasoning applies to those two lines:

            #$d_dup2 HAS_DUP2   /**/
            #$i_string I_STRING      /**/

       and assuming config.sh defines:

            d_dup2=’define’
            i_string=’undef’

       we’ll get in the produced config.h:

            #define HAS_DUP2   /**/
            /*#define I_STRING      /**/

       Clear as running water? Good!

       Now it should be obvious that by  including  config.h  in  all  your  C
       source  files,  you  get  to  know  what  Configure has guessed on your
       system. In effect, by using those symbols, you are writing configured C
       code,  since  metaconfig will know that you need those symbols and will
       generate a suitable config_h.SH file as well as all the necessary  code
       in Configure to compute a proper value for them (by assigning values to
       associated shell variables).

   Running Metaconfig
       Let’s focus on the metaconfig program for a while to understand how  it
       uses  its  units  and  your  source  code  to  produce  all  the needed
       configuration files. If you intend to write new units, you should  have
       a good understanding of the whole scheme.

       If  there  is  no  MANIFEST.new  file,  metaconfig  will try to use the
       MANIFEST  file  instead,  for  convenience.   Everywhere   we   mention
       MANIFEST.new,  it  can  be  understood as MANIFEST provided there is no
       MANIFEST.new file found at the root of your package.

       Assuming your MANIFEST.new file is  properly  set  and  lists  all  the
       source  files  you  wish to configure, and that you have run packint in
       your root source directory to create  a  .package  file,  you  may  run
       metaconfig and you’ll get the following:

            $ metaconfig
            Locating units...
            Extracting dependency lists from 312 units...
            Extracting filenames (*.[chyl] and *.SH) from MANIFEST.new...
            Building a Wanted file...
              Scanning .[chyl] files for symbols...
              Scanning .SH files for symbols...
            Computing optimal dependency graph...
              Building private make file...
              Determining loadable units...
              Updating make file...
            Determining the correct order for the units...
            Creating Configure...
            Done.

       The  first  phase looks for all the units files (ending with .U) in the
       public directory first, then in your private one. If you copy a  public
       file  in  your private U directory (i.e. a directory named U at the top
       level of your package), it will override the public  version.  Once  it
       has  a list of all the available units, it parses them and extracts all
       the ?MAKE: lines to know about the dependencies  and  the  known  shell
       symbols.  It also focuses on the ?H: lines to learn about the C symbols
       and which shell symbols needs to be computed to get a proper value  for
       that C symbol (so we have another level of dependencies here).

       Next,  the  proper  filenames are extracted from the MANIFEST.new files
       and a Wanted file is built: that file lists all the C symbols  and  the
       shell  symbols  needed for that package. We first scan the C-type files
       for C symbols, then propagate  the  dependencies  to  their  associated
       shell symbols (gathered from ?H: lines). Next .SH files are scanned and
       finally all the shell symbols are known.

       A temporary Makefile is built and metaconfig  tries  to  make  all  the
       shell  symbols to see what commands (listed on the second ?MAKE: lines)
       are executed, and thus which units are really  needed.  Optional  units
       not  otherwise required are removed and a second Makefile is generated.
       This time, we know about all the units  and  their  respective  orders,
       optional  units  having  been  removed  and default values computed for
       their shell symbols. The Configure script can then be generated,  along
       with config_h.SH. We’re done.

   Conventions
       Proper  conventions  needs  to  be  followed  to make the whole process
       sound.  There is a case convention for  units  and  a  variable  naming
       convention.

       All  units  should have their first letter lower-cased, unless they are
       special units. By special, we mean they do not really define new  shell
       variables  that  can  be  used by the user in his .SH files, but rather
       units producing  scripts  or  shell  variables  that  are  to  be  used
       internally  by  the  Configure  script. Typical examples are the Init.U
       file which is the  main  variable  initialization,  or  Myread.U  which
       produces  the  myread script used almost everywhere in Configure when a
       question is to be asked to the user.

       Non-special units then subdivise in two distinct groups: units defining
       variables  associated  to a C symbol and units defining shell variables
       of their own. The first group is further divided in  variables  related
       to  include  files  (their name begin with i_) and variables related to
       other definitions (name starting with d_). The second group have  names
       standing  for  itself, for instance cc.U defines the $cc shell variable
       whose value is the C compiler to be used.

       Special units sometimes reserve themselves  some  pre-defined  variable
       and  return  "results" in other well-known variables. For instance, the
       myread script produced by Myread.U  expects  the  prompt  in  $rp,  the
       default answer in $dflt and places the user answer in $ans. This is not
       documented in this manual page: you have to go and  look  at  the  unit
       itself to understand which variables are used and how the unit is to be
       used.

   Using The Glossary
       The Glossary file is automatically produced by  the  makegloss  script,
       which  extracts  the  information  from  ?S:,  ?C: and ?MAKE: lines and
       reformats them into an alphabetically sorted glossary.  It is important
       to  read the Glossary to know about the symbols you are allowed to use.
       However, the Glossary will not tell you  how  to  use  them.   Usually,
       that’s up to you.

       One  day,  you  will  probably  write  your own units and you will know
       enough about metaconfig to do  so  quickly  and  efficiently.  However,
       never  forget  to properly document your work in the ?S: and ?C: lines,
       or other people will not be able to reuse it. Remember about  the  time
       where you had only the Glossary and this manual page to get started.

   Conclusion
       Now   that  you  know  the  metaconfig  basics,  you  should  read  the
       DESCRIPTION section, then skip to the REFERENCE section to learn  about
       all  the gory details such as the allowed syntax for unit control lines
       (lines starting with a ’?’) or  the  distinct  MAKE  commands  you  are
       allowed to use.

REFERENCE

       This  section documents the internals of metaconfig, basically the unit
       syntax, the special units you should know about and the hint files.

   General Unit Syntax
       A metaconfig unit is  divided  into  two  distinct  parts.  The  header
       section  (lines  starting  with  ’?’)  and  a shell section (code to be
       included in the Configure script). It is possible to add ’?X:’ comments
       anywhere  within the unit, but the other ’?’ lines (also called control
       lines) have a strict ordering policy.

       If a control line is too long, it is possible to use a continuation  by
       escaping the final new-line with a backslash and continuing on the next
       line (which should then be indented by spaces or tabs).

       The following is a formal description of each  of  the  control  lines.
       Unless stated otherwise, the order of this presentation is the order to
       be used within the unit.

       ?RCS: free text
            To be used for RCS comments, at the top of the unit.

       ?X: any text
            General purpose comments. May appear anywhere in the unit but must
            be  left  justfied. For RCS comments, please use the ?RCS: comment
            form.

       ?MAKE:symbol list: dependency list [+optional]
            This is the first dependency line. The first  symbol  list  should
            list  all  the  symbols  built  by  this unit (i.e. whose value is
            computed by the shell section of  the  unit).  Symbols  should  be
            space  separated. If a defined symbol is for internal use only and
            should  not appear in the generated config.sh file, then it should
            be   preceded   by  a  ’+’  (not  to  be  confused  with  optional
            dependencies defined hereafter).  The  second  part  of  the  list
            (after the middle ’:’) is the unit dependency.  It should list all
            the needed special units, as well as all the symbols used  by  the
            shell  implementation. If a symbol is nedded but its configuration
            value is not critical, it can be preceded by a ’+’, in which  case
            it is called a conditional dependency: its corresponding unit will
            be loaded if, and only if, that symbol is otherwise really wanted;
            otherwise the default value will be used.

       ?MAKE:tab command
            There  can  be  one  or  more  command lines following the initial
            dependency lines.  Those commands will be executed when  the  unit
            is  wanted  to  load  them into Configure. See the paragraph about
            make commands for more information.  Note  that  the  leading  tab
            character is required before the command.

       ?Y:layout
            Declare  a  layout  directive for this unit. That directive may be
            one of the strings top, default or bottom (case does  not  matter,
            recommended  style  is  to spell them out uppercased). If omitted,
            default is assumed.

            This directive is only required if you wish to force a unit at the
            top  or  the  bottom  of  the  generated Configure script, as unit
            dependencies permit it. Important questions may thus be forced  at
            the  beginning.  Within  the  same  layout class, units are sorted
            alphabetically with two special  cases  for  d_*  and  i_*  units,
            forced  respectively  at  the top and bottom of their classes (but
            these should belong to the default class).

            It you force at the top a unit whose dependencies require all  the
            other  unit  to  precede  it,  you  achieve  nothing  interesting.
            Therefore, that directive should really be used  to  increase  the
            priority  of  some  interactive  units  that do not depend on many
            other user-visible symbols, like path-related questions.

       ?S:symbol_name [(obsolete symbol list)]:
            Introduces a shell symbol.  This  first  line  names  the  symbol,
            optionally  followed  by  a  list enclosed between parenthesis and
            giving the obsolete equivalent. Those  obsolete  symbols  will  be
            remapped  to  the  new  symbol_name  if  the -o option is given to
            metaconfig.

       ?S:any text, for Glossary
            Basically a comment describing the shell  symbol,  which  will  be
            extracted by makegloss into the Glossary file.

       ?S:. Closes the shell symbol comment.

       ?C:symbol_name [~ alias] [(obsolete symbol list)]:
            Introduces  a new C symbol. The alias name is the name under which
            the C symbol will be controlled,  i.e.  if  the  alias  symbol  is
            wanted,  then  that  C  symbol  will be written in the config_h.SH
            file. Usually, the alias is just ’%<’ (stands for the unit’s name)
            and there is also a ?W: line mapping a C symbol to the alias. Also
            the relevant parts of the ?H: lines are explicitely protected by a
            ’?%<’  condition.  See  the  symbol  aliasing  paragraph  for more
            details.  The remaining of  the  line  is  the  optional  obsolete
            symbol  list, which lists old equivalents for the new symbol_name.

       ?C:any text, for Glossary and config_h.SH
            Basically a  comment  describing  the  C  symbol,  which  will  be
            extracted  by  makegloss  into the Glossary file and by metaconfig
            into the config_h.SH file if the symbol is wanted (or if its alias
            is wanted when symbol aliasing is used).

       ?C:. Closes the C symbol comment.

       ?H:?symbol:config_h.SH stuff
            This  is  the general inclusion request into config_h.SH. The line
            is only written when the guarding symbol is  really  wanted.  This
            general form is needed when C symbol aliasing was used. Otherwise,
            if you use one of the other  "standard"  forms,  the  guarding  is
            automatically done by metaconfig itself.

       ?H:#$d_var VAR "$var"
            Conditionally  defines  the  VAR C symbol into $var when is set to
            ’define’. Implies a ’?VAR:’  guarding  condition,  and  metaconfig
            automatically  links  VAR  to  its two shell variable dependencies
            (i.e. both $d_var and $var will be flagged as  wanted  if  VAR  is
            used in C sources).

       ?H:#define VAR [optional text]
            Always  defines  the VAR C symbol to some value. Implies a ’?VAR:’
            guarding condition. An automatic shell dependency is made  to  the
            unit itself.

       ?H:#define VAR(x,y,z) $var
            Always defines the macro VAR to be the value of the $var variable.
            It is up to the unit to ensure $var holds a   sensible  value.  An
            automatic  dependency  between  the  C  macro  VAR  and  the shell
            variable is established, and the  whole  line  is  guarded  by  an
            implicit ’?VAR:’.

       ?H:#$d_var VAR
            Conditionally defines VAR if $d_var is set to ’define’.  Implies a
            ’?VAR:’ guarding  condition.  An  automatic  shell  dependency  is
            generated towards $d_war.

       ?H:#define VAR "$var"
            Assigns  a configured value to the VAR C symbol. Implies a ’?VAR:’
            gurading condition. An automatic shell dependency is generated  to
            link VAR and $var.

       ?H:. Closes the config_h.SH inclusion requests.

       ?M:C symbol: C dependencies
            Introduces   magic   definition   concerning  the  C  symbol,  for
            confmagic.h, and defines the guarding symbol for the remaining ?M:
            definitions. This line silently implies ’?W:%<:C symbol’, i.e. the
            unit will be loaded into Configure if the C symbol appears  within
            the  C  sources,  whether magic is used or not. The C dependencies
            are activated  when  magic  is  used,  in  order  to  force  their
            definition in config_h.SH. However, if magic is not used but the C
            symbol appears in the source without the  needed  C  dependencies,
            you  will  be warned every time the Wanted file is built, since it
            may  be  a  portability  issue  (and  also  because  the  unit  is
            unconditionally  loaded  into  Configure  whenever the C symbol is
            used, regardless of the other ?C: lines from the unit).

       ?M:cpp defs
            Defines the magic cpp mapping  to  be  introduced  in  confmagic.h
            whenever the concerned symbol is used. There is an implicit ’?sym’
            guarding where sym is the symbol name defined by the  leading  ?M:
            line.

       ?M:. Closes the confmagic.h inclusion request.

       ?W:shell symbol list:C symbol list
            Ties  up  the  destiny  of  the  shell  symbols with that of the C
            symbols: if any of the C symbols listed is wanted,  then  all  the
            shell symbols are marked as wanted. Useful to force inclusion of a
            unit (shell symbol list set to ’%<’) when the presence of  some  C
            symbol  is  detected.  The shell symbol list may be left empty, to
            benefit from the side effect  of  C  symbol  location  within  the
            builtin pre-processor (symbol being defined for that pre-processor
            if located in the source). To look for patterns with  a  space  in
            them,  you need to quote the C symbols within simple quotes, as in
            ’struct timezone’.

       ?V:read-only symbols:read-write symbols
            This is a metalint hint and should be used only in  special  units
            exporting  some  shell  variables. The variables before the middle
            ’:’ are exported read-only (changing them will issue  a  warning),
            while other symbols may be freely read and changed.

       ?F:files created
            This  line  serves two purposes: it is a metalint hint, and also a
            placeholder for future jmake use.  It  must  list  three  kind  of
            files: the temporary one which are created for a test, the private
            UU ones created in the UU directory for  later  perusal,  and  the
            public  ones  left in the root directory of the package. Temporary
            files must be listed with a preceding ’!’ character (meaning  "no!
            they’re  not re-used later!"), private UU files should be preceded
            by a ’./’ (meaning: to use them, say ./file, not just  file),  and
            public ones should be named as-is.

       ?T:shell temporaries
            Another  metalint  hint.  This  line lists all the shell variables
            used as temporaries within the shell section of this unit.

       ?D:symbol=’value’
            Initialization value for symbols used as conditional dependencies.
            If  no  ?D:  line is found, then a null value is used instead. The
            metalint program will warn you if a symbol is used at  least  once
            as  a  conditional  dependency  and  does  not  have  a proper ?D:
            initialization. It’s a good practice to add those lines even for a
            null  initialization  since it emphasizes on the possibly optional
            nature of a symbol.

       ?O:any message you want
            This directive indicates that this unit is obsolete  as  a  whole.
            Whenever  usage  of  any of its symbols is made (or indirect usage
            via dependencies),  the  message  is  output  on  the  screen  (on
            stderr).  You  can put one ore more lines, in which case each line
            will be printed, in order.

       ?LINT:metalint hints
            See the metalint manual page for an explaination of  the  distinct
            hints that can be used.

       ?INIT:initialization code
            The  initialization  code specified by this line will be loaded at
            the top of the Configure script provided the unit is needed.

   C Symbol Aliasing
       Sometimes it is not  possible  to  rely  on  metaconfig’s  own  default
       selection  for  config_h.SH  comments  and  C symbol definition. That’s
       where aliasing comes into play. Since it’s rather  tricky  to  explain,
       we’ll study an example to understand the underlying mechanism.

       The  d_const.U  unit  tries to determine whether or not your C compiler
       known about the const keyword. If it doesn’t  we  want  to  remap  that
       keyword  to  a  null  string,  in  order  to  let  the program compile.
       Moreover, we want to automatically trigger the test when the const word
       is used.

       Here are the relevant parts of the d_const.U unit:

            ?MAKE:d_const: cat cc ccflags Setvar
            ?MAKE:    -pick add $@ %<
            ?S:d_const:
            ?S:  This variable conditionally defines the HASCONST symbol, which
            ?S:  indicates to the C program that this C compiler knows about the
            ?S:  const type.
            ?S:.
            ?C:HASCONST ~ %<:
            ?C:  This symbol, if defined, indicates that this C compiler knows about
            ?C:  the const type. There is no need to actually test for that symbol
            ?C:  within your programs. The mere use of the "const" keyword will
            ?C:  trigger the necessary tests.
            ?C:.
            ?H:?%<:#$d_const HASCONST     /**/
            ?H:?%<:#ifndef HASCONST
            ?H:?%<:#define const
            ?H:?%<:#endif
            ?H:.
            ?W:%<:const
            ?LINT:set d_const
            ?LINT:known const
            : check for const keyword
            echo " "
            echo ’Checking to see if your C compiler knows about "const"...’ >&4
            /bin/cat >const.c <<’EOCP’
            main()
            {
                 const char *foo;
            }
            EOCP
            if $cc -c $ccflags const.c >/dev/null 2>&1 ; then
                 val="$define"
                 echo "Yup, it does."
            else
                 val="$undef"
                 echo "Nope, it doesn’t."
            fi
            set d_const
            eval $setvar

       First we notice the use of a ?W: line, which basically says: "This unit
       is wanted when the const keyword is used in a C  file.".  In  order  to
       conditionally  remap  const  to  a  null string in config.h, I chose to
       conditionally define HASCONST via $d_const.

       However, this raises a problem, because  the  HASCONST  symbol  is  not
       going  to  be used in the sources, only the const token is. And the ?H:
       line  defining  HASCONST  is  implicitely   guarded   by   ’?HASCONST’.
       Therefore, we must add the explicit ’?%<’ constraint to tell metaconfig
       that those lines should be included in config_h.SH  whenever  the  ’%<’
       symbol gets wanted (%< refers to the unit’s name, here d_const).

       That’s  almost perfect, because the ?W: line will want d_const whenever
       const is used, then the ?H: lines will get included in the  config_h.SH
       file.  However, the leading comment (?C: lines) attached to HASCONST is
       itself also guarded via HASCONST, i.e. it has an  implicit  ’?HASCONST’
       constraint. Hence the need for aliasing the HASCONST symbol to ’%<’.

       The   remaining   part   of   the  unit  (the  shell  part)  is  really
       straightforward.  It simply tries to compile a sample C  program  using
       the  const  keyword.   If  it can, then it will define $d_const via the
       $setvar fonction (defined by the  Setvar.U  unit).  See  the  paragraph
       about special units for more details.

   Make Commands
       On  the  ?MAKE:  command  line,  you  may  write  a shell command to be
       executed  as-is  or  a  special  -pick  command  which  is  trapped  by
       metaconfig  and  parsed  to see what should be done. The leading ’-’ is
       only there to prevent make from failing when the command returns a non-
       zero status -- it’s not really needed since we use ’make -n’ to resolve
       the dependencies, but I advise you  to  keep  it  in  case  it  becomes
       mandatory in future versions.  The syntax of the pick command is:

            -pick cmd $@ target_file

       where  $@  is  the  standard  macro  within  Makefiles standing for the
       current target (the name of the unit being built,  with  the  final  .U
       extension  stripped).  The cmd part is the actual metaconfig command to
       be  run,  and  the  target_file  is  yet   another   parameter,   whose
       interpretation  depends  on  the  cmd  itself. It also has its final .U
       extension stripped and normally refers to a unit file, unless it  start
       with  ’./’  in  which  case it references one of the metaconfig control
       files in the ’.MT directory.

       The available commands are:

       add       Adds the target_file to Configure.

       add.Config_sh
                 Fills in that part of Configure producing the config.sh file.
                 Only   used  variables  are  added,  conditional  ones  (from
                 conditional dependencies) are skipped.

       add.Null  Adds the section initializing all the shell variables used to
                 an empty string.

       c_h_weed  Produces  the  config_h.SH file. Only the necessary lines are
                 printed.

       cm_h_weed Produces the confmagic.h file. Only the necessary  lines  are
                 printed.   This command is only enabled when the -M switch is
                 given, or when a confmagic.h file already exists.

       close.Config_sh
                 Adds the final ’EOT’ symbol on a line by itself  to  end  the
                 here document construct producing the config.sh file.

       prepend   Prepends the content of the target to the target_file if that
                 file is not empty.

       weed      Adds the unit to Configure like the  add  command,  but  make
                 some  additional  tests to remove the ’?symbol’ and ’%symbol’
                 lines from the target_file if the symbol  is  not  wanted  or
                 conditionally wanted. The ’%’ form is only used internally by
                 metaconfig while producing its own  .U  files  in  the  ’.MT’
                 directory.

       wipe      Same   as  add  really,  but  performs  an  additional  macro
                 substitution.  The available  macros  are  described  in  the
                 Hardwired Macros paragraph.

       As a side note, metaconfig generates a -cond command internally to deal
       with conditional dependencies. You should not use it by  yourself,  but
       you  will  see  it  if  scanning  the  generated  Makefile  in  the .MT
       directory.

   Hardwired Macros
       The following macros are recognized by the wipe command and  subsituted
       before inclusion in Configure:

       <BASEREV> The  base  revision  number  of  the  package,  derived  from
                 .package.

       <DATE>    The current date.

       <MAINTLOC>
                 The e-mail address of the maintainer of this package, derived
                 from your .package.

       <PACKAGENAME>
                 The  name of the package, as derived from your .package file.

       <PATCHLEVEL>
                 The patch level of  the  metaconfig  program  (deprecated  in
                 favor of <REVISION>).

       <REVISION>
                 The SVN revision level of the metaconfig program.

       <VERSION> The version number of the metaconfig program.

       Those  macros  are  mainly used to identify the metaconfig version that
       generated a particular Configure script and for which  package  it  was
       done.  The e-mail address of the maintainer is hardwired in the leading
       instructions that Configure prints when starting.

       Recent metaconfig versions understand a much more general syntax of the
       form:

                 <$variable>

       which is replaced at Configure-generation time by the value of variable
       taken from your .package file.  Eventually,  the  old  hardwired  macro
       format will disappear, and <$baserev> will replace <BASEREV> in all the
       supplied units.

   Special Units
       The following special units are used  to  factorize  code  and  provide
       higher  level  functionalities. They either produce a shell script that
       can be sourced or a shell  variable  that  can  be  eval’ed.  Parameter
       passing is done via well-know variables, either named or anonymous like
       $1, $2, etc... (which can be easily set via the  shell  set  operator).
       When  Configure  executes,  it creates and goes into a UU directory, so
       every produced script lies in there and does  not  interfere  with  the
       files from your package.

       Here  are  the sepcial units that you should know about, and the way to
       use them.

       Cppsym.U
            This unit produces a shell script called Cppsym, which can be used
            to  determine  whether  any  symbol  in a list is defined by the C
            preprocessor or C compiler you have specified.  It  can  determine
            the  status  of any symbol, though the symbols in (attribute list)
            are more easily determined.

       Csym.U
            This sets the $csym shell variable, used internally  by  Configure
            to check whether a given C symbol is defined or not. A typical use
            is:

                 set symbol result [-fva] [previous]
                 eval $csym

            That will set the result variable to ’true’ if the function  [-f],
            variable  [-v]  or  array [-a] is defined, ’false’ otherwise. If a
            previous value  is  given  and  the  -r  switch  was  provided  to
            Configure  (see  the Configure Options paragraph), then that value
            is re-used without questioning.

            The way this computation is done depends on the  answer  the  user
            gives  to  the question Configure will ask about whether it should
            perform an nm extraction or not. If the exctraction was performed,
            the  unit  simply  looks  through  the  symbol  list, otherwise it
            performs a compile-link test, unless -r was  given  to  reuse  the
            previously computed value, naturally...

       End.U
            By  copying  this unit into your private U directory and appending
            dependencies on the ?MAKE: line, you can force a given unit to  be
            loaded  into  Configure  even  if it is not otherwise wanted. Some
            units may only be forced into Configure that way.

       Filexp.U
            This unit  produces  a  shell  script  filexp  which  will  expand
            filenames beginning with tildes. A typical use is:

                 exp_name=‘./filexp $name‘

            to assign the expanded file name in exp_name.

       Findhdr.U
            This  unit  produces  a findhdr script which is used to locate the
            header files  in  $usrinc  or  other  stranger  places  using  cpp
            capabilities.   The script is given an include file base name like
            ’stdio.h’ or ’sys/file.h’ and it returns  the  full  path  of  the
            inlcude  file and a zero status if found, or an empty string and a
            non-zero status if the file could not be located.

       Getfile.U
            This unit produces a bit of shell code that  must  be  sourced  in
            order  to get a file name and make some sanity checks. Optionally,
            a ~name expansion is performed.

            To use this unit, $rp and $dflt must hold  the  question  and  the
            default  answer,  which  will be passed as-is to the myread script
            (see  forthcoming  Myread.U).  The  $fn  variable   controls   the
            operation and the result is returned into $ans.

            To  locate  a  file  or directory, put ’f’ or ’d’ in f~/. If a ’~’
            appears, then ~name substitution is allowed.  If  a  ’/’  appears,
            only  absolute  pathnames  are accepted and ~name subsitutions are
            always expanded before returning.  If ’+’ is specified,  existence
            checks  are  skipped.  If ’n’ appears within $fn, then the user is
            allowed to answer ’none’.

            Usually, unless you  asked  for  portability,  ~name  substitution
            occurs  when  requested. However, there are some times you wish to
            bypass portability and force the substitution. You may use the ’e’
            letter (expand) to do that.

            If  the  special  ’l’ (locate) type is used, then the $fn variable
            must end with a ’:’, followed by a file basename. If the answer is
            a directory, the file basename will be appended before testing for
            file existence. This is  useful  in  locate-style  questions  like
            this:

                 dflt=’~news/lib’
                 : no need to specify ’d’ or ’f’ when ’l’ is used
                 fn=’l~:active’
                 rp=’Where is the active file?’
                 . ./getfile
                 active="$ans"

            Additionally,  the  ’p’  (path)  letter may be used in conjunction
            with ’l’ to tell getfile that an answer without a ’/’ in it should
            be  accepted,  assuming  that it will be in everyone’s PATH at the
            time this value will be needed.

            Also useful is the possibility to specify a list of  answers  that
            should  be  accepted verbatim, bypassing all the checks. This list
            must be within parenthesis and items must be comma separated, with
            no  interleaving  spaces.   Don’t  forget  to  quote the resulting
            string  since  parenthesis  are  meaningful  to  the  shell.   For
            instance:

                 dflt=’/bin/install’
                 fn=’/fe~(install,./install)’
                 rp=’Use which install program?’
                 . ./getfile
                 install="$ans"

            would let the user only specify fully qualified paths referring to
            existing  files,  but  still  allow  the  special  "install"   and
            "./install"  answers as-is (assuming of course something will deal
            with them specially later on  in  the  chain  since  they  do  not
            conform with the general expected frame).

            If the answer to the question is ’none’, then the existence checks
            are skipped and the empty string  is  returned.  Note  that  since
            getfile  calls  myread internally, all the features available with
            myread apply here to.

            If a completely expanded  value  is  needed  (for  instance  in  a
            Makefile), you may use the $ansexp variable which is always set up
            properly by getfile as the expanded version of $ans. Of course, it
            will not expand ~name if you did not allow that in the first place
            in the $fn variable.

       Inhdr.U
            This unit produces the $inhdr shell variable, used  internally  by
            Configure  to  check  whether  a  set  of  headers exist or not. A
            typical use is:

                 set header i_header [ header2 i_header2 ... ]
                 eval $inhdr

            That will print a message, saying whether the header was found  or
            not  and  set  the i_header variable accordingly. If more than one
            header is specified and the first header is not found, we try  the
            next one, until the list is empty or one is found.

       Inlibc.U
            This  unit produces the $inlibc shell variable, used internally by
            Configure to check whether a given C function is defined  or  not.
            A typical use is:

                 set function d_func
                 eval $inlibc

            That  will  print a message, saying whether the function was found
            or not and set $d_func accordingly. Internally, it used the  $csym
            routine.

       Loc.U
            This  important unit produces a shell script loc which can be used
            to find out where in a list of directories a given file lies.  The
            first  argument  specifies  the  file  to  be  located, the second
            argument is what will be returned if the  search  fails,  and  the
            reamining arguments are a list of directories where the file is to
            be searched. For instance:

                 dflt=‘./loc sendmail.cf X /usr/lib /var/adm/sendmail /lib‘

            would set $dflt to X if no sendmail.cf file was  found  under  the
            listed directories, or something like /usr/lib/sendmail.cf on some
            systems. See also Getfile.U.

       MailAuthor.U
            This unit needs to be included on the  ?MAKE:  line  of  your  own
            private  End.U  to  make  it into Configure. It offers the user to
            register himself to the author, optionally being notified when new
            patches  arrive  or  receiving them automatically when issued. You
            need to install mailagent to do this (at least version 3.0).

       MailList.U
            This unit needs to be included on the  ?MAKE:  line  of  your  own
            private  End.U  to  make  it into Configure. It offers the user to
            subscribe or  unsubscribe  to  a  mailing  list  where  discussion
            related  to the package are taking place. You need to run packinit
            and answer the mailing list related questions to set up the proper
            variables   in   your   .package   before  this  unit  may  become
            operational.

       Myinit.U
            Copy this unit into your private  U  directory  to  add  your  own
            default  values  to  some  internal variables. This unit is loaded
            into Configure after all the  default  initializations  have  been
            done.

       Myread.U
            This unit produces the myread shell script that must be sourced in
            order to do a read. It allows shell  escapes,  default  assignment
            and parameter evaluation, as documented in the Instruct.U unit. It
            also allows dynamic setting of the -d option, which will  be  used
            for the remaining of the script execution.

            To  use  this  unit,  $rp  must hold the question and $dflt should
            contain the default answer. The question will be  printed  by  the
            script itself, and the result is returned in the $ans variable.

            Here is a typical usage:

                 dflt=’y’
                 rp=’Question?’
                 . ./myread
                 value="$ans"

            See the unit itself for more information.

       Oldconfig.U
            This unit must be part of your dependency ?MAKE: line when some of
            your units tries to reuse  an  old  symbol  value.  This  unit  is
            responsible   for  getting  the  old  answers  from  config.sh  or
            providing useful hints when running on a given  platform  for  the
            first time. See the Configure Hints paragraph for more information
            about hints.

       Prefixit.U
            The purpose of this unit is to detect changes in the  installation
            prefix directory to recompute automatically suitable defaults from
            previous answers.  It  relies  on  the  value  of  the  $oldprefix
            variable  which  holds  the  previous  prefix  directory  when  it
            changed, and is empty otherwise. For instance, if the  prefix  was
            changed   from  /opt  to  /usr/local,  then  the  previous  binary
            installation  directory  will  be   changed   from   /opt/bin   to
            /usr/local/bin, or will remain unchanged if it was, say, /bin.

            You need to call set before issuing an eval on $prefixit, such as:

                 set dflt var [dir]
                 eval $prefixit

            which would set $dflt to $var or $prefix/dir depending on  whether
            the  prefix remained the same or not. If dir is the string none, a
            single space value in $dflt is kept as-is, even  when  the  prefix
            changes.  If  dir is omitted, then $dflt is set to an empty string
            if the prefix changed, to $var otherwise.

       Prefixup.U
            The intent of thit unit is similar to that of Prefixit.U, i.e.  it
            helps  fixing  the  default  string  to accomodate prefix changes.
            However, the shell variable $prefixup, when evaluated,  will  only
            restore  ~name  expansions,  should  prefix  use  such  an  escape
            mechanism. Use it as:

                 set dflt
                 eval $prefixup

            before prompting via getfile for instance. If the prefix does  not
            make  use  of  ~name expanstion, then the above will be a no-op on
            the y variable, naturally.

       Typedef.U
            This unit produces the $typedef shell variable, used internally by
            Configure  to check whether a typedef exists or not. A typical use
            is:

                 set typedef val_t default [ includes ]
                 eval $typedef

            This will set the variable val_t to the value of  default  if  the
            typedef  was  not  found  among  the  listed  include files, or to
            typedef if found. If no include  files  are  specified,  the  unit
            looks  in  <sys/types.h> only. If you specifiy some includes, only
            those are looked at.

       Unix.U
            The purpose of this unit is to define  some  of  the  most  common
            UNIX-isms via variables which can be altered from the command line
            or via proper hint files. In particular, $_exe, $_o  and  $_a  are
            set. All the units should refer to $_o and not to .o directly. The
            ’.’ is part of these variables.

       Setvar.U
            This unit produces the  variable,  which  is  used  internally  by
            Configure  to set a define/undef value to a given symbol, emitting
            a warning when it suddenly changes  from  a  previous  value.  For
            instance:

                 val="$define"
                 set d_variable
                 eval $setvar

            If  the  previous  $d_variable  value  was  non-null  and  $val is
            different, a "whoa" warning is issued.

       Whoa.U
            This unit produces the whoa script, which emits a warning when the
            value  in  variable  whose name is $var is not the same as its old
            previous value held in $was. Upon return, $td  and  $tu  hold  the
            proper  value  to  define  or undef the variable.  See examples in
            Inlibc.U.

   Builtin Pre-processor
       Each unit to be included in Configure is ran through  a  built-in  pre-
       processor. Pre-processor statements are introduced by the ’@’ character
       (’#’ is the shell comment character). It functions merely as the C pre-
       processor  does  but  allows  for  shell and perl escapes. Here are the
       available functions:

       @if expression
                 If expression is true,  continue  loading  code  until  @end,
                 @elsif or @else.

       @elsif expression
                 Alternative  choice.  If expression is true, continue loading
                 code until @end, another @elsif or @else.

       @else     Default code to be loaded if the @if expression was false and
                 none of the optional @elsif matched. Load until @end.

       @end      Close the conditional loading statement opened by @if.

       @define symbol
                 Tells the pre-processor that symbol is defined from now on.

       The  conditional  expression can include symbol names (value is true if
       symbol is wanted or defined via @define or  shell/perl  escapes.  Those
       atoms  can  be combined using the traditional boolean operators ’!’ for
       negation, ’&&’ for logical and, and ’||’ for logical or.

       Text enclosed within single  brackets  is  a  shell  test,  while  text
       between double brakets is a perl test. Namely the expressions:

            { shell text }
            {{ perl text }}

       are translated into:

            if shell text >/dev/null 2>&1; then exit 0; else exit 1; fi
            if (perl text) {exit 0;} else {exit 1;}

       and the exit status is used in the standard way to get a boolean value,
       i.e. 0 is true and everything else is  false.  Note  that  only  simple
       conditions  can  be  expressed  in perl, until some complex code can be
       loaded within metaconfig and executed.

       The built-in pre-processor can be used to finely tune some  units  (see
       d_gethname.U  for  a complex example) depending on the symbols actually
       used by the program or the files  present  in  the  distribution.   For
       instance, the Oldconfig.U uses a test like:

            @if {test -d ../hints}

       and Configure will contain hint-dependent code only if there is a hints
       directory in the package’s top level directory. Note that tests are ran
       from within the ’.MT’ directory, hence the needed ’../’ in the test.

       The pre-processor can also be used to avoid putting useless code when a
       symbol is not defined. Units defining  more  than  one  symbol  can  be
       protected  that  way (since the unit is loaded as a whole) by gathering
       symbol-dependent code within an @if/@end pair. For instance:

            @if I_TIME || I_SYS_TIME || I_SYS_TIME_KERNEL
            need_time_h=’true’
            @else
            need_time_h=’false’
            @end

       will test whether the source code makes any use of  one  of  the  three
       symbols  that control the time.h or sys/time.h inclusion and define the
       shell symbol accordingly. That gives Configure a feedback on  what  the
       sources need and avoid the drawback of having fixed frozen units.

       Via the ’?W:’ lines, you can get intersting combinations. For instance,
       the i_time.U unit needs to know whether the C sources make any  use  of
       the struct timezone type. Therefore, the line:

            ?W::timezone

       is  used  for  its  side-effect of defining the symbol timezone for the
       pre-processor. The unit code can then say:

            @if timezone
            for s_timezone in ’-DS_TIMEZONE’ ’’; do
            @else
            s_timezone=’’
            @end

            ... code using s_timezone ...

            @if timezone
            done
            @end

       and have an extra loop trying two successive values for the  s_timezone
       variable, but only if needed.

   Obsolete Symbols
       Obsolete  symbols  are  preserved  to  ease  the  transition with older
       metaconfig units. Unless the -o switch is  passed  to  metaconfig  they
       will  be  ignored. However, an Obsolete file will be generated, telling
       you which files are making use of those obsolete symbols and  what  are
       the new symbols to be used.

       The  lifetime for obsolete symbols is one full revision, i.e. they will
       be removed when the next base revision is issued (patch upgrades do not
       count  of  course). Therefore, it is wise to translate your sources and
       start using the new symbols as soon as possible.

   Configure Hints
       It may happen that the internal configuration  logic  makes  the  wrong
       choices.   For  instance,  on some platform, the vfork() system call is
       present but broken, so it should not be used. It  is  not  possible  to
       include that knowledge in the units themselves, because that might be a
       temporary problem which the vendor will eventually  fix,  or  something
       that was introduced by a new OS upgrade.

       Anyway,  for  all  those  tiny  little  problems  that  are too system-
       specific, metaconfig provides hint files support. To use it,  you  need
       to  create  a hints directory in the package’s top level directory, and
       have it when you run metaconfig. That will load the  hint-related  part
       from Oldconfig.U.

       From  then  on,  you  may pre-set some of the shell variables Configure
       uses in an OS-specific .sh file. There  is  code  in  Oldconfig.U  that
       tries to guess which hint files are needed by computing a standard name
       based on the system OS name,  the  kernel  name,  the  release  number,
       etc...  Since  this  information  is  likely to change rapidly, I’m not
       documenting it here.  You  have  to  reverse  engineer  the  code  from
       Oldconfig.U.

       When  you  first release your package, your hints file directory should
       be empty.  If the users of your package complain that they have problem
       with Configure defaults on a particular system, you have to see whether
       this is a platform-specific problem or a general  one.  In  the  former
       case,  it’s time to introduce a new hint file, while in the latter, the
       corresponding unit should be revised.

       For instance, SGI systems are known to have  a  broken  vfork()  system
       call,  as  of  this  writing.  And  the corresponding hint file name is
       sgi.sh.  So all you need to do is create a hints/sgi.sh file  in  which
       you write:

            d_vfork="$define"

       which  will always remap vfork on fork (see d_vfork.U). When running on
       SGI systems for the first time, Configure will detect that there is  an
       hints/sgi.sh  file, and that we are on an IRIX machine (the kernel name
       is often /irix), therefore it will propose sgi as a possible hint.   If
       the  user  accepts it, and since the $d_vfork value is modified via the
       $setvar call, a whoa! will be emitted to warn  that  we  are  about  to
       override the value computed by Configure.

       Note that you don’t have to provide all the hints known by Oldconfig.U.
       If a hint file is missing, it  will  not  be  proposed  as  a  possible
       choice. The heuristic tests ran to compute the possible hint candidates
       are flaky. If you have new values or different tests, please send  them
       to me...

   Overriding Choices
       If  you create a config.over file in the top level directory, Configure
       will ask you if you wish to load it to  override  the  default  values.
       This  is  done  prior creation of the config.sh file, so it gives you a
       chance to patch the values stored in there.

       This is distinct from the hints approach in that it is  a  local  file,
       which  the  user  is  free  to create for his own usage. You should not
       provide such a  file  yourself,  but  let  the  user  know  about  this
       possibility.

   Configure Options
       The  Configure  script may be called with some options specified on the
       command line, to slightly modify its behaviour. Here  are  the  allowed
       options:

       -d        Use defaults for all answers.

       -e        Go on without questioning past the production of config.sh.

       -f file   Use  the  specified  file as a default configuration. If this
                 switch  is  not  used,  the  configuration  is   taken   from
                 config.sh, when present.

       -h        Print help message and exit.

       -r        Reuse  C symbols value if possible. This will skip the costly
                 nm symbol  extraction.  If  used  the  first  time  (with  no
                 previous  configuration  file), Configure will try to compile
                 and link a small program in order to know about the  presence
                 of a symbol, or absence thereof.

       -s        Silent  mode. Only strings printed on file descriptor #4 will
                 be seen on the screen (that’s the important  messages).  It’s
                 not  possible  to completely turn off any output, but you may
                 use ’Configure -ders >/dev/null 2>&1’ to have  a  full  batch
                 run with no output and no user interaction required.

       -D symbol=value
                 Pre-defines  symbol  to  bear the specified value. It is also
                 possible to use ’-D symbol’ which will use a default value of
                 ’define’.

       -E        Stop  at the end of the configuration questions, after having
                 produced a config.sh. This will not perform any ’make depend’
                 or .SH files extraction.

       -K        Knowledgeable  user.  When you use this option, you know what
                 you are doing and therefore the config.sh file will always be
                 handled  as  if it was intended to be re-used, even though it
                 might have  been  generated  on  an  alien  system.  It  also
                 prevents  aborting  when  Configure  detects  an  unusable  C
                 compiler or a wrong set of C flags.  Further shortcuts  might
                 be  turned  on  by  this  option as well in the future.  This
                 option is documented  in  the  Configure  usage  message,  to
                 remind  us  about its existence, but the given description is
                 hoped to be cryptic enough. :-)

       -O        Allow values specified via a -D or -U  to  override  settings
                 from  any  loaded configuration file. This is not the default
                 behaviour since the overriding  will  not  be  propagated  to
                 variables  derived  from  those  you  are presently altering.
                 Naturally, without -O, the  setting  is  only  done  when  no
                 configuration  file is loaded, which is safe since derivative
                 variables have not been computed yet...

       -S        Perform variable substitution on all the .SH files.  You  can
                 combine  it with the -f switch to propagate any configuration
                 you like.

       -U symbol=
                 Pre-sets symbol to bear an empty value. It is  also  possible
                 to use ’-U symbol’ which will set symbol to ’undef’.

       -V        Print  the  version  number  of the metaconfig that generated
                 this Configure script and exit.

   Running Environment
       Upon starting, Configure creates a local UU  directory  and  runs  from
       there. The directory is removed when Configure ends, but this means you
       must run the script from a place where you can write, i.e. not  from  a
       read-only file system.

       You can run Configure remotely though, as in:

                 ../package/Configure

       to  configure  sources  that are not present locally. All the generated
       files will be put in the directory  where  you’re  running  the  script
       from. This magic is done thanks to the src.U unit, which is setting the
       $src and $rsrc variables to point to the package sources. That path  is
       full or relative, depending on whether Configure was invoked via a full
       or relative path.

       From within the UU subdirectory, you can use $rsrc to access the source
       files (units referring to source files link hints shall always use this
       mechanism and not assume the file is present in the parent  directory).
       All  the  Makefiles  should  use  the $src variable as a pointer to the
       sources from the top of the build directory (where Configure  is  run),
       either directly or via a VPATH setting.

       When  running  Configure  remotely,  the .SH files are extracted in the
       build directory, not in the source tree. However, it requires some kind
       of  a  make  support  to be able to compile things in a build directory
       whilst the sources lie elsewhere.

   Using Magic Redefinitions
       By making use of the -M switch, some magic remappings  may  take  place
       within  a  confmagic.h  file.  That  file  needs  to  be included after
       config.h, of course, but also after all the other needed include files.
       Namely:

            #include "config.h"
            ...
            ... other inclusions ...
            ...
            #include "confmagic.h"

       Typically,  confmagic.h will attempt to remap bcopy() on memcpy() if no
       bcopy() is  available  locally,  or  transform  vfork  into  fork  when
       necessary,  hence  making  it  useless  to  bother  about the HAS_VFORK
       symbol.

       This configuration magic is documented in the Glossary file.

   Unit Templates
       There is a set of unit templates in the  metaconfig  source  directory,
       which are intended to be used by a (not yet written) program to quickly
       produce new units for various kind of situations. No documentation  for
       this unfinished project, but I thought I would mention it in the manual
       page in case you wish to do it yourself and then contribute it...

AUTHORS

       Larry Wall <lwall@netlabs.com> for version 2.0.
       Harlan Stenn <harlan@mumps.pfcs.com> for important unit extensions.
       Raphael Manfredi <ram@hptnos02.grenoble.hp.com>.
       Many other contributors for the metaconfig units. See the  credit  file
       for a list.

FILES

       LIB/dist/mcon/U/*.U
                 Public unit files
       U/*.U     Private unit files
       LIB/dist/mcon/Glossary
                 Glossary file, describing all the metaconfig symbols.
       Obsolete  Lists all the obsolete symbols used by the sources.
       Wanted    Lists all the wanted symbols.

                      where LIB is /usr/share/dist.

BUGS

       Units  are  sometimes  included  unnecessarily if one of its symbols is
       accidentally mentioned, e.g. in a comment.  Better too many units  than
       too few, however.

SEE ALSO

       pat(1), makeSH(1), makedist(1), metalint(1)

                                Version 3.5 PL0