merentha_fluffos_v2/
merentha_fluffos_v2/bin/
merentha_fluffos_v2/fluffos-2.9-ds2.03/
merentha_fluffos_v2/fluffos-2.9-ds2.03/ChangeLog.old/
merentha_fluffos_v2/fluffos-2.9-ds2.03/Win32/
merentha_fluffos_v2/fluffos-2.9-ds2.03/compat/
merentha_fluffos_v2/fluffos-2.9-ds2.03/compat/simuls/
merentha_fluffos_v2/fluffos-2.9-ds2.03/include/
merentha_fluffos_v2/fluffos-2.9-ds2.03/testsuite/
merentha_fluffos_v2/fluffos-2.9-ds2.03/testsuite/clone/
merentha_fluffos_v2/fluffos-2.9-ds2.03/testsuite/command/
merentha_fluffos_v2/fluffos-2.9-ds2.03/testsuite/data/
merentha_fluffos_v2/fluffos-2.9-ds2.03/testsuite/etc/
merentha_fluffos_v2/fluffos-2.9-ds2.03/testsuite/include/
merentha_fluffos_v2/fluffos-2.9-ds2.03/testsuite/inherit/
merentha_fluffos_v2/fluffos-2.9-ds2.03/testsuite/inherit/master/
merentha_fluffos_v2/fluffos-2.9-ds2.03/testsuite/log/
merentha_fluffos_v2/fluffos-2.9-ds2.03/testsuite/single/
merentha_fluffos_v2/fluffos-2.9-ds2.03/testsuite/single/tests/compiler/
merentha_fluffos_v2/fluffos-2.9-ds2.03/testsuite/single/tests/efuns/
merentha_fluffos_v2/fluffos-2.9-ds2.03/testsuite/single/tests/operators/
merentha_fluffos_v2/fluffos-2.9-ds2.03/testsuite/u/
merentha_fluffos_v2/fluffos-2.9-ds2.03/tmp/
merentha_fluffos_v2/fluffos-2.9-ds2.03/windows/
merentha_fluffos_v2/lib/cfg/
merentha_fluffos_v2/lib/cfg/races/
merentha_fluffos_v2/lib/cmds/abilities/
merentha_fluffos_v2/lib/cmds/actions/
merentha_fluffos_v2/lib/cmds/spells/
merentha_fluffos_v2/lib/daemon/include/
merentha_fluffos_v2/lib/daemon/services/
merentha_fluffos_v2/lib/doc/
merentha_fluffos_v2/lib/doc/building/
merentha_fluffos_v2/lib/doc/help/classes/
merentha_fluffos_v2/lib/doc/help/general/
merentha_fluffos_v2/lib/doc/help/races/
merentha_fluffos_v2/lib/doc/help/skills/
merentha_fluffos_v2/lib/doc/help/stats/
merentha_fluffos_v2/lib/doc/man/efuns/
merentha_fluffos_v2/lib/doc/man/lfuns/
merentha_fluffos_v2/lib/doc/news/
merentha_fluffos_v2/lib/doc/old/
merentha_fluffos_v2/lib/doc/old/concepts/
merentha_fluffos_v2/lib/doc/old/lpc/constructs/
merentha_fluffos_v2/lib/doc/old/lpc/types/
merentha_fluffos_v2/lib/domains/ROOMS/
merentha_fluffos_v2/lib/domains/obj/armour/
merentha_fluffos_v2/lib/domains/obj/monsters/
merentha_fluffos_v2/lib/domains/obj/other/
merentha_fluffos_v2/lib/domains/obj/weapons/
merentha_fluffos_v2/lib/realms/petrarch/
merentha_fluffos_v2/lib/save/daemons/
merentha_fluffos_v2/lib/save/rid/
merentha_fluffos_v2/lib/save/users/a/
merentha_fluffos_v2/lib/save/users/p/
merentha_fluffos_v2/lib/save/users/t/
merentha_fluffos_v2/lib/std/login/
merentha_fluffos_v2/lib/std/obj/
merentha_fluffos_v2/win32/
#include "std.h"
#include "dumpstat.h"
#include "comm.h"
#include "file.h"

/*
 * Write statistics about objects on file.
 */

static int sumSizes (mapping_t *, mapping_node_t *, void *);
static int svalue_size (svalue_t *);

static int sumSizes (mapping_t * m, mapping_node_t * elt, void * tp)
{
    int *t = (int *)tp;

    *t += (svalue_size(&elt->values[0]) + svalue_size(&elt->values[1]));
    *t += sizeof(mapping_node_t);
    return 0;
}

int depth = 0;

static int svalue_size (svalue_t * v)
{
    int i, total;

    switch (v->type) {
    case T_OBJECT:
    case T_REAL:
    case T_NUMBER:
        return 0;
    case T_STRING:
        return (strlen(v->u.string) + 1);
    case T_ARRAY:
    case T_CLASS:
        if (++depth > 100)
            return 0;

        /* first svalue is stored inside the array struct */
        total = sizeof(array_t) - sizeof(svalue_t);
        for (i = 0; i < v->u.arr->size; i++) {
            total += svalue_size(&v->u.arr->item[i]) + sizeof(svalue_t);
        }
        depth--;
        return total;
    case T_MAPPING:
        if (++depth > 100)
            return 0;
        total = sizeof(mapping_t);
        mapTraverse(v->u.map, sumSizes, &total);
        depth--;
        return total;
    case T_FUNCTION:
        {
            svalue_t tmp;
            tmp.type = T_ARRAY;
            tmp.u.arr = v->u.fp->hdr.args;

            if (++depth > 100)
                return 0;

            if (tmp.u.arr)
                total = sizeof(funptr_hdr_t) + svalue_size(&tmp);
            else
                total = sizeof(funptr_hdr_t);
            switch (v->u.fp->hdr.type) {
            case FP_EFUN:
                total += sizeof(efun_ptr_t);
                break;
            case FP_LOCAL | FP_NOT_BINDABLE:
                total += sizeof(local_ptr_t);
                break;
            case FP_SIMUL:
                total += sizeof(simul_ptr_t);
                break;
            case FP_FUNCTIONAL:
            case FP_FUNCTIONAL | FP_NOT_BINDABLE:
                total += sizeof(functional_t);
                break;
            }

            depth--;
            return total;
        }
#ifndef NO_BUFFER_TYPE
    case T_BUFFER:
        /* first byte is stored inside the buffer struct */
        return sizeof(buffer_t) + v->u.buf->size - 1;
#endif
    default:
      //some freed value or a reference (!) to one (in all my test cases
      //anyway), it will be removed by reclaim_objects later, Wodan
      //fatal("Illegal type: %d\n", v->type);
      ;
    }
    /* NOTREACHED */
    return 0;
}

int data_size (object_t * ob)
{
    int total = 0, i;

    if (ob->prog) {
        for (i = 0; i < ob->prog->num_variables_total; i++) {
            depth = 0;
            total += svalue_size(&ob->variables[i]) + sizeof(svalue_t);
        }
    }
    return total;
}

void dumpstat (const char * tfn)
{
    FILE *f;
    object_t *ob;
    const char *fn;
#ifdef F_SET_HIDE
    int display_hidden;
#endif

    fn = check_valid_path(tfn, current_object, "dumpallobj", 1);
    if (!fn) {
        error("Invalid path '/%s' for writing.\n", tfn);
        return;
    }
    f = fopen(fn, "w");
    if (!f) {
        error("Unable to open '/%s' for writing.\n", fn);
        return;
    }

#ifdef F_SET_HIDE
    display_hidden = -1;
#endif
    for (ob = obj_list; ob; ob = ob->next_all) {
        int tmp;

#ifdef F_SET_HIDE
        if (ob->flags & O_HIDDEN) {
            if (display_hidden == -1)
                display_hidden = valid_hide(current_object);
            if (!display_hidden)
                continue;
        }
#endif
        /* FIXME */
        if (ob->prog && (ob->prog->ref == 1 || !(ob->flags & O_CLONE)))
            tmp = ob->prog->total_size;
        else
            tmp = 0;
        fprintf(f, "%-20s %ld ref %2d %s %s (%d)\n", ob->obname,
                tmp + data_size(ob) + sizeof(object_t), ob->ref,
                ob->flags & O_HEART_BEAT ? "HB" : "  ",
#ifndef NO_ENVIRONMENT
                ob->super ? ob->super->obname : "--",
#else
                "--",
#endif
                /* ob->cpu */ 0);
    }
    fclose(f);
}