Index: trunk/Ohana/src/opihi/lib.data/book.c
===================================================================
--- trunk/Ohana/src/opihi/lib.data/book.c	(revision 10847)
+++ trunk/Ohana/src/opihi/lib.data/book.c	(revision 10997)
@@ -1,45 +1,7 @@
 # include "data.h"
-
-typedef struct {
-  int Nvalues;
-  char *id;
-  char **word;
-  char **value;
-} Page;
-
-typedef struct {
-  int Npages;
-  char *name;
-  int *index;
-  char **sorted;
-  Page *pages;
-} Book;
-
-/* commands:
-   book list
-   book create
-   book newpage (book.page)
-   book delpage (book.page)
-   book newword (book.page.word) (value)
-*/
 
 Book **books;   /* book to store the list of all books */
 int    Nbooks;   /* number of currently defined books */
 int    NBOOKS;   /* number of currently allocated books */
-
-int CreatePage (Book *book, char *id) {
-  int N;
-
-  N = book[0].Npages;
-  book[0].page[N].id = strcreate (name);
-  book[0].page[N].Nvalues = 0;
-  book[0].Npages ++;
-
-  if (book[0].Npages == book[0].NPAGES - 1) {
-    REALLOC ();
-  }
-
-
-}
 
 void InitBooks () {
@@ -49,13 +11,38 @@
 }
 
-/* list known books */
-void ListBooks () {
+void InitBook (Book *book, char *name) {
+
+    book[0].name = strcreate (name);
+
+    book[0].Npages = 0;
+    book[0].NPAGES = 16;
+    ALLOCATE (book[0].pages, Page *, book[0].NPAGES);
+    ALLOCATE (book[0].pageIDs, char *, book[0].NPAGES);
+    ALLOCATE (book[0].index, int, book[0].NPAGES);
+}
+
+void FreeBook (Book *book) {
+
+    int i;
+
+    free (book[0].name);
+    for (i = 0; i < book[0].Npages; i++) {
+	FreePage (book[0].pages[i]);
+	free (book[0].pageIDs[i]);
+    }
+    free (book[0].pages);
+    free (book[0].pageIDs);
+    free (book[0].index);
+}
+
+/* return the given book */
+Book *GetBook (int where) {
 
   int i;
 
-  for (i = 0; i < Nbooks; i++) {
-    gprint (GP_ERR, "%-15s %3d\n", books[i][0].name, books[i][0].Nlines);
-  }
-  return;
+  if (where < 0) where += Nbooks;
+  if (where < 0) return NULL;
+  if (where >= Nbooks) return NULL;
+  return (books[where]);
 }
 
@@ -67,22 +54,8 @@
   for (i = 0; i < Nbooks; i++) {
     if (!strcmp (books[i][0].name, name)) {
-      return (&books[i][0]);
+      return (books[i]);
     }
   }
   return (NULL);
-}
-
-/* make a new named book */
-int InitBook (Book *book) {
-
-  int i;
-
-  for (i = 0; i < book[0].Nlines; i++) {
-    free (book[0].lines[i]);
-  }
-  book[0].Nlines = 0;
-  book[0].NLINES = 16;
-  REALLOCATE (book[0].lines, char *, book[0].NLINES);
-  return (TRUE);
 }
 
@@ -100,8 +73,5 @@
   CHECK_REALLOCATE (books, Book *, NBOOKS, Nbooks, 16);
   ALLOCATE (book, Book, 1);
-  book[0].Nlines = 0;
-  book[0].NLINES = 16;
-  book[0].name = strcreate (name);
-  ALLOCATE (book[0].lines, char *, book[0].NLINES);
+  InitBook (book, name);
   books[N] = book;
   return (book);
@@ -133,284 +103,16 @@
   }
 
-  free (book[0].name);
-  for (i = 0; i < book[0].Nlines; i++) {
-    free (book[0].lines[i]);
-  }
-  free (book[0].lines);
-  free (book);
+  FreeBook (book);
   return (TRUE);
 }
 
-void PushNamedBook (char *name, char *line) {
-
-  Book *book;
-  
-  book = FindBook (name);
-  if (book == NULL) {
-    book = CreateBook (name);
-  }
-  PushBook (book, line);
-  return;
-}
-
-/* push line onto book.  return chars create new lines */
-void PushBook (Book *book, char *line) {
-
-  int N;
-  char *p, *q;
-
-  p = line;
-  q = strchr (line, '\n');
-  N = book[0].Nlines;
-  while (q != NULL) {
-    book[0].lines[N] = strncreate (p, q - p);
-    N++;
-    CHECK_REALLOCATE (book[0].lines, char *, book[0].NLINES, N, 16);
-    p = q + 1;
-    q = strchr (p, '\n');
-  }    
-  if (*p) {
-    book[0].lines[N] = strcreate (p);
-    N++;
-    CHECK_REALLOCATE (book[0].lines, char *, book[0].NLINES, N, 16);
-  }
-  book[0].Nlines = N;
-  return;
-}
-
-// return a newly allocated string containing the requested key value
-char *ChooseSingleKey (char *line, int Key) {
-
-  int i;
-  char *key, *p;
-
-  if (Key == -1) {
-    key = strcreate (line);
-    return (key);
-  }
-
-  key = line;
-  for (i = 0; (i < Key) && (key != NULL); i++) {
-    p = nextword (key);
-    key = p;
-  }
-  key = thisword (key);
-  return (key);
-}
-
-/* construct merged key given keylist of the form K:N:M */ 
-char *ChooseKey (char *line, char *keylist) {
-
-  char *output, *entry, *key, *p, *q;
-  int first, keynum;
-
-  if (line == NULL) return (NULL);
-  if (keylist == NULL) return (line);
-
-  ALLOCATE (output, char, strlen(line) + 1);
-  memset (output, 0, strlen(line) + 1);
-
-  first = TRUE;
-  p = q = keylist;
-  while (q != NULL) {
-    q = strchr (p, ':');
-    if (q == NULL) {
-      entry = strcreate (p);
-    } else {
-      entry = strncreate (p, q - p);
-    }
-    keynum = atoi (entry);
-    free (entry);
-
-    key = ChooseSingleKey (line, keynum);
-
-    if (!first) strcat (output, ":");
-    if (key) {
-	strcat (output, key);
-	free (key);
-    }
-
-    if (q != NULL) p = q + 1;
-    first = FALSE;
-  }
-  return (output);
-}
-
-/* push line onto book, skipping existing matches (optionally by key) */
-void PushBookUnique (Book *book, char *line, char *Key) {
-
-  int i, j, N, found;
-  char *p, *q, *key1, *key2;
-  Book tmp;
-
-  /* init tmp book */
-  tmp.Nlines = 0;
-  tmp.NLINES = 16;
-  ALLOCATE (tmp.lines, char *, tmp.NLINES);
-
-  /* push entries on tmp book */
-  p = line;
-  q = strchr (line, '\n');
-  N = tmp.Nlines;
-  while (q != NULL) {
-    tmp.lines[N] = strncreate (p, q - p);
-    N++;
-    CHECK_REALLOCATE (tmp.lines, char *, tmp.NLINES, N, 16);
-    p = q + 1;
-    q = strchr (p, '\n');
-  }    
-  if (*p) {
-    tmp.lines[N] = strcreate (p);
-    N++;
-    CHECK_REALLOCATE (tmp.lines, char *, tmp.NLINES, N, 16);
-  }
-  tmp.Nlines = N;
-
-  /* add unique entries in tmp to book */
-  for (i = 0; i < tmp.Nlines; i++) {
-    key1 = ChooseKey (tmp.lines[i], Key);
-    if (key1 == NULL) continue;
-    found = FALSE;
-    for (j = 0; !found && (j < book[0].Nlines); j++) {
-      key2 = ChooseKey (book[0].lines[j], Key);
-      if (key2 == NULL) continue;
-      found = !strcmp (key1, key2);
-      free (key2);
-    }      
-    if (!found) PushBook (book, tmp.lines[i]);
-    free (key1);
-  }
-  for (i = 0; i < tmp.Nlines; i++) {
-    free (tmp.lines[i]);
-  } 
-  free (tmp.lines);
-  return;
-}
-
-/* push line onto book, replacing matches (optionally by Key) */
-void PushBookReplace (Book *book, char *line, char *Key) {
-
-  int i, j, N, found;
-  char *p, *q, *key1, *key2;
-  Book tmp;
-
-  /* init tmp book */
-  tmp.Nlines = 0;
-  tmp.NLINES = 16;
-  ALLOCATE (tmp.lines, char *, tmp.NLINES);
-
-  /* push entries on tmp book */
-  p = line;
-  q = strchr (line, '\n');
-  N = tmp.Nlines;
-  while (q != NULL) {
-    tmp.lines[N] = strncreate (p, q - p);
-    N++;
-    CHECK_REALLOCATE (tmp.lines, char *, tmp.NLINES, N, 16);
-    p = q + 1;
-    q = strchr (p, '\n');
-  }    
-  if (*p) {
-    tmp.lines[N] = strcreate (p);
-    N++;
-    CHECK_REALLOCATE (tmp.lines, char *, tmp.NLINES, N, 16);
-  }
-  tmp.Nlines = N;
-
-  /* add unique entries in tmp to book */
-  for (i = 0; i < tmp.Nlines; i++) {
-    key1 = ChooseKey (tmp.lines[i], Key);
-    if (key1 == NULL) continue;
-    found = FALSE;
-    for (j = 0; !found && (j < book[0].Nlines); j++) {
-      key2 = ChooseKey (book[0].lines[j], Key);
-      if (key2 == NULL) continue;
-      found = !strcmp (key1, key2);
-      if (found) {
-	// XXX do I need to free book[0].lines[j]??
-	book[0].lines[j] = strcreate (tmp.lines[i]);
-      }
-      free (key2);
-    }      
-    if (!found) PushBook (book, tmp.lines[i]);
-    free (key1);
-  }
-  for (i = 0; i < tmp.Nlines; i++) {
-    free (tmp.lines[i]);
-  } 
-  free (tmp.lines);
-  return;
-}
-
-char *PopBook (Book *book) {
-
-  int i, NLINES_2;
-  char *line;
-
-  if (book[0].Nlines == 0) return (NULL);
-  line = book[0].lines[0];
-
-  for (i = 0; i < book[0].Nlines - 1; i++) {
-    book[0].lines[i] = book[0].lines[i+1];
-  }
-  book[0].Nlines --;
-
-  /* shrink book allocation if small enough */
-  NLINES_2 = MAX (16, book[0].NLINES / 2);
-  if (book[0].Nlines < NLINES_2) {
-    book[0].NLINES = NLINES_2;
-    REALLOCATE (book[0].lines, char *, book[0].NLINES);
-  }    
-  return (line);
-}
-
-/* pop the first entry which for which the key matches */
-char *PopBookMatch (Book *book, char *Key, char *value) {
-
-  int i, choice, NLINES_2;
-  char *line, *test;
-
-  if (book[0].Nlines == 0) return (NULL);
-
-  /* find the matching key */
-  choice = -1;
-  for (i = 0; (i < book[0].Nlines) && (choice == -1); i++) {
-      test = ChooseKey (book[0].lines[i], Key);
-      if (test == NULL) continue;
-      if (strcmp (value, test)) { 
-	free (test);
-	continue;
-      }
-      free (test);
-      choice = i;
-  }
-  if (choice == -1) return NULL;
-
-  line = book[0].lines[choice];
-
-  for (i = choice; i < book[0].Nlines - 1; i++) {
-    book[0].lines[i] = book[0].lines[i+1];
-  }
-  book[0].Nlines --;
-
-  /* shrink book allocation if small enough */
-  NLINES_2 = MAX (16, book[0].NLINES / 2);
-  if (book[0].Nlines < NLINES_2) {
-    book[0].NLINES = NLINES_2;
-    REALLOCATE (book[0].lines, char *, book[0].NLINES);
-  }    
-  return (line);
-}
-
-int PrintBook (Book *book) {
+/* list known books */
+void ListBooks () {
 
   int i;
 
-  if (book[0].Nlines == 0) return (TRUE);
-
-  for (i = 0; i < book[0].Nlines; i++) {
-    gprint (GP_LOG, "%s\n", book[0].lines[i]);
+  for (i = 0; i < Nbooks; i++) {
+    gprint (GP_ERR, "%-15s %3d\n", books[i][0].name, books[i][0].Npages);
   }
-  return (TRUE);
+  return;
 }
-
