#! /bin/sh # -*- Mode: Shell-script -*- # ---------------------------------------------------------------------- # getopt.test --- test getopt_long argument processing # # Time-stamp: "2007-07-15 16:56:46 bkorb" # Author: Bruce Korb ## ## This file is part of AutoOpts, a companion to AutoGen. ## AutoOpts is free software. ## AutoOpts is copyright (c) 1992-2007 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: ## ## 239588c55c22c60ffe159946a760a33e pkg/libopts/COPYING.gplv3 ## fa82ca978890795162346e661b47161a pkg/libopts/COPYING.lgplv3 ## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd # # $Id: getopt.test,v 4.17 2007/07/16 00:17:31 bkorb Exp $ # ---------------------------------------------------------------------- . ./defs # This test relies on being able to use the "getopt.tpl" template. # Unfortunately, that template requires that autoopts be properly # installed. If not, the compile will fail. Therefore, test now # for the proper functioning of "autoopts-config". # f=`autoopts-config cflags` test -z "${f}" && echo ${testname} disabled -- autoopts not installed && exit 0 CC="${CC} ${CFLAGS} ${INC}" CFLAGS='' INC='' compile_getopt() { echo ${AG_L} ${testname}.def ${AG_L} ${testname}.def || \ failure "AutoGen could not process ${testname}.def #${1}" ${AG_L} -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:-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: # TMPDIR=`pwd`/${testname}-inc mkdir ${TMPDIR} ${TMPDIR}/autoopts srcdir=`pwd` CFLAGS="-I ${TMPDIR} ${CFLAGS} ${INC}" LDFLAGS="${LDFLAGS} ${LIB}" export srcdir CFLAGS LDFLAGS TMPDIR aolib=${top_builddir}/autoopts/.libs/libopts.a test -f ${aolib} || aolib=${top_builddir}/autoopts/libopts.a sed -e '/ CFLAGS=/s@ *`autoopts-config cflags`@'" -I${top_srcdir}/autoopts@" \ -e '/ LDFLAGS=/s@ *`autoopts-config ldflags`@'" ${aolib}@" \ ${top_srcdir}/autoopts/getopt.tpl > ${TMPDIR}/getopt.tpl # 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:-/bin/sh} ${top_srcdir}/autoopts/install-options-h # # # # # # # # # # 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; copyright = { date = "2003-2007"; 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 . * */ #include #include #include #include #include #include "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 --help' for more information.\n"), test_getoptOptions.pzProgName); else { fputs (_("test_getopt - Test AutoOpts for getopt - Ver. 1.2.3\n\ USAGE: test_getopt { - [] }...\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\ -! Extended usage information passed thru pager\n\n\n\ please send bug reports to: bkorb@gnu.org\n"), stdout); } exit (status); } void optionPagedUsage( tOptions* pOptions, tOptDesc* pOptDesc ) { fputs (_("test_getopt error: paged usage help has been disabled\n"), stderr); optionUsage (pOptions, EXIT_FAILURE); } 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-2007 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"); printf (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"); printf (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 `%s'\n"); printf (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 `%s'\n"); printf (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 . * */ #include #include #include #include #include #include "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 { - [] | --[{=| }] }...\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 optionPagedUsage( tOptions* pOptions, tOptDesc* pOptDesc ) { fputs (_("test_getopt error: paged usage help has been disabled\n"), stderr); optionUsage (pOptions, EXIT_FAILURE); } 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-2007 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"); printf (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"); printf (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 `%s'\n"); printf (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 `%s'\n"); printf (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 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 ## sh-indentation: 2 ## End: # end of getopt.test