/////////////////// /// 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); }
Plain text interface to join
Subscribe to:
Posts (Atom)
No comments:
Post a Comment