mud/
mud/2.4.5/dgd/include/
mud/2.4.5/dgd/std/
mud/2.4.5/dgd/sys/
mud/2.4.5/doc/
mud/2.4.5/doc/examples/
mud/2.4.5/log/
mud/2.4.5/obj/Go/
mud/2.4.5/players/
mud/2.4.5/players/lars/
mud/2.4.5/room/death/
mud/2.4.5/room/maze1/
mud/2.4.5/room/post_dir/
mud/2.4.5/room/sub/
/*
 * NAME:	badarg()
 * DESCRIPTION:	cause a bad argument error
 */
private void badarg(string func, int arg)
{
    error("Bad argument " + arg + " to function " + func);
}

/*
 * NAME:	capitalize()
 * DESCRIPTION:	capitalize a string
 */
static string capitalize(string str)
{
    ARGCHECK(str, capitalize, 1);

    if (str[0] >= 'a' && str[0] <= 'z') {
	str[0] -= 'a' - 'A';
    }
    return str;
}

/*
 * NAME:	lower_case()
 * DESCRIPTION:	convert a string to lower case
 */
static string lower_case(string str)
{
    int i, len, c;

    ARGCHECK(str, lower_case, 1);

    for (i = 0, len = strlen(str); i < len; i++) {
	c = str[i];
	if (c >= 'A' && c <= 'Z') {
	    str[i] += 'a' - 'A';
	}
    }
    return str;
}

/*
 * NAME:	set_bit()
 * DESCRIPTION:	set a bit in a bit string
 */
static string set_bit(string str, int bit)
{
    int ind, len, c;

    ARGCHECK(str, set_bit, 1);

    if (bit > MAX_BITS) {
	error("Too big bit number " + bit);
    }
    ind = bit / 6;
    len = strlen(str);
    if (ind >= len) {
	do {
	    str += "                    ";
	    len += 20;
	} while (ind >= len);
	str = str[0 .. ind];
    }
    c = str[ind];
    if (c < ' ') {
	error("Illegal bit pattern in character " + ind);
    }
    str[ind] = (c - ' ' | 1 << bit % 6) + ' ';

    return str;
}

/*
 * NAME:	clear_bit()
 * DESCRIPTION:	clear a bit in a bit string
 */
static string clear_bit(string str, int bit)
{
    int ind, c;

    ARGCHECK(str, clear_bit, 1);

    if (bit > MAX_BITS) {
	error("Too big bit number " + bit);
    }
    ind = bit / 6;
    if (ind >= strlen(str)) {
	return str;
    }
    c = str[ind];
    if (c < ' ') {
	error("Illegal bit pattern in character " + ind);
    }
    str[ind] = (c - ' ' & ~(1 << bit % 6)) + ' ';

    return str;
}

/*
 * NAME:	test_bit()
 * DESCRIPTION:	test a bit in a bit string
 */
static int test_bit(string str, int bit)
{
    int ind;

    ARGCHECK(str, test_bit, 1);

    ind = bit / 6;
    if (ind >= strlen(str)) {
	return 0;
    }

    return (str[ind] - ' ' & 1 << bit % 6) != 0;
}

/*
 * NAME:	member_array()
 * DESCRIPTION:	return the index of the element in the array, or -1
 */
static int member_array(mixed elt, mixed *arr)
{
    int i, sz;

    ARGCHECK(arr, member_array, 1);

    for (i = 0, sz = sizeof(arr); i < sz; i++) {
	if (arr[i] == elt) {
	    return i;
	}
    }
    return -1;
}

/*
 * NAME:	filter_array
 * DESCRIPTION:	filter the elements of an array
 */
static varargs mixed *
filter_array(mixed *arr, string func, mixed obj, mixed arg)
{
    mixed *copy, elt;
    int i, j, sz;

    ARGCHECK(arr, filter_array, 1);
    ARGCHECK(func && function_object(func, this_object()) != AUTO,
	     filter_array, 2);
    if (stringp(obj)) {
	call_other(obj = ::find_object(DRIVER)->path_object(obj), "???");
	obj = find_object(obj);
    }
    ARGCHECK(objectp(obj) && sscanf(object_name(obj), "/dgd/%*s") == 0,
	     filter_array, 3);

    copy = allocate(sz = sizeof(arr));
    for (i = 0, j = -1; i < sz; i++) {
	if (call_other(obj, func, elt = arr[i], arg)) {
	    copy[++j] = elt;
	}
    }

    return copy[0 .. j];
}

/*
 * NAME:	map_array
 * DESCRIPTION:	map the elements of an array
 */
static varargs mixed *map_array(mixed *arr, string func, mixed obj, mixed arg)
{
    mixed *copy;
    int i, sz;

    ARGCHECK(arr, map_array, 1);
    ARGCHECK(func && function_object(func, this_object()) != AUTO,
	     map_array, 2);
    if (stringp(obj)) {
	call_other(obj = ::find_object(DRIVER)->path_object(obj), "???");
	obj = find_object(obj);
    }
    ARGCHECK(objectp(obj) && sscanf(object_name(obj), "/dgd/%*s") == 0,
	     map_array, 3);

    copy = allocate(sz = sizeof(arr));
    for (i = 0; i < sz; i++) {
	copy[i] = call_other(obj, func, arr[i], arg);
    }

    return copy;
}

/*
 * NAME:	extract()
 * DESCRIPTION:	extract a substring
 */
static varargs string extract(string str, int first, int last)
{
    ARGCHECK(str, extract, 1);

    /* will mistake extract(str, 0) for extract(str, 0, 0) */
    if (first != 0 && last == 0) {
	last = strlen(str) - 1;
    } else if (first >= strlen(str) || last < first) {
	return "";
    }

    return str[first .. last];
}

/*
 * NAME:	slice_array()
 * DESCRIPTION:	return part on an array
 */
static mixed *slice_array(mixed *arr, int first, int last)
{
    ARGCHECK(arr, slice_array, 1);

    if (first >= sizeof(arr) || last < first) {
	return ({ });
    }
    return arr[first .. last];
}

/*
 * NAME:	sort_array()
 * DESCRIPTION:	sort an array
 */
static varargs mixed *sort_array(mixed *source, string func, mixed obj)
{
    int step, halfstep, size;
    int i, j, i1, i2, end1, end2;
    mixed *dest, *temp;

    ARGCHECK(source, sort_array, 1);
    ARGCHECK(func && function_object(func, this_object()) != AUTO,
	     sort_array, 2);
    if (obj == 0) {
	obj = this_object();
    } else if (stringp(obj)) {
	call_other(obj = ::find_object(DRIVER)->path_object(obj), "???");
	obj = find_object(obj);
    }
    ARGCHECK(objectp(obj) && sscanf(object_name(obj), "/dgd/%*s") == 0,
	     sort_array, 3);

    size = sizeof(source = source[..]);
    if (size < 2) {
        return source;
    }
    dest = allocate(size);
    step = 2;
    halfstep = 1;

    while (halfstep < size) {
        for (i = j = 0; i < size; i += step) {
            i1 = i;
            i2 = i + halfstep;
            end1 = i2;
            if (end1 > size) {
                end1 = size;
            }
            end2 = i + step;
            if (end2 > size) {
                end2 = size;
            }
            while (i1 < end1 && i2 < end2) {
                if (call_other(obj, func, source[i1], source[i2]) > 0) {
                    dest[j++] = source[i2++];
                } else {
                    dest[j++] = source[i1++];
                }
            }
            if (i1 == end1) {
                while (i2 < end2) {
                    dest[j++] = source[i2++];
                }
            } else {
                while (i1 < end1) {
                    dest[j++] = source[i1++];
                }
            }
        }
        halfstep = step;
        step += step;
        temp = source;
        source = dest;
        dest = temp;
    }
    return source;
}

/*
 * NAME:	unique_array()
 * DESCRIPTION:	subdevide an array of objects into arrays with objects where
 *		obj->func() returned identical descriptions
 */
static varargs mixed *unique_array(mixed *arr, string func, mixed exclude)
{
    mapping map;
    int i, sz;
    mixed val, elt;
    object *list;

    ARGCHECK(arr, unique_array, 1);
    ARGCHECK(func && function_object(func, this_object()) != AUTO,
	     unique_array, 2);

    map = ([ ]);
    for (i = 0, sz = sizeof(arr); i < sz; i++) {
	elt = arr[i];
	if (objectp(elt) && sscanf(object_name(elt), "/dgd/%*s") == 0 &&
	    (val=call_other(elt, func)) != exclude) {
	    list = map[val];
	    if (list == 0) {
		list = ({ elt });
	    } else {
		list = ({ elt }) + list;
	    }
	    map[val] = list;
	}
    }
    return map_values(map);
}