/* replace v 1.0 */
/* a simple search & replace file utility */
/* by GLYPH <y82s1@unb.ca> */

#include<stdio.h>

void setbuffer();
void reploop();
void purge();
void readdata();
int atend;
int coffset;
int curchk;
unsigned char strchars;
unsigned char repchars;
unsigned char strchar[255];
unsigned char repchar[255];
unsigned char buffchar[255];
int usechar[255];

FILE *src;
FILE *dest;
FILE *rep;
char *srcname;
char *destname;
char *repname;

main(argc, argv)
int argc;
char *argv[];
{
 if(argc != 4){
     printf("Syntax: REPLACE src dest datafile\n\n");
     exit(1);
 }
 srcname = argv[1];
 destname = argv[2];
 repname = argv[3];

 readdata();

 if((src = fopen(srcname,"r")) == NULL){
  printf("Can't open file for input.\n\n");
  exit(1);
 }
 if((dest = fopen(destname,"w")) == NULL){
  printf("Can't open file for output.\n\n");
  exit(1);
 }

 atend = 0;
 setbuffer();
 while (atend == 0) reploop();
 purge();
 fclose(dest);
 fclose(src);
}

void readdata()
{
 int c;
 if((rep = fopen(repname,"r")) == NULL){
  printf("Can't open data file.\n\n");
  exit(1);
 }
 strchars = (unsigned char)fgetc(rep);
 for(c = 1;c <= strchars;c++)
 {
  strchar[c] = (unsigned char)fgetc(rep);
 }
 repchars = (unsigned char)fgetc(rep);
 for(c = 1;c <= repchars;c++)
 {
  repchar[c] = (unsigned char)fgetc(rep);
 }
}

void setbuffer()
{
 int c;
 for(c = 1;c <= strchars;c++)
 {
  buffchar[c] = (unsigned char)fgetc(src);
  atend = (int)feof(src);
  usechar[c] = atend;
 }
 coffset = 1;
}

void reploop()
{
 int cmat = 1;
 int done = 0;
 int c;
 curchk = cmat + coffset - 1;
 if (curchk > strchars) curchk -= strchars;
 while ((buffchar[curchk] == strchar[cmat]) && (done == 0) && (usechar[curchk] == 0))
 {
  cmat++;
  if (cmat > strchars) done = 1;
  curchk = cmat + coffset - 1;
  if (curchk > strchars) curchk -= strchars;
 }
 if (done == 0)
 {
  if (usechar[coffset] == 0) putc(buffchar[coffset],dest);
  buffchar[coffset] = (unsigned char)fgetc(src);
  atend = (int)feof(src);
  usechar[coffset] = atend;
  coffset++;
  if (coffset > strchars) coffset = 1;
 }
 if (done == 1)
 {
  for(c = 1;c <= repchars;c++) putc(repchar[c],dest);
  setbuffer();
 }
}

void purge()
{
 int c;
 for(c = 1;c < strchars;c++)
 {
  curchk = c + coffset - 1;
  if (curchk > strchars) curchk -= strchars;
  if (usechar[curchk] == 0) putc(buffchar[curchk],dest);
 }
}
