tmi2/
tmi2/bin/
tmi2/etc/
tmi2/lib/
tmi2/lib/adm/
tmi2/lib/adm/daemons/languages/
tmi2/lib/adm/daemons/network/I3/
tmi2/lib/adm/daemons/virtual/template/
tmi2/lib/adm/obj/master/
tmi2/lib/adm/priv/
tmi2/lib/adm/shell/
tmi2/lib/adm/tmp/
tmi2/lib/cmds/
tmi2/lib/d/
tmi2/lib/d/Conf/
tmi2/lib/d/Conf/adm/
tmi2/lib/d/Conf/boards/
tmi2/lib/d/Conf/cmds/
tmi2/lib/d/Conf/data/
tmi2/lib/d/Conf/logs/
tmi2/lib/d/Conf/obj/
tmi2/lib/d/Conf/text/help/
tmi2/lib/d/Fooland/adm/
tmi2/lib/d/Fooland/data/
tmi2/lib/d/Fooland/data/attic/
tmi2/lib/d/Fooland/items/
tmi2/lib/d/TMI/
tmi2/lib/d/TMI/adm/
tmi2/lib/d/TMI/boards/
tmi2/lib/d/TMI/data/
tmi2/lib/d/TMI/rooms/
tmi2/lib/d/grid/
tmi2/lib/d/grid/adm/
tmi2/lib/d/grid/data/
tmi2/lib/d/std/
tmi2/lib/d/std/adm/
tmi2/lib/data/adm/
tmi2/lib/data/adm/daemons/
tmi2/lib/data/adm/daemons/doc_d/
tmi2/lib/data/adm/daemons/emoted/
tmi2/lib/data/adm/daemons/network/http/
tmi2/lib/data/adm/daemons/network/services/mail_q/
tmi2/lib/data/adm/daemons/network/smtp/
tmi2/lib/data/adm/daemons/news/archives/
tmi2/lib/data/attic/connection/
tmi2/lib/data/attic/user/
tmi2/lib/data/std/connection/b/
tmi2/lib/data/std/connection/l/
tmi2/lib/data/std/user/a/
tmi2/lib/data/std/user/b/
tmi2/lib/data/std/user/d/
tmi2/lib/data/std/user/f/
tmi2/lib/data/std/user/l/
tmi2/lib/data/std/user/x/
tmi2/lib/data/u/d/dm/working/doc_d/
tmi2/lib/data/u/l/leto/doc_d/
tmi2/lib/data/u/l/leto/smtp/
tmi2/lib/doc/
tmi2/lib/doc/driverdoc/applies/
tmi2/lib/doc/driverdoc/concepts/
tmi2/lib/doc/driverdoc/driver/
tmi2/lib/doc/driverdoc/efuns/arrays/
tmi2/lib/doc/driverdoc/efuns/buffers/
tmi2/lib/doc/driverdoc/efuns/compile/
tmi2/lib/doc/driverdoc/efuns/ed/
tmi2/lib/doc/driverdoc/efuns/floats/
tmi2/lib/doc/driverdoc/efuns/functions/
tmi2/lib/doc/driverdoc/efuns/general/
tmi2/lib/doc/driverdoc/efuns/numbers/
tmi2/lib/doc/driverdoc/efuns/parsing/
tmi2/lib/doc/driverdoc/lpc/constructs/
tmi2/lib/doc/driverdoc/lpc/preprocessor/
tmi2/lib/doc/driverdoc/lpc/types/
tmi2/lib/doc/driverdoc/platforms/
tmi2/lib/doc/mudlib/
tmi2/lib/ftp/
tmi2/lib/log/
tmi2/lib/obj/net/
tmi2/lib/obj/shells/
tmi2/lib/std/board/
tmi2/lib/std/body/
tmi2/lib/std/fun/
tmi2/lib/std/living/
tmi2/lib/std/object/
tmi2/lib/std/shop/
tmi2/lib/std/socket/
tmi2/lib/std/virtual/
tmi2/lib/student/
tmi2/lib/student/kalypso/
tmi2/lib/student/kalypso/armor/
tmi2/lib/student/kalypso/rooms/
tmi2/lib/student/kalypso/weapons/
tmi2/lib/u/l/leto/
tmi2/lib/u/l/leto/cmds/
tmi2/lib/www/errors/
tmi2/lib/www/gateways/
tmi2/lib/www/images/
tmi2/old/
tmi2/v21.7a10/
tmi2/v21.7a10/ChangeLog.old/
tmi2/v21.7a10/compat/simuls/
tmi2/v21.7a10/include/
tmi2/v21.7a10/testsuite/
tmi2/v21.7a10/testsuite/clone/
tmi2/v21.7a10/testsuite/command/
tmi2/v21.7a10/testsuite/data/
tmi2/v21.7a10/testsuite/etc/
tmi2/v21.7a10/testsuite/include/
tmi2/v21.7a10/testsuite/inherit/
tmi2/v21.7a10/testsuite/inherit/master/
tmi2/v21.7a10/testsuite/log/
tmi2/v21.7a10/testsuite/u/
tmi2/v21.7a10/tmp/
#ifndef _STRALLOC_H_
#define _STRALLOC_H_

/* ref-count debugging code */
#undef NOISY_DEBUG
#define NOISY_STRING "workroom"

/* implementation */
#ifdef NOISY_DEBUG
   void bp PROT((void));
#  ifdef NOISY_STRING
#    define NDBG(x) if (strcmp(STRING(x), NOISY_STRING)==0) \
                    debug_message("%s - %d\n", STRING(x), REFS(x)), bp()
#  else
#    define NDBG(x) debug_message("%s - %d\n", STRING(x), REFS(x)), bp()
#  endif
#else
#  define NDBG(x)
#endif

#if defined(DEBUGMALLOC_EXTENSIONS) && defined(STRING_STATS)
#define CHECK_STRING_STATS /* check_string_stats(0) */
#else
#define CHECK_STRING_STATS
#endif

#ifdef STRING_STATS
#define ADD_NEW_STRING(len, overhead) num_distinct_strings++; bytes_distinct_strings += len + 1; overhead_bytes += overhead
#define SUB_NEW_STRING(len, overhead) num_distinct_strings--; bytes_distinct_strings -= len + 1; overhead_bytes -= overhead

#define ADD_STRING(len) allocd_strings++; allocd_bytes += len + 1; CHECK_STRING_STATS
#define ADD_STRING_SIZE(len) allocd_bytes += len; bytes_distinct_strings += len
#define SUB_STRING(len) allocd_strings--; allocd_bytes -= len + 1; CHECK_STRING_STATS
#else
/* Blazing fast macros :) */
#define ADD_NEW_STRING(x, y)
#define SUB_NEW_STRING(x, y)
#define ADD_STRING(x)
#define ADD_STRING_SIZE(x)
#define SUB_STRING(x)
#endif

typedef struct malloc_block_s {
#ifdef DEBUGMALLOC_EXTENSIONS
    int extra_ref;
#endif
    unsigned short size;
    unsigned short ref;
} malloc_block_t;

#define MSTR_BLOCK(x) (((malloc_block_t *)(x)) - 1) 
#define MSTR_EXTRA_REF(x) (MSTR_BLOCK(x)->extra_ref)
#define MSTR_REF(x) (MSTR_BLOCK(x)->ref)
#define MSTR_SIZE(x) (MSTR_BLOCK(x)->size)
#define MSTR_UPDATE_SIZE(x, y) SAFE(\
				    ADD_STRING_SIZE(y - MSTR_SIZE(x));\
				    MSTR_BLOCK(x)->size = \
				    (y > USHRT_MAX ? USHRT_MAX : y);\
				)

#define FREE_MSTR(x) SAFE(\
			  SUB_STRING(MSTR_SIZE(x));\
			  SUB_NEW_STRING(MSTR_SIZE(x), \
					 sizeof(malloc_block_t));\
			  FREE(MSTR_BLOCK(x));\
		      )

/* This counts on some rather crucial alignment between malloc_block_t and
   block_t */
#define COUNTED_STRLEN(x) ((svalue_strlen_size = MSTR_BLOCK(x)->size), svalue_strlen_size != USHRT_MAX ? svalue_strlen_size : strlen((x)+USHRT_MAX)+USHRT_MAX)
#define COUNTED_REF(x)    MSTR_REF(x)

typedef struct block_s {
    struct block_s *next;	/* next block in the hash chain */
#if defined(DEBUGMALLOC_EXTENSIONS) || (SIZEOF_PTR == 8)
    int extra_ref;
#endif
    /* these two must be last */
    unsigned short size;	/* length of the string */
    unsigned short refs;	/* reference count    */
}       block_t;

#define NEXT(x) (x)->next
#define REFS(x) (x)->refs
#define EXTRA_REF(x) (x)->extra_ref
#define SIZE(x) (x)->size
#define BLOCK(x) (((block_t *)(x)) - 1)	/* pointer arithmetic */
#define STRING(x) ((char *)(x + 1))

#define SHARED_STRLEN(x) COUNTED_STRLEN(x)

#define SVALUE_STRLEN(x) (((x)->subtype & STRING_COUNTED) ? \
			  COUNTED_STRLEN((x)->u.string) : \
			  strlen((x)->u.string))

/* For quick checks.  Avoid strlen(), etc */
#define SVALUE_STRLEN_DIFFERS(x, y) ((((x)->subtype & STRING_COUNTED) && \
				     ((y)->subtype & STRING_COUNTED)) ? \
				     MSTR_SIZE((x)->u.string) != \
				     MSTR_SIZE((y)->u.string) : 0)

/*
 * stralloc.c
 */
void init_strings PROT((void));
char *findstring PROT((char *));
char *make_shared_string PROT((char *));
char *ref_string PROT((char *));
void free_string PROT((char *));
void deallocate_string PROT((char *));
int add_string_status PROT((outbuffer_t *, int));

char *extend_string PROT((char *, int));

extern int svalue_strlen_size;

#ifdef STRING_STATS
extern int num_distinct_strings;
extern int bytes_distinct_strings;
extern int allocd_strings;
extern int allocd_bytes;
extern int overhead_bytes;
#endif

#endif