From 8e3e242cb46db81a302525f4d2e63299becb002b Mon Sep 17 00:00:00 2001 From: Robert Collins Date: Sun, 14 Apr 2002 02:23:32 +0000 Subject: [PATCH] 2002-04-14 Robert Collins * Makefile.am: New file. * README: New file. * bootstrap.sh: New file. * configure.in: New file. * include/BoolOption.h: New file. * include/GetOption.h: New file. * include/Option.h: New file. * src/BoolOption.cc: New file. * src/GetOption.cc: New file. * src/Option.cc: New file. * tests/testoption.cc: New file. --- libgetopt++/Makefile.am | 26 +++++ libgetopt++/README | 72 ++++++++++++++ libgetopt++/bootstrap.sh | 29 ++++++ libgetopt++/configure.ac | 87 ++++++++++++++++ libgetopt++/configure.in | 87 ++++++++++++++++ libgetopt++/include/getopt++/BoolOption.h | 45 +++++++++ libgetopt++/include/getopt++/GetOption.h | 37 +++++++ libgetopt++/include/getopt++/Option.h | 47 +++++++++ libgetopt++/src/BoolOption.cc | 57 +++++++++++ libgetopt++/src/GetOption.cc | 116 ++++++++++++++++++++++ libgetopt++/src/Option.cc | 24 +++++ libgetopt++/tests/testoption.cc | 23 +++++ 12 files changed, 650 insertions(+) create mode 100644 libgetopt++/Makefile.am create mode 100644 libgetopt++/README create mode 100755 libgetopt++/bootstrap.sh create mode 100644 libgetopt++/configure.ac create mode 100644 libgetopt++/configure.in create mode 100644 libgetopt++/include/getopt++/BoolOption.h create mode 100644 libgetopt++/include/getopt++/GetOption.h create mode 100644 libgetopt++/include/getopt++/Option.h create mode 100644 libgetopt++/src/BoolOption.cc create mode 100644 libgetopt++/src/GetOption.cc create mode 100644 libgetopt++/src/Option.cc create mode 100644 libgetopt++/tests/testoption.cc diff --git a/libgetopt++/Makefile.am b/libgetopt++/Makefile.am new file mode 100644 index 00000000..8bccb6f7 --- /dev/null +++ b/libgetopt++/Makefile.am @@ -0,0 +1,26 @@ +## Process this file with automake to produce Makefile.in +# +# $Id$ +# + +AUTOMAKE_OPTIONS = dist-bzip2 subdir-objects VERSION=1.5 +##DIST_SUBDIRS = src +##SUBDIRS = src + +DISTCLEANFILES = include/stamp-h include/stamp-h[0-9]* + +AM_CXXFLAGS = -I$(top_srcdir)/include + +getoptincludedir = $(includedir)/getopt++ + +lib_LTLIBRARIES = libgetopt++.la +check_PROGRAMS = testoption + +libgetopt___la_SOURCES = src/GetOption.cc src/Option.cc src/BoolOption.cc +libgetopt___la_LDFLAGS = -lstdc++ -version-info 0:0:0 + +getoptinclude_HEADERS = include/Option.h include/GetOption.h \ + include/BoolOption.h + +testoption_SOURCES = tests/testoption.cc +testoption_LDADD = libgetopt++.la diff --git a/libgetopt++/README b/libgetopt++/README new file mode 100644 index 00000000..aa023bd5 --- /dev/null +++ b/libgetopt++/README @@ -0,0 +1,72 @@ +This is the README for libgetopt++. Libgetopt++ is a C++ library for command +line parsing. + +It has/allows: + +1) Minimal footprint in main.cc, and no header or source changes outside the + user of an option when the option is altered/a new option added. +2) Multiple option sets can co-exist safely. The default option set is a + singleton, but additional static sets can be created and used. +3) Easy to use. Adding a new option is simply a case of adding a static + variable (can be a class member for instance) for the option, in the scope + that the option needs to be visible - be that class scope or translation + unit scope. +4) There are (will be when feature complete) multiple concrete Option classes + provided (currently BoolOption is the only one implemented). +5) Extensible. Simply create a new subclass of Option to implement a new + Option type, and use it in your program. + +Libgetopt++ is licenced under the GPL. + +The primary mailing list for discussion of libgetopt++ is +cygwin-apps@cygwin.com (unless/until traffic on libgetopt++ becomes worthy +of a dedicated list). Use this list for all bug reports, development discussion +and help requests. + +Getting libgetopt++: +Currently there are no user distributions that I know of. Libgetopt++ source is +available via anonymous cvs from +:pserver:sources.redhat.com:/cvs/cygwin-apps/libgetopt++. + +Building libgetopt++: +For libgetopt++ developers: +You need autoconf 2.52 or better, automake 1.5 or better, and a recent libtool. +Depending on your platform static and or shared libraries will be built by +default. You will also need a C++ compiler, a linker and other such usual tools. + +Once you have the source, and the required tools, run ./bootstrap.sh in the +top of the source tree. This should succeed - if it doesn't check you have all +the tools available and working before seeking help from the mailing list. + +After successfully running the bootstrap.sh script, you can follow the user +building instructions below. As a developer you will likely want to build in +a separate directory to the source code, and to add --enable-maintainer-mode +and --enable-dependency-tracking to the configure line. + +For libgetopt++ users: +You only need a C++ compiler toolchain. The user distributions include a +pregenerated configure script. + +Once you have that, + 1) unpack the source somewhere. + 2) (optional) make a separate build directory - ie $(path to source)/build + 3) cd to wherever you plan to build from - either a dedicated directory + or the top level source directory. + 4) run $(path to source)/configure + 5) run make. + +Installing libgetopt++: +Run make install in the build tree. If you are using shared libraries you need +to ensure that the library load path on your system includes the appropriate +location for the libraries. The default behaviour is to install the libraries +to /usr/local/lib (or for cygwin /usr/local/bin). If you are not sure whether +this has been done, check your system manual for more information. + +Using libgetopt++: + +To be written. Essentially include in main.cc, and + where you need to declare a command line option. + +All options must be static variables or static members. + + diff --git a/libgetopt++/bootstrap.sh b/libgetopt++/bootstrap.sh new file mode 100755 index 00000000..a21c14fd --- /dev/null +++ b/libgetopt++/bootstrap.sh @@ -0,0 +1,29 @@ +#! /bin/sh +# Used to setup the configure.in, autoheader and Makefile.in's if configure +# has not been generated. This script is only needed for developers when +# configure has not been run, or if a Makefile.am in a non-configured directory +# has been updated + + +bootstrap() { + if "$@"; then + true # Everything OK + else + echo "$1 failed" + echo "Autotool bootstrapping failed. You will need to investigate and correct" ; + echo "before you can develop on this source tree" + exit 1 + fi +} + +# Make sure cfgaux exists +mkdir -p cfgaux + +# Bootstrap the autotool subsystems +bootstrap aclocal +bootstrap autoheader +bootstrap libtoolize --automake +bootstrap automake --foreign --add-missing +bootstrap autoconf + +echo "Autotool bootstrapping complete." diff --git a/libgetopt++/configure.ac b/libgetopt++/configure.ac new file mode 100644 index 00000000..4df598f3 --- /dev/null +++ b/libgetopt++/configure.ac @@ -0,0 +1,87 @@ +dnl +dnl Configuration input file for GetOpt++ +dnl +dnl Robert Collins, rbtcollins@hotmail.com +dnl +dnl $Id$ +dnl +dnl +dnl +AC_INIT(src/GetOption.cc) +AC_PREREQ(2.52) +AC_CONFIG_AUX_DIR(cfgaux) +AM_INIT_AUTOMAKE(GetOpt++, 0.0.1-DEVEL) +AM_CONFIG_HEADER(include/autoconf.h) +AC_REVISION($Revision$)dnl +AC_PREFIX_DEFAULT(/usr/local) +AM_MAINTAINER_MODE + +dnl Set default LDFLAGS +if test -z "$LDFLAGS"; then + LDFLAGS="-g" +fi + +PRESET_CFLAGS="$CFLAGS" + +dnl Check for GNU cc +AC_LANG_CPLUSPLUS +dnl AC_API_WIN32 +AC_PROG_CXX +AM_PROG_CC_C_O +AC_CANONICAL_BUILD +AC_CANONICAL_HOST +AC_PROG_LIBTOOL + +CRYPTLIB='' +REGEXLIB='' # -lregex +LIBREGEX='' # libregex.a + +dnl find out the exe extension for this platform. If it's not empty, use it for CGI's as well. +AC_EXEEXT +AC_OBJEXT + +AC_CHECK_HEADERS( \ + unistd.h \ + string \ + string.h +) + +AC_C_CONST +AC_C_BIGENDIAN + +AC_TYPE_SIZE_T +AC_CHECK_TYPE(ssize_t, int) +AC_TYPE_PID_T +AC_TYPE_MODE_T + +dnl Check for special functions +AC_FUNC_ALLOCA + +dnl Check for needed libraries + +AC_CHECK_LIB(regex, main, [REGEXLIB="-lregex"]) +AC_CHECK_LIB(m, main) + +dnl Check for libcrypt +dnl We use crypt(3) which may be in libc, or in libcrypt (eg FreeBSD) +AC_CHECK_LIB(crypt, crypt, [CRYPTLIB="-lcrypt"]) +AC_SUBST(CRYPTLIB) + +dnl Check for pthreads +dnl We use pthreads when doing ASYNC I/O +AC_CHECK_LIB(pthread, main, [PTHREADLIB="-lpthread"]) +AC_SUBST(PTHREADLIB) + +dnl Check for librt +dnl We use AIO in the coss store +AC_CHECK_LIB(rt, aio_read, [AIOLIB="-lrt"]) +AC_SUBST(AIOLIB) + +dnl Check for library functions +dnl AC_CHECK_FUNCS(\ +dnl ) + + +AC_OUTPUT([\ + Makefile +]) diff --git a/libgetopt++/configure.in b/libgetopt++/configure.in new file mode 100644 index 00000000..4df598f3 --- /dev/null +++ b/libgetopt++/configure.in @@ -0,0 +1,87 @@ +dnl +dnl Configuration input file for GetOpt++ +dnl +dnl Robert Collins, rbtcollins@hotmail.com +dnl +dnl $Id$ +dnl +dnl +dnl +AC_INIT(src/GetOption.cc) +AC_PREREQ(2.52) +AC_CONFIG_AUX_DIR(cfgaux) +AM_INIT_AUTOMAKE(GetOpt++, 0.0.1-DEVEL) +AM_CONFIG_HEADER(include/autoconf.h) +AC_REVISION($Revision$)dnl +AC_PREFIX_DEFAULT(/usr/local) +AM_MAINTAINER_MODE + +dnl Set default LDFLAGS +if test -z "$LDFLAGS"; then + LDFLAGS="-g" +fi + +PRESET_CFLAGS="$CFLAGS" + +dnl Check for GNU cc +AC_LANG_CPLUSPLUS +dnl AC_API_WIN32 +AC_PROG_CXX +AM_PROG_CC_C_O +AC_CANONICAL_BUILD +AC_CANONICAL_HOST +AC_PROG_LIBTOOL + +CRYPTLIB='' +REGEXLIB='' # -lregex +LIBREGEX='' # libregex.a + +dnl find out the exe extension for this platform. If it's not empty, use it for CGI's as well. +AC_EXEEXT +AC_OBJEXT + +AC_CHECK_HEADERS( \ + unistd.h \ + string \ + string.h +) + +AC_C_CONST +AC_C_BIGENDIAN + +AC_TYPE_SIZE_T +AC_CHECK_TYPE(ssize_t, int) +AC_TYPE_PID_T +AC_TYPE_MODE_T + +dnl Check for special functions +AC_FUNC_ALLOCA + +dnl Check for needed libraries + +AC_CHECK_LIB(regex, main, [REGEXLIB="-lregex"]) +AC_CHECK_LIB(m, main) + +dnl Check for libcrypt +dnl We use crypt(3) which may be in libc, or in libcrypt (eg FreeBSD) +AC_CHECK_LIB(crypt, crypt, [CRYPTLIB="-lcrypt"]) +AC_SUBST(CRYPTLIB) + +dnl Check for pthreads +dnl We use pthreads when doing ASYNC I/O +AC_CHECK_LIB(pthread, main, [PTHREADLIB="-lpthread"]) +AC_SUBST(PTHREADLIB) + +dnl Check for librt +dnl We use AIO in the coss store +AC_CHECK_LIB(rt, aio_read, [AIOLIB="-lrt"]) +AC_SUBST(AIOLIB) + +dnl Check for library functions +dnl AC_CHECK_FUNCS(\ +dnl ) + + +AC_OUTPUT([\ + Makefile +]) diff --git a/libgetopt++/include/getopt++/BoolOption.h b/libgetopt++/include/getopt++/BoolOption.h new file mode 100644 index 00000000..6fa522e2 --- /dev/null +++ b/libgetopt++/include/getopt++/BoolOption.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2002 Robert Collins. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * A copy of the GNU General Public License can be found at + * http://www.gnu.org/ + * + * Written by Robert Collins + * + */ + +#ifndef _BOOLOPTION_H_ +#define _BOOLOPTION_H_ + +#include +#include + +// Each registered option must implement this class. +class BoolOption : public Option +{ +public: + BoolOption(bool const defaultvalue, char shortopt, char const *longopt = 0, + String const &shorthelp = String(), + GetOption &owner=GetOption::GetInstance()); + virtual ~ BoolOption (); + virtual char const shortOption () const; + virtual struct option longOption () const; + virtual String const shortHelp () const; + virtual bool Process (char const *); + operator bool () const; + + +private: + bool _value; + bool _ovalue; + char _shortopt; + char const *_longopt; + String _shorthelp; +}; + +#endif // _BOOLOPTION_H_ diff --git a/libgetopt++/include/getopt++/GetOption.h b/libgetopt++/include/getopt++/GetOption.h new file mode 100644 index 00000000..415573b9 --- /dev/null +++ b/libgetopt++/include/getopt++/GetOption.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2002 Robert Collins. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * A copy of the GNU General Public License can be found at + * http://www.gnu.org/ + * + * Written by Robert Collins + * + */ + +#ifndef _GETOPTION_H_ +#define _GETOPTION_H_ + +#include +class Option; + +class GetOption +{ +public: + static GetOption & GetInstance (); + void Register (Option *); + bool Process (int argc, char **argv); +private: + static GetOption Instance; + void Init (); + int inited; //we can't use a bool in case it is + // non zero on startup. + Option **options; + int optCount; +}; + +#endif // _GETOPTION_H_ diff --git a/libgetopt++/include/getopt++/Option.h b/libgetopt++/include/getopt++/Option.h new file mode 100644 index 00000000..1db2e81e --- /dev/null +++ b/libgetopt++/include/getopt++/Option.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2002 Robert Collins. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * A copy of the GNU General Public License can be found at + * http://www.gnu.org/ + * + * Written by Robert Collins + * + */ + +#ifndef _OPTION_H_ +#define _OPTION_H_ + +#if HAVE_CONFIG_H +#include "autoconf.h" +#endif +#if HAVE_STRING___H +#include "String++.h" +// this is bogus, because autoconf doesn't understand +// vs +#elif HAVE_STRING_H +#include +typedef string String; +#else +#error ""String++.h" or required" +#endif + +// Each registered option must implement this class. +class Option +{ +public: + virtual ~ Option (); + virtual char const shortOption () const = 0; + virtual struct option longOption () const = 0; + virtual String const shortHelp () const = 0; + virtual bool Process (char const *) = 0; + +protected: + Option (); +}; + +#endif // _OPTION_H_ diff --git a/libgetopt++/src/BoolOption.cc b/libgetopt++/src/BoolOption.cc new file mode 100644 index 00000000..9fb1dc90 --- /dev/null +++ b/libgetopt++/src/BoolOption.cc @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2002 Robert Collins. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * A copy of the GNU General Public License can be found at + * http://www.gnu.org/ + * + * Written by Robert Collins + * + */ + +#include + +BoolOption::BoolOption(bool const defaultvalue, char shortopt, + char const *longopt, String const &shorthelp, + GetOption &owner) : _value (defaultvalue) , + _ovalue (defaultvalue), _shortopt(shortopt), + _longopt (longopt), _shorthelp (shorthelp) +{ + owner.Register (this); +}; + +BoolOption::~ BoolOption () {}; + +char const +BoolOption::shortOption () const +{ + return _shortopt; +} + +struct option +BoolOption::longOption () const +{ + struct option foo = {_longopt, no_argument, NULL, _shortopt}; + return foo; +} + +String const +BoolOption::shortHelp () const +{ + return _shorthelp; +} + +bool +BoolOption::Process (char const *) +{ + _value = !_ovalue; +} + +BoolOption::operator bool () const +{ + return _value; +} diff --git a/libgetopt++/src/GetOption.cc b/libgetopt++/src/GetOption.cc new file mode 100644 index 00000000..48fd379b --- /dev/null +++ b/libgetopt++/src/GetOption.cc @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2002 Robert Collins. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * A copy of the GNU General Public License can be found at + * http://www.gnu.org/ + * + * Written by Robert Collins + * + */ + +#if HAVE_CONFIG_H +#include "autoconf.h" +#endif +#include "GetOption.h" +#include "Option.h" + +GetOption + GetOption::Instance; + +GetOption & GetOption::GetInstance () +{ + if (Instance.inited != 42) + { + Instance.Init (); + } + return Instance; +} + +bool GetOption::Process (int argc, char **argv) +{ + if (argc == 1) + { +// log (LOG_TIMESTAMP, "No command line options pass\n"); + return true; + } + if (optCount == 0) + { +// log (LOG_TIMESTAMP, +// "%d Command line options passed, and no options registered\n", +// argc); + return false; + } +// log (LOG_TIMESTAMP, "Process command line options\n"); + struct option + longopts[optCount + 1]; + String + shortopts; + for (int i = 0; i < optCount; ++i) + { + Option *anOption = options[i]; + shortopts += anOption->shortOption (); + longopts[i] = anOption->longOption (); + } + char const * + opts = shortopts.c_str (); + { + struct option + foo = { + 0, + 0, + 0, + 0 }; + longopts[optCount] = foo; + } +// where is this correctly defined? opterr=0; + int + lastoption; + while ((lastoption = getopt_long (argc, argv, opts, longopts, 0)) != -1) + { + if (lastoption) + { + if (lastoption == '\?') + { + //ambigous option +#if HAVE_STRING___H + delete[]opts; +#endif + return false; + } + for (int i = 0; i < optCount; ++i) + { + if (longopts[i].val == lastoption && !longopts[i].flag) + options[i]->Process (optarg); + } + } + } +#if HAVE_STRING___H + delete[]opts; +#endif + return true; +} + +void +GetOption::Init () +{ + optCount = 0; + options = 0; + inited = 42; +} + +//FIXME: check for conflicts. +void +GetOption::Register (Option * anOption) +{ + Option **t = new Option *[optCount + 1]; + for (int i = 0; i < optCount; ++i) + t[i] = options[i]; + t[optCount++] = anOption; + delete[]options; + options = t; +} diff --git a/libgetopt++/src/Option.cc b/libgetopt++/src/Option.cc new file mode 100644 index 00000000..a5bf2578 --- /dev/null +++ b/libgetopt++/src/Option.cc @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2002 Robert Collins. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * A copy of the GNU General Public License can be found at + * http://www.gnu.org/ + * + * Written by Robert Collins + * + */ + +#include "Option.h" + +Option::Option () +{ +} + +Option::~Option () +{ +} diff --git a/libgetopt++/tests/testoption.cc b/libgetopt++/tests/testoption.cc new file mode 100644 index 00000000..1e562a8d --- /dev/null +++ b/libgetopt++/tests/testoption.cc @@ -0,0 +1,23 @@ +#include "GetOption.h" +#include "BoolOption.h" + +static BoolOption testoption (false, 't', "testoption", "Tests the use of boolean options"); +int +main (int argc, char **argv) +{ + if (!GetOption::GetInstance().Process (argc, argv)) + { + cout << "Failed to process options" << endl; + return 1; + } + if (testoption) + { + cout << "Option used" << endl; + return 1; + } + else + { + cout << "Option not used" << endl; + return 0; + } +} -- 2.43.5