#include #if defined(DOS) | defined(NT) #include #endif struct Item {struct Item *Next; unsigned char *Value;} *Olditem=NULL, *Newitem=NULL, *T_Olditem, *T_Newitem; char *Oldfile, *Newfile, *Listfile, Buffer[513]; int Binary=0, Oldline, Newline, T_Oldline, T_Newline, I, Inserted, Deleted, Howfar, Done, Oldread=0, Newread=0, E_Count=2; FILE *Old, *New, *List; struct Item *Read_Old() {int I; struct Item *Temp; if (fgets(Buffer,512,Old)!=NULL) {I=strlen(Buffer); if (I==0||Buffer[I-1]!='\n') {Buffer[I]='\n'; Buffer[I+1]=0; } if ((Temp=(struct Item *)malloc(sizeof(struct Item)))==NULL) Fatalerror("Out of memory"); Temp->Next=NULL; if ((Temp->Value=malloc(I=strlen(Buffer)+1))==NULL) Fatalerror("Out of Memory"); memcpy(Temp->Value,Buffer,I); return Temp; } else {Oldread=1; return NULL; } } struct Item *Read_New() {int I; struct Item *Temp; if (fgets(Buffer,512,New)!=NULL) {I=strlen(Buffer); if (I==0||Buffer[I-1]!='\n') {Buffer[I]='\n'; Buffer[I+1]=0; } if ((Temp=(struct Item *)malloc(sizeof(struct Item)))==NULL) Fatalerror("Out of memory"); Temp->Next=NULL; if ((Temp->Value=malloc(I=strlen(Buffer)+1))==NULL) Fatalerror("Out of Memory"); memcpy(Temp->Value,Buffer,I); return Temp; } else {Newread=1; return NULL; } } main(Argc,Argv) int Argc; char *Argv[]; {Oldfile=Newfile=NULL; Get_Arg(Argc,Argv); Newline=Oldline=1; Olditem=Read_Old(); Newitem=Read_New(); while (Olditem!=NULL||Newitem!=NULL) {if (Olditem!=NULL&&Newitem!=NULL&&strcmp(Olditem->Value,Newitem->Value)==0) {T_Newitem=Newitem; T_Olditem=Olditem; Newitem=Newitem->Next; Olditem=Olditem->Next; free(T_Newitem->Value); free(T_Olditem->Value); free(T_Newitem); free(T_Olditem); Oldline++; Newline++; } else Find_Change(); if (Olditem==NULL&&!Oldread) Olditem=Read_Old(); if (Newitem==NULL&&!Newread) Newitem=Read_New(); } fclose(Old); fclose(New); fclose(List); } Get_Arg(Argc,Argv) int Argc; char *Argv[]; {char *P; for (I=1;I='0'&&P[1]<='9') {int I=1; E_Count=0; while (P[I]!=0) {E_Count=E_Count*10+P[I]-'0'; I++; } } } else if (Oldfile==NULL) Oldfile=Argv[I]; else if (Newfile==NULL) Newfile=Argv[I]; else if (Listfile==NULL) Listfile=Argv[I]; else Fatalerror("Too many file arguments"); } if (Oldfile==NULL) {puts(""); puts("Dif: Create a differences file from an old and a new file"); puts("Dif {-} {}"); puts(""); puts("Merg: Create a new file from an old file and a differences file"); puts("Merg {}"); puts(""); puts("Clist: Create a file containing unchanged, deleted and inserted lines"); puts("Clist {-} {}"); puts(""); puts("N is the number of lines that must be the same for a match (default 2)"); #if defined(VMS) exit(); #endif #if defined(DOS) | defined(NT) _exit(0); #endif } if (Listfile==NULL) Listfile="CON"; if ((Old=fopen(Oldfile,"r"))==NULL) Fatalerror("Could not find old file"); if ((New=fopen(Newfile,"r"))==NULL) Fatalerror("Could not find new file"); #if defined(VMS) if ((List=fopen(Listfile,"w","fop=tef","rat=cr","rfm=var"))==NULL) #endif #if defined(DOS) | defined(NT) if ((List=fopen(Listfile,"w"))==NULL) #endif Fatalerror("Could not dreate differences file"); } Find_Change() {Howfar=0; Done=0; while (!Done) {Howfar++; Inserted=Howfar; for (Deleted=0;Deleted<=Howfar&&!Done;Deleted++) {T_Oldline=Oldline; T_Newline=Newline; T_Olditem=Olditem; T_Newitem=Newitem; while (T_Olditem!=NULL&&T_Oldline-OldlineNext==NULL&&!Oldread) T_Olditem->Next=Read_Old(); T_Olditem=T_Olditem->Next; T_Oldline++; } while (T_Newitem!=NULL&&T_Newline-NewlineNext==NULL&&!Newread) T_Newitem->Next=Read_New(); T_Newitem=T_Newitem->Next; T_Newline++; } if (T_Olditem==NULL||T_Newitem==NULL) {if (T_Olditem==NULL&&Inserted!=0) Done=1; else if (T_Newitem==NULL&&Deleted!=0) Done=1; } else if (strcmp(T_Newitem->Value,T_Olditem->Value)==0) {int I=1; while (1) {if (I++==E_Count||T_Olditem==NULL||T_Newitem==NULL) {Done=1; break; } if (T_Newitem->Next==NULL&&!Newread) T_Newitem->Next=Read_New(); if (T_Olditem->Next==NULL&&!Oldread) T_Olditem->Next=Read_Old(); if (T_Newitem->Next!=NULL&&T_Olditem->Next!=NULL) if (strcmp(T_Newitem->Next->Value,T_Olditem->Next->Value)==0) {T_Olditem=T_Olditem->Next; T_Newitem=T_Newitem->Next; } else break; } } } if (!Done) {Deleted=Howfar; for (Inserted=0;Inserted<=Howfar&&!Done;Inserted++) {T_Oldline=Oldline; T_Newline=Newline; T_Olditem=Olditem; T_Newitem=Newitem; while (T_Olditem!=NULL&&T_Oldline-OldlineNext==NULL&&!Oldread) T_Olditem->Next=Read_Old(); T_Olditem=T_Olditem->Next; T_Oldline++; } while (T_Newitem!=NULL&&T_Newline-NewlineNext==NULL&&!Newread) T_Newitem->Next=Read_New(); T_Newitem=T_Newitem->Next; T_Newline++; } if (T_Olditem==NULL||T_Newitem==NULL) {if (T_Olditem==NULL&&Inserted!=0) Done=1; else if (T_Newitem==NULL&&Deleted!=0) Done=1; } else if (strcmp(T_Newitem->Value,T_Olditem->Value)==0) {int I=1; while (1) {if (I++==E_Count||T_Olditem==NULL||T_Newitem==NULL) {Done=1; break; } if (T_Newitem->Next==NULL&&!Newread) T_Newitem->Next=Read_New(); if (T_Olditem->Next==NULL&&!Oldread) T_Olditem->Next=Read_Old(); if (T_Newitem->Next!=NULL&&T_Olditem->Next!=NULL) if (strcmp(T_Newitem->Next->Value,T_Olditem->Next->Value)==0) {T_Olditem=T_Olditem->Next; T_Newitem=T_Newitem->Next; } else break; } } } } } while (Oldline!=T_Oldline) {fprintf(List,"d%d:%s",Oldline,Olditem->Value); T_Olditem=Olditem; Olditem=Olditem->Next; Oldline++; free(T_Olditem->Value); free(T_Olditem); } while (Newline!=T_Newline) {fprintf(List,"i%d:%s",Newline,Newitem->Value); T_Newitem=Newitem; Newitem=Newitem->Next; Newline++; free(T_Newitem->Value); free(T_Newitem); } } Fatalerror(S) char *S; {printf(S); _exit(1); } #if defined(VMS) memcpy(D,S,C) char *D, *S; int C; {while (C--) (*D++)=(*S++); } #endif