/* ini.cc #include #include #include #include #include #include #include */ #include "stdafx.h" #define assert(a) ASSERT(a) //#define TEST #ifndef TRUE enum BOOL { FALSE, TRUE, }; #endif #define LINEMAX 256 #define TABLEMAX (64*1024) //#define min(a,b) (((a)<(b))?(a):(b)) //#define max(a,b) (((a)>(b))?(a):(b)) FILE *descDesc = NULL, *infileDesc = NULL; int verbose = 0; static int ntable = 0; static char *table = NULL; int pmod(int a, int b) { int c = (a % b + b) % b; return(c); } /* compute index of character c in string str */ int strind(char *str, char c) { int i = 0; char *loc = strchr(str,(int)c); if (loc) i = (int)(loc - str); else i = strlen(str); return(i); } /* table is a list of null terminated strings either 1) [Sections] or 2) variable=value entries or 3) \n blank lines or 4) ; comments sections, entries, or values may be retrieved values may be terminal, symbolic, recursive evaluations, or expressions */ char *matcht( int nmatch, char *input, int ntable, char *table) { /* Performs a match of input over the total table returns for nmatch >0 nmatch match, 0 last, <0 last - nmatch nmatch % last returns a pointer to the entry or the value if immediately followed by an equal sign */ int ni = strlen(input), im = 0, nm = 0; char *ti = input, *t0 = input, *t1 = NULL, *t = table; /* Match over table */ t = table; while (TRUE) { if (strncmp(t,ti,ni) == 0) { /* Save found string, line or value t1 = t+ni == '=' if ((t1 = strstr(t,"=")) != NULL) */ t0 = t; t1 = t+ni; if (*t1 == '=') t0 = t1 + 1; ++nm; if (0 < nmatch && nmatch <= nm) break; } /* Test next string */ t += strlen(t)+1; if (t-table > ntable) break; /* Terminate at end of file */ } if (nmatch < 0 || nmatch > nm) { im = pmod(nmatch,nm); t0 = matcht( im, input, ntable, table); } if (verbose>2) fprintf(stderr,"\t\t%s %s\n",ti,t0); ti = t0; if (verbose>1) fprintf(stderr,"\t%s %s\n",input,t0); return(t0); } char *matchs( int nmatch, char *input, int ntable, char *table) { /* Performs a match over a section in a table table should point to the beginning of the section and ntable be the remaining size returns for nmatch >0 nmatch match, 0 last, <0 last - nmatch nmatch % last returns a pointer to the entry or the value if immediately followed by an equal sign */ int ni = strlen(input), im = 0, nm = 0; char *ti = input, *t0 = input, *t1 = NULL, *t = table; /* Match over section */ t = table; while (TRUE) { if (strncmp(t,ti,ni) == 0) { /* Save found string, line or value t1 = t+ni == '=' if ((t1 = strstr(t,"=")) != NULL) */ t0 = t; t1 = t+ni; if (*t1 == '=') t0 = t1 + 1; ++nm; if (0 < nmatch && nmatch <= nm) break; } /* Test next string */ t += strlen(t)+1; if (t-table > ntable) break; /* Terminate at end of file */ if (*t == '\0') break; /* Terminate at blank/null lines */ if (*t == '[') break; /* Terminate at next section */ } if (nmatch < 0 || nmatch > nm) { im = pmod(nmatch,nm); t0 = matchs( im, input, ntable, table); } if (verbose>2) fprintf(stderr,"\t\t%s %s\n",ti,t0); ti = t0; if (verbose>1) fprintf(stderr,"\t%s %s\n",input,t0); return(t0); } char *match_nline( char *line, int ntable, char *table) { /* For line in table return next line */ return( min(table + ntable, line + strlen(line) + 1) ); } char *match_lline( char *line, int ntable, char *table) { /* For line in table return previous line */ assert(table <= line && line <= table+ntable); while (line > table && *line != '\0') --line; --line; while (line > table && *line != '\0') --line; if (*line == '\0') ++line; return( line ); } char *match_section( char *section) { /* Match section in table, returning a pointer location */ return( matcht( 0, section, ntable, table)); } char *match_line1( char *line) { /* For line in table return next line */ return( match_nline(line, ntable, table)); } char *match_line0( char *line) { /* For line in table return previous line */ return (match_lline(line, ntable, table)); } char *match_entry( char *section, char *entry) { char *sect = matcht( 0, section, ntable, table); return( matchs( 0, entry, ntable - (sect - table), sect) ); } void insertline ( char* nline, char *line, int *ntable, char **table) { /* Insert nline before line */ int nc = strlen(nline) + 1; char *t0 = (*table) + *ntable; char *t1 = (*table) + *ntable + nc; assert(((*table) <= line) && (line <= (*table) + *ntable)); while (t0 >= line) *t1-- = *t0--; *t1-- = '\0'; t0 = nline + nc - 2; while (t0 >= nline) *t1-- = *t0--; *ntable += nc; } void deleteline ( char* line, int *ntable, char **table) { /* Delete line */ int nc = strlen(line) + 1; char *t0 = line; char *t1 = line + nc; assert(((*table) <= line) && (line <= (*table) + *ntable)); while (t1 <= (*table) + *ntable) *t0++ = *t1++; *ntable -= nc; } void replaceline ( char *nline, char *line, int *ntable, char **table) { /* Replace line with nline */ /* insert if line is null, delete if nline is null */ int nc = strlen(nline) - strlen(line); char *t0, *t1; assert(((*table) <= line) && (line <= (*table) + *ntable)); if (nc > 0) { if (*line == '\0') nc++; t0 = (*table) + *ntable - 1; t1 = t0 + nc; while (t0 >= line) *t1-- = *t0--; } else if (nc < 0) { if (*nline == '\0') nc--; t0 = line; t1 = t0 - nc; while (t1 < (*table) + *ntable) *t0++ = *t1++; } t0 = nline + strlen(nline); t1 = line + strlen(nline); if ( *line == '\0') t1++; if (*nline == '\0') t0--; while (t0 >= nline) *t1-- = *t0--; *ntable += nc; } void subline ( char *nline, char *line, int *ntable, char **table) { /* Substitute line with nline from beginning to ; comment or end */ /* insert if line is null, delete if nline is null */ int nc = max(0, strlen(nline) - strind(line,';')); char *t0, *t1; assert(((*table) <= line) && (line <= (*table) + *ntable)); if (nc > 0) { t0 = (*table) + *ntable; t1 = t0 + nc; if (*line == '\0') t1++; while (t0 >= line) *t1-- = *t0--; } else if (nc < 0) { t0 = line; t1 = t0 - nc; if (*nline == '\0') t1++; while (t1 <= (*table) + *ntable) *t0++ = *t1++; } t0 = nline + strlen(nline); t1 = line + strlen(nline); while (t0 >= nline) *t1-- = *t0--; *ntable += nc; } char *appendline(char *nline, int *ntable, char **table) { int nc = strlen(nline); char *t0 = (*table) + *ntable; strncpy(t0,nline,nc); *ntable += nc; t0 += nc - 1; if (*t0 == '\n') *t0 = '\0'; ++t0; return(t0); } int begintable(int *ntable, char **table) { /* Allocate table */ if (*table == NULL) { *ntable = 0; *table = (char *)malloc(TABLEMAX); if (*table == NULL) { perror("No space"); exit(1); } else { memset(*table,0,TABLEMAX); } } return(0); } int endtable(int *ntable, char **table) { /* Deallocate table */ if (*table) { free(*table); *table = NULL; *ntable = 0; } return(0); } /* process file */ int inputtable(const char *descFile, int *ntable, char **table) { /* Read file into table */ FILE *descDesc = NULL; char *t = NULL; char input[LINEMAX]; int status = 1, ns = 0; if (descFile != NULL) { /* Open file */ if (descDesc == NULL && (descDesc = fopen(descFile,"r")) == NULL) { fprintf(stderr, "error opening %s", descFile); exit(1); } /* Read file */ infileDesc = descDesc; while (status) { /* Read a line */ if (fgets(input, LINEMAX, infileDesc) == NULL) { /* On eof, return to original file, otherwise end */ if (infileDesc != descDesc) { fclose(infileDesc); infileDesc = descDesc; if (fgets(input, LINEMAX, infileDesc) == NULL) { fclose(infileDesc); infileDesc = NULL; descDesc = NULL; break; } } else { fclose(infileDesc); infileDesc = NULL; descDesc = NULL; break; } } ns = strlen(input); if (ns >= LINEMAX-1) fprintf(stderr,"Warning: Line length exceed! %s %s: %s\n", descFile, input); /* Process line */ if (*ntable + ns > TABLEMAX) { fprintf (stderr,"Warning: Table length exceeded! %d %s\n", TABLEMAX, input); break; } else { --ns; /* Convert /n into /0 */ if (input[ns-1]=='\n') --ns; if (input[ns-1]=='\r') --ns; strncpy(&((*table)[*ntable]),input,ns); (*table)[*ntable+ns] = '\0'; *ntable += ns + 1; } } } return (status); } int outputtable(const char *descFile, int *ntable, char **table) { /* Write table to file and free */ FILE *descDesc = NULL; char *t = NULL; if (descFile != NULL) { /* Open output file */ if (descDesc == NULL && (descDesc = fopen(descFile,"w")) == NULL) { fprintf(stderr, "error opening %s", descFile); exit(1); } /* Write file and close */ t = *table; while (t < *table + *ntable) { fprintf(descDesc,"%s\n",t); /* Restore /n */ t += strlen(t) + 1; } fclose (descDesc); } return(0); } int beginfile(const char *descFile, int *ntable, char **table) { begintable(ntable,table); inputtable(descFile,ntable,table); return(0); } int endfile(const char *descFile, int *ntable, char **table) { outputtable(descFile,ntable,table); endtable(ntable,table); return(0); } int strchg(char a, char b, int *ntable, char **table) { /* Change character a to b throughout table Used for '\n' to '\0' and '\0' to '\n' conversions */ for (int i = 0; i < *ntable; i++) if ((*table)[i] == a) (*table)[i] = b; return(0); } #ifdef TEST int main(int argc, char *argv[]) { int n = 0; /* Separate references for arrays and pointers to avoid losing access */ char thedescFile[80] = "plpccw.inc"; char *descFile = thedescFile; char cvalues[256], cmodels[256], cconfs[256]; char* cvalue = cvalues; char* cmodel = cmodels; char* cconf = cconfs; if (argc > 1) descFile = argv[1]; /* Allocate table of necessary size or allow beginfile to allocate it */ beginfile(descFile, &ntable, &table); cvalue = match_section("[Models]"); while ( (cvalue = match_line1( cvalue)) && *cvalue != '[') { n++; fprintf(stderr, " %d %s\n", n, cvalue); } cvalue = match_section("[Models]"); fprintf( stderr, "%s\n", cvalue); cvalue = match_entry(cvalue,"Plotter000="); /* Model */ fprintf( stderr, "%s\n", cvalue); sprintf( cmodel,"[%s]",&cvalue[strind(cvalue,'=')+1]); cmodel = match_section(cmodel); fprintf( stderr, "%s\n", cmodel); cvalue = match_entry(cmodel,"Cfg000="); /* Config */ fprintf( stderr, "%s\n", cvalue); sprintf( cconf, "[%s]", &cvalue[strind(cvalue,'=')+1]); cconf = match_section(cconf); fprintf( stderr, "%s\n", cconf); cvalue = match_entry(cconf,"Qualities="); fprintf( stderr, "%s\n", &cvalue[strind(cvalue,'=')+1]); cvalue = match_entry(cconf,"Modes="); fprintf( stderr, "%s\n", &cvalue[strind(cvalue,'=')+1]); deleteline(cvalue,&ntable,&table); insertline("IniEdit=True",cvalue,&ntable,&table); replaceline("IniEdits=False",cvalue,&ntable,&table); cvalue--; replaceline("IniEdits=Insert",cvalue,&ntable,&table); replaceline("",cvalue,&ntable,&table); cvalue = match_line1(cvalue); fprintf( stderr, "%s\n", cvalue); cvalue = match_line0(cvalue); fprintf( stderr, "%s\n", cvalue); cvalue = match_line1(cvalue); fprintf( stderr, "%s\n", cvalue); cvalue = cvalues; strcpy(cvalue,"Input="); fprintf( stderr, " Section\n"); cvalue = matchs(-2,cvalues,ntable-(table-cconf),cconf); fprintf( stderr, "%s\n", cvalue); cvalue = matchs(-1,cvalues,ntable-(table-cconf),cconf); fprintf( stderr, "%s\n", cvalue); cvalue = matchs(0,cvalues,ntable-(table-cconf),cconf); fprintf( stderr, "%s\n", cvalue); cvalue = matchs(1,cvalues,ntable-(table-cconf),cconf); fprintf( stderr, "%s\n", cvalue); cvalue = matchs(2,cvalues,ntable-(table-cconf),cconf); fprintf( stderr, "%s\n", cvalue); fprintf( stderr, " Total\n"); cvalue = matcht(-2,cvalues,ntable,table); fprintf( stderr, "%s\n", cvalue); cvalue = matcht(-1,cvalues,ntable,table); fprintf( stderr, "%s\n", cvalue); cvalue = matcht(0,cvalues,ntable,table); fprintf( stderr, "%s\n", cvalue); cvalue = matcht(1,cvalues,ntable,table); fprintf( stderr, "%s\n", cvalue); cvalue = matcht(2,cvalues,ntable,table); fprintf( stderr, "%s\n", cvalue); /* Write file if desired and deallocate memory */ endfile("plpccw.ino", &ntable, &table); return(0); } #endif