ParseArg.H

Go to the documentation of this file.
00001 /*!@file Transport/ParseArg.H */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the University of Southern California (USC) and the iLab at USC.  //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Transport/ParseArg.H $
00035 // $Id: ParseArg.H 7877 2007-02-08 21:57:00Z rjpeters $
00036 //
00037 
00038 #ifndef TRANSPORT_PARSEARG_H_DEFINED
00039 #define TRANSPORT_PARSEARG_H_DEFINED
00040 
00041 #include "Util/StringUtil.H"
00042 #include "Util/log.H"
00043 
00044 #include <string>
00045 
00046 /// Parse a command-line arg and return a product from the appropriate factory
00047 /** This is where all of the parsing of --in, --out, and --io options
00048     happens. In principle, it is a simple procedure, looking for
00049     formats of the form type:spec, except it's not simple because we
00050     also implement a number of special cases to allow for less verbose
00051     command-line options. The algorithm is like this:
00052 
00053     (1) if we find a colon, then we split 'type:spec' on the colon and
00054     we're done.
00055 
00056     (2) With no colon, we try to see if we can infer that the user
00057     has passed either a bare 'type' or a bare 'spec', as
00058     follows:
00059 
00060     (3) Check if it's a bare 'spec' -- see if there is a filename
00061     extension that we recognize and for which we can guess an
00062     appropriate FrameIstream type; if so, we're done.
00063 
00064     (4) Check if it's a bare 'type', one of the particular type
00065     names that we know; if so, we're done.
00066 
00067     (5) Give up with an LFATAL() -- in particular, we DON'T try to
00068     do some default option, which could cause a future backward
00069     compatibility headache.
00070 
00071     Note that the sets of known types and filename extensions are set
00072     up in makeFrameIstream() and makeFrameOstream() below; if you
00073     want to add a new FrameIstream or FrameOstream type, you should
00074     add it to one of those functions.
00075 */
00076 template <class Factory>
00077 typename Factory::ProductType
00078 parseStreamArg(const std::string& arg,
00079                std::string& extrainfo,
00080                const Factory* typeFactory,
00081                const Factory* extFactory)
00082 {
00083   using std::string;
00084 
00085   const string::size_type colon = arg.find(':');
00086 
00087   // (1) try to split on the colon
00088   if (colon != string::npos)
00089     {
00090       // ok, we have a colon, so just split on that
00091       const string type = arg.substr(0, colon);
00092       extrainfo = arg.substr(colon+1, string::npos);
00093       return typeFactory->createObj(type.c_str());
00094     }
00095 
00096   // (2) ok, no colon, so let's search the filename for clues; first
00097   // look for a filename extension:
00098   const string::size_type dot = arg.rfind('.');
00099 
00100   if (dot != string::npos)
00101     {
00102       // (3) ok, found a filename extension, let's see if it's one
00103       // that we recognize and can associate with a particular
00104       // FrameIstream type
00105       const string ext = arg.substr(dot+1, string::npos);
00106 
00107       if (extFactory->is_valid_key(ext.c_str()))
00108         {
00109           extrainfo = arg;
00110           return extFactory->createObj(ext.c_str());
00111         }
00112 
00113       // (3a) ok, we didn't find a known matching filename extension,
00114       // but now let's try to find a two-part extension
00115       // (e.g. ".ext.gz" or ".ext.bz2") that matches
00116       if (dot > 0)
00117         {
00118           const string::size_type dot2 = arg.rfind('.', dot-1);
00119 
00120           if (dot2 != string::npos)
00121             {
00122               const string ext2 = arg.substr(dot2+1, string::npos);
00123 
00124               if (extFactory->is_valid_key(ext2.c_str()))
00125                 {
00126                   extrainfo = arg;
00127                   return extFactory->createObj(ext2.c_str());
00128                 }
00129             }
00130         }
00131 
00132       // ok, here we didn't find any known filename extension, but
00133       // don't give up yet, we still have one more thing to try...
00134     }
00135 
00136   // (4) ok, no colon and no (special) filename extension, last
00137   // thing is to check if the single word is a keyword with no
00138   // extrainfo
00139   if (typeFactory->is_valid_key(arg.c_str()))
00140     {
00141       extrainfo = "";
00142       return typeFactory->createObj(arg.c_str());
00143     }
00144 
00145   // (5) give up
00146   LFATAL("couldn't parse <type:spec> from '%s':\n"
00147          "\t* no colon was found\n"
00148          "\t* no bare 'spec' was found with a known filename extension\n"
00149          "\t     (known extensions are\n"
00150          "%s)\n"
00151          "\t* no bare 'type' was found with a known type name\n"
00152          "\t     (known types are\n"
00153          "%s)\n",
00154          arg.c_str(),
00155          stdLineWrap(extFactory->get_known_keys(", ").c_str(), 60, "\t\t").c_str(),
00156          stdLineWrap(typeFactory->get_known_keys(", ").c_str(), 60, "\t\t").c_str());
00157 
00158   /* can't happen */ return *((typename Factory::ProductType*)0);
00159 }
00160 
00161 // ######################################################################
00162 /* So things look consistent in everyone's emacs... */
00163 /* Local Variables: */
00164 /* mode: c++ */
00165 /* indent-tabs-mode: nil */
00166 /* End: */
00167 
00168 #endif // TRANSPORT_PARSEARG_H_DEFINED
Generated on Sun May 8 08:42:24 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3