int readtable0(table* tab,FILE * txt) { linelist lastln,newline; int len,i; linerec zeroline; if(txt==NULL) return 1; cleartab(tab); if(!fgets1(tab->mdlName,STRSIZ,txt)) return 1; if(!fgets1(tab->headln,70,txt))return 1; if(!fgets1(tab->format,STRSIZ,txt))return 1; len=strlen(tab->format); while( len && tab->format[len] !='|') len--; if(len==0) return 1; tab->format[len+1]=0; zeroline.next=NULL; lastln= &zeroline; newline=(linelist)m_alloc(sizeof(linerec)-STRSIZ+len+2); while (fgets1(newline->line ,len+1,txt) && newline->line[0]!='=') { newline->line[len+1]=0; for (i=strlen(newline->line);i<=len;i++) newline->line[i]=' '; lastln->next=newline; newline->next=NULL; newline->pred=lastln; lastln=newline; newline=(linelist)m_alloc(sizeof(linerec)-STRSIZ+len+2); } free( newline); tab->strings=zeroline.next; if (tab->strings != NULL)tab->strings->pred=NULL; return 0; }
int main(int argc, char* argv[]) { if (argc != 3) Err("mdiff version 1.3\n\n" "usage: mdiff FILE1 FILE2 (FILE2 can be a directory)"); FILE *file1 = fopen(argv[1], "rt"); if (NULL == file1) Err("mdiff: cannot open %s", argv[1]); char path2[MAX_LEN]; strcpy(path2, argv[2]); size_t pathlen = strlen(path2); if (path2[pathlen-1] == '\\' || path2[pathlen-1] == '/') path2[pathlen-1] = 0; // remove trailing slash if any // if argv[2] is a directory, create a path by prepending the dir to the basename of argv[1] #if _MSC_VER // microsoft only to avoid hassles with splitpath struct _stat st; if (_stat(path2, &st) == 0 && (st.st_mode & S_IFDIR)) { // path2 is a directory char base[1024], ext[1024]; _splitpath(argv[1], NULL, NULL, base, ext); _makepath(path2, NULL, argv[2], base, ext); for (int i = 0; path2[i]; i++) // convert backslashes (created by makepath) to forward slashes if (path2[i] == '\\') path2[i] = '/'; } #else struct stat st; if (stat(path2, &st) == 0 && (st.st_mode & S_IFDIR)) Err("%s is a directory, not supported in this version of mdiff", path2); #endif FILE *file2 = fopen(path2, "rt"); if (NULL == file2) Err("mdiff: cannot open %s", path2); // following are static simply to keep these big variables off the stack static char line1[MAX_LEN+1], line2[MAX_LEN+1]; static char prev1[MAX_LEN+1], prev2[MAX_LEN+1]; int linenbr = 0, err = 0; bool prev_has_err = false; while (fgets1(line1, MAX_LEN, file1)) { // fLineHasErr prevents us printing the same line twice, if it has multiple errors bool line_has_err = false; linenbr++; if (!fgets1(line2, MAX_LEN, file2)) { if (err++ < MAX_DIFFS) // can't get line from path2 PrintErr(linenbr, argv[1], line1, path2, "SHORT FILE"); err = MAX_DIFFS; // prevent further messages line_has_err = true; break; } if (prev_has_err) { // basic resync (allows resynch after extra lines in one of the input files) if (0 == strcmpskip(line1, prev2)) fgets1(line1, MAX_LEN, file1); if (0 == strcmpskip(line2, prev1)) fgets1(line2, MAX_LEN, file2); } int i, j; for (i = 0, j = 0; line1[i] && line2[j]; i++, j++) { if (line1[i] == '[') // skip [] while (line1[i] && line1[i] != ']') i++; if (line2[j] == '[') while (line2[j] && line2[j] != ']') // skip [] j++; if (line1[i] != line2[j]) { if (!prev_has_err // don't print consecutive differences && err++ < MAX_DIFFS) PrintErr(linenbr, argv[1], line1, path2, line2); line_has_err = true; prev_has_err = true; break; } } if (!line_has_err) prev_has_err = false; if (!line_has_err && (line1[i] != 0 || line2[j] != 0) // different line lens? && err++ < MAX_DIFFS) { PrintErr(linenbr, argv[1], line1, path2, line2); prev_has_err = true; } if (err >= MAX_DIFFS) { printf("Reached MAX_DIFFS %d\n", MAX_DIFFS); break; } strcpy(prev1, line1); strcpy(prev2, line2); } if (fgets1(line2, MAX_LEN, file2)) // extra line(s) in File2? { linenbr++; if (err++ < MAX_DIFFS) PrintErr(linenbr, argv[1], "SHORT FILE", path2, line2); } return err != 0; // return 0 on success }
int getfirstchar() { fgetsp=&fgetsdest; *fgetsp=0; thechar=fgets1(); }
int next() {char r; r = thechar; globC=r; thechar = fgets1(); return r; }