Index: /trunk/Ohana/src/opihi/cmd.basic/Makefile
===================================================================
--- /trunk/Ohana/src/opihi/cmd.basic/Makefile	(revision 42080)
+++ /trunk/Ohana/src/opihi/cmd.basic/Makefile	(revision 42081)
@@ -28,4 +28,5 @@
 $(SRC)/file.$(ARCH).o	     \
 $(SRC)/getchr.$(ARCH).o     \
+$(SRC)/getargs.$(ARCH).o     \
 $(SRC)/help.$(ARCH).o	     \
 $(SRC)/input.$(ARCH).o	     \
Index: /trunk/Ohana/src/opihi/cmd.basic/getargs.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.basic/getargs.c	(revision 42081)
+++ /trunk/Ohana/src/opihi/cmd.basic/getargs.c	(revision 42081)
@@ -0,0 +1,102 @@
+# include "basic.h"
+# define NLINE 1024
+
+enum {MODE_NONE, MODE_BOOL, MODE_VALUE};
+
+int getargs (int argc, char **argv) {
+
+  int N;
+  char templine[NLINE];
+
+  // variable name to save the value
+  char *varName = NULL;
+  if ((N = get_argument (argc, argv, "-var"))) {
+    remove_argument (N, &argc, argv);
+    varName = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if (argc != 3) {
+    gprint (GP_ERR, "USAGE: getargs (key) (mode) [-var out]\n");
+    gprint (GP_ERR, "  find argument key and remove from the arglist, optionally saving value on variable\n");
+    return (FALSE);
+  }
+
+  int mode = MODE_NONE;
+  if (!strcasecmp (argv[2], "bool"))    mode = MODE_BOOL;
+  if (!strcasecmp (argv[2], "boolean")) mode = MODE_BOOL;
+  if (!strcasecmp (argv[2], "val"))     mode = MODE_VALUE;
+  if (!strcasecmp (argv[2], "value"))   mode = MODE_VALUE;
+  if (mode == MODE_NONE) { gprint (GP_ERR, "ERROR: invalid mode %s\n", argv[2]); return (FALSE); }
+  
+  // get macro name and depth
+  int   MacroDepth = GetMacroDepth ();
+
+  // real name of $0 (number of arguments)
+  snprintf (templine, NLINE, "%d.%d", MacroDepth, 0);
+  char *p = get_variable_ptr (templine);
+  myAssert (p, "coding error");
+
+  int argnum = atoi (p);
+
+  // look for the requested key (only selects the first example)
+  int argmatch = 0;
+  for (int i = 1; (i < argnum) && !argmatch; i++) {
+    // real name of $i (number of arguments)
+    snprintf (templine, NLINE, "%d.%d", MacroDepth, i);
+    char *p = get_variable_ptr (templine);
+    myAssert (p, "coding error");
+    if (strcmp (argv[1], p)) continue;
+    argmatch = i;
+  }
+  
+  if (!argmatch) {
+    if (varName) {
+      // default for a boolean is FALSE
+      // default for a value is to keep an existing value
+      if (mode == MODE_BOOL) {
+	set_str_variable (varName, "0"); // NOTE: if a local variable with the same name exists, that will be used
+      }
+    }
+    return TRUE;
+  }
+
+  if (mode == MODE_VALUE) {
+    if (argnum < argmatch + 2) { gprint (GP_ERR, "ERROR: missing value for argument %s\n", argv[1]); return (FALSE); }
+    snprintf (templine, NLINE, "%d.%d", MacroDepth, argmatch + 1);
+    char *p = get_variable_ptr (templine);
+    myAssert (p, "coding error");
+
+    if (varName) set_str_variable (varName, p); // NOTE: if a local variable with the same name exists, that will be used
+
+    for (int i = argmatch + 2; i < argnum; i++) {
+      // move $i+2 to $i
+      snprintf (templine, NLINE, "%d.%d", MacroDepth, i);
+      char *p = get_variable_ptr (templine);
+      myAssert (p, "coding error");
+
+      snprintf (templine, NLINE, "%d.%d", MacroDepth, i - 2);
+      set_str_variable (templine, p);
+    }
+    // reduce $0 by 2
+    snprintf (templine, NLINE, "%d.%d", MacroDepth, 0);
+    set_int_variable (templine, argnum - 2);
+  } 
+  if (mode == MODE_BOOL) {
+    if (varName) set_str_variable (varName, "1"); // NOTE: if a local variable with the same name exists, that will be used
+
+    for (int i = argmatch + 1; i < argnum; i++) {
+      // move $i+1 to $i
+      snprintf (templine, NLINE, "%d.%d", MacroDepth, i);
+      char *p = get_variable_ptr (templine);
+      myAssert (p, "coding error");
+
+      snprintf (templine, NLINE, "%d.%d", MacroDepth, i - 1);
+      set_str_variable (templine, p);
+    }
+    // reduce $0 by 1
+    snprintf (templine, NLINE, "%d.%d", MacroDepth, 0);
+    set_int_variable (templine, argnum - 1);
+  }
+  return (TRUE);
+}
Index: /trunk/Ohana/src/opihi/cmd.basic/init.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.basic/init.c	(revision 42080)
+++ /trunk/Ohana/src/opihi/cmd.basic/init.c	(revision 42081)
@@ -14,4 +14,5 @@
 int file            PROTO((int, char **));
 int getchr_func     PROTO((int, char **));
+int getargs         PROTO((int, char **));
 int help            PROTO((int, char **));
 int input           PROTO((int, char **));
@@ -66,4 +67,5 @@
   {1, "file",          file,               "test file existence"},
   {1, "getchr",        getchr_func,        "find character in string"},
+  {1, "getargs",       getargs,            "find and remove arguments from the macro argument list"},
   {1, "help",          help,               "get help on a function *"},
   {1, "input",         input,              "read command lines from a file *"},
Index: /trunk/Ohana/src/opihi/cmd.basic/list.c
===================================================================
--- /trunk/Ohana/src/opihi/cmd.basic/list.c	(revision 42080)
+++ /trunk/Ohana/src/opihi/cmd.basic/list.c	(revision 42081)
@@ -119,4 +119,11 @@
   // return an error if -add is given with no other args
   if ((argc > 2) && (!strcmp (argv[2], "-join"))) {
+    int start = 0;
+    if ((N = get_argument (argc, argv, "-start"))) {
+      remove_argument (N, &argc, argv);
+      start = atoi (argv[N]);
+      remove_argument (N, &argc, argv);
+    }
+
     if (argc != 4) {
       gprint (GP_ERR, "USAGE: list (root) -join (variable)\n");
@@ -137,5 +144,5 @@
     memset (output, 0, MAX_LINE_LENGTH);
 
-    for (i = 0; i < nList; i++) {
+    for (i = start; i < nList; i++) {
       snprintf (line, MAX_LINE_LENGTH, "%s:%d", argv[1], i);
       char *word = get_variable (line);
Index: /trunk/Ohana/src/opihi/cmd.basic/test/getargs.ch
===================================================================
--- /trunk/Ohana/src/opihi/cmd.basic/test/getargs.ch	(revision 42081)
+++ /trunk/Ohana/src/opihi/cmd.basic/test/getargs.ch	(revision 42081)
@@ -0,0 +1,40 @@
+
+macro t1
+  getargs -myopt bool  -var tbool
+  getargs -myval value -var tvalue
+
+  # echo $0
+  for i 1 $0
+    echo -no-return "$$i "
+  end
+  echo "EOL"
+end
+
+macro g1
+  t1;                               echo result: $tbool ..$tvalue..
+  t1 -ignore;                       echo result: $tbool ..$tvalue..
+  t1 -myopt;                        echo result: $tbool ..$tvalue..
+  t1 -myval 5;                      echo result: $tbool ..$tvalue..
+  t1 -myopt -myval 5;               echo result: $tbool ..$tvalue..
+  t1 -myopt -myval 5 extra1 extra2; echo result: $tbool ..$tvalue..
+end
+
+macro t2
+  getargs -myopt BOOL  -var tbool
+  getargs -myval VALUE -var tvalue
+
+  # echo $0
+  for i 1 $0
+    echo -no-return "$$i "
+  end
+  echo "EOL"
+end
+
+macro g2
+  t2;                               echo result: $tbool ..$tvalue..
+  t2 -ignore;                       echo result: $tbool ..$tvalue..
+  t2 -myopt;                        echo result: $tbool ..$tvalue..
+  t2 -myval 5;                      echo result: $tbool ..$tvalue..
+  t2 -myopt -myval 5;               echo result: $tbool ..$tvalue..
+  t2 -myopt -myval 5 extra1 extra2; echo result: $tbool ..$tvalue..
+end
