home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume42
/
c2man-2.0
/
part04
< prev
next >
Wrap
Internet Message Format
|
1994-05-06
|
51KB
From: greyham@research.canon.oz.au (Graham Stoney)
Newsgroups: comp.sources.misc
Subject: v42i058: c2man-2.0 - automatic C documentation generator, Part04/09
Date: 25 Apr 1994 22:30:35 -0500
Organization: Canon Information Systems Research Australia
Sender: kent@sparky.sterling.com
Approved: kent@sparky.sterling.com
Message-ID: <2pi1sr$jnl@sparky.sterling.com>
References: <csm-v42i055=c2man-2.0.222803@sparky.sterling.com>
Summary: a complete posting of the latest c2man: version 2.0 patchlevel 27
X-Md4-Signature: bed17be3265b93ee9f3b0fcb3d03a7cd
Submitted-by: greyham@research.canon.oz.au (Graham Stoney)
Posting-number: Volume 42, Issue 58
Archive-name: c2man-2.0/part04
Environment: UNIX, DOS, OS/2, lex, yacc
#! /bin/sh
#
# This is c2man version 2.0 at patchlevel 27.
# Make a new directory for the c2man sources, cd to it, and run kits 1 up
# to 9 through sh. When all 9 kits have been run, read README.
#
echo " "
cat <<EOM
This is c2man 2.0 at patchlevel 27, kit 4 (of 9):
If this shell archive is complete, the line "End of kit 4 (of 9)"
will echo at the end.
EOM
export PATH || (echo "Please use sh to unpack this archive." ; kill $$)
mkdir pc 2>/dev/null
echo Extracting pc/getopt.c
sed >pc/getopt.c <<'!STUFFY!FUNK!' -e 's/X//'
X/* Getopt for GNU.
X NOTE: getopt is now part of the C library, so if you don't know what
X "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
X before changing it!
X
X Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
X Free Software Foundation, Inc.
X
X This program is free software; you can redistribute it and/or modify it
X under the terms of the GNU General Public License as published by the
X Free Software Foundation; either version 2, or (at your option) any
X later version.
X
X This program is distributed in the hope that it will be useful,
X but WITHOUT ANY WARRANTY; without even the implied warranty of
X MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X GNU General Public License for more details.
X
X You should have received a copy of the GNU General Public License
X along with this program; if not, write to the Free Software
X Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
X
X/* NOTE!!! AIX requires this to be the first thing in the file.
X Do not put ANYTHING before it! */
X#if !defined (__GNUC__) && defined (_AIX)
X #pragma alloca
X#endif
X
X#ifdef HAVE_CONFIG_H
X#include "config.h"
X#endif
X
X#ifdef __GNUC__
X#define alloca __builtin_alloca
X#else /* not __GNUC__ */
X#if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__))))
X#include <alloca.h>
X#else
X#ifdef _MSC_VER
X#include <malloc.h>
X#else
X#ifndef _AIX
Xchar *alloca ();
X#endif
X#endif
X#endif /* alloca.h */
X#endif /* not __GNUC__ */
X
X#if !__STDC__ && !defined(const) && IN_GCC
X#define const
X#endif
X
X/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. */
X#ifndef _NO_PROTO
X#define _NO_PROTO
X#endif
X
X#include <stdio.h>
X
X/* Comment out all this code if we are using the GNU C Library, and are not
X actually compiling the library itself. This code is part of the GNU C
X Library, but also included in many other GNU distributions. Compiling
X and linking in this code is a waste when using the GNU C library
X (especially if it is a shared library). Rather than having every GNU
X program understand `configure --with-gnu-libc' and omit the object files,
X it is simpler to just do this in the source for each such file. */
X
X#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
X
X
X/* This needs to come after some library #include
X to get __GNU_LIBRARY__ defined. */
X#ifdef __GNU_LIBRARY__
X#undef alloca
X/* Don't include stdlib.h for non-GNU C libraries because some of them
X contain conflicting prototypes for getopt. */
X#include <stdlib.h>
X#else /* Not GNU C library. */
X#define __alloca alloca
X#endif /* GNU C library. */
X
X/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
X long-named option. Because this is not POSIX.2 compliant, it is
X being phased out. */
X/* #define GETOPT_COMPAT */
X
X/* This version of `getopt' appears to the caller like standard Unix `getopt'
X but it behaves differently for the user, since it allows the user
X to intersperse the options with the other arguments.
X
X As `getopt' works, it permutes the elements of ARGV so that,
X when it is done, all the options precede everything else. Thus
X all application programs are extended to handle flexible argument order.
X
X Setting the environment variable POSIXLY_CORRECT disables permutation.
X Then the behavior is completely standard.
X
X GNU application programs can use a third alternative mode in which
X they can distinguish the relative order of options and other arguments. */
X
X#include "getopt.h"
X
X/* For communication from `getopt' to the caller.
X When `getopt' finds an option that takes an argument,
X the argument value is returned here.
X Also, when `ordering' is RETURN_IN_ORDER,
X each non-option ARGV-element is returned here. */
X
Xchar *optarg = 0;
X
X/* Index in ARGV of the next element to be scanned.
X This is used for communication to and from the caller
X and for communication between successive calls to `getopt'.
X
X On entry to `getopt', zero means this is the first call; initialize.
X
X When `getopt' returns EOF, this is the index of the first of the
X non-option elements that the caller should itself scan.
X
X Otherwise, `optind' communicates from one call to the next
X how much of ARGV has been scanned so far. */
X
X/* XXX 1003.2 says this must be 1 before any call. */
Xint optind = 0;
X
X/* The next char to be scanned in the option-element
X in which the last option character we returned was found.
X This allows us to pick up the scan where we left off.
X
X If this is zero, or a null string, it means resume the scan
X by advancing to the next ARGV-element. */
X
Xstatic char *nextchar;
X
X/* Callers store zero here to inhibit the error message
X for unrecognized options. */
X
Xint opterr = 1;
X
X/* Set to an option character which was unrecognized.
X This must be initialized on some systems to avoid linking in the
X system's own getopt implementation. */
X
Xint optopt = '?';
X
X/* Describe how to deal with options that follow non-option ARGV-elements.
X
X If the caller did not specify anything,
X the default is REQUIRE_ORDER if the environment variable
X POSIXLY_CORRECT is defined, PERMUTE otherwise.
X
X REQUIRE_ORDER means don't recognize them as options;
X stop option processing when the first non-option is seen.
X This is what Unix does.
X This mode of operation is selected by either setting the environment
X variable POSIXLY_CORRECT, or using `+' as the first character
X of the list of option characters.
X
X PERMUTE is the default. We permute the contents of ARGV as we scan,
X so that eventually all the non-options are at the end. This allows options
X to be given in any order, even with programs that were not written to
X expect this.
X
X RETURN_IN_ORDER is an option available to programs that were written
X to expect options and other ARGV-elements in any order and that care about
X the ordering of the two. We describe each non-option ARGV-element
X as if it were the argument of an option with character code 1.
X Using `-' as the first character of the list of option characters
X selects this mode of operation.
X
X The special argument `--' forces an end of option-scanning regardless
X of the value of `ordering'. In the case of RETURN_IN_ORDER, only
X `--' can cause `getopt' to return EOF with `optind' != ARGC. */
X
Xstatic enum
X{
X REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
X} ordering;
X
X#ifdef __GNU_LIBRARY__
X/* We want to avoid inclusion of string.h with non-GNU libraries
X because there are many ways it can cause trouble.
X On some systems, it contains special magic macros that don't work
X in GCC. */
X#include <string.h>
X#define my_index strchr
X#define my_bcopy(src, dst, n) memcpy ((dst), (src), (n))
X#else
X
X/* Avoid depending on library functions or files
X whose names are inconsistent. */
X
Xchar *getenv ();
X
Xstatic char *
Xmy_index (str, chr)
X const char *str;
X int chr;
X{
X while (*str)
X {
X if (*str == chr)
X return (char *) str;
X str++;
X }
X return 0;
X}
X
Xstatic void
Xmy_bcopy (from, to, size)
X const char *from;
X char *to;
X int size;
X{
X int i;
X for (i = 0; i < size; i++)
X to[i] = from[i];
X}
X#endif /* GNU C library. */
X
X/* Handle permutation of arguments. */
X
X/* Describe the part of ARGV that contains non-options that have
X been skipped. `first_nonopt' is the index in ARGV of the first of them;
X `last_nonopt' is the index after the last of them. */
X
Xstatic int first_nonopt;
Xstatic int last_nonopt;
X
X/* Exchange two adjacent subsequences of ARGV.
X One subsequence is elements [first_nonopt,last_nonopt)
X which contains all the non-options that have been skipped so far.
X The other is elements [last_nonopt,optind), which contains all
X the options processed since those non-options were skipped.
X
X `first_nonopt' and `last_nonopt' are relocated so that they describe
X the new indices of the non-options in ARGV after they are moved. */
X
Xstatic void
Xexchange (argv)
X char **argv;
X{
X int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
X char **temp = (char **) __alloca (nonopts_size);
X
X /* Interchange the two blocks of data in ARGV. */
X
X my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size);
X my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt],
X (optind - last_nonopt) * sizeof (char *));
X my_bcopy ((char *) temp,
X (char *) &argv[first_nonopt + optind - last_nonopt],
X nonopts_size);
X
X /* Update records for the slots the non-options now occupy. */
X
X first_nonopt += (optind - last_nonopt);
X last_nonopt = optind;
X}
X
X/* Scan elements of ARGV (whose length is ARGC) for option characters
X given in OPTSTRING.
X
X If an element of ARGV starts with '-', and is not exactly "-" or "--",
X then it is an option element. The characters of this element
X (aside from the initial '-') are option characters. If `getopt'
X is called repeatedly, it returns successively each of the option characters
X from each of the option elements.
X
X If `getopt' finds another option character, it returns that character,
X updating `optind' and `nextchar' so that the next call to `getopt' can
X resume the scan with the following option character or ARGV-element.
X
X If there are no more option characters, `getopt' returns `EOF'.
X Then `optind' is the index in ARGV of the first ARGV-element
X that is not an option. (The ARGV-elements have been permuted
X so that those that are not options now come last.)
X
X OPTSTRING is a string containing the legitimate option characters.
X If an option character is seen that is not listed in OPTSTRING,
X return '?' after printing an error message. If you set `opterr' to
X zero, the error message is suppressed but we still return '?'.
X
X If a char in OPTSTRING is followed by a colon, that means it wants an arg,
X so the following text in the same ARGV-element, or the text of the following
X ARGV-element, is returned in `optarg'. Two colons mean an option that
X wants an optional arg; if there is text in the current ARGV-element,
X it is returned in `optarg', otherwise `optarg' is set to zero.
X
X If OPTSTRING starts with `-' or `+', it requests different methods of
X handling the non-option ARGV-elements.
X See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
X
X Long-named options begin with `--' instead of `-'.
X Their names may be abbreviated as long as the abbreviation is unique
X or is an exact match for some defined option. If they have an
X argument, it follows the option name in the same ARGV-element, separated
X from the option name by a `=', or else the in next ARGV-element.
X When `getopt' finds a long-named option, it returns 0 if that option's
X `flag' field is nonzero, the value of the option's `val' field
X if the `flag' field is zero.
X
X The elements of ARGV aren't really const, because we permute them.
X But we pretend they're const in the prototype to be compatible
X with other systems.
X
X LONGOPTS is a vector of `struct option' terminated by an
X element containing a name which is zero.
X
X LONGIND returns the index in LONGOPT of the long-named option found.
X It is only valid when a long-named option has been found by the most
X recent call.
X
X If LONG_ONLY is nonzero, '-' as well as '--' can introduce
X long-named options. */
X
Xint
X_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
X int argc;
X char *const *argv;
X const char *optstring;
X const struct option *longopts;
X int *longind;
X int long_only;
X{
X int option_index;
X
X optarg = 0;
X
X /* Initialize the internal data when the first call is made.
X Start processing options with ARGV-element 1 (since ARGV-element 0
X is the program name); the sequence of previously skipped
X non-option ARGV-elements is empty. */
X
X if (optind == 0)
X {
X first_nonopt = last_nonopt = optind = 1;
X
X nextchar = NULL;
X
X /* Determine how to handle the ordering of options and nonoptions. */
X
X if (optstring[0] == '-')
X {
X ordering = RETURN_IN_ORDER;
X ++optstring;
X }
X else if (optstring[0] == '+')
X {
X ordering = REQUIRE_ORDER;
X ++optstring;
X }
X else if (getenv ("POSIXLY_CORRECT") != NULL)
X ordering = REQUIRE_ORDER;
X else
X ordering = PERMUTE;
X }
X
X if (nextchar == NULL || *nextchar == '\0')
X {
X if (ordering == PERMUTE)
X {
X /* If we have just processed some options following some non-options,
X exchange them so that the options come first. */
X
X if (first_nonopt != last_nonopt && last_nonopt != optind)
X exchange ((char **) argv);
X else if (last_nonopt != optind)
X first_nonopt = optind;
X
X /* Now skip any additional non-options
X and extend the range of non-options previously skipped. */
X
X while (optind < argc
X && (argv[optind][0] != '-' || argv[optind][1] == '\0')
X#ifdef GETOPT_COMPAT
X && (longopts == NULL
X || argv[optind][0] != '+' || argv[optind][1] == '\0')
X#endif /* GETOPT_COMPAT */
X )
X optind++;
X last_nonopt = optind;
X }
X
X /* Special ARGV-element `--' means premature end of options.
X Skip it like a null option,
X then exchange with previous non-options as if it were an option,
X then skip everything else like a non-option. */
X
X if (optind != argc && !strcmp (argv[optind], "--"))
X {
X optind++;
X
X if (first_nonopt != last_nonopt && last_nonopt != optind)
X exchange ((char **) argv);
X else if (first_nonopt == last_nonopt)
X first_nonopt = optind;
X last_nonopt = argc;
X
X optind = argc;
X }
X
X /* If we have done all the ARGV-elements, stop the scan
X and back over any non-options that we skipped and permuted. */
X
X if (optind == argc)
X {
X /* Set the next-arg-index to point at the non-options
X that we previously skipped, so the caller will digest them. */
X if (first_nonopt != last_nonopt)
X optind = first_nonopt;
X return EOF;
X }
X
X /* If we have come to a non-option and did not permute it,
X either stop the scan or describe it to the caller and pass it by. */
X
X if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
X#ifdef GETOPT_COMPAT
X && (longopts == NULL
X || argv[optind][0] != '+' || argv[optind][1] == '\0')
X#endif /* GETOPT_COMPAT */
X )
X {
X if (ordering == REQUIRE_ORDER)
X return EOF;
X optarg = argv[optind++];
X return 1;
X }
X
X /* We have found another option-ARGV-element.
X Start decoding its characters. */
X
X nextchar = (argv[optind] + 1
X + (longopts != NULL && argv[optind][1] == '-'));
X }
X
X if (longopts != NULL
X && ((argv[optind][0] == '-'
X && (argv[optind][1] == '-' || long_only))
X#ifdef GETOPT_COMPAT
X || argv[optind][0] == '+'
X#endif /* GETOPT_COMPAT */
X ))
X {
X const struct option *p;
X char *s = nextchar;
X int exact = 0;
X int ambig = 0;
X const struct option *pfound = NULL;
X int indfound;
X
X while (*s && *s != '=')
X s++;
X
X /* Test all options for either exact match or abbreviated matches. */
X for (p = longopts, option_index = 0; p->name;
X p++, option_index++)
X if (!strncmp (p->name, nextchar, s - nextchar))
X {
X if (s - nextchar == strlen (p->name))
X {
X /* Exact match found. */
X pfound = p;
X indfound = option_index;
X exact = 1;
X break;
X }
X else if (pfound == NULL)
X {
X /* First nonexact match found. */
X pfound = p;
X indfound = option_index;
X }
X else
X /* Second nonexact match found. */
X ambig = 1;
X }
X
X if (ambig && !exact)
X {
X if (opterr)
X fprintf (stderr, "%s: option `%s' is ambiguous\n",
X argv[0], argv[optind]);
X nextchar += strlen (nextchar);
X optind++;
X return '?';
X }
X
X if (pfound != NULL)
X {
X option_index = indfound;
X optind++;
X if (*s)
X {
X /* Don't test has_arg with >, because some C compilers don't
X allow it to be used on enums. */
X if (pfound->has_arg)
X optarg = s + 1;
X else
X {
X if (opterr)
X {
X if (argv[optind - 1][1] == '-')
X /* --option */
X fprintf (stderr,
X "%s: option `--%s' doesn't allow an argument\n",
X argv[0], pfound->name);
X else
X /* +option or -option */
X fprintf (stderr,
X "%s: option `%c%s' doesn't allow an argument\n",
X argv[0], argv[optind - 1][0], pfound->name);
X }
X nextchar += strlen (nextchar);
X return '?';
X }
X }
X else if (pfound->has_arg == 1)
X {
X if (optind < argc)
X optarg = argv[optind++];
X else
X {
X if (opterr)
X fprintf (stderr, "%s: option `%s' requires an argument\n",
X argv[0], argv[optind - 1]);
X nextchar += strlen (nextchar);
X return optstring[0] == ':' ? ':' : '?';
X }
X }
X nextchar += strlen (nextchar);
X if (longind != NULL)
X *longind = option_index;
X if (pfound->flag)
X {
X *(pfound->flag) = pfound->val;
X return 0;
X }
X return pfound->val;
X }
X /* Can't find it as a long option. If this is not getopt_long_only,
X or the option starts with '--' or is not a valid short
X option, then it's an error.
X Otherwise interpret it as a short option. */
X if (!long_only || argv[optind][1] == '-'
X#ifdef GETOPT_COMPAT
X || argv[optind][0] == '+'
X#endif /* GETOPT_COMPAT */
X || my_index (optstring, *nextchar) == NULL)
X {
X if (opterr)
X {
X if (argv[optind][1] == '-')
X /* --option */
X fprintf (stderr, "%s: unrecognized option `--%s'\n",
X argv[0], nextchar);
X else
X /* +option or -option */
X fprintf (stderr, "%s: unrecognized option `%c%s'\n",
X argv[0], argv[optind][0], nextchar);
X }
X nextchar = (char *) "";
X optind++;
X return '?';
X }
X }
X
X /* Look at and handle the next option-character. */
X
X {
X char c = *nextchar++;
X char *temp = my_index (optstring, c);
X
X /* Increment `optind' when we start to process its last character. */
X if (*nextchar == '\0')
X ++optind;
X
X if (temp == NULL || c == ':')
X {
X if (opterr)
X {
X#if 0
X if (c < 040 || c >= 0177)
X fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
X argv[0], c);
X else
X fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
X#else
X /* 1003.2 specifies the format of this message. */
X fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
X#endif
X }
X optopt = c;
X return '?';
X }
X if (temp[1] == ':')
X {
X if (temp[2] == ':')
X {
X /* This is an option that accepts an argument optionally. */
X if (*nextchar != '\0')
X {
X optarg = nextchar;
X optind++;
X }
X else
X optarg = 0;
X nextchar = NULL;
X }
X else
X {
X /* This is an option that requires an argument. */
X if (*nextchar != '\0')
X {
X optarg = nextchar;
X /* If we end this ARGV-element by taking the rest as an arg,
X we must advance to the next element now. */
X optind++;
X }
X else if (optind == argc)
X {
X if (opterr)
X {
X#if 0
X fprintf (stderr, "%s: option `-%c' requires an argument\n",
X argv[0], c);
X#else
X /* 1003.2 specifies the format of this message. */
X fprintf (stderr, "%s: option requires an argument -- %c\n",
X argv[0], c);
X#endif
X }
X optopt = c;
X if (optstring[0] == ':')
X c = ':';
X else
X c = '?';
X }
X else
X /* We already incremented `optind' once;
X increment it again when taking next ARGV-elt as argument. */
X optarg = argv[optind++];
X nextchar = NULL;
X }
X }
X return c;
X }
X}
X
Xint
Xgetopt (argc, argv, optstring)
X int argc;
X char *const *argv;
X const char *optstring;
X{
X return _getopt_internal (argc, argv, optstring,
X (const struct option *) 0,
X (int *) 0,
X 0);
X}
X
X#endif /* _LIBC or not __GNU_LIBRARY__. */
X
X#ifdef TEST
X
X/* Compile with -DTEST to make an executable for use in testing
X the above definition of `getopt'. */
X
Xint
Xmain (argc, argv)
X int argc;
X char **argv;
X{
X int c;
X int digit_optind = 0;
X
X while (1)
X {
X int this_option_optind = optind ? optind : 1;
X
X c = getopt (argc, argv, "abc:d:0123456789");
X if (c == EOF)
X break;
X
X switch (c)
X {
X case '0':
X case '1':
X case '2':
X case '3':
X case '4':
X case '5':
X case '6':
X case '7':
X case '8':
X case '9':
X if (digit_optind != 0 && digit_optind != this_option_optind)
X printf ("digits occur in two different argv-elements.\n");
X digit_optind = this_option_optind;
X printf ("option %c\n", c);
X break;
X
X case 'a':
X printf ("option a\n");
X break;
X
X case 'b':
X printf ("option b\n");
X break;
X
X case 'c':
X printf ("option c with value `%s'\n", optarg);
X break;
X
X case '?':
X break;
X
X default:
X printf ("?? getopt returned character code 0%o ??\n", c);
X }
X }
X
X if (optind < argc)
X {
X printf ("non-option ARGV-elements: ");
X while (optind < argc)
X printf ("%s ", argv[optind++]);
X printf ("\n");
X }
X
X exit (0);
X}
X
X#endif /* TEST */
!STUFFY!FUNK!
echo Extracting c2man.c
sed >c2man.c <<'!STUFFY!FUNK!' -e 's/X//'
X/* $Id: c2man.c,v 2.0.1.29 1994/01/07 07:04:56 greyham Exp $
X *
X * C Manual page generator.
X * Reads C source code and outputs manual pages.
X */
X#include <ctype.h>
X#include <errno.h>
X
X#include "c2man.h"
X#include "enum.h"
X#include "strconcat.h"
X#include "strappend.h"
X#include "manpage.h"
X#include "output.h"
X#include "patchlevel.h"
X
X#ifdef I_FCNTL
X#include <fcntl.h>
X#endif
X
X#ifdef I_SYS_FILE
X#include <sys/file.h>
X#endif
X
X#include <sys/stat.h>
X#include <signal.h>
X
X/* getopt declarations */
Xextern int getopt();
Xextern char *optarg;
Xextern int optind;
X
X/* lex declarations */
Xextern FILE *yyin; /* lex input stream */
X
X/* Name of the program */
Xconst char *progname = "c2man";
X
X/* Program options */
X
X/* TRUE if static declarations are also output. */
Xboolean static_out = FALSE;
X
X/* TRUE if variable declarations are output. */
Xboolean variables_out = FALSE;
X
X/* TRUE if formal parameter promotion is enabled. */
Xboolean promote_param = TRUE;
X
X/* String output before prototype declaration specifiers */
Xconst char *decl_spec_prefix = "";
X
X/* String output before prototype declarator */
Xconst char *declarator_prefix = " ";
X
X/* String output after prototype declarator */
Xconst char *declarator_suffix = "\n";
X
X/* String output before the first parameter in a function prototype */
Xconst char *first_param_prefix = "\n\t";
X
X/* String output before each subsequent parameter in a function prototype */
Xconst char *middle_param_prefix = "\n\t";
X
X/* String output after the last parameter in a function prototype */
Xconst char *last_param_suffix = "\n";
X
X/* Directory to write output files in */
Xchar *output_dir = NULL;
X
X/* Name of the manual */
Xchar *manual_name = NULL;
X
X/* Section for manual page */
Xconst char *manual_section = NULL;
X
X/* prefix for generated #include lines */
Xchar *header_prefix = NULL;
X
X/* list of include file specified by user */
XIncludeFile *first_include;
Xstatic IncludeFile **last_next_include = &first_include;
X
X/* do we group related stuff into one file? */
Xboolean group_together;
X
X/* was terse description read from file or command line option? */
Xboolean terse_specified;
X
X/* terse description when grouped together */
Xchar *group_terse = NULL;
X
X/* should we always document parameters, even if it's only "Not Documented" */
Xboolean always_document_params = TRUE;
X
X/* default output info for each object type */
Xstruct Output_Object_Info output_object[_OBJECT_NUM] =
X{
X#if 0
X {'c', "class"},
X {'s', "struct"},
X {'e', "enum"},
X {'t', "typedef"},
X#endif
X {'f', "function"},
X {'v', "variable"},
X {'F', "static function"},
X {'V', "static variable"}
X};
X
X/* Include file directories */
X#ifdef MSDOS
Xint num_inc_dir = 1;
Xconst char *inc_dir[MAX_INC_DIR] = { ".\\" };
X#else
Xint num_inc_dir = 2;
Xconst char *inc_dir[MAX_INC_DIR] = { "./", "/usr/include/" };
X#endif
X
X/* total number of errors encountered */
Xint errors;
X
X/* name of the base file being processed; NULL = stdin */
Xconst char *basefile;
XTime_t basetime; /* modification time of base file */
Xboolean inbasefile; /* are we parsing in that base file? */
X
X/* is the base file a header file? */
Xboolean header_file;
X
X/* use nroff output by default */
Xstruct Output *output = &nroff_output;
X
X/* should we generate the output file named after the input file? */
Xboolean use_input_name = FALSE;
X
X/* should we generate embeddable files? */
Xboolean make_embeddable = FALSE;
X
X#define USE_CPP
X#ifdef USE_CPP
Xconst char *cpp_cmd = CPP_FILE_COM;
X#if defined(MSDOS)
X#include "popen.h"
X#define popen(c,m) os_popen(c,m)
X#define pclose(f) os_pclose(f)
X#else
X#if defined (_MSC_VER)
X#define popen(c,m) _popen(c,m)
X#define pclose(f) _pclose(f)
X#endif
X#endif
X#endif
X
Xboolean verbose = FALSE;
X
X/* can cpp read standard input? */
Xstatic boolean cppcanstdin
X#ifdef CPP_CAN_STDIN
X = 1
X#endif
X;
X/* does cpp ignore header files */
Xstatic boolean cppignhdrs
X#ifdef CPP_IGN_HDRS
X = 1
X#endif
X;
X
X/* nifty little function for handling I/O errors */
Xvoid my_perror(action, filename)
Xconst char *action, *filename;
X{
X int err = errno;
X fprintf(stderr,"%s: %s ", progname, action);
X errno = err;
X perror(filename);
X}
X
X/* write the #include lines as specified by the user */
Xvoid print_includes(f)
XFILE *f;
X{
X IncludeFile *incfile;
X
X for (incfile = first_include; incfile; incfile=incfile->next)
X {
X char *name = incfile->name;
X boolean surrounded = *name == '"' || *name == '<';
X
X fputs("#include ", f);
X if (!surrounded) fputc('<',f);
X fputs(name, f);
X if (!surrounded) fputc('>',f);
X fputc('\n',f);
X }
X}
X
Xvoid outmem()
X{
X fprintf(stderr,"%s: Out of memory!\n", progname);
X exit(1);
X}
X
X#ifndef DBMALLOC
Xvoid *safe_malloc(size)
Xsize_t size;
X{
X void *mem;
X
X if ((mem = (void *)malloc(size)) == NULL)
X outmem();
X
X return mem;
X}
X#endif
X
X/* Replace any character escape sequences in a string with the actual
X * characters. Return a pointer to malloc'ed memory containing the result.
X * This function knows only a few escape sequences.
X */
Xstatic char *
Xescape_string (src)
Xchar *src;
X{
X char *result, *get, *put;
X
X result = strduplicate(src);
X put = result;
X get = src;
X while (*get != '\0') {
X if (*get == '\\') {
X switch (*(++get)) {
X case 'n':
X *put++ = '\n';
X ++get;
X break;
X case 't':
X *put++ = '\t';
X ++get;
X break;
X default:
X if (*get != '\0')
X *put++ = *get++;
X }
X } else {
X *put++ = *get++;
X }
X }
X *put = *get;
X return result;
X}
X
X/* Output usage message and exit.
X */
Xstatic void
Xusage ()
X{
X int i;
X
X fprintf(stderr, "usage: %s [ option ... ] [ file ... ]\n", progname);
X fputs(" -o directory\twrite output files in directory\n",stderr);
X fputs(" -p\t\tdisable prototype promotion\n", stderr);
X fputs(" -s\t\toutput static declarations\n", stderr);
X fputs(" -v\t\toutput variable declarations\n", stderr);
X fputc('\n', stderr);
X fputs(" -i incfile\n", stderr);
X fputs(" -i \"incfile\"\n", stderr);
X fputs(" -i <incfile>\tadd #include for incfile to SYNOPSIS\n",
X stderr);
X fputc('\n', stderr);
X fputs(" -H prefix\tspecify prefix for #include in SYNOPSIS\n", stderr);
X fputc('\n', stderr);
X fputs(" -g\n", stderr);
X fputs(" -G terse\tgroup info from each file into a single page\n",
X stderr);
X fputs(" -e\t\tmake embeddable files\n", stderr);
X fputc('\n', stderr);
X fputs(" -l ", stderr);
X#ifdef HAS_LINK
X fputs("h|", stderr);
X#endif
X#ifdef HAS_SYMLINK
X fputs("s|", stderr);
X#endif
X fputs("f|n|r\t", stderr);
X fputs("linking for grouped pages: ", stderr);
X#ifdef HAS_LINK
X fputs("hard, ", stderr);
X#endif
X#ifdef HAS_SYMLINK
X fputs("soft, ", stderr);
X#endif
X fputs("file, none or remove\n", stderr);
X fputs(" -n\t\tName output file after input source file\n", stderr);
X fputs(" -L\t\tLazy: Be silent about undocumented parameters\n",
X stderr);
X fputs(" -T n|l|t\tselect typesetting output format: nroff, LaTeX or TeXinfo\n",
X stderr);
X fputs(" -M name\tset name of the manual in which the page goes\n",
X stderr);
X fputc('\n', stderr);
X fputs(" -D name[=value]\n", stderr);
X fputs(" -U name\n", stderr);
X fputs(" -I directory\tC preprocessor options\n", stderr);
X fputc('\n', stderr);
X fputs(" -F template\tset prototype template in the form ", stderr);
X fputs("\"int f (a, b)\"\n",stderr);
X fputs(" -P preprocessor\tAlternate C preprocessor ", stderr);
X fputs("(e.g., \"gcc -E -C\")\n", stderr);
X fputs(" -V\t\tbe verbose and print version information\n", stderr);
X fputs(" -S section\tset the section for the manual page (default = 3)\n",
X stderr);
X fputs(" -O ", stderr);
X for (i = 0; i < _OBJECT_NUM; i++)
X fputc(output_object[i].flag, stderr);
X fputs("[subdir][.ext]", stderr);
X fputs("\tOutput control over different object types:\n\t\t", stderr);
X for (i = 0; i < _OBJECT_NUM; i++)
X {
X fputs(output_object[i].name, stderr);
X if (i <= _OBJECT_NUM - 2)
X fprintf(stderr,i == _OBJECT_NUM-2 ? " or " : ", ");
X }
X fputs(".\n", stderr);
X exit(1);
X}
X
X/* name of the temporary file; kept here so we can blast it if hit with ctrl-C
X */
Xstatic char temp_name[20];
XSignal_t (*old_interrupt_handler)();
X
X/* ctrl-C signal handler for use when we have a temporary file */
Xstatic Signal_t interrupt_handler(sig)
Xint sig;
X{
X unlink(temp_name);
X exit(128 + sig);
X}
X
X/* open a unique temporary file.
X * To be universally accepted by cpp's, the file's name must end in .c; so we
X * can't use mktemp, tmpnam or tmpfile.
X * returns an open stream & sets ret_name to the name.
X */
XFILE *open_temp_file()
X{
X int fd;
X long n = getpid();
X FILE *tempf;
X boolean remove_temp_file();
X
X /* keep generating new names until we hit one that does not exist */
X do
X {
X /* ideally we'd like to put the temporary file in /tmp, but it must go
X * in the current directory because when cpp processes a #include, it
X * looks in the same directory as the file doing the include; so if we
X * use /tmp/blah.c to fake reading fred.h via `#include "fred.h"', cpp
X * will look for /tmp/fred.h, and fail.
X */
X sprintf(temp_name,"c2man%ld.c",n++ % 1000000);
X }
X while((fd =
X#ifdef HAS_OPEN3
X open(temp_name,O_WRONLY|O_CREAT|O_EXCL,0666)
X#else
X creat(temp_name,O_EXCL|0666) /* do it the old way */
X#endif
X ) == -1
X && errno == EEXIST);
X
X /* install interrupt handler to remove the temporary file */
X old_interrupt_handler = signal(SIGINT, interrupt_handler);
X
X /* convert it to a stream */
X if ((fd == -1 && errno != EEXIST) || (tempf = fdopen(fd, "w")) == NULL)
X {
X my_perror("error fdopening temp file",temp_name);
X remove_temp_file();
X return NULL;
X }
X
X return tempf;
X}
X
X/* remove the temporary file & restore ctrl-C handler.
X * returns FALSE in the event of failure.
X */
Xboolean remove_temp_file()
X{
X int ok = unlink(temp_name) == 0; /* this should always succeed */
X signal(SIGINT, old_interrupt_handler);
X return ok;
X}
X
X/* process the specified source file through the pre-processor.
X * This is a lower level routine called by both process_stdin and process_file
X * to actually get the work done once any required temporary files have been
X * generated.
X */
Xint process_file_directly(base_cpp_cmd, name)
Xconst char *base_cpp_cmd;
Xconst char *name;
X{
X char *full_cpp_cmd;
X
X#ifdef DEBUG
X fprintf(stderr,"process_file_directly: %s, %s\n", base_cpp_cmd, name);
X#endif
X
X#ifdef USE_CPP
X full_cpp_cmd = strconcat(base_cpp_cmd, " ", name, NULLCP);
X if (verbose)
X fprintf(stderr,"%s: running `%s'\n", progname, full_cpp_cmd);
X
X if ((yyin = popen(full_cpp_cmd, "r")) == NULL) {
X my_perror("error running", base_cpp_cmd);
X free(full_cpp_cmd);
X return 0;
X }
X#else
X if (verbose) fprintf(stderr,"%s: reading %s\n", progname, name);
X if (name && freopen(name, "r", yyin) == NULL)
X {
X my_perror("cannot open", name);
X return 0;
X }
X#endif
X
X parse_file(name);
X
X#ifdef USE_CPP
X free(full_cpp_cmd);
X if (pclose(yyin) & 0xFF00)
X return 0;
X#else
X if (fclose(yyin))
X {
X my_perror("error closing", name);
X return 0;
X }
X#endif
X
X return !errors;
X}
X
X/* process a specified file */
Xint process_file(base_cpp_cmd, name)
Xconst char *base_cpp_cmd;
Xconst char *name;
X{
X char *period;
X struct stat statbuf;
X
X#ifdef DEBUG
X fprintf(stderr,"process_file: %s, %s\n", base_cpp_cmd, name);
X#endif
X basefile = name;
X header_file = (period = strrchr(name,'.')) &&
X (period[1] == 'h' || period[1] == 'H');
X
X /* use the file's date as the date in the manual page */
X if (stat(name,&statbuf) != 0)
X {
X my_perror("can't stat", name);
X return 0;
X }
X basetime = statbuf.st_mtime;
X
X /* should we do this via a temporary file?
X * Only if it's a header file and either CPP ignores them, or the user
X * has specified files to include.
X *
X * For HP/Apollo (SR10.3, CC 6.8), we must always use a temporary file,
X * because its compiler recognizes the special macro "__attribute(p)",
X * which we cannot redefine in the command line because it has parameters.
X */
X#ifndef apollo
X if (header_file && (cppignhdrs || first_include))
X#endif
X {
X FILE *tempf;
X int ret;
X
X if (verbose)
X fprintf(stderr, "%s: preprocessing via temporary file\n", progname);
X
X if ((tempf = open_temp_file()) == NULL)
X return 0;
X
X print_includes(tempf);
X if (verbose) print_includes(stderr);
X
X#ifdef apollo
X fprintf(tempf,"#define __attribute(p)\n", basefile);
X#endif
X fprintf(tempf,"#include \"%s\"\n", basefile);
X if (verbose) fprintf(stderr,"#include \"%s\"\n", basefile);
X
X if (fclose(tempf) == EOF)
X {
X my_perror("error closing temp file", temp_name);
X remove_temp_file();
X return 0;
X }
X
X /* since we're using a temporary file, it's not the base file */
X inbasefile = 0;
X ret = process_file_directly(base_cpp_cmd, temp_name);
X remove_temp_file();
X return ret;
X }
X
X /* otherwise, process it directly */
X inbasefile = 1;
X
X return process_file_directly(base_cpp_cmd,name);
X}
X
X/* process the thing on the standard input */
Xint process_stdin(base_cpp_cmd)
Xconst char *base_cpp_cmd;
X{
X if (isatty(fileno(stdin)))
X fprintf(stderr,"%s: reading standard input\n", progname);
X
X header_file = 0; /* assume it's not since it's from stdin */
X basefile = NULL;
X
X /* use the current date in the man page */
X basetime = time((Time_t *)NULL);
X
X inbasefile = 1; /* reading stdin, we start in the base file */
X
X /* always use a temp file if the preprocessor can't read stdin, otherwise
X * only use one if the user specified files for inclusion.
X */
X if (!cppcanstdin || first_include) /* did user specify include files? */
X {
X FILE *tempf;
X int c, ret;
X
X if (verbose)
X fprintf(stderr,"%s: reading stdin to a temporary file\n", progname);
X
X if ((tempf = open_temp_file()) == NULL)
X return 0;
X
X print_includes(tempf);
X if (verbose) print_includes(stderr);
X fprintf(tempf,"#line 1 \"stdin\"\n");
X
X while ((c = getchar()) != EOF)
X putc(c,tempf);
X
X if (fclose(tempf) == EOF)
X {
X my_perror("error closing temp file", temp_name);
X remove_temp_file();
X return 0;
X }
X ret = process_file_directly(base_cpp_cmd, temp_name);
X remove_temp_file();
X return ret;
X }
X else
X {
X char *full_cpp_cmd = strconcat(base_cpp_cmd," ", CPP_STDIN_FLAGS,
X NULLCP);
X
X if (verbose)
X fprintf(stderr,"%s: running `%s'\n", progname, full_cpp_cmd);
X
X if ((yyin = popen(full_cpp_cmd, "r")) == NULL) {
X my_perror("error running", full_cpp_cmd);
X return 0;
X }
X
X parse_file(basefile);
X
X free(full_cpp_cmd);
X if (pclose(yyin) & 0xFF00)
X return 0;
X
X return !errors;
X }
X}
X
Xint
Xmain (argc, argv)
Xint argc;
Xchar **argv;
X{
X int i, c, ok = 0;
X char *s, cbuf[2];
X const char *base_cpp_cmd;
X IncludeFile *includefile;
X char *cpp_opts;
X const char *default_section = "3";
X#ifdef HAS_LINK
X enum LinkType link_type = LINK_HARD; /* for -g/G */
X#else
X enum LinkType link_type = LINK_FILE;
X#endif
X
X#ifdef YYDEBUG
X extern int yydebug;
X#endif
X
X /* initialise CPP options with -D__C2MAN__ */
X cbuf[0] = VERSION + '0';
X cbuf[1] = '\0';
X cpp_opts = strconcat("-D__C2MAN__=", cbuf, NULLCP);
X#ifdef NeXT
X cpp_opts = strappend(cpp_opts, " -D_NEXT_SOURCE", NULLCP);
X#endif
X
X /* Scan command line options. */
X while ((c = getopt(argc, argv, "P:D:F:I:psU:Vvo:eM:H:G:gi:S:l:LT:nO:"))
X != EOF)
X {
X switch (c) {
X case 'I':
X case 'D':
X case 'U':
X cbuf[0] = c; cbuf[1] = '\0';
X if (cpp_opts)
X cpp_opts = strappend(cpp_opts," -",cbuf,optarg,NULLCP);
X else
X cpp_opts = strconcat("-",cbuf,optarg,NULLCP);
X break;
X case 'P':
X cpp_cmd = optarg;
X
X /* with no better info to go on, we have to assume that this
X * preprocessor is minimally capable.
X */
X cppcanstdin = 0;
X cppignhdrs = 1;
X break;
X case 'G':
X group_terse = optarg;
X terse_specified = TRUE;
X /* FALLTHROUGH */
X case 'g':
X group_together = TRUE;
X break;
X case 'F':
X s = escape_string(optarg);
X
X decl_spec_prefix = s;
X while (*s != '\0' && isascii(*s) && !isalnum(*s)) ++s;
X if (*s == '\0') usage();
X *s++ = '\0';
X while (*s != '\0' && isascii(*s) && isalnum(*s)) ++s;
X if (*s == '\0') usage();
X
X declarator_prefix = s;
X while (*s != '\0' && isascii(*s) && !isalnum(*s)) ++s;
X if (*s == '\0') usage();
X *s++ = '\0';
X while (*s != '\0' && isascii(*s) && isalnum(*s)) ++s;
X if (*s == '\0') usage();
X
X declarator_suffix = s;
X while (*s != '\0' && *s != '(') ++s;
X if (*s == '\0') usage();
X *s++ = '\0';
X
X first_param_prefix = s;
X while (*s != '\0' && isascii(*s) && !isalnum(*s)) ++s;
X if (*s == '\0') usage();
X *s++ = '\0';
X while (*s != '\0' && *s != ',') ++s;
X if (*s == '\0') usage();
X
X middle_param_prefix = ++s;
X while (*s != '\0' && isascii(*s) && !isalnum(*s)) ++s;
X if (*s == '\0') usage();
X *s++ = '\0';
X while (*s != '\0' && isascii(*s) && isalnum(*s)) ++s;
X if (*s == '\0') usage();
X
X last_param_suffix = s;
X while (*s != '\0' && *s != ')') ++s;
X *s = '\0';
X
X break;
X case 'p':
X promote_param = FALSE;
X break;
X case 's':
X static_out = TRUE;
X break;
X case 'V':
X verbose = TRUE;
X fprintf(stderr, "%s: Version %d, Patchlevel %d\n",
X progname, VERSION, PATCHLEVEL);
X break;
X case 'v':
X variables_out = TRUE;
X break;
X case 'o':
X output_dir = optarg;
X break;
X case 'M':
X manual_name = optarg;
X break;
X case 'H':
X header_prefix = optarg;
X break;
X case 'i':
X *last_next_include = includefile =
X (IncludeFile *)safe_malloc(sizeof *includefile);
X includefile->name = optarg;
X includefile->next = NULL;
X last_next_include = &includefile->next;
X break;
X case 'S':
X manual_section = optarg;
X break;
X case 'l':
X switch(optarg[0])
X {
X#ifdef HAS_LINK
X case 'h': link_type = LINK_HARD; break;
X#endif
X#ifdef HAS_SYMLINK
X case 's': link_type = LINK_SOFT; break;
X#endif
X case 'f': link_type = LINK_FILE; break;
X case 'n': link_type = LINK_NONE; break;
X case 'r': link_type = LINK_REMOVE;break;
X default: usage();
X }
X break;
X case 'e':
X make_embeddable = TRUE;
X break;
X case 'n':
X use_input_name = TRUE;
X break;
X case 'L':
X always_document_params = FALSE;
X break;
X case 'T':
X switch(optarg[0])
X {
X case 'n': output = &nroff_output; break;
X case 'l': output = &latex_output; default_section = "tex";
X break;
X case 't': output = &texinfo_output; default_section = "texi";
X break;
X default: usage();
X }
X break;
X case 'O':
X for (i = 0; i < _OBJECT_NUM; i++)
X if (output_object[i].flag == optarg[0])
X break;
X
X if (i == _OBJECT_NUM)
X {
X fprintf(stderr,"%s: -O option must specify one of:\n\t",
X progname);
X for (i = 0; i < _OBJECT_NUM; i++)
X {
X fprintf(stderr,"%c (%s)", output_object[i].flag,
X output_object[i].name);
X if (i <= _OBJECT_NUM - 2)
X fprintf(stderr,i == _OBJECT_NUM-2 ? " or " : ", ");
X }
X fprintf(stderr, ".\n");
X exit(1);
X }
X
X if ((s = strchr(++optarg,'.'))) /* look for an extension */
X {
X output_object[i].subdir = alloc_string(optarg, s);
X output_object[i].extension = strduplicate(s+1);
X }
X else
X output_object[i].subdir = strduplicate(optarg);
X
X break;
X case '?':
X default:
X usage();
X }
X }
X
X /* make sure we have a manual section */
X if (manual_section == NULL) manual_section = default_section;
X
X#ifdef MALLOC_DEBUG
X getchar(); /* wait so we can start up NeXT MallocDebug tool */
X#endif
X#ifdef YYDEBUG
X yydebug = 1;
X#endif
X
X if (cpp_opts)
X {
X base_cpp_cmd = strconcat(cpp_cmd, " ", cpp_opts, NULLCP);
X free(cpp_opts);
X }
X else
X base_cpp_cmd = cpp_cmd;
X
X if (optind == argc) {
X if (use_input_name)
X {
X fprintf(stderr,"%s: %s\n", progname,
X "cannot name output after input file if there isn't one!");
X usage();
X }
X ok = process_stdin(base_cpp_cmd);
X }
X else
X for (i = optind; i < argc; ++i)
X if (!(ok = process_file(base_cpp_cmd,argv[i]))) break;
X
X if (ok && firstpage)
X output_manual_pages(firstpage,argc - optind, link_type);
X free_manual_pages(firstpage);
X destroy_enum_lists();
X
X if (cpp_opts) free((char *)base_cpp_cmd);
X
X for (includefile = first_include; includefile;)
X {
X IncludeFile *next = includefile->next;
X free(includefile);
X includefile = next;
X }
X
X for (i = 0; i < _OBJECT_NUM; i++)
X {
X safe_free(output_object[i].subdir);
X safe_free(output_object[i].extension);
X }
X
X#ifdef DBMALLOC
X malloc_dump(2);
X malloc_chain_check(1);
X#endif
X#ifdef MALLOC_DEBUG
X sleep(1000000);
X#endif
X return !ok;
X}
!STUFFY!FUNK!
echo Extracting pc/Makefile.pc
sed >pc/Makefile.pc <<'!STUFFY!FUNK!' -e 's/X//'
X# NOTE: This file is generated automatically by processing the Makefile in the
X# main directory with a perl script.
X# Makefile for c2man 23 Aug 1993
X#
X# - for GNU gcc (emx 0.8g kit) under OS/2 2.x or DOS (32-bit)
X# - for Microsoft C 6.00 under OS/2 or DOS (16-bit)
X
X# To use, enter "{d,n}make -f Makefile.pc" (this makefile depends on its
X# name being "Makefile.pc").
X#
X# tested with dmake 3.8 and GNU make 3.68 under OS/2
X
Xdefault:
X @echo "Enter $(MAKE) -f Makefile.pc target "
X @echo " where 'target' is chosen from "
X @echo " msc OS/2 and DOS exe [Microsoft C 6.00a] "
X @echo " emx OS/2 and DOS 32-bit exe [EMX/gcc] "
X
Xemx:
X $(MAKE) -f Makefile.pc all \
X CC="gcc -O -s" O=".o" \
X CFLAGS="-DOS2 -DMSDOS" \
X OBJS2="popen.o" \
X LDFLAGS="" \
X LIBS="c2man-32.def" \
X
Xmsc:
X $(MAKE) -f Makefile.pc all \
X CC="cl -nologo -AS" O=".obj" \
X CFLAGS="-D__STDC__ -DOS2" \
X OBJS2="getopt.obj popen.obj" \
X LDFLAGS="-Lp -F 2000" \
X LIBS="setargv.obj c2man.def -link /NOE" \
X BIND="bind c2man.exe /n DOSMAKEPIPE DOSCWAIT"
X
XYACC=bison -y
XLEX=flex
XSED=sed
XRM=rm
XMV=mv
XECHO=echo
XMKDEP=mkdep
X
X# where we get installed
Xbin=/bin
X
Xmansrc=/etc/man/manl
Xmanext=l
X
X# As Larry said, "Grrrr"
XSHELL=/bin/sh
X
XOSOURCES = config.h c2man.h semantic.h symbol.h strconcat.h \
X strappend.h manpage.h enum.h output.h lex.l grammar.y
XDCSOURCES = c2man.c semantic.c string.c symbol.c strconcat.c \
X strappend.c manpage.c enum.c nroff.c texinfo.c
XSOURCES = $(OSOURCES) $(DCSOURCES)
XCSOURCES = $(DCSOURCES) y.tab.c
XOBJECTS = c2man$O semantic$O string$O symbol$O y.tab$O strconcat$O \
X strappend$O manpage$O enum$O nroff$O texinfo$O
XGENERATED = c2man example.inc ctype_ex.inc y.tab.c lex.yy.c y.output \
X fixexample.sed flatten.sed
X
Xall: c2man.exe example.inc ctype_ex.inc flatten.sed
X
Xinstall:
X cp c2man.exe $(bin)
X $(SED) -f flatten.sed < c2man.1 > $(mansrc)/c2man.$(manext)
X -mkdir $(privlib)
X -mkdir $(privlib)/eg
X cp eg/*.[chly] $(privlib)/eg
X
Xuninstall:
X $(RM) -f $(bin)/c2man $(mansrc)/c2man.$(manext)
X $(RM) -f $(privlib)/eg/*
X rmdir $(privlib)/eg
X rmdir $(privlib)
X
Xc2man.exe: $(OBJECTS)
X $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBS)
X $(BIND)
X
X.c$O:
X $(CC) $(CFLAGS) $(WARNFLAGS) -c $<
X
Xy.tab.c: grammar.y
X @$(ECHO) Expect 48 shift/reduce conflicts.
X $(YACC) grammar.y
X
X# don't compile y.tab.c with all warnings; yacc/bison are not up to it.
Xy.tab$O: y.tab.c lex.yy.c
X $(CC) $(CFLAGS) -c y.tab.c
X
Xlex.yy.c: lex.l
X $(LEX) -t -n lex.l > $@
X cp $@ lex_yy.c
X
Xexample.inc: c2man.exe example.h fixexample.sed
X ./c2man -o- example.h | $(SED) -f fixexample.sed >example.inc
X
Xctype_ex.inc: c2man.exe ctype_ex.h fixexample.sed
X ./c2man -o- -g ctype_ex.h | $(SED) -f fixexample.sed >ctype_ex.inc
X
Xfixexample.sed: fixexample.in
X $(SED) -e '/^#/d' fixexample.in > fixexample.sed
X
Xflatten.sed: flatten_sed.SH
X sh flatten_sed.SH
X
XMakefile: Makefile.SH
X sh Makefile.SH
X
Xconfig.h: config_h.SH
X sh config_h.SH
X
XTAGS: $(SOURCES)
X etags -t $(SOURCES)
X
Xclean:
X $(RM) -f *$O *.s *.bak *~ *.log $(GENERATED) core
X
Xdistclean realclean: clean
X $(RM) -f Makefile config.sh mkdep c2man.kit?
X
Xlint:
X lint -b $(CFLAGS) $(CSOURCES)
X
Xprint:
X cpr $(SOURCES) | lpr -J'c2man'
X
Xtest: c2man.exe
X @echo "Running c2man over the examples..." 1>&2
X @for file in eg/*.[chly]; do ./c2man -v -o- $$file; done
X @echo "Running c2man over its own source code..." 1>&2
X @for file in $(DCSOURCES); do ./c2man -v -o- $$file; done
X @echo "Hmmm, test seemed to go OK." 1>&2
X
Xdepend:
X $(SED) -e '1,/^# DO NOT/!d' < Makefile > Makefile.new
X $(MKDEP) $(DCSOURCES) >> Makefile.new
X - test ! -f y.tab.c -o ! -f lex.yy.c || $(MKDEP) y.tab.c >> Makefile.new
X $(MV) -f Makefile.new Makefile
X
X# y.tab.c dependancies updated manually since it won't exist yet when make
X# depend is first run.
Xy.tab$O: c2man.h config.h confmagic.h enum.h manpage.h semantic.h strappend.h\
X strconcat.h symbol.h
X
X
X# DO NOT DELETE THIS LINE! make depend DEPENDS ON IT!
Xc2man$O: c2man.c c2man.h config.h confmagic.h enum.h manpage.h output.h\
X patchlevel.h strappend.h strconcat.h symbol.h
X
Xsemantic$O: c2man.h config.h confmagic.h enum.h manpage.h semantic.c\
X semantic.h strconcat.h symbol.h
X
Xstring$O: c2man.h config.h confmagic.h string.c symbol.h
X
Xsymbol$O: c2man.h config.h confmagic.h symbol.c symbol.h
X
Xstrconcat$O: c2man.h config.h confmagic.h strconcat.c strconcat.h symbol.h
X
Xstrappend$O: c2man.h config.h confmagic.h strappend.c strappend.h symbol.h
X
Xmanpage$O: c2man.h config.h confmagic.h manpage.c manpage.h output.h\
X semantic.h strconcat.h symbol.h
X
Xenum$O: c2man.h config.h confmagic.h enum.c enum.h manpage.h strconcat.h\
X symbol.h
X
Xnroff$O: c2man.h config.h confmagic.h manpage.h nroff.c output.h symbol.h
X
!STUFFY!FUNK!
echo Extracting strconcat.h
sed >strconcat.h <<'!STUFFY!FUNK!' -e 's/X//'
X/* $Id: strconcat.h,v 2.0.1.1 1993/05/17 02:11:47 greyham Exp $
X * concatenate a list of strings, storing them in a malloc'ed region
X */
X#include "config.h"
X
Xchar *strconcat _V((const char *first, ...));
!STUFFY!FUNK!
echo "End of kit 4 (of 9)"
echo " "
cat /dev/null >kit4isdone
run=''
config=''
for iskit in 1 2 3 4 5 6 7 8 9; do
if test -f kit${iskit}isdone; then
run="$run $iskit"
else
todo="$todo $iskit"
fi
done
case $todo in
'')
echo "You have run all your kits."
if test -f PACKNOTES; then
sh PACKNOTES
else
echo "You have to rebuild split files by hand (see PACKLIST)."
fi
echo "Please read README and then type Configure."
chmod 755 Configure
rm -f kit*isdone
;;
*) echo "You have run$run."
echo "You still need to run$todo."
;;
esac
: Someone might mail this, so exit before signature...
exit 0
--
Graham Stoney, Hardware/Software Engineer
Canon Information Systems Research Australia
Ph: + 61 2 805 2909 Fax: + 61 2 805 2929
exit 0 # Just in case...