/* * IRE - text file routines, loading and indexing thru' VFS layer */ #define NO_FORTIFY // Disable FORTIFY here (for speed) #include #include #include #include #include "textfile.h" #include "loadfile.h" #include "ithelib.h" #define FUDGE_CHARACTER -2 // This is for string munging static void fix_quotes(char *line); static void unfix_quotes(char *line); // set values to reasonable defaults void TF_init(struct TF_S *s) { if(!s) return; s->size=0; s->lines=0; s->linewords=0; s->block=NULL; s->line=NULL; s->lineword=NULL; } // free memory if necessary and set to defaults void TF_term(struct TF_S *s) { if(s->size) { if(s->block) free(s->block); if(s->lineword) free(s->lineword); s->size=0; } if(s->lines) { if(s->line) free(s->line); s->lines=0; } } // open file, alloc memory and index by line void TF_load(struct TF_S *s, const char *filename) { int ctr,current; char fn[1024]; IFILE *fp; if(!loadfile(filename,fn)) ithe_panic("Could not open text file:",filename); fp=iopen(fn); // Open file s->size = ifilelength(fp); s->block = (char *)calloc(1,s->size+1); // Alloc memory for block, and a NULL iread((unsigned char *)s->block,s->size,fp); // Read the file into block iclose(fp); // Finished s->lines = 1; // Count Carriage Returns for(ctr = 0;ctr < s->size;ctr++) if(s->block[ctr] == '\n') // Found one s->lines++; // We now know how many lines there are, so allocate the line index s->line = (char **)calloc(s->lines,sizeof(char *)); // Now we go through the lines indexing them. current = 0; // First line s->line[0] = s->block; // This is the first line for(ctr = 0;ctr < s->size;ctr++) if(s->block[ctr] == '\n') // Found a line break { s->block[ctr] = 0; // End the string // If we've got an MSDOS-style CR/LF format if(ctr>0) if(s->block[ctr-1] == 13) s->block[ctr-1]=0; // Kill it s->line[++current] = &s->block[ctr+1]; // This is the next line } } // Split loaded file into words void TF_splitwords(struct TF_S *s, char comment) { int ctr,ctr2,len,word,maxwords; char *cptr; if(!s) return; if(s->linewords) return; // Allocate the line word index s->linewords = (int *)calloc(s->lines,sizeof(int *)); s->lineword = (char ***)calloc(s->lines,sizeof(char **)); // Now we go through the lines indexing them. for(ctr = 0;ctr < s->lines;ctr++) { // Smash any comments cptr=strchr(s->line[ctr],comment); if(cptr) *cptr=0; fix_quotes(s->line[ctr]); // Count number of words in the line len=strcount(s->line[ctr]); s->linewords[ctr]=len; if(!len) { s->lineword[ctr]=NULL; continue; // Round again } // Reserve space for at least 10 words (parser expects NULL for checking) maxwords=16; if(len>16) maxwords=len; s->lineword[ctr]=calloc(maxwords,sizeof(char **)); // Find the gaps between each word cptr=s->line[ctr]; word=0; do { if(*cptr == ' ') cptr++; else { s->lineword[ctr][word++]=cptr; cptr=strchr(cptr,' '); if(cptr) *cptr++=0; else break; // Found the end } } while(*cptr); // Fix the quotes for(ctr2=0;ctr2lineword[ctr][ctr2]); } } // Turn all spaces inside quotes to solid mass of guck for parameter system static void fix_quotes(char *line) { char *p,inquote; inquote=0; for(p=line;*p;p++) { if(*p == '\"') inquote=!inquote; if(inquote && isxspace(*p)) *p=FUDGE_CHARACTER; } } // Undo the operation of the previous function void unfix_quotes(char *line) { char *p; do { p=strchr(line,FUDGE_CHARACTER); if(p) *p=' '; } while(p); }