Index: branches/SHM-dev/source/Lib/TAppCommon/program_options_lite.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TAppCommon/program_options_lite.cpp	(revision 1300)
+++ branches/SHM-dev/source/Lib/TAppCommon/program_options_lite.cpp	(revision 1301)
@@ -50,4 +50,18 @@
   namespace program_options_lite
   {
+    ErrorReporter default_error_reporter;
+
+    ostream& ErrorReporter::error(const string& where)
+    {
+      is_errored = 1;
+      cerr << where << " error: ";
+      return cerr;
+    }
+
+    ostream& ErrorReporter::warn(const string& where)
+    {
+      cerr << where << " warning: ";
+      return cerr;
+    }
 
     Options::~Options()
@@ -97,5 +111,5 @@
     }
 
-    static void setOptions(Options::NamesPtrList& opt_list, const string& value)
+    static void setOptions(Options::NamesPtrList& opt_list, const string& value, ErrorReporter& error_reporter)
     {
       /* multiple options may be registered for the same name:
@@ -103,5 +117,5 @@
       for (Options::NamesPtrList::iterator it = opt_list.begin(); it != opt_list.end(); ++it)
       {
-        (*it)->opt->parse(value);
+        (*it)->opt->parse(value, error_reporter);
       }
     }
@@ -236,5 +250,24 @@
     }
 
-    bool storePair(Options& opts, bool allow_long, bool allow_short, const string& name, const string& value)
+    struct OptionWriter
+    {
+      OptionWriter(Options& rOpts, ErrorReporter& err)
+      : opts(rOpts), error_reporter(err)
+      {}
+      virtual ~OptionWriter() {}
+
+      virtual const string where() = 0;
+
+      bool storePair(bool allow_long, bool allow_short, const string& name, const string& value);
+      bool storePair(const string& name, const string& value)
+      {
+        return storePair(true, true, name, value);
+      }
+
+      Options& opts;
+      ErrorReporter& error_reporter;
+    };
+
+    bool OptionWriter::storePair(bool allow_long, bool allow_short, const string& name, const string& value)
     {
       bool found = false;
@@ -261,22 +294,29 @@
       if (!found)
       {
-        /* not found */
-        cerr << "Unknown option: `" << name << "' (value:`" << value << "')" << endl;
+        error_reporter.error(where())
+          << "Unknown option `" << name << "' (value:`" << value << "')\n";
         return false;
       }
 
-      setOptions((*opt_it).second, value);
+      setOptions((*opt_it).second, value, error_reporter);
       return true;
     }
 
-    bool storePair(Options& opts, const string& name, const string& value)
-    {
-      return storePair(opts, true, true, name, value);
-    }
+    struct ArgvParser : public OptionWriter
+    {
+      ArgvParser(Options& rOpts, ErrorReporter& rError_reporter)
+      : OptionWriter(rOpts, rError_reporter)
+      {}
+
+      const string where() { return "command line"; }
+
+      unsigned parseGNU(unsigned argc, const char* argv[]);
+      unsigned parseSHORT(unsigned argc, const char* argv[]);
+    };
 
     /**
      * returns number of extra arguments consumed
      */
-    unsigned parseGNU(Options& opts, unsigned argc, const char* argv[])
+    unsigned ArgvParser::parseGNU(unsigned argc, const char* argv[])
     {
       /* gnu style long options can take the forms:
@@ -304,5 +344,5 @@
         extra_argc_consumed = 1;
 #endif
-        if(!storePair(opts, true, false, option, "1"))
+        if(!storePair(true, false, option, "1"))
         {
           return 0;
@@ -313,5 +353,5 @@
         /* argument occurs after option_sep */
         string val = arg.substr(arg_opt_sep + 1);
-        storePair(opts, true, false, option, val);
+        storePair(true, false, option, val);
       }
 
@@ -319,5 +359,5 @@
     }
 
-    unsigned parseSHORT(Options& opts, unsigned argc, const char* argv[])
+    unsigned ArgvParser::parseSHORT(unsigned argc, const char* argv[])
     {
       /* short options can take the forms:
@@ -334,8 +374,9 @@
       if (argc == 1)
       {
-        cerr << "Not processing option without argument `" << option << "'" << endl;
+        error_reporter.error(where())
+          << "Not processing option `" << option << "' without argument\n";
         return 0; /* run out of argv for argument */
       }
-      storePair(opts, false, true, option, string(argv[1]));
+      storePair(false, true, option, string(argv[1]));
 
       return 1;
@@ -343,6 +384,8 @@
 
     list<const char*>
-    scanArgv(Options& opts, unsigned argc, const char* argv[])
-    {
+    scanArgv(Options& opts, unsigned argc, const char* argv[], ErrorReporter& error_reporter)
+    {
+      ArgvParser avp(opts, error_reporter);
+
       /* a list for anything that didn't get handled as an option */
       list<const char*> non_option_arguments;
@@ -366,9 +409,5 @@
         {
           /* handle short (single dash) options */
-#if 0
-          i += parsePOSIX(opts, argc - i, &argv[i]);
-#else
-          i += parseSHORT(opts, argc - i, &argv[i]);
-#endif
+          i += avp.parseSHORT(argc - i, &argv[i]);
           continue;
         }
@@ -385,5 +424,5 @@
 
         /* handle long (double dash) options */
-        i += parseGNU(opts, argc - i, &argv[i]);
+        i += avp.parseGNU(argc - i, &argv[i]);
       }
 
@@ -391,5 +430,26 @@
     }
 
-    void scanLine(Options& opts, string& line)
+    struct CfgStreamParser : public OptionWriter
+    {
+      CfgStreamParser(const string& rName, Options& rOpts, ErrorReporter& rError_reporter)
+      : OptionWriter(rOpts, rError_reporter)
+      , name(rName)
+      , linenum(0)
+      {}
+
+      const string name;
+      int linenum;
+      const string where()
+      {
+        ostringstream os;
+        os << name << ":" << linenum;
+        return os.str();
+      }
+
+      void scanLine(string& line);
+      void scanStream(istream& in);
+    };
+
+    void CfgStreamParser::scanLine(string& line)
     {
       /* strip any leading whitespace */
@@ -414,4 +474,5 @@
       {
         /* error: badly formatted line */
+        error_reporter.warn(where()) << "line formatting error\n";
         return;
       }
@@ -419,4 +480,5 @@
       {
         /* error: badly formatted line */
+        error_reporter.warn(where()) << "line formatting error\n";
         return;
       }
@@ -427,4 +489,5 @@
       {
         /* error: badly formatted line */
+        error_reporter.warn(where()) << "line formatting error\n";
         return;
       }
@@ -457,18 +520,20 @@
       {
         /* error: no value */
+        error_reporter.warn(where()) << "no value found\n";
         return;
       }
 
       /* store the value in option */
-      storePair(opts, true, false, option, value);
-    }
-
-    void scanFile(Options& opts, istream& in)
+      storePair(true, false, option, value);
+    }
+
+    void CfgStreamParser::scanStream(istream& in)
     {
       do
       {
+        linenum++;
         string line;
         getline(in, line);
-        scanLine(opts, line);
+        scanLine(line);
       } while(!!in);
     }
@@ -484,13 +549,14 @@
     }
 
-    void parseConfigFile(Options& opts, const string& filename)
+    void parseConfigFile(Options& opts, const string& filename, ErrorReporter& error_reporter)
     {
       ifstream cfgstream(filename.c_str(), ifstream::in);
       if (!cfgstream)
       {
-        cerr << "Failed to open config file: `" << filename << "'" << endl;
-        exit(EXIT_FAILURE);
-      }
-      scanFile(opts, cfgstream);
+        error_reporter.error(filename) << "Failed to open config file\n";
+        return;
+      }
+      CfgStreamParser csp(filename, opts, error_reporter);
+      csp.scanStream(cfgstream);
     }
 
Index: branches/SHM-dev/source/Lib/TAppCommon/program_options_lite.h
===================================================================
--- branches/SHM-dev/source/Lib/TAppCommon/program_options_lite.h	(revision 1300)
+++ branches/SHM-dev/source/Lib/TAppCommon/program_options_lite.h	(revision 1301)
@@ -64,13 +64,19 @@
     };
 
+    struct ErrorReporter
+    {
+      ErrorReporter() : is_errored(0) {}
+      virtual ~ErrorReporter() {}
+      virtual std::ostream& error(const std::string& where);
+      virtual std::ostream& warn(const std::string& where);
+      bool is_errored;
+    };
+
+    extern ErrorReporter default_error_reporter;
+
     void doHelp(std::ostream& out, Options& opts, unsigned columns = 80);
-    unsigned parseGNU(Options& opts, unsigned argc, const char* argv[]);
-    unsigned parseSHORT(Options& opts, unsigned argc, const char* argv[]);
-    std::list<const char*> scanArgv(Options& opts, unsigned argc, const char* argv[]);
-    void scanLine(Options& opts, std::string& line);
-    void scanFile(Options& opts, std::istream& in);
+    std::list<const char*> scanArgv(Options& opts, unsigned argc, const char* argv[], ErrorReporter& error_reporter = default_error_reporter);
     void setDefaults(Options& opts);
-    void parseConfigFile(Options& opts, const std::string& filename);
-    bool storePair(Options& opts, const std::string& name, const std::string& value);
+    void parseConfigFile(Options& opts, const std::string& filename, ErrorReporter& error_reporter = default_error_reporter);
 
     /** OptionBase: Virtual base class for storing information relating to a
@@ -86,5 +92,5 @@
 
       /* parse argument arg, to obtain a value for the option */
-      virtual void parse(const std::string& arg) = 0;
+      virtual void parse(const std::string& arg, ErrorReporter&) = 0;
       /* set the argument to the default value */
       virtual void setDefault() = 0;
@@ -102,5 +108,5 @@
       {}
 
-      void parse(const std::string& arg);
+      void parse(const std::string& arg, ErrorReporter&);
 
       void setDefault()
@@ -116,5 +122,5 @@
     template<typename T>
     inline void
-    Option<T>::parse(const std::string& arg)
+    Option<T>::parse(const std::string& arg, ErrorReporter&)
     {
       std::istringstream arg_ss (arg,std::istringstream::in);
@@ -134,5 +140,5 @@
     template<>
     inline void
-    Option<std::string>::parse(const std::string& arg)
+    Option<std::string>::parse(const std::string& arg, ErrorReporter&)
     {
       opt_storage = arg;
@@ -142,5 +148,5 @@
     struct OptionFunc : public OptionBase
     {
-      typedef void (Func)(Options&, const std::string&);
+      typedef void (Func)(Options&, const std::string&, ErrorReporter&);
 
       OptionFunc(const std::string& name, Options& parent_, Func *func_, const std::string& desc)
@@ -148,7 +154,7 @@
       {}
 
-      void parse(const std::string& arg)
-      {
-        func(parent, arg);
+      void parse(const std::string& arg, ErrorReporter& error_reporter)
+      {
+        func(parent, arg, error_reporter);
       }
 
@@ -160,5 +166,5 @@
     private:
       Options& parent;
-      void (*func)(Options&, const std::string&);
+      Func* func;
     };
 
