Plain text interface to join

   
///////////////////
/// An external attachment for the join engine.
// The 'database' is unformatted text
// this interface just extracts words from raw text.
//t is an endless Comma sequence

// An external attachment for the join engine.
// The 'database' is unformatted text
// this interface just extracts words from raw text.
//t is an endless Comma sequence
//
#include 
#include 
#include 
#include 
#include 
#include "cursor.h"  // header file explains everything
#include "slots.h"
// Min and max word size allowed
#define WSIZE 6
#define KEYSIZE 20

// Skip past the current large word from raw ascii
char * next_word(char * s2) {
 char * word;
 int count=0;
// Pass the current word and find he next large word
 skip_alpha(s2); 
 while(count < WSIZE) {
  skip_non_alpha(s2);
  if( !(*s2))
   return(s2);
  else {
   word=s2;
   count=0;
   while(isalpha(*s2)) {
    count++;
    s2++;}
   }
  }
 return(word);
}

// The word is already found
char * fetch_word(char * dest, char * src) {
 char * word = dest;
 collect_alpha(src,dest);
 *dest=0;
 return(word);
}
// Join compatible Fetch method
int FetchText(PCursor self) {
 char* p;
 p=(char *) self->current;
 if(*p)
  p =  fetch_word(self->element.key,p);
 if(*p)
  self->element.op = ',';
 else
  self->element.op = '@';  
 return(Null);
}
// Just find the next word
int StepText(PCursor self) {
 char *p = (char *) self->current;
 if(!*p ) return(Done);
 self->current = (void *) next_word(p);
 p = (char *) self->current;
 return(Null);
}
// Step and fetch is all this does
int ExecText(PCursor self,int method, void* data) {
 if(method == Fetch) 
  return(FetchText(self));
 else if(method == Step) 
  return(StepText(self));
 else if(method == Set)
   self->state=self->current;
 else if(method == Reset)
  self->current=self->state; 
 else  
  return(Null);
}
//
int EvalText(PCursor self,PCursor other) {
 int status;
 switch(self->element.op) {
  case '@':  // This can be null, changed for debug visibility
   status = End;
   break;  
  case ',':
   status =  
     MatchKey(&self->element,&other->element);
   if(status != Match)
    status = Null; // Plain text never breaks.
   break;
  default:
   status=Null;
  }
 self->prevOp = self->element.op;  // keep track of previous opcode
 return(status); 
}

//Unique to the particular attachment.
//Read in in a text file and feed it to join
//

PCursor new_text_cursor(va_list ap){
 FILE * fin;
 PCursor self;
 char * str;
 int size,i;
 void * p;
 str = va_arg(ap,char*); 
 size = va_arg(ap,int);
 fin = fopen(str,"rb");
 if(!fin)
  return(0);
 p = malloc(size);
 self=init_cursor(ExecText,EvalText,KEYSIZE,p);
 i = fread(self->current,1,size,fin);
 printf("Read from %s , %d bytes\n",str,i);
 str=(char *)self->current;
 str[i-1]=0;
 fclose(fin);
 return(self);
}
void delete_text_cursor(PCursor p) {
  free(p->start);
  del_cursor(p);
}
int InitText(void) {
 
 AddHandlers(ExecText,EvalText,"TEXT");
 return(0);
}
// Console as a data base, it talks back!
// 
int EvalConsole(PCursor q,PCursor  p)  { 
 return(MatchKey(&q->element,&p->element));
}
// do put and get with the console terminql.
PCursor InitConsoleCursor(PCursor self, char* args[] ); 
int ExecConsole(PCursor self,int method, void* data) {
 char utext[100];
 char * p;
 FILE* f;
 f = (FILE *) self->start;
 if(method == Append){
  if(!f) f= stdout;
  fputs(self->element.key,f);
  fputs(",\n",f);
  }
 else if(method == Fetch) {
  int i;
  if(!f) f= stdin;
  printf("\n>");
  fgets(utext,100,f);
  p = utext;
  skip_eol(p);  // not needed except for my IDE bug
  *p = 0;
  element_from_string(utext,&self->element);
  }
 else if(method == Init) 
  InitConsoleCursor(self, data ); 
 return Null;
 }
// Cursors are half duplex
PCursor InitConsoleCursor(PCursor self, char * args[]) {
 // install the handlers
 char* filename = *args;
 if(*filename==0)
  self->start = 0; 
 else
  self->start= (void *) fopen(filename,"r++");
 return(self);
}
int InitConsole(void) {
 
 AddHandlers(ExecConsole,EvalConsole,"CONSOLE");
 return(0);
} 
 void delete_console_cursor(PCursor p) {
  fclose((FILE *) p->start);
  del_cursor(p);
 }


No comments: