Provided by: dist_3.5-236-0.1build1_all bug

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 Raphael.Manfredi@pobox.com (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 developed 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.

       -X file        When examining the source files, ignore any symbols listed in the file.  This is useful in
                      situations where a  particular  unit  is  known  not  to  be  needed  for  your  package's
                      portability  targets, but your source files nevertheless contain occurrences of words that
                      look to metaconfig like symbols defined in that unit. (For example,  you  might  need  the
                      word  "index"  in  a  source file, but not need the unit that determines whether strcpy or
                      index should be used.)  The file can contain blank lines, comment  lines  introduced  with
                      '#',  and lines containing a single symbol.  If this option is not supplied, any  variable
                      in .package is honored instead.

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 system structure lacks one otherwise standard field, or simply whether 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 whether 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 explicitly 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/lib/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
            accommodate 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 <Raphael.Manfredi@pobox.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                                   METACONFIG(1)