nightmare3_mudos_v1/
nightmare3_mudos_v1/bin/
nightmare3_mudos_v1/lib/cmds/ambassador/
nightmare3_mudos_v1/lib/cmds/database/
nightmare3_mudos_v1/lib/cmds/hm/
nightmare3_mudos_v1/lib/cmds/soul/
nightmare3_mudos_v1/lib/daemon/cfg/
nightmare3_mudos_v1/lib/daemon/cfg/mon_races/
nightmare3_mudos_v1/lib/daemon/cfg/races/
nightmare3_mudos_v1/lib/daemon/include/
nightmare3_mudos_v1/lib/daemon/save/
nightmare3_mudos_v1/lib/daemon/services/
nightmare3_mudos_v1/lib/daemon/soul/
nightmare3_mudos_v1/lib/doc/
nightmare3_mudos_v1/lib/doc/TestPlans/
nightmare3_mudos_v1/lib/doc/approval/
nightmare3_mudos_v1/lib/doc/approval/QC/
nightmare3_mudos_v1/lib/doc/approval/balance/
nightmare3_mudos_v1/lib/doc/build/
nightmare3_mudos_v1/lib/doc/build/armours/
nightmare3_mudos_v1/lib/doc/build/economy/
nightmare3_mudos_v1/lib/doc/build/etc/
nightmare3_mudos_v1/lib/doc/build/monster/
nightmare3_mudos_v1/lib/doc/build/room/
nightmare3_mudos_v1/lib/doc/build/virtual/
nightmare3_mudos_v1/lib/doc/build/weapon/
nightmare3_mudos_v1/lib/doc/classes/
nightmare3_mudos_v1/lib/doc/efun/
nightmare3_mudos_v1/lib/doc/etc/
nightmare3_mudos_v1/lib/doc/help/creator/
nightmare3_mudos_v1/lib/doc/help/hm/
nightmare3_mudos_v1/lib/doc/lpc/basic/
nightmare3_mudos_v1/lib/doc/lpc/data_types/
nightmare3_mudos_v1/lib/doc/lpc/etc/
nightmare3_mudos_v1/lib/doc/lpc/intermediate/
nightmare3_mudos_v1/lib/doc/lpc/types/
nightmare3_mudos_v1/lib/doc/mudlib/
nightmare3_mudos_v1/lib/doc/mudlib/features/
nightmare3_mudos_v1/lib/domains/Examples/etc/
nightmare3_mudos_v1/lib/domains/Examples/room/
nightmare3_mudos_v1/lib/domains/Examples/virtual/
nightmare3_mudos_v1/lib/domains/Examples/virtual/exaA/
nightmare3_mudos_v1/lib/domains/Examples/virtual/exaB/
nightmare3_mudos_v1/lib/domains/Examples/weapon/
nightmare3_mudos_v1/lib/domains/Praxis/
nightmare3_mudos_v1/lib/domains/Praxis/adm/
nightmare3_mudos_v1/lib/domains/Praxis/attic/
nightmare3_mudos_v1/lib/domains/Praxis/cemetary/
nightmare3_mudos_v1/lib/domains/Praxis/cemetary/mon/
nightmare3_mudos_v1/lib/domains/Praxis/data/
nightmare3_mudos_v1/lib/domains/Praxis/death/
nightmare3_mudos_v1/lib/domains/Praxis/mountains/
nightmare3_mudos_v1/lib/domains/Praxis/obj/armour/
nightmare3_mudos_v1/lib/domains/Praxis/obj/magic/
nightmare3_mudos_v1/lib/domains/Praxis/obj/weapon/
nightmare3_mudos_v1/lib/domains/Praxis/orc_valley/
nightmare3_mudos_v1/lib/domains/Praxis/quests/
nightmare3_mudos_v1/lib/domains/Praxis/standardOld/
nightmare3_mudos_v1/lib/log/
nightmare3_mudos_v1/lib/log/errors/
nightmare3_mudos_v1/lib/log/reports/
nightmare3_mudos_v1/lib/log/watch/
nightmare3_mudos_v1/lib/news/
nightmare3_mudos_v1/lib/secure/cfg/
nightmare3_mudos_v1/lib/secure/cmds/ambassador/
nightmare3_mudos_v1/lib/secure/cmds/mortal/
nightmare3_mudos_v1/lib/secure/save/users/d/
nightmare3_mudos_v1/lib/secure/std/
nightmare3_mudos_v1/lib/std/hm/
nightmare3_mudos_v1/lib/std/living/
nightmare3_mudos_v1/lib/std/room/
nightmare3_mudos_v1/lib/std/user/
nightmare3_mudos_v1/lib/std/virtual/
nightmare3_mudos_v1/lib/www/
nightmare3_mudos_v1/lib/www/errors/
nightmare3_mudos_v1/lib/www/gateways/
nightmare3_mudos_v1/source/
nightmare3_mudos_v1/source/ChangeLog.old/
nightmare3_mudos_v1/source/Win32/
nightmare3_mudos_v1/source/compat/
nightmare3_mudos_v1/source/compat/simuls/
nightmare3_mudos_v1/source/include/
nightmare3_mudos_v1/source/mudlib/
nightmare3_mudos_v1/source/testsuite/
nightmare3_mudos_v1/source/testsuite/clone/
nightmare3_mudos_v1/source/testsuite/command/
nightmare3_mudos_v1/source/testsuite/data/
nightmare3_mudos_v1/source/testsuite/etc/
nightmare3_mudos_v1/source/testsuite/include/
nightmare3_mudos_v1/source/testsuite/inherit/
nightmare3_mudos_v1/source/testsuite/inherit/master/
nightmare3_mudos_v1/source/testsuite/log/
nightmare3_mudos_v1/source/testsuite/single/
nightmare3_mudos_v1/source/testsuite/single/tests/compiler/
nightmare3_mudos_v1/source/testsuite/single/tests/efuns/
nightmare3_mudos_v1/source/testsuite/single/tests/operators/
nightmare3_mudos_v1/source/testsuite/u/
nightmare3_mudos_v1/source/tmp/
/*
 * replace.c:
 *   search & replace, from stdin or file, to stdout
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
 * Use a 4K temporary buffer
 */
#define MAXBUFSIZE 4096

/*
 * Boyer-Moore string search algorithm
 */
static char *search(char *spc, int slen, char *pat, int plen)
{
    int skip[256];
    int i, j, t;

    for (i = 0; i < 256; i++)
	skip[i] = plen;
    for (i = 0; i < plen; i++)
	skip[pat[i]] = plen - i - 1;

    for (i = plen - 1, j = plen - 1; j > 0; i--, j--)
	while (spc[i] != pat[j]) {
	    t = skip[spc[i]];
	    i += plen - j > t ? plen - j : t;
	    if (i >= slen)
		return NULL;
	    j = plen - 1;
	}
    return spc + i;
}

int main(int argc, char *argv[])
{
    FILE *FIn;
    int plen, slen, rlen;
    char *buf;
    char *pbuf, *sbuf;
    int r, w;

    /*
     * process command line args
     */
    if (argc < 3 || argc > 4) {
	fprintf(stderr, "Syntax: replace search_str replace_str [src_file]\n");
	exit(0);
    }
    /*
     * get input
     */
    if (argc == 3)
	FIn = stdin;
    else {
	if (!(FIn = fopen(argv[3], "rb"))) {
	    fprintf(stderr, "Error opening %s\n", argv[3]);
	    exit(0);
	}
    }

    /*
     * set up
     */
    plen = strlen(argv[1]);	/* search pattern length */
    rlen = strlen(argv[2]);	/* replacement string length */
    slen = plen + MAXBUFSIZE;
    pbuf = NULL;
    w = 0;
    buf = (char *) malloc(slen + 1);
    if (!buf) {
	fprintf(stderr, "Error allocating memory for buffer.\n");
	exit(0);
    }
    /*
     * use small buffers for lower memory usage
     */
    r = fread(buf, 1, slen, FIn);
    while (r > 0) {
	/*
	 * ensure buffer is null terminated
	 */
	buf[r] = '\0';

	/*
	 * scan buffer for the pattern
	 */
	pbuf = buf;
	while (sbuf = search(pbuf, r, argv[1], plen)) {
	    /*
	     * write characters from pbuf to sbuf -1
	     */
	    w = sbuf - pbuf;
	    if (w) {
		fwrite(pbuf, 1, w, stdout);
		r -= w;
	    }
	    /*
	     * write replacement string
	     */
	    fwrite(argv[2], 1, rlen, stdout);

	    /*
	     * keep searching
	     */
	    pbuf = sbuf + plen;
	    r -= plen;
	}

	/*
	 * Write out remaining chars in excess of plen
	 */
	if (r > plen) {
	    fwrite(pbuf, 1, r - plen, stdout);
	    pbuf += r - plen;
	    w = plen;
	} else {
	    w = r;
	}

	/*
	 * Copy plen chars to beginning of buffer
	 */
	if (w) {
	    strncpy(buf, pbuf, w);
	}
	if (feof(FIn))
	    break;

	r = fread(buf + w, 1, slen - w, FIn);
	if (r >= 0) {
	    w += r;
	    r = w;
	}
    }

    /*
     * Write out remaining chars in buffer
     */
    if (w) {
	fwrite(buf, 1, w, stdout);
    }
    /*
     * Clean up
     */
    free(buf);

    fflush(stdout);

    if (argc == 4)
	fclose(FIn);

    return 0;
}