#! /bin/sh
# -*- Mode: Shell-script -*-
# ----------------------------------------------------------------------
# getopt.test --- test getopt_long argument processing
#
# Time-stamp: "2009-01-01 09:01:32 bkorb"
# Author: Bruce Korb <bkorb@gnu.org>
##
## This file is part of AutoOpts, a companion to AutoGen.
## AutoOpts is free software.
## AutoOpts is copyright (c) 1992-2009 by Bruce Korb - all rights reserved
##
## AutoOpts is available under any one of two licenses. The license
## in use must be one of these two and the choice is under the control
## of the user of the license.
##
## The GNU Lesser General Public License, version 3 or later
## See the files "COPYING.lgplv3" and "COPYING.gplv3"
##
## The Modified Berkeley Software Distribution License
## See the file "COPYING.mbsd"
##
## These files have the following md5sums:
##
## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
#
# $Id: getopt.test,v 4.29 2009/08/01 17:44:37 bkorb Exp $
# ----------------------------------------------------------------------
. ./defs
CC="${CC} ${CFLAGS} ${INC}"
CFLAGS=''
INC=''
compile_getopt() {
echo ${AGexe} -L${TMPDIR} ${testname}.def
${AGexe} -L${TMPDIR} ${testname}.def || \
failure "AutoGen could not process ${testname}.def #${1}"
${AGexe} -L${TMPDIR} -T getopt.tpl ${testname}.def || \
failure "could not generate getopt-test_${testname}.c"
# Remove the variable comments so we can test against the expected result
#
sed '2,/and the template file/d
/\$Id:/d
/Last template edit:/d' getopt-test_${testname}.c \
> ${testname}${1}-getopt.c
# Finally, compile this thing:
#
${CC} ${CFLAGS} -c ${testname}${1}-getopt.c || \
failure "could not compile ${testname}1-getopt.c"
cmp -s ${testname}${1}-base.c ${testname}${1}-getopt.c || { set +x ; \
failure "`diff -c ${testname}${1}-base.c ${testname}${1}-getopt.c`" ; }
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Fix up a test-specific include directory:
#
# The getopt template presumes that everything has been installed.
# However, we have to work with the local stuff. So, remove the
# "autoopts-config" probing and replace with local stuff:
#
mkdir -p ${TMPDIR}/autoopts
CFLAGS="-I${TMPDIR} ${CFLAGS} ${INC}"
LDFLAGS="${LDFLAGS} ${LIB}"
export CFLAGS LDFLAGS TMPDIR
aolib=${top_builddir}/autoopts/.libs/libopts.a
test -f ${aolib} || aolib=${top_builddir}/autoopts/libopts.a
case " ${LDFLAGS} " in
*' -lgen '* ) aolib=${aolib}\ -lgen ;;
esac
cd ${top_srcdir}/autoopts
cp opt*.tpl getopt.tpl ${TMPDIR}/.
sed -e "/^cflags=/s@=.*@='-I${TMPDIR}/autoopts -I${top_builddir}'@" \
-e "/^ldflags=/s@=.*@='${aolib}'@" \
usage.tpl > ${TMPDIR}/usage.tpl
cd ${builddir}/testdir
# In order to compile correctly, we have to temporarily install the options.h
# header in our TMPDIR. We also must find that header first. Tweak CFLAGS:
#
destdir=${TMPDIR}/autoopts \
top_builddir=${top_builddir} \
${SHELL} ${top_srcdir}/autoopts/install-options-h
AUTOGEN_TEMPL_DIRS=${TMPDIR}
export AUTOGEN_TEMPL_DIRS
# # # # # # # # # # DEFINITIONS FILE # # # # # # # # #
echo "creating ${testname}.def in `pwd`"
cat >> ${testname}.def <<_EOF_
AutoGen definitions options;
prog-name = "test_${testname}";
prog-title = "Test AutoOpts for ${testname}";
test-main = 'yes';
config-header = 'config.h';
settable;
version = '1.2.3';
help-value = 'h';
gnu-usage;
no-libopts;
copyright = {
date = "2003-2009";
owner = "Odyssey Computing Concepts, Inc.";
author= "Bruce Korb";
eaddr = "bkorb@gnu.org";
type = lgpl;
};
flag = {
name = "option";
descrip = "The option option descrip";
value = 'o';
arg_type = string; arg_default = 'opt init';
};
flag = {
name = "second";
descrip = "The second option descrip";
value = 's';
arg_type = string; arg_default = '020';
};
flag = {
name = no_val;
descrip = 'option with no flag';
value = 'F'; /* REMOVE */
flags-must = max_val;
};
flag = {
name = max_val;
descrip = 'option with max ct';
value = 'X'; /* REMOVE */
max = '5';
};
flag = {
name = min2_val;
descrip = 'option with min ct';
value = 'M'; /* REMOVE */
max = '50';
flags-cant = max_val;
min = '5';
};
flag = {
name = min_val;
descrip = 'option with min ct';
value = '2'; /* REMOVE */
max = '50';
min = '5';
};
_EOF_
# # # # # # # # # # BASE-1 OUTPUT FILE # # # # # # # # #
echo creating ${testname}1-base.c
cat > ${testname}1-base.c <<\_EndOfSample_
/* -*- buffer-read-only: t -*- vi: set ro:
*
* test_getopt is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* test_getopt is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "getopt.h"
#include "getopt-test_getopt.h"
#ifndef DIRCH
# if defined(_WIN32) && !defined(__CYGWIN__)
# define DIRCH '\\'
# else
# define DIRCH '/'
# endif
#endif
/*
* Option flag character list
*/
static char z_opts[] = "o:s:FXM2hv";
/*
* AutoOpts library replacement routines:
*/
void
optionUsage (tOptions* pOptions, int status)
{
if (status != 0)
fprintf (stderr, _("Try `%s -h' for more information.\n"),
test_getoptOptions.pzProgName);
else
{
fputs (_("test_getopt - Test AutoOpts for getopt - Ver. 1.2.3\n\
USAGE: test_getopt { -<flag> [<val>] }...\n\n\
-o str The option option descrip\n\
-s str The second option descrip\n\
-F option with no flag\n\
-X option with max ct\n\
-M option with min ct\n\
-2 option with min ct\n\
-v Output version information and exit\n\
-h Display usage information and exit\n\n\n\
please send bug reports to: bkorb@gnu.org\n"), stdout);
}
exit (status);
}
void
optionPrintVersion(
tOptions* pOptions,
tOptDesc* pOptDesc )
{
char const * pz_by =
_("test_getopt 1.2.3\n\
Written by Bruce Korb.\n\n\
copyright (c) 2003-2009 by Odyssey Computing Concepts, Inc.\n\
This is free software; see the source for copying conditions. There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
fputs (pz_by, stdout);
exit (EXIT_SUCCESS);
}
/*
* If an option appears more often than is allowed, ...
*/
static void
usage_too_many (tOptDesc* pOptDesc)
{
char const * pz =
_("test_getopt error: the '%s' option appears more than %d times\n");
fprintf (stderr, pz, pOptDesc->pz_Name, pOptDesc->optMaxCt);
USAGE(EXIT_FAILURE);
}
/*
* There is at least one option that must appear.
*/
static void
usage_too_few (tOptDesc* pOptDesc)
{
char const * pz =
_("test_getopt error: the '%s' option must appear %d times\n");
fprintf (stderr, pz, pOptDesc->pz_Name, pOptDesc->optMinCt);
USAGE(EXIT_FAILURE);
}
/*
* There is at least one pair of options that may not appear together
* on the command line.
*/
static void
usage_cannot (char const* pz_what, char const* pz_cant)
{
char const * pz =
_("test_getopt error: the `%s' option conflicts with the `%s' option.\n");
fprintf (stderr, pz, pz_what, pz_cant);
USAGE(EXIT_FAILURE);
}
/*
* There is at least one pair of options that are required to appear
* together on the command line.
*/
static void
usage_must (char const* pz_what, char const* pz_must)
{
char const * pz =
_("test_getopt error: the `%s' option requires the `%s' option.\n");
fprintf (stderr, pz, pz_what, pz_must);
USAGE(EXIT_FAILURE);
}
/*
* Process the options for the "test_getopt" program.
* This function was generated to use the getopt_long(3GNU) function.
* There are 8 options for this program,
* including "help (usage)" and "version".
*/
int
process_test_getopt_opts (int argc, char** argv)
{
{
char const * pz_prog = strrchr (argv[0], DIRCH);
if (pz_prog != NULL)
pz_prog++;
else
pz_prog = argv[0];
test_getoptOptions.pzProgName = pz_prog;
}
for (;;) {
switch (getopt (argc, argv, z_opts)) {
case -1: goto leave_processing;
case 0: break;
case VALUE_OPT_OPTION:
if (HAVE_OPT( OPTION ))
usage_too_many (&DESC(OPTION));
SET_OPT_OPTION(optarg);
break;
case VALUE_OPT_SECOND:
if (HAVE_OPT( SECOND ))
usage_too_many (&DESC(SECOND));
SET_OPT_SECOND(optarg);
break;
case VALUE_OPT_NO_VAL:
if (HAVE_OPT( NO_VAL ))
usage_too_many (&DESC(NO_VAL));
SET_OPT_NO_VAL;
break;
case VALUE_OPT_MAX_VAL:
if (DESC(MAX_VAL).optOccCt++ >= DESC(MAX_VAL).optMaxCt)
usage_too_many (&DESC(MAX_VAL));
SET_OPT_MAX_VAL;
break;
case VALUE_OPT_MIN2_VAL:
if (DESC(MIN2_VAL).optOccCt++ >= DESC(MIN2_VAL).optMaxCt)
usage_too_many (&DESC(MIN2_VAL));
SET_OPT_MIN2_VAL;
break;
case VALUE_OPT_MIN_VAL:
if (DESC(MIN_VAL).optOccCt++ >= DESC(MIN_VAL).optMaxCt)
usage_too_many (&DESC(MIN_VAL));
SET_OPT_MIN_VAL;
break;
case VALUE_OPT_HELP:
USAGE(EXIT_SUCCESS);
/* NOTREACHED */
case VALUE_OPT_VERSION:
optionPrintVersion (&test_getoptOptions, &DESC(VERSION));
/* NOTREACHED */
default:
USAGE(EXIT_FAILURE);
}
} leave_processing:;
if (HAVE_OPT( NO_VAL )) {
if (! HAVE_OPT( MAX_VAL ))
usage_must (DESC(NO_VAL).pz_Name, DESC(MAX_VAL).pz_Name);
}
if (HAVE_OPT( MIN2_VAL )) {
if (HAVE_OPT( MAX_VAL ))
usage_cannot (DESC(MIN2_VAL).pz_Name, DESC(MAX_VAL).pz_Name);
if (DESC(MIN2_VAL).optOccCt < DESC(MIN2_VAL).optMinCt)
usage_too_few (&DESC(MIN2_VAL));
}
else
usage_too_few (&DESC(MIN2_VAL));
if (DESC(MIN_VAL).optOccCt < DESC(MIN_VAL).optMinCt)
usage_too_few (&DESC(MIN_VAL));
return 0;
}
_EndOfSample_
# # # # # # # # # # BASE-2 OUTPUT FILE # # # # # # # # #
echo creating ${testname}2-base.c
cat > ${testname}2-base.c <<\_EndOfSample_
/* -*- buffer-read-only: t -*- vi: set ro:
*
* test_getopt is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* test_getopt is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <getopt.h>
#include "getopt.h"
#include "getopt-test_getopt.h"
#ifndef DIRCH
# if defined(_WIN32) && !defined(__CYGWIN__)
# define DIRCH '\\'
# else
# define DIRCH '/'
# endif
#endif
/*
* getopt_long option descriptor
*/
static struct option a_long_opts[] = {
{ "option", 1, NULL, VALUE_OPT_OPTION },
{ "second", 1, NULL, VALUE_OPT_SECOND },
{ "no_val", 0, NULL, VALUE_OPT_NO_VAL },
{ "max_val", 0, NULL, VALUE_OPT_MAX_VAL },
{ "min2_val", 0, NULL, VALUE_OPT_MIN2_VAL },
{ "min_val", 0, NULL, VALUE_OPT_MIN_VAL },
{ "help", 0, NULL, VALUE_OPT_HELP },
{ "version", 0, NULL, VALUE_OPT_VERSION },
{ NULL, 0, NULL, 0 }
};
/*
* Option flag character list
*/
static char z_opts[] = "o:s:h";
/*
* AutoOpts library replacement routines:
*/
void
optionUsage (tOptions* pOptions, int status)
{
if (status != 0)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
test_getoptOptions.pzProgName);
else
{
fputs (_("test_getopt - Test AutoOpts for getopt - Ver. 1.2.3\n\
USAGE: test_getopt { -<flag> [<val>] | --<name>[{=| }<val>] }...\n\n\
-o, --option=str The option option descrip\n\
-s, --second=str The second option descrip\n\
--no-val option with no flag\n\
--max-val option with max ct\n\
--min2-val option with min ct\n\
--min-val option with min ct\n\
--version Output version information and exit\n\
-h, --help Display usage information and exit\n\n\
Options are specified by doubled hyphens and their name\n\
or by a single hyphen and the flag character.\n\n\
please send bug reports to: bkorb@gnu.org\n"), stdout);
}
exit (status);
}
void
optionPrintVersion(
tOptions* pOptions,
tOptDesc* pOptDesc )
{
char const * pz_by =
_("test_getopt 1.2.3\n\
Written by Bruce Korb.\n\n\
copyright (c) 2003-2009 by Odyssey Computing Concepts, Inc.\n\
This is free software; see the source for copying conditions. There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
fputs (pz_by, stdout);
exit (EXIT_SUCCESS);
}
/*
* If an option appears more often than is allowed, ...
*/
static void
usage_too_many (tOptDesc* pOptDesc)
{
char const * pz =
_("test_getopt error: the '%s' option appears more than %d times\n");
fprintf (stderr, pz, pOptDesc->pz_Name, pOptDesc->optMaxCt);
USAGE(EXIT_FAILURE);
}
/*
* There is at least one option that must appear.
*/
static void
usage_too_few (tOptDesc* pOptDesc)
{
char const * pz =
_("test_getopt error: the '%s' option must appear %d times\n");
fprintf (stderr, pz, pOptDesc->pz_Name, pOptDesc->optMinCt);
USAGE(EXIT_FAILURE);
}
/*
* There is at least one pair of options that may not appear together
* on the command line.
*/
static void
usage_cannot (char const* pz_what, char const* pz_cant)
{
char const * pz =
_("test_getopt error: the `%s' option conflicts with the `%s' option.\n");
fprintf (stderr, pz, pz_what, pz_cant);
USAGE(EXIT_FAILURE);
}
/*
* There is at least one pair of options that are required to appear
* together on the command line.
*/
static void
usage_must (char const* pz_what, char const* pz_must)
{
char const * pz =
_("test_getopt error: the `%s' option requires the `%s' option.\n");
fprintf (stderr, pz, pz_what, pz_must);
USAGE(EXIT_FAILURE);
}
/*
* Process the options for the "test_getopt" program.
* This function was generated to use the getopt_long(3GNU) function.
* There are 8 options for this program,
* including "help (usage)" and "version".
*/
int
process_test_getopt_opts (int argc, char** argv)
{
{
char const * pz_prog = strrchr (argv[0], DIRCH);
if (pz_prog != NULL)
pz_prog++;
else
pz_prog = argv[0];
test_getoptOptions.pzProgName = pz_prog;
}
for (;;) {
switch (getopt_long (argc, argv, z_opts, a_long_opts, NULL)) {
case -1: goto leave_processing;
case 0: break;
case VALUE_OPT_OPTION:
if (HAVE_OPT( OPTION ))
usage_too_many (&DESC(OPTION));
SET_OPT_OPTION(optarg);
break;
case VALUE_OPT_SECOND:
if (HAVE_OPT( SECOND ))
usage_too_many (&DESC(SECOND));
SET_OPT_SECOND(optarg);
break;
case VALUE_OPT_NO_VAL:
if (HAVE_OPT( NO_VAL ))
usage_too_many (&DESC(NO_VAL));
SET_OPT_NO_VAL;
break;
case VALUE_OPT_MAX_VAL:
if (DESC(MAX_VAL).optOccCt++ >= DESC(MAX_VAL).optMaxCt)
usage_too_many (&DESC(MAX_VAL));
SET_OPT_MAX_VAL;
break;
case VALUE_OPT_MIN2_VAL:
if (DESC(MIN2_VAL).optOccCt++ >= DESC(MIN2_VAL).optMaxCt)
usage_too_many (&DESC(MIN2_VAL));
SET_OPT_MIN2_VAL;
break;
case VALUE_OPT_MIN_VAL:
if (DESC(MIN_VAL).optOccCt++ >= DESC(MIN_VAL).optMaxCt)
usage_too_many (&DESC(MIN_VAL));
SET_OPT_MIN_VAL;
break;
case VALUE_OPT_HELP:
USAGE(EXIT_SUCCESS);
/* NOTREACHED */
case VALUE_OPT_VERSION:
optionPrintVersion (&test_getoptOptions, &DESC(VERSION));
/* NOTREACHED */
default:
USAGE(EXIT_FAILURE);
}
} leave_processing:;
if (HAVE_OPT( NO_VAL )) {
if (! HAVE_OPT( MAX_VAL ))
usage_must (DESC(NO_VAL).pz_Name, DESC(MAX_VAL).pz_Name);
}
if (HAVE_OPT( MIN2_VAL )) {
if (HAVE_OPT( MAX_VAL ))
usage_cannot (DESC(MIN2_VAL).pz_Name, DESC(MAX_VAL).pz_Name);
if (DESC(MIN2_VAL).optOccCt < DESC(MIN2_VAL).optMinCt)
usage_too_few (&DESC(MIN2_VAL));
}
else
usage_too_few (&DESC(MIN2_VAL));
if (DESC(MIN_VAL).optOccCt < DESC(MIN_VAL).optMinCt)
usage_too_few (&DESC(MIN_VAL));
return 0;
}
_EndOfSample_
# # # # # # # # # # RESULTS TESTING # # # # # # # # #
compile_getopt 1
grep 'getopt_long' /usr/include/getopt.h >/dev/null && {
CFLAGS="${CFLAGS} -D_GNU_SOURCE=1"
sed '/REMOVE/d;$a\
long-opts;\
version-value;
' ${testname}.def > ${testname}2.def
mv -f ${testname}2.def ${testname}.def
compile_getopt 2
}
cleanup
## Local Variables:
## mode: shell-script
## indent-tabs-mode: nil
## End:
# end of getopt.test