arguments.h

00001 /*
00002  * All of the documentation and software included in the
00003  * Alchemy Software is copyrighted by Stanley Kok, Parag
00004  * Singla, Matthew Richardson, Pedro Domingos, Marc
00005  * Sumner and Hoifung Poon.
00006  * 
00007  * Copyright [2004-07] Stanley Kok, Parag Singla, Matthew
00008  * Richardson, Pedro Domingos, Marc Sumner and Hoifung
00009  * Poon. All rights reserved.
00010  * 
00011  * Contact: Pedro Domingos, University of Washington
00012  * (pedrod@cs.washington.edu).
00013  * 
00014  * Redistribution and use in source and binary forms, with
00015  * or without modification, are permitted provided that
00016  * the following conditions are met:
00017  * 
00018  * 1. Redistributions of source code must retain the above
00019  * copyright notice, this list of conditions and the
00020  * following disclaimer.
00021  * 
00022  * 2. Redistributions in binary form must reproduce the
00023  * above copyright notice, this list of conditions and the
00024  * following disclaimer in the documentation and/or other
00025  * materials provided with the distribution.
00026  * 
00027  * 3. All advertising materials mentioning features or use
00028  * of this software must display the following
00029  * acknowledgment: "This product includes software
00030  * developed by Stanley Kok, Parag Singla, Matthew
00031  * Richardson, Pedro Domingos, Marc Sumner and Hoifung
00032  * Poon in the Department of Computer Science and
00033  * Engineering at the University of Washington".
00034  * 
00035  * 4. Your publications acknowledge the use or
00036  * contribution made by the Software to your research
00037  * using the following citation(s): 
00038  * Stanley Kok, Parag Singla, Matthew Richardson and
00039  * Pedro Domingos (2005). "The Alchemy System for
00040  * Statistical Relational AI", Technical Report,
00041  * Department of Computer Science and Engineering,
00042  * University of Washington, Seattle, WA.
00043  * http://www.cs.washington.edu/ai/alchemy.
00044  * 
00045  * 5. Neither the name of the University of Washington nor
00046  * the names of its contributors may be used to endorse or
00047  * promote products derived from this software without
00048  * specific prior written permission.
00049  * 
00050  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF WASHINGTON
00051  * AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00052  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00053  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00054  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY
00055  * OF WASHINGTON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00056  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00057  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00058  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00059  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00060  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00061  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00062  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00063  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00064  * 
00065  */
00066 // *************************************************************************
00067 // * A general mechanism to parse command line and file arguments for 
00068 // * C++ programs.
00069 // * <bilmes@media.mit.edu> Aug 1992
00070 // *
00071 // *************************************************************************
00072 //
00073 
00074 // TO DO:
00075 //    1. Usage message should print required arguments first.  
00076 //    2. Parse from file should have capability to read multi word string args.
00077 //    3. Make error reports better.
00078 //    4. Fix bug with empty line in parse args from file (libg++ 2.2).
00079 //    5. negative action, action called if argument is not present.
00080 //    6. Add ability to specify controls in documentation string.
00081 //       i.e. to we can do:  ... "Parm X, default = %d",default);
00082 
00083 #ifndef ARGS_h
00084 #define ARGS_h
00085 
00086 //#include "common.h"
00087   // ... OR ...
00088   // The following bool definition will work fine.
00089 #include <iostream>
00090 using namespace std;
00091 // enum bool {true = 1, false = 0};
00092 // inline ostream& operator << (ostream&os,bool b) 
00093 // {
00094 //   return (os << ((b == true) ? "T" : "F"));
00095 // }
00096 
00097 class ARGS;
00098 class argsAction;
00099 extern ostream& operator << (ostream& os, ARGS*);
00100 extern ostream& operator << (ostream& os, ARGS&);
00101 
00102 
00103 class unionClass 
00104 {
00105   friend class ARGS;
00106   friend class argsAction;
00107   friend ostream& operator << (ostream&, ARGS*);
00108   friend ostream& operator << (ostream&, ARGS&);
00109  
00110  public:
00111   enum argType 
00112   { bool_t, char_t, str_t, int_t, uint_t, float_t, double_t, action_t };
00113 
00114  private:
00115   union argU 
00116   {
00117     bool         boolean;
00118     char         ch;
00119     char*        string;
00120     int          integer;
00121     unsigned int uinteger;
00122     float        single_prec;
00123     double       double_prec;
00124     argsAction*  action;  // dummy field.
00125   };
00126 
00127   argU* ptr;
00128   argType type;
00129   static char* typeStr(unionClass::argType);
00130   friend ostream& operator << (ostream&, unionClass::argType&);
00131  
00132  public:
00133   unionClass(bool& b)          { ptr = (argU*)&b; type = bool_t; }
00134   unionClass(char& c)          { ptr = (argU*)&c; type = char_t; }
00135   unionClass(char*& s)         { ptr = (argU*)&s; type = str_t; }
00136   unionClass(int& i)           { ptr = (argU*)&i; type = int_t; }
00137   unionClass(unsigned int& i)  { ptr = (argU*)&i; type = uint_t; }
00138   unionClass(float& f)         { ptr = (argU*)&f; type = float_t; }
00139   unionClass(double& d)        { ptr = (argU*)&d; type = double_t; }
00140   unionClass(argsAction& a)    { ptr = (argU*)&a; type = action_t; }
00141 };
00142 
00143 
00144 extern ostream& operator << (ostream&, unionClass::argType&);
00145 
00146 class argsAction 
00147 {
00148   enum ActionRetCode { OK, ERR };
00149  public:
00150   virtual ~argsAction() {}
00151  private:
00152   ActionRetCode setArg(char*, unionClass::argType, unionClass::argU);
00153 
00154  protected:
00155   ActionRetCode setArg(char*, bool);
00156   ActionRetCode setArg(char*, char);
00157   ActionRetCode setArg(char*, char*);
00158   ActionRetCode setArg(char*, int);
00159   ActionRetCode setArg(char*, float);
00160   ActionRetCode setArg(char*, double);
00161   ActionRetCode satisfy(char*);
00162 
00163  public:
00164   virtual void act()           {}
00165   virtual void act(bool& b)    { b = b;}
00166   virtual void act(char& c)    { c = c; }
00167   virtual void act(char*& str) { str = str; }
00168   virtual void act(int& i)     { i = i; }
00169   virtual void act(unsigned int& ui) { ui = ui; }
00170   virtual void act(float& f)   { f = f; }
00171   virtual void act(double& d)  { d = d; }
00172 };
00173 
00174 
00175 
00176 class ARGS 
00177 {
00178   friend class unionClass;
00179   friend class argsAction;
00180 
00181  public:
00182 
00183   enum argKind     { Opt, Req, Tog }; // optional, required, or toggle
00184   enum ArgsRetCode { ARG_MISSING, ARG_OK, ARG_ERR };
00185   static ARGS Args[];
00186   static ARGS END;
00187 
00188  private:
00189 
00190   static char* const NOFLAG;
00191   static char* const NOFL_FOUND;
00192   static const char CommentChar;  // for argument files.
00193   static bool usage_called;
00194   static int numArgs;
00195   static bool* found;
00196   static char* progName;
00197   static bool ignoreUnknownSwitch;
00198 
00199     // instance data members.
00200   char* flag;        // name to match on command line, NULL when end.
00201   argKind arg_kind;  // optional, required, toggle
00202   unionClass uc;
00203   char* description;
00204   argsAction* action;
00205 
00206   
00207   static argsAction no_action;
00208   static bool __args__dummy__;
00209 
00210   static ostream* pout; //used to print parameters
00211 
00212  public:
00213   ARGS(char*,argKind, unionClass, char*d=NULL, argsAction&a=no_action);
00214   ARGS(argKind, unionClass, char*d=NULL, argsAction&a=no_action);
00215   ARGS(unionClass, char*d=NULL, argsAction&a=no_action);
00216   ARGS(const ARGS&);
00217   ARGS();
00218 
00219   static void cleanUp();
00220   static ArgsRetCode parseFromCommandLine(int,char**);
00221   static ArgsRetCode parseFromFile(char*f="argsFile");
00222   static void parse(int, char**, char*&, ostream* prout=NULL);
00223   static void parse(int i, char**c, ostream* prout=NULL) 
00224   { char*d=NULL; parse(i,c,d, prout); }
00225   static void printMissing()        { checkMissing(true); }
00226   static void usage(bool force=false);
00227   static void ignoreUnknownFlag()   { ignoreUnknownSwitch = true; }
00228   static void regardUnknownFlag()   { ignoreUnknownSwitch = false; }
00229 
00230  private:
00231   void init(char*, argKind, char*, argsAction&);
00232   static void Error(const char*, const char*s2=NULL, const char*s3=NULL,
00233                     const char*s4=NULL, const char*s5=NULL);
00234 
00235   static bool noFlagP(char *);
00236   static ArgsRetCode argsSwitch(ARGS*, char*, int&, bool&, char*);
00237   static ARGS* findMatch(ARGS*, char*);
00238   static void makeFound();
00239   static bool checkMissing(bool printMessage=false);
00240   static bool boolable(char* string, bool&value);
00241   friend ostream& operator << (ostream&,ARGS*);
00242   friend ostream& operator << (ostream&,ARGS&);
00243 
00244 };
00245 
00246 #endif

Generated on Tue Jan 16 05:30:05 2007 for Alchemy by  doxygen 1.5.1