dsI/bin/
dsI/extra/creremote/
dsI/extra/mingw/
dsI/extra/wolfpaw/
dsI/fluffos-2.7-ds2.018/
dsI/fluffos-2.7-ds2.018/ChangeLog.old/
dsI/fluffos-2.7-ds2.018/Win32/
dsI/fluffos-2.7-ds2.018/compat/
dsI/fluffos-2.7-ds2.018/compat/simuls/
dsI/fluffos-2.7-ds2.018/testsuite/
dsI/fluffos-2.7-ds2.018/testsuite/clone/
dsI/fluffos-2.7-ds2.018/testsuite/command/
dsI/fluffos-2.7-ds2.018/testsuite/data/
dsI/fluffos-2.7-ds2.018/testsuite/etc/
dsI/fluffos-2.7-ds2.018/testsuite/include/
dsI/fluffos-2.7-ds2.018/testsuite/inherit/
dsI/fluffos-2.7-ds2.018/testsuite/inherit/master/
dsI/fluffos-2.7-ds2.018/testsuite/log/
dsI/fluffos-2.7-ds2.018/testsuite/single/
dsI/fluffos-2.7-ds2.018/testsuite/single/tests/compiler/
dsI/fluffos-2.7-ds2.018/testsuite/single/tests/efuns/
dsI/fluffos-2.7-ds2.018/testsuite/single/tests/operators/
dsI/fluffos-2.7-ds2.018/testsuite/u/
dsI/fluffos-2.7-ds2.018/tmp/
dsI/lib/cfg/
dsI/lib/cmds/common/
dsI/lib/cmds/creators/include/
dsI/lib/cmds/creators/include/SCCS/
dsI/lib/daemon/services/
dsI/lib/doc/
dsI/lib/domains/Ylsrim/
dsI/lib/domains/Ylsrim/adm/
dsI/lib/domains/Ylsrim/armour/
dsI/lib/domains/Ylsrim/broken/
dsI/lib/domains/Ylsrim/fish/
dsI/lib/domains/Ylsrim/meal/
dsI/lib/domains/Ylsrim/npc/
dsI/lib/domains/Ylsrim/virtual/
dsI/lib/domains/Ylsrim/weapon/
dsI/lib/domains/default/creator/
dsI/lib/domains/default/etc/
dsI/lib/domains/default/room/
dsI/lib/lib/comp/
dsI/lib/lib/lvs/
dsI/lib/lib/user/
dsI/lib/lib/virtual/
dsI/lib/obj/
dsI/lib/obj/include/
dsI/lib/realms/
dsI/lib/save/kills/a/
dsI/lib/save/kills/b/
dsI/lib/save/kills/f/
dsI/lib/save/kills/m/
dsI/lib/save/kills/q/
dsI/lib/save/kills/r/
dsI/lib/secure/cfg/
dsI/lib/secure/cfg/classes/
dsI/lib/secure/cfg/races/SCCS/
dsI/lib/secure/cmds/creators/include/
dsI/lib/secure/cmds/players/
dsI/lib/secure/cmds/players/include/
dsI/lib/secure/daemon/include/
dsI/lib/secure/lib/
dsI/lib/secure/lib/include/
dsI/lib/secure/lib/net/
dsI/lib/secure/lib/net/include/
dsI/lib/secure/lib/std/
dsI/lib/secure/obj/
dsI/lib/secure/obj/include/
dsI/lib/secure/save/
dsI/lib/spells/
dsI/lib/verbs/admins/include/
dsI/lib/verbs/common/
dsI/lib/verbs/common/include/
dsI/lib/verbs/creators/
dsI/lib/verbs/creators/include/
dsI/lib/verbs/players/include/SCCS/
dsI/lib/verbs/rooms/
dsI/lib/verbs/rooms/include/
dsI/lib/www/
dsI/v22.2b14/
dsI/win32/
/*
 * 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;
}