ds2.1.1/bin/
ds2.1.1/extra/wolfpaw/
ds2.1.1/lib/cmds/admins/
ds2.1.1/lib/cmds/common/
ds2.1.1/lib/cmds/creators/include/
ds2.1.1/lib/cmds/creators/include/SCCS/
ds2.1.1/lib/daemon/services/
ds2.1.1/lib/doc/
ds2.1.1/lib/doc/efun/all/
ds2.1.1/lib/doc/efun/arrays/
ds2.1.1/lib/doc/efun/buffers/
ds2.1.1/lib/doc/efun/compile/
ds2.1.1/lib/doc/efun/floats/
ds2.1.1/lib/doc/efun/functions/
ds2.1.1/lib/doc/efun/general/
ds2.1.1/lib/doc/efun/mixed/
ds2.1.1/lib/doc/efun/numbers/
ds2.1.1/lib/doc/efun/parsing/
ds2.1.1/lib/doc/faq/
ds2.1.1/lib/doc/hbook/
ds2.1.1/lib/doc/help/classes/
ds2.1.1/lib/doc/lpc/basic/
ds2.1.1/lib/doc/lpc/concepts/
ds2.1.1/lib/doc/lpc/constructs/
ds2.1.1/lib/doc/lpc/etc/
ds2.1.1/lib/doc/lpc/intermediate/
ds2.1.1/lib/doc/lpc/types/
ds2.1.1/lib/doc/misc/
ds2.1.1/lib/doc/old/
ds2.1.1/lib/domains/Ylsrim/
ds2.1.1/lib/domains/Ylsrim/adm/
ds2.1.1/lib/domains/Ylsrim/armor/
ds2.1.1/lib/domains/Ylsrim/broken/
ds2.1.1/lib/domains/Ylsrim/fish/
ds2.1.1/lib/domains/Ylsrim/meal/
ds2.1.1/lib/domains/Ylsrim/npc/
ds2.1.1/lib/domains/Ylsrim/obj/
ds2.1.1/lib/domains/Ylsrim/virtual/
ds2.1.1/lib/domains/Ylsrim/weapon/
ds2.1.1/lib/domains/campus/adm/
ds2.1.1/lib/domains/campus/etc/
ds2.1.1/lib/domains/campus/meals/
ds2.1.1/lib/domains/campus/npc/
ds2.1.1/lib/domains/campus/txt/ai/charles/
ds2.1.1/lib/domains/campus/txt/ai/charles/bak2/
ds2.1.1/lib/domains/campus/txt/ai/charles/bak2/bak1/
ds2.1.1/lib/domains/campus/txt/ai/charly/
ds2.1.1/lib/domains/campus/txt/ai/charly/bak/
ds2.1.1/lib/domains/campus/txt/jenny/
ds2.1.1/lib/domains/default/creator/
ds2.1.1/lib/domains/default/doors/
ds2.1.1/lib/domains/default/etc/
ds2.1.1/lib/domains/default/weap/
ds2.1.1/lib/domains/town/doors/
ds2.1.1/lib/domains/town/txt/
ds2.1.1/lib/domains/town/txt/shame/
ds2.1.1/lib/domains/town/virtual/
ds2.1.1/lib/lib/comp/
ds2.1.1/lib/lib/lvs/
ds2.1.1/lib/lib/user/
ds2.1.1/lib/lib/virtual/
ds2.1.1/lib/log/
ds2.1.1/lib/obj/book_source/
ds2.1.1/lib/obj/include/
ds2.1.1/lib/realms/template/
ds2.1.1/lib/realms/template/area/armor/
ds2.1.1/lib/realms/template/area/npc/
ds2.1.1/lib/realms/template/area/obj/
ds2.1.1/lib/realms/template/area/room/
ds2.1.1/lib/realms/template/area/weap/
ds2.1.1/lib/realms/template/bak/
ds2.1.1/lib/realms/template/cmds/
ds2.1.1/lib/save/kills/o/
ds2.1.1/lib/secure/cfg/
ds2.1.1/lib/secure/cfg/classes/
ds2.1.1/lib/secure/cfg/races/SCCS/
ds2.1.1/lib/secure/cmds/creators/include/
ds2.1.1/lib/secure/cmds/players/
ds2.1.1/lib/secure/cmds/players/include/
ds2.1.1/lib/secure/daemon/include/
ds2.1.1/lib/secure/lib/
ds2.1.1/lib/secure/lib/include/
ds2.1.1/lib/secure/lib/net/
ds2.1.1/lib/secure/lib/net/include/
ds2.1.1/lib/secure/lib/std/
ds2.1.1/lib/secure/modules/
ds2.1.1/lib/secure/npc/
ds2.1.1/lib/secure/obj/include/
ds2.1.1/lib/secure/room/
ds2.1.1/lib/secure/save/
ds2.1.1/lib/secure/save/boards/
ds2.1.1/lib/secure/verbs/creators/
ds2.1.1/lib/shadows/
ds2.1.1/lib/spells/
ds2.1.1/lib/verbs/admins/include/
ds2.1.1/lib/verbs/common/
ds2.1.1/lib/verbs/common/include/
ds2.1.1/lib/verbs/creators/
ds2.1.1/lib/verbs/creators/include/
ds2.1.1/lib/verbs/players/include/SCCS/
ds2.1.1/lib/verbs/rooms/
ds2.1.1/lib/verbs/rooms/include/
ds2.1.1/lib/www/errors/
ds2.1.1/lib/www/images/
ds2.1.1/v22.2b14/
ds2.1.1/v22.2b14/ChangeLog.old/
ds2.1.1/v22.2b14/Win32/
ds2.1.1/v22.2b14/compat/
ds2.1.1/v22.2b14/compat/simuls/
ds2.1.1/v22.2b14/include/
ds2.1.1/v22.2b14/testsuite/
ds2.1.1/v22.2b14/testsuite/clone/
ds2.1.1/v22.2b14/testsuite/command/
ds2.1.1/v22.2b14/testsuite/data/
ds2.1.1/v22.2b14/testsuite/etc/
ds2.1.1/v22.2b14/testsuite/include/
ds2.1.1/v22.2b14/testsuite/inherit/
ds2.1.1/v22.2b14/testsuite/inherit/master/
ds2.1.1/v22.2b14/testsuite/log/
ds2.1.1/v22.2b14/testsuite/single/
ds2.1.1/v22.2b14/testsuite/single/tests/compiler/
ds2.1.1/v22.2b14/testsuite/single/tests/efuns/
ds2.1.1/v22.2b14/testsuite/single/tests/operators/
ds2.1.1/v22.2b14/testsuite/u/
ds2.1.1/v22.2b14/tmp/
ds2.1.1/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;
}