Index: trunk/Ohana/src/opihi/cmd.data/Makefile
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/Makefile	(revision 10844)
+++ trunk/Ohana/src/opihi/cmd.data/Makefile	(revision 10997)
@@ -14,4 +14,6 @@
 $(SDIR)/applyfit.$(ARCH).o	\
 $(SDIR)/box.$(ARCH).o		\
+$(SDIR)/book.$(ARCH).o		\
+$(SDIR)/book_commands.$(ARCH).o	\
 $(SDIR)/center.$(ARCH).o	\
 $(SDIR)/clear.$(ARCH).o		\
@@ -71,4 +73,5 @@
 $(SDIR)/queuedrop.$(ARCH).o	\
 $(SDIR)/queuelist.$(ARCH).o	\
+$(SDIR)/queueload.$(ARCH).o	\
 $(SDIR)/queuesize.$(ARCH).o	\
 $(SDIR)/queuepush.$(ARCH).o	\
Index: trunk/Ohana/src/opihi/cmd.data/book.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/book.c	(revision 10997)
+++ trunk/Ohana/src/opihi/cmd.data/book.c	(revision 10997)
@@ -0,0 +1,77 @@
+# include "data.h"
+
+int book_list (int argc, char **argv);
+int book_create (int argc, char **argv);
+int book_delete (int argc, char **argv);
+int book_getbook (int argc, char **argv);
+int book_listbook (int argc, char **argv);
+int book_npages (int argc, char **argv);
+int book_newpage (int argc, char **argv);
+int book_getpage (int argc, char **argv);
+int book_delpage (int argc, char **argv);
+int book_listpage (int argc, char **argv);
+int book_setword (int argc, char **argv);
+int book_getword (int argc, char **argv);
+
+static Command book_commands[] = {
+  {"list",     book_list,     "list books"},
+  {"create",   book_create,   "create a book"},
+  {"delete",   book_delete,   "delete a book"},
+  {"getbook",  book_getbook,  "get book name by location"},
+  {"listbook", book_listbook, "list pages in a book"},
+  {"npages",   book_npages,   "return number of pages in a book"},
+  {"newpage",  book_newpage,  "create a new page in a book"},
+  {"getpage",  book_getpage,  "get page name by location"},
+  {"delpage",  book_delpage,  "delete a page in a book"},
+  {"listpage", book_listpage, "list a page in a book"},
+  {"setword",  book_setword,  "set the value of a word in a page"},
+  {"getword",  book_getword,  "set the value of a word from a page"},
+};
+
+int book_command (int argc, char **argv) {
+
+  int i, N, status;
+
+  if (argc < 2) {
+    gprint (GP_ERR, "USAGE: book (command)\n");
+    gprint (GP_ERR, "    book list             			: list books\n");
+    gprint (GP_ERR, "    book create   (book)   		: create book (name)\n");
+    gprint (GP_ERR, "    book delete   (book)                   : delete book (name)\n");
+    gprint (GP_ERR, "    book getbook  (where)  		: get book name\n");
+    gprint (GP_ERR, "    book listbook (book)    		: list a book\n");
+    gprint (GP_ERR, "    book npages   (book)   		: return number of pages in a book\n");
+    gprint (GP_ERR, "    book newpage  (book) (page)  		: create a new page in a book\n");
+    gprint (GP_ERR, "    book getpage  (book) (where)  		: get page name in a book\n");
+    gprint (GP_ERR, "    book delpage  (book) (page)  		: delete a page in a book\n");
+    gprint (GP_ERR, "    book listpage (book) (page)  		: list a page in a book\n");
+    gprint (GP_ERR, "    book setword  (book) (page) (word) (value)  : set the value of a word in a page\n");
+    gprint (GP_ERR, "    book getword  (book) (page) (word) [-var var] : set the value of a word from a page\n");
+    return (FALSE);
+  }
+
+  N = sizeof (book_commands) / sizeof (Command);
+
+  /* find the book sub-command which matches */
+  for (i = 0; i < N; i++) {
+    if (!strcmp (book_commands[i].name, argv[1])) {
+      status = (*book_commands[i].func) (argc - 1, argv + 1);
+      return (status);
+    }
+  }
+
+  gprint (GP_ERR, "unknown book command %s\n", argv[1]);
+  return (FALSE);
+}
+
+/* book is called with the command "book".  
+   the command line word "book" is meant to be followed the one of several 
+   possible options:
+   
+   book create
+   book delete
+   book list
+   book edit
+   book read
+   book write
+
+*/
Index: trunk/Ohana/src/opihi/cmd.data/book_commands.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/book_commands.c	(revision 10997)
+++ trunk/Ohana/src/opihi/cmd.data/book_commands.c	(revision 10997)
@@ -0,0 +1,330 @@
+# include "data.h"
+
+int book_list (int argc, char **argv) {
+    ListBooks();
+}
+
+int book_create (int argc, char **argv) {
+  if (argc != 2) {
+    gprint (GP_ERR, "USAGE: book create (book)\n");
+    return FALSE;
+  }
+
+  CreateBook (argv[1]);
+  return TRUE;
+}
+
+int book_delete (int argc, char **argv) {
+
+  int status;
+  Book *book;
+
+  if (argc != 2) {
+    gprint (GP_ERR, "USAGE: book delete (book)\n");
+    return FALSE;
+  }
+
+  book = FindBook (argv[1]);
+  if (book == NULL) {
+    gprint (GP_ERR, "book %s not found\n", argv[1]);
+    return FALSE;
+  }
+
+  status = DeleteBook (book);
+  if (!status) abort ();
+  return TRUE;
+}
+
+int book_listbook (int argc, char **argv) {
+
+  int status;
+  Book *book;
+
+  if (argc != 2) {
+    gprint (GP_ERR, "USAGE: book listbook (book)\n");
+    return FALSE;
+  }
+
+  book = FindBook (argv[1]);
+  if (book == NULL) {
+    gprint (GP_ERR, "book %s not found\n", argv[1]);
+    return FALSE;
+  }
+
+  ListPages (book);
+  return TRUE;
+}
+
+int book_npages (int argc, char **argv) {
+
+  int N, status;
+  Book *book;
+  char *varName;
+
+  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 != 2) {
+    gprint (GP_ERR, "USAGE: book npages (book)\n");
+    return FALSE;
+  }
+
+  book = FindBook (argv[1]);
+  if (book == NULL) {
+    gprint (GP_ERR, "book %s not found\n", argv[1]);
+    return FALSE;
+  }
+
+  if (varName) {
+    set_int_variable (varName, book[0].Npages);
+  } else {
+    gprint (GP_ERR, "%d pages\n", book[0].Npages);
+  }
+  return TRUE;
+}
+
+int book_getbook (int argc, char **argv) {
+
+  int where, N;
+  char *varName;
+  Book *book;
+
+  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 != 2) {
+    gprint (GP_ERR, "USAGE: book getbook (where) [-var var]\n");
+    return FALSE;
+  }
+
+  where = atoi (argv[1]);
+  book = GetBook (where);
+  if (book == NULL) {
+    gprint (GP_ERR, "book %s not found\n", argv[1]);
+    return FALSE;
+  }
+
+  if (varName) {
+    set_str_variable (varName, book[0].name);
+  } else {
+    gprint (GP_ERR, "%s\n", book[0].name);
+  }
+  return TRUE;
+}
+
+int book_newpage (int argc, char **argv) {
+
+  if (argc != 3) {
+    gprint (GP_ERR, "USAGE: book newpage (book) (page)\n");
+    return FALSE;
+  }
+
+  Book *book;
+
+  book = FindBook (argv[1]);
+  if (book == NULL) {
+    gprint (GP_ERR, "book %s not found\n", argv[1]);
+    return FALSE;
+  }
+  
+  CreatePage (book, argv[2]);
+  return TRUE;
+}
+
+int book_delpage (int argc, char **argv) {
+
+  int i, N;
+  Page *page;
+  Book *book;
+  char *Key, *Value, *value;
+
+  Key = NULL;
+  Value = NULL;
+  if ((N = get_argument (argc, argv, "-key"))) {
+    remove_argument (N, &argc, argv);
+    Key = strcreate (argv[N]);
+    remove_argument (N, &argc, argv);
+    Value = strcreate (argv[N]);
+  }
+
+  if ((argc != 3) && (argc != 2)) {
+    gprint (GP_ERR, "USAGE: book delpage (book) (page)\n");
+    gprint (GP_ERR, "USAGE: book delpage (book) -key name value\n");
+    return FALSE;
+  }
+
+  book = FindBook (argv[1]);
+  if (book == NULL) {
+    gprint (GP_ERR, "book %s not found\n", argv[1]);
+    return FALSE;
+  }
+  
+  if (Key) {
+    /* delete by matching key */
+    for (i = 0; i < book[0].Npages; i++) {
+      value = BookGetWord (book[0].pages[i], Key);
+      if (value == NULL) continue;
+      if (!strcmp(value, Value)) {
+	DeletePage (book, book[0].pages[i]);
+	i--; /* if we delete this page, don't advance the counter */
+      }
+    }
+    return TRUE;
+  }
+
+  page = FindPage (book, argv[2]);
+  if (page == NULL) {
+    gprint (GP_ERR, "page %s in book %s not found\n", argv[2], argv[1]);
+    return FALSE;
+  }
+
+  DeletePage (book, page);
+  return TRUE;
+}
+
+int book_listpage (int argc, char **argv) {
+
+  Page *page;
+  Book *book;
+
+  if (argc != 3) {
+    gprint (GP_ERR, "USAGE: book listpage (book) (page)\n");
+    return FALSE;
+  }
+
+  book = FindBook (argv[1]);
+  if (book == NULL) {
+    gprint (GP_ERR, "book %s not found\n", argv[1]);
+    return FALSE;
+  }
+  
+  page = FindPage (book, argv[2]);
+  if (page == NULL) {
+    gprint (GP_ERR, "page %s in book %s not found\n", argv[2], argv[1]);
+    return FALSE;
+  }
+
+  ListWords (page);
+  return TRUE;
+}
+
+int book_getpage (int argc, char **argv) {
+
+  int where, N;
+  char *varName;
+  Book *book;
+  Page *page;
+
+  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: book getpage (book) (where) [-var var]\n");
+    return FALSE;
+  }
+
+  where = atoi (argv[2]);
+
+  book = FindBook (argv[1]);
+  if (book == NULL) {
+    gprint (GP_ERR, "book %s not found\n", argv[1]);
+    return FALSE;
+  }
+
+  page = GetPage (book, where);
+  if (page == NULL) {
+    gprint (GP_ERR, "page %s in book %s not found\n", argv[2], argv[1]);
+    return FALSE;
+  }
+
+  if (varName) {
+    set_str_variable (varName, page[0].name);
+  } else {
+    gprint (GP_ERR, "%s\n", page[0].name);
+  }
+  return TRUE;
+}
+
+int book_setword (int argc, char **argv) {
+
+  Page *page;
+  Book *book;
+
+  if (argc != 5) {
+    gprint (GP_ERR, "USAGE: book setword (book) (page) (word) (value)\n");
+    return FALSE;
+  }
+
+  book = FindBook (argv[1]);
+  if (book == NULL) {
+    gprint (GP_ERR, "book %s not found\n", argv[1]);
+    return FALSE;
+  }
+  
+  page = FindPage (book, argv[2]);
+  if (page == NULL) {
+    gprint (GP_ERR, "page %s in book %s not found\n", argv[2], argv[1]);
+    return FALSE;
+  }
+
+  BookSetWord (page, argv[3], argv[4]);
+  return TRUE;
+}
+
+int book_getword (int argc, char **argv) {
+
+  int N;
+  Page *page;
+  Book *book;
+  char *value, *varName;
+
+  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 != 4) {
+    gprint (GP_ERR, "USAGE: book newword (book) (page) (word)\n");
+    return FALSE;
+  }
+
+  book = FindBook (argv[1]);
+  if (book == NULL) {
+    gprint (GP_ERR, "book %s not found\n", argv[1]);
+    return FALSE;
+  }
+  
+  page = FindPage (book, argv[2]);
+  if (page == NULL) {
+    gprint (GP_ERR, "page %s in book %s not found\n", argv[2], argv[1]);
+    return FALSE;
+  }
+
+  value = BookGetWord (page, argv[3]);
+  if (value == NULL) {
+    gprint (GP_ERR, "value %s on page %s in book %s not found\n", argv[3], argv[2], argv[1]);
+    return FALSE;
+  }
+
+  if (varName) {
+    set_str_variable (varName, value);
+  } else {
+    gprint (GP_ERR, "%s\n", value);
+  }
+    
+  return TRUE;
+}
Index: trunk/Ohana/src/opihi/cmd.data/init.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/init.c	(revision 10844)
+++ trunk/Ohana/src/opihi/cmd.data/init.c	(revision 10997)
@@ -5,4 +5,5 @@
 int applyfit2d       PROTO((int, char **));
 int box              PROTO((int, char **));
+int book_command     PROTO((int, char **));
 int center           PROTO((int, char **));
 int circstats        PROTO((int, char **));
@@ -63,4 +64,5 @@
 int ps               PROTO((int, char **));
 int queuelist        PROTO((int, char **));
+int queueload        PROTO((int, char **));
 int queueinit        PROTO((int, char **));
 int queuedelete      PROTO((int, char **));
@@ -117,4 +119,5 @@
   {"applyfit2d",   applyfit2d,	     "apply 2-d fit to new vector"},
   {"box",     	   box,		     "draw a box on the plot"},
+  {"book",    	   book_command,     "commands to manipulate book/page/word data"},
   {"center",       center,	     "center image on coords"},
   {"circstats",    circstats,	     "circular statistics"},
@@ -183,4 +186,5 @@
   {"queuedelete",  queuedelete,	     "delete a queue"},
   {"queuelist",	   queuelist,	     "list defined queues"},
+  {"queueload",	   queueload,	     "load queue from command"},
   {"queuesize",    queuesize,	     "show queue size"},
   {"rd",           rd,		     "load fits image"},
Index: trunk/Ohana/src/opihi/cmd.data/queueload.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.data/queueload.c	(revision 10997)
+++ trunk/Ohana/src/opihi/cmd.data/queueload.c	(revision 10997)
@@ -0,0 +1,69 @@
+# include "data.h"
+
+int queueload (int argc, char **argv) {
+  
+  char *A, *B, *val;
+  int i, done, status;
+  int N, Nread, Nbytes, NBYTES;
+  FILE *f;
+  Queue *queue;
+
+  if (argc != 4) goto usage;
+  if (strcmp(argv[2], "-x")) goto usage;
+  
+  /* will create a queue if none exists */
+  queue = CreateQueue (argv[1]);
+
+  /* val will hold the result of the command */
+  NBYTES = 1024;
+  ALLOCATE (val, char, NBYTES);
+    
+  /* loop until command produces no more output,  REALLOCATE as needed. */
+  f = popen (argv[3], "r");
+  Nbytes = 0;
+  Nread = 1;
+  while (Nread > 0) {
+    Nread = fread (&val[Nbytes], 1, 1023, f);
+    if (Nread < 0) { 
+      gprint (GP_ERR, "error reading from command\n");
+    }
+    if (Nread > 0) {
+      Nbytes += Nread;
+      NBYTES = 1024 + Nbytes;
+      REALLOCATE (val, char, NBYTES);
+    }
+  }
+  val[Nbytes] = 0;
+  status = pclose (f);
+    
+  if (status) {
+    gprint (GP_ERR, "warning: exit status of command %d\n", status);
+  }
+      
+  A = B = val;
+  for (i = 0; B != (char *) NULL;) {
+    while (isspace (*A) && (*A != 0)) A++;
+    B = strchr (A, '\n');
+    if (B != (char *) NULL) { *B = 0; }
+    if (*A != 0) {
+      PushQueue (queue, A);
+      A = B + 1;
+      i++;
+    }
+  }      
+  free (val);
+    
+  return (TRUE);
+
+usage:
+  gprint (GP_ERR, "USAGE: queueload (queue) -x (command)\n");
+  return (FALSE);
+}
+
+
+/* 
+ * -key only needed for replace or unique : give an error otherwise
+ * -uniq searched for a match and does NOT replace if matched
+ * -replace searches for a match and replaces if matched
+ * should trigger an error if -uniq and -replace...
+ */
