/*
 *    PROJECT:      DVS
 *    SUBSYSTEM:    du
 *    MODULE:       du.h
 *
 *    File:         $RCSfile: du.h,v $
 *    Revision:     $Revision: 2.17 $
 *    Date:         $Date: 1995/05/18 09:40:33 $
 *    Author:       $Author: jeff $
 *    RCS Ident:    $Id: du.h,v 2.17 1995/05/18 09:40:33 jeff beta $
 *
 *    FUNCTION:
 *    external declarations of functions in the du library.
 *
 *
 * Copyright (c) 1994 Division Ltd.
 *
 * All Rights Reserved.
 *
 * This Document may not, in whole or in part, be copied,
 * photocopied, reproduced, translated, or reduced to any
 * electronic medium or machine readable form without prior
 * written consent from Division Ltd.
 */
#ifndef _DU_H
#define _DU_H

#include <stdio.h>

#include <dsys/divtypes.h>

#ifdef _WIN31
#include <alloc.h>
#define malloc farmalloc
#endif

#ifdef __cplusplus
extern "C" {
#endif

/*
 * searching fopen/searching flook functions.
 */

#define SF_READ  1
#define SF_WRITE 2
#define SF_EXEC  4
#define SF_EXIST 8

typedef enum { DU_PATH_SYSTEM, DU_PATH_USER, DU_PATH_OFFSET } duPathType;

typedef struct duPathIterator
{
    void *entry;
} duPathIterator;

extern void duVersion(FILE *fp);

extern void *duConvertPathToTable(char *sysPath,
                                  char *userPath,
                                  char *offset);
extern void *duAddPathToTable(void *table,
                              char *path,
                              duPathType type);
extern FILE *duSearchingFopen(char *fileName,
                              void *pathList,
                              char **extensions,
                              char  *mode,
                              char  *fullPath,
                              int maxFullPathSize,
                              int *extensionIndex,
                              int absolute);
extern int duSearchingFlook(char *fileName,
                            void *pathList,
                            char **extensions,
                            int32 mode,
                            char  *fullPath,
                            int maxFullPathSize,
                            int *extensionIndex,
                            int absolute);
char *duPathIterateInit(duPathIterator *iter, void *table);
char *duPathIterate(duPathIterator *iter);
void *duPathRemoveEntry(void *table, char *entry);
void duPathDelete(void *table);
void duSfSearchPath(char *searchPath);
void duSfSearchVariable(char *searchVariable);

/*
 * Functions for efficient allocation of many identically sized blocks.
 */

/*
 * many small chunks are allocated at once. One of these
 * structures manages that.
 */
typedef struct duBlkAllocChunk duBlkAllocChunk;

/*
 * the block header. Contains house keeping info for the block allocator.
 */
typedef struct duBlkCtrl {
    duBlkAllocChunk *freeChunks;  /* Ptr to linked list of free blocks */
    void              *freeList;  /* Pointer to the free list          */
    uint32           totalItems;  /* Total number of block items       */
    uint32            freeItems;  /* Total number of free items        */
    uint32            chunkSize;  /* Number of items to alloc at once  */
    uint32            itemAlign;  /* Alignment of units in bytes.      */
    uint32             itemSize;  /* Size of items in bytes            */
} duBlkCtrl;
extern void duBlkAllocConstruct(duBlkCtrl *ctrlBlock,
                                uint32 is,
                                uint32 cs,
                                uint32 align);
typedef void* (*duAllocFunc)(uint32);
typedef void   (*duFreeFunc)(void*);

extern void  duBlkAllocDestruct(duBlkCtrl *ctrlBlock,
                               duFreeFunc ffunc);
extern void         *duBlkAlloc(duBlkCtrl *ctrlBlock,
                               duAllocFunc afunc);
extern void           duBlkFree(duBlkCtrl *ctrlBlock, void *item);

/*
 * Functions to manipulate hash tables.
 */
typedef int32 (*duHfunc)(void *key, int32 size);
typedef int (*duCfunc)(void *a, void *b);
typedef struct duHashElem duHashElem;
typedef struct duHashTab duHashTab;

/*
 * the following is used if iterating over all the elements in a hash
 * table. It keeps track of where in the table you are for use with the
 * iteration functions.
 */
typedef struct duHashIterator {
    duHashTab  *h;
    int32      bucket;
    duHashElem *e;
} duHashIterator;

extern void           *duHashLookup  (duHashTab *t, void *key);
extern void           duHashInstall  (duHashTab *t, void *key, void *datum);

#define duHashRemove(t, key)    duHashRemoveK((t), (key), NULL)
#define duHashRemoveK(t, key, old)    duHashRemoveKDatum ((t), (key), NULL, (old) )

extern void           *duHashRemoveKDatum (duHashTab *t, void *key, void *d, void **old_key);
extern duHashTab      *duNewHashTab  (int32 Size, duHfunc hashfun,
                                     duCfunc cmpfun);
extern void         duDeleteHashTab  (duHashTab *t);

#define duHashIterateInit(iter, t) \
    duHashIterateInitK(iter, t, NULL)

#define duHashIterate(iter) \
    duHashIterateK(iter, NULL)

extern void      *duHashIterateInitK (duHashIterator *iter, duHashTab *t,
                                      void **key);
extern void          *duHashIterateK (duHashIterator *iter, void **key);




void 	__duVerboseStart(int level);
void 	__duDebugStart(int level, char *file, int line);
void 	__duVerboseMessage(char *format, ...);
uint32  duVerbose_SetLevel(uint32 level);
uint32 	duVerbose_GetLevel(void) ;
uint32	duDebug_SetLevel(uint32 level);
uint32	duDebug_GetLevel(void);
FILE	*duDebug_SetLogFile(FILE *, int mode);
char	*duDebug_SetName(char *, int mode);
void	duDebug_Quiet(void);
void	duDebug_VeryQuiet(void);
void	duDebug_Noisy(void);
void 	duWarn(char *format, ...);
void 	duError(char *format, ...);
void 	duFatal(char *format, ...);

extern uint32 __duVerbose_level;
extern uint32 __duDebug_level;

#define DU_DEBUG_DONT_OVERIDE	0
#define DU_DEBUG_OVERIDE	1

#define duVerbose(x,y)  do {                                        \
                            if (__duVerbose_level & (x))            \
                            {                                       \
                                __duVerboseStart(x);		    \
                                __duVerboseMessage y;               \
                            }                                       \
                        } while (0)

#ifdef NDEBUG
#undef duDebug
#define duDebug(x,y) ((void)0)
#else
#undef duDebug
#define duDebug(x,y)  do {                                        	\
                            if (__duDebug_level & (x))           	\
                            {                                       	\
                                __duDebugStart(x, __FILE__, __LINE__);	\
                                __duVerboseMessage y;               	\
                            }                                       	\
                        } while (0)
#endif


#ifdef __cplusplus
}
#endif
#endif /*_DU_H */
