gurba-0.40/
gurba-0.40/bin/
gurba-0.40/lib/
gurba-0.40/lib/cmds/guild/fighter/
gurba-0.40/lib/cmds/monster/
gurba-0.40/lib/cmds/race/catfolk/
gurba-0.40/lib/cmds/race/dwarf/
gurba-0.40/lib/cmds/verb/
gurba-0.40/lib/daemons/data/
gurba-0.40/lib/data/boards/
gurba-0.40/lib/data/messages/
gurba-0.40/lib/data/players/
gurba-0.40/lib/design/
gurba-0.40/lib/domains/gurba/
gurba-0.40/lib/domains/gurba/guilds/fighter/
gurba-0.40/lib/domains/gurba/monsters/
gurba-0.40/lib/domains/gurba/objects/armor/
gurba-0.40/lib/domains/gurba/objects/clothing/
gurba-0.40/lib/domains/gurba/objects/weapons/
gurba-0.40/lib/domains/gurba/vendors/
gurba-0.40/lib/kernel/cmds/admin/
gurba-0.40/lib/kernel/daemons/
gurba-0.40/lib/kernel/include/
gurba-0.40/lib/kernel/lib/
gurba-0.40/lib/kernel/net/
gurba-0.40/lib/kernel/sys/
gurba-0.40/lib/logs/
gurba-0.40/lib/pub/
gurba-0.40/lib/std/modules/languages/
gurba-0.40/lib/std/races/
gurba-0.40/lib/std/races/monsters/
gurba-0.40/lib/wiz/fudge/
gurba-0.40/lib/wiz/spud/
gurba-0.40/src/host/beos/
gurba-0.40/src/host/pc/res/
gurba-0.40/src/kfun/
gurba-0.40/src/lpc/
gurba-0.40/src/parser/
gurba-0.40/tmp/
# include "dgd.h"
# include "str.h"
# include "array.h"
# include "object.h"
# include "interpret.h"
# include "edcmd.h"
# include "editor.h"

typedef struct _editor_ {
    cmdbuf *ed;			/* editor instance */
    struct _editor_ *next;	/* next in free list */
} editor;

static editor *editors;		/* editor table */
static editor *flist;		/* free list */
static int neditors;		/* # of editors */
static char *tmpedfile;		/* proto temporary file */
static char *outbuf;		/* output buffer */
static unsigned int outbufsz;	/* chars in output buffer */
static bool recursion;		/* recursion in editor command */
static bool internal;		/* flag editor internal error */

/*
 * NAME:	ed->init()
 * DESCRIPTION:	initialize editor handling
 */
void ed_init(tmp, num)
char *tmp;
register int num;
{
    register editor *e, *f;

    tmpedfile = tmp;
    f = (editor *) NULL;
    neditors = num;
    if (num != 0) {
	outbuf = ALLOC(char, USHRT_MAX + 1);
	editors = ALLOC(editor, num);
	for (e = editors + num; num != 0; --num) {
	    (--e)->ed = (cmdbuf *) NULL;
	    e->next = f;
	    f = e;
	}
    }
    flist = f;
}

/*
 * NAME:	ed->finish()
 * DESCRIPTION:	terminate all editor sessions
 */
void ed_finish()
{
    register int i;
    register editor *e;

    for (i = neditors, e = editors; i > 0; --i, e++) {
	if (e->ed != (cmdbuf *) NULL) {
	    cb_del(e->ed);
	}
    }
}

/*
 * NAME:	check_recursion()
 * DESCRIPTION:	check for recursion in editor commands
 */
static void check_recursion()
{
    if (recursion) {
	error("Recursion in editor command");
    }
}

/*
 * NAME:	ed->new()
 * DESCRIPTION:	start a new editor
 */
void ed_new(obj)
object *obj;
{
    char tmp[STRINGSZ + 3];
    register editor *e;

    check_recursion();
    e = flist;
    if (e == (editor *) NULL) {
	error("Too many editor instances");
    }
    flist = e->next;
    obj->etabi = e - editors;
    obj->flags |= O_EDITOR;

    sprintf(tmp, "%s%03d", tmpedfile, UCHAR(obj->etabi));
    e->ed = cb_new(tmp);
}

/*
 * NAME:	ed->del()
 * DESCRIPTION:	delete an editor instance
 */
void ed_del(obj)
object *obj;
{
    register editor *e;

    check_recursion();
    e = &editors[UCHAR(obj->etabi)];
    cb_del(e->ed);
    e->ed = (cmdbuf *) NULL;
    e->next = flist;
    flist = e;
    obj->flags &= ~O_EDITOR;
}

/*
 * NAME:	ed->handler()
 * DESCRIPTION:	fake error handler
 */
static void ed_handler(f, depth)
frame *f;
Int depth;
{
    /*
     * This function just exists to prevent the higher level error handler
     * from being called.
     */
}

/*
 * NAME:	ed->command()
 * DESCRIPTION:	handle an editor command
 */
string *ed_command(obj, cmd)
object *obj;
char *cmd;
{
    register editor *e;
    extern void output();

    check_recursion();
    if (strchr(cmd, LF) != (char *) NULL) {
	error("Newline in editor command");
    }

    e = &editors[UCHAR(obj->etabi)];
    outbufsz = 0;
    internal = FALSE;
    if (ec_push((ec_ftn) ed_handler)) {
	e->ed->flags &= ~(CB_INSERT | CB_CHANGE);
	lb_inact(e->ed->edbuf->lb);
	recursion = FALSE;
	if (!internal) {
	    error((char *) NULL);	/* pass on error */
	}
	output("%s\012", errormesg());	/* LF */
    } else {
	recursion = TRUE;
	if (cb_command(e->ed, cmd)) {
	    lb_inact(e->ed->edbuf->lb);
	    recursion = FALSE;
	} else {
	    recursion = FALSE;
	    ed_del(obj);
	}
	ec_pop();
    }

    if (outbufsz == 0) {
	return (string *) NULL;
    }
    return str_new(outbuf, (long) outbufsz);
}

/*
 * NAME:	ed->status()
 * DESCRIPTION:	return the editor status of an object
 */
char *ed_status(obj)
object *obj;
{
    return (editors[UCHAR(obj->etabi)].ed->flags & CB_INSERT) ?
	    "insert" : "command";
}

/*
 * NAME:	output()
 * DESCRIPTION:	handle output from the editor
 */
void output(f, a1, a2, a3)
char *f, *a1, *a2, *a3;
{
    char buf[2 * MAX_LINE_SIZE + 15];
    unsigned int len;

    sprintf(buf, f, a1, a2, a3);
    len = strlen(buf);
    if (outbufsz + len > USHRT_MAX) {
	error("Editor output string too long");
    }
    memcpy(outbuf + outbufsz, buf, len);
    outbufsz += len;
}

/*
 * NAME:	ed_error()
 * DESCRIPTION:	handle an editor internal error
 */
void ed_error(f, a1, a2, a3)
char *f, *a1, *a2, *a3;
{
    if (f != (char *) NULL) {
	internal = TRUE;
    }
    error(f, a1,a2, a3);
}