From e1d2c30b9d7c08b658464e3db4bf48d5fe52cf5e Mon Sep 17 00:00:00 2001
From: John Denker <jsd@av8n.com>
Date: Thu, 22 Nov 2012 15:00:29 -0800
Subject: much smarter argument parser; add usage message

---
 tools/ltgrey.c | 138 +++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 89 insertions(+), 49 deletions(-)

diff --git a/tools/ltgrey.c b/tools/ltgrey.c
index 75c8438..577cbe9 100644
--- a/tools/ltgrey.c
+++ b/tools/ltgrey.c
@@ -4,6 +4,7 @@
 #include "libltgrey.h"
 #include "utils.h"
 #include "qq_exit_codes.h"
+#include <list>
 
 using namespace std;
 pid_t mypid;
@@ -11,6 +12,68 @@ string progname;
 
 #define exeunt exit
 
+typedef const char cc;
+typedef cc* str;
+
+class argParser{
+public:
+  list<str> argv;
+  string current_arg;
+
+  argParser(const int _argc, const str _argv[])
+  {
+    for (int ii=0; ii < _argc; ii++) {
+      argv.push_back(_argv[ii]);
+    }
+  }
+  string shift() {
+    string rslt = argv.front();
+    argv.pop_front();
+    return rslt;
+  }
+  void next(){
+    current_arg = shift();
+  }
+  size_t size() const {
+    return argv.size();
+  }
+  int prefix(const string longer, const size_t required = 0){
+    if (argv.size() < required) {
+      if (required==1)
+        cerr << "Option '" << current_arg
+          << "' requires an argument." << endl;
+      else
+        cerr << "Option '" << current_arg
+          << "' requires " << required << " arguments." << endl;
+      exeunt(ex_syserr);
+    }
+    return current_arg == longer.substr(0, current_arg.length());
+  }
+};
+
+void usage(const string parent_dir){
+  cout <<
+"Usage:  ltgrey [options]\n"
+"\n"
+"Options include\n"
+"  -scan40      # scan the quarantine directory\n"
+"  -scanrep     # scan the reputation directory\n"
+"  -copy        # no idea\n"
+"  -verbose     # increase the verbosity\n"
+"  -setrep mid  # set the reputation for the given message-id\n"
+"  -getrep mid  # look up the reputation\n"
+"  -shift ???   # no idea\n"
+"  -stain ???   # not implemented\n"
+"  -suffix ???  # no idea\n"
+"  -help        # print this msg (and exit immediately)\n"
+"\n"
+;
+
+  cout << "parent dir is " << parent_dir << endl;
+  cout << "box_40.dir is "  << box_40.dir << endl;
+  cout << "box_rep.dir is " << box_rep.dir << endl;
+}
+
 int main(int _argc, char** _argv){
 
   mypid = getpid();
@@ -39,64 +102,41 @@ int main(int _argc, char** _argv){
   string set_40_mid;
   string get_rep_mid;
   string set_rep_mid;
-  while (argc > 0) {
-    string arg = argv[0]; argc--; argv++;
+  argParser ARGS(argc, argv);
+
+  while (ARGS.size()) {
+    ARGS.next();
     if (0){
-    } else if (prefix(arg, "-scan40")) {
+    } else if (ARGS.prefix("-help")) {
+      usage(foo.parent_dir);
+      exit(0);
+    } else if (ARGS.prefix("-scan40")) {
       scan40mode++;
-    } else if (prefix(arg, "-scanrep")) {
+    } else if (ARGS.prefix("-scanrep")) {
       scanrepmode++;
-    } else if (prefix(arg, "-copy")) {
+    } else if (ARGS.prefix("-copy")) {
       copies++;
-    } else if (prefix(arg, "-verbose")) {
+    } else if (ARGS.prefix("-verbose")) {
       foo.verbosity++;
-    } else if (prefix(arg, "-dns_mode")) {
+    } else if (ARGS.prefix("-dns_mode")) {
       dns_mode++;
-    } else if (prefix(arg, "-get40")) {
-      if (!argc){
-        cerr << "Option '" << arg << "' requires an argument" << endl;
-        exeunt(ex_syserr);
-      }
-      get_40_mid = *argv++;  argc--;
-    } else if (prefix(arg, "-set40")) {
-      if (!argc){
-        cerr << "Option '" << arg << "' requires an argument" << endl;
-        exeunt(ex_syserr);
-      }
-      set_40_mid = *argv++;  argc--;
-    } else if (prefix(arg, "-setrep")) {
-      if (!argc){
-        cerr << "Option '" << arg << "' requires an argument" << endl;
-        exeunt(ex_syserr);
-      }
-      set_rep_mid = *argv++;  argc--;
-    } else if (prefix(arg, "-getrep")) {
-      if (!argc){
-        cerr << "Option '" << arg << "' requires an argument" << endl;
-        exeunt(ex_syserr);
-      }
-      get_rep_mid = *argv++;  argc--;
-    } else if (prefix(arg, "-shift")
-        || prefix(arg, "-shift")) {
-      if (!argc){
-        cerr << "Option '" << arg << "' requires an argument" << endl;
-        exeunt(ex_syserr);
-      }
+    } else if (ARGS.prefix("-get40", 1)) {
+      get_40_mid = ARGS.shift();
+    } else if (ARGS.prefix("-set40", 1)) {
+      set_40_mid = ARGS.shift();
+    } else if (ARGS.prefix("-setrep", 1)) {
+      set_rep_mid = ARGS.shift();
+    } else if (ARGS.prefix("-getrep", 1)) {
+      get_rep_mid = ARGS.shift();
+    } else if (ARGS.prefix("-shift"), 1) {
       shift = atoi(*argv++);  argc--;
-    } else if (prefix(arg, "-stain")) {
-      if (!argc){
-        cerr << "Option '" << arg << "' requires an argument" << endl;
-        exeunt(ex_syserr);
-      }
+    } else if (ARGS.prefix("-stain", 1)) {
       stain = atoi(*argv++);  argc--;
-    } else if (prefix(arg, "-suffix")) {
-      if (!argc){
-        cerr << "Option '" << arg << "' requires an argument" << endl;
-        exeunt(ex_syserr);
-      }
-      foo.suffix += *argv++;  argc--;
+      if (stain) {}             /* FIXME */
+    } else if (ARGS.prefix("-suffix", 1)) {
+      foo.suffix += ARGS.shift();
     } else {
-      cerr << "Unrecognized arg: " << arg << endl;
+      cerr << "Unrecognized arg: " << ARGS.current_arg << endl;
       exeunt(ex_syserr);
     }
   }
-- 
cgit v1.2.3