/*
 * (C) Copyright Cogent Real-Time Systems Inc., 1997-2000.
 *     All rights reserved.
 *
 * This file constitutes a part of the Cascade (TM) C-Language
 * application programming interface.  It is not to be modified.  This
 * file is licensed for the purpose of creating programs that will
 * communicate with Cogent's products, and for no other purpose.
 * Cogent claims no rights in any program created by a party other than
 * Cogent by compiling this file, and accepts no responsibility or
 * liability in such a program.
 *
 * It is illegal for any party other than Cogent to sell the contents of
 * this file, or any part thereof, or to attempt to gain in any way from
 * the transmission of this file.  It is illegal to remove this notice
 * from this file.
 */


#ifndef UTIL_H
#define UTIL_H

#ifdef __cplusplus
extern "C" {
#endif

#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif

#ifdef HAVE_TIME_H
#include <time.h>
#endif

#ifndef STDTOOL_H
#include <cogent/stdtool.h>
#endif

#ifndef CRSERROR_H
#include <cogent/crserror.h>
#endif

#ifndef LINKLIST_H
#include <cogent/linklist.h>
#endif

#ifndef UTINDEX_T_DEF
#define UTINDEX_T_DEF
typedef int32_t utindex_t;
#endif

#include <stdio.h>

typedef enum UT_TOKEN
{
    UT_TOKEN_REAL = 1, UT_TOKEN_LONG, UT_TOKEN_STRING, UT_TOKEN_HEX,
	UT_TOKEN_BINARY, UT_TOKEN_OCTAL
} UT_TOKEN;

typedef struct UT_stARRAY
{
	utindex_t	usedsize;
	void 		**array;
	utindex_t	allocsize;
	utindex_t	growsize;
	utindex_t 	*index;
	utindex_t	indexsize;
} UT_stARRAY;

typedef UT_stARRAY *UT_pARRAY;

#define	UT_ARRAY_END	-1

/* returns int because of qsort */
typedef int	(*UT_pfCOMPARE)(const void *, const void *);
typedef ST_STATUS (*UT_pfDESTROY)(void *);
typedef ST_STATUS (*UT_pfAPPLY)(void *);
typedef ST_STATUS (*UT_pfAPPLYARG)(void *, void *);
typedef utindex_t (*UT_pfHASH)(const void *);

typedef struct  ut_stHASHTABLE
{
	UT_pfHASH		pfhash;
	UT_pfCOMPARE 	pfcomp;
	utindex_t		size;
	UT_pARRAY		bins;
} UT_stHASHTABLE;

typedef UT_stHASHTABLE	*ut_pHASHTABLE;
typedef void 			*UT_hHASHTABLE;

#ifdef notdef
typedef struct UT_stHASHENT
{
	void 	*key;		// Unique
	void	*data;
} UT_stHASHENT;

typedef struct UT_stHASHENT *UT_pHASHENT;
#endif

typedef ST_STATUS (*UT_pfCMD)(int argc, char** argv, void* data);

typedef struct UT_stCMD
{
	char		*name;
	int			minargs;
	int			maxargs;
	UT_pfCMD	pfunc;
	char		*description;
} UT_stCMD;

typedef UT_stCMD	*UT_pCMD;

typedef struct UT_stFORMAT
{
	char		*original;
	int			nfields;
	char		**fields;
	long		ldata;
	void		*vdata;
} UT_stFORMAT;

typedef UT_stFORMAT	*UT_pFORMAT;

typedef struct UT_stFMTFIELD
{
	char		fmtchar;
	char		printfchar;
} UT_stFMTFIELD;

/* --------------------------- MACROS ---------------------------------- */

#define UT_ARRAYELEM(a,i)	((a)->array[i])
#define UT_ARRAYIND(a,i)	((a)->array[(a)->index[i]])

/* ------------------------ FUNCTION PROTOTYPES ------------------------ */

/* ----------------------------- ut_array.c ----------------------------- */

DllSym UT_pARRAY UT_ArrayCreate ( utindex_t growsize, ER_hLIST);
DllSym UT_pARRAY UT_ArrayIndCreate ( utindex_t growsize, ER_hLIST);
DllSym ST_STATUS UT_ArrayAdd 	( UT_pARRAY, void *data, 
							utindex_t position, ER_hLIST);
DllSym ST_STATUS UT_ArraySet (UT_pARRAY parray, void *data,
					   utindex_t position, ER_hLIST elist);
DllSym ST_STATUS UT_ArrayIndAdd ( UT_pARRAY, void *data,
								 utindex_t position, ER_hLIST);
DllSym ST_STATUS UT_ArraySort 	( UT_pARRAY, UT_pfCOMPARE, ER_hLIST);
DllSym ST_STATUS UT_ArrayIndSort ( UT_pARRAY, UT_pfCOMPARE, ER_hLIST);
DllSym void * UT_ArraySearch ( UT_pARRAY, void *data, UT_pfCOMPARE, 
							  utindex_t *position,ER_hLIST);
DllSym void * UT_ArrayIndSearch ( UT_pARRAY, void *data, UT_pfCOMPARE, 
								 utindex_t *position,ER_hLIST);
DllSym void * UT_ArrayRemove ( UT_pARRAY, utindex_t positon, ER_hLIST);
DllSym void * UT_ArrayIndRemove ( UT_pARRAY, utindex_t positon, ER_hLIST);
DllSym ST_STATUS UT_ArrayDestroy ( UT_pARRAY, UT_pfDESTROY, ER_hLIST);
DllSym ST_STATUS UT_ArrayIndDestroy ( UT_pARRAY, UT_pfDESTROY, ER_hLIST);
DllSym ST_STATUS UT_ArrayApply ( UT_pARRAY, UT_pfAPPLY, ER_hLIST);
DllSym ST_STATUS UT_ArrayApplyArg ( UT_pARRAY, UT_pfAPPLYARG, void *arg,
									  ER_hLIST);
DllSym void * UT_ArrayElem ( UT_pARRAY, utindex_t position );
DllSym void * UT_ArrayInd  ( UT_pARRAY, utindex_t position );
DllSym ST_STATUS UT_ArrayAddSorted (UT_pARRAY parray, void* data,
									UT_pfCOMPARE pfcomp, ER_hLIST elist);
									
/* ----------------------------- ut_binfm.c ----------------------------- */
typedef struct UT_BinFormat
{
	char		*name;
	LL_LIST		entries;
	int16_t		flags;
} UT_BinFormat;

UT_BinFormat *UT_NewBinFormat (void);
void 		  UT_DeleteBinFormat (UT_BinFormat* fmt);
UT_BinFormat *UT_LookupBinFormat (char* name, utindex_t *pos);
void 		  UT_InsertBinFormat (char* name, UT_BinFormat* format);
int 		  UT_RemoveBinFormat (char* name);
UT_BinFormat *UT_CreateBinFormat (char* format, char* name, char* errbuf);

typedef struct UT_BinFormatEntry
{
	int8_t				type;
	uint8_t				flags;
	int16_t				length;
	int16_t				offset;
	char				*literal;
	struct UT_BinFormat	*format;
	char				*printf_fmt;
	UT_BinFormat		*repeat_fmt;
} UT_BinFE;

UT_BinFE	*UT_NewBinFormatEntry (void);
ST_STATUS	UT_DeleteBinFormatEntry (void* vfe);
UT_BinFE	*UT_CopyBinFormatEntry (UT_BinFE* fe);

void UT_HexToAscii (char* outbuf, uint8_t* inbuf, int ninput);
void UT_AsciiToHex (uint8_t *outbuf, char* inbuf, int inlength);

int UT_FormatBinBuffer (uint8_t* buffer, int len, UT_BinFormat* format,
						int *argcio, char** argv, char* errbuf);
int UT_ParseBinBuffer (uint8_t* inbuf, uint8_t *outbuf, int inlen, int outlen,
					   UT_BinFormat* format, char* errbuf);



/* ----------------------------- ut_cmd.c ----------------------------- */

DllSym int UT_ValidateCommandArgs (UT_pCMD command, int argc);
DllSym int UT_DoCommand (UT_pCMD command, int argc, char** argv,void* data);
DllSym UT_pCMD UT_FindCommand (UT_pCMD commands, int ncmds, char* name);
DllSym int UT_CmdApropos (UT_pCMD commands, int ncmds, char* pattern,
						  char* outbuf, int buflen);
DllSym int UT_CmdSyntax (UT_pCMD commands, int ncmds, char* pattern,
						 char* outbuf, int buflen);

/* ----------------------------- ut_fmt.c ----------------------------- */

DllSym int UT_ApplyFormatField (char* format, char printf_sub,
								   void* pdata, char* buf);
DllSym UT_pFORMAT UT_MakeFormat (char* fmt_string, char* terminators,
									int printf_ok);
DllSym void UT_FreeFormat (UT_pFORMAT format);

/* ----------------------------- ut_hash.c ----------------------------- */

DllSym UT_hHASHTABLE UT_HashtableCreate (UT_pfHASH x, UT_pfCOMPARE y, 
										 utindex_t size, ER_hLIST z);
DllSym ST_STATUS UT_HashtableAdd (UT_hHASHTABLE, void *key, void *data,
								  ER_hLIST);
DllSym void* UT_HashtableRemove (UT_hHASHTABLE, void *key, ER_hLIST);
DllSym ST_STATUS UT_HashtableDestroy (UT_hHASHTABLE, UT_pfDESTROY,
									  ER_hLIST);
DllSym void * UT_HashtableLookup (UT_hHASHTABLE, void *key, ER_hLIST);
DllSym ST_STATUS UT_HashtableApply (UT_hHASHTABLE, UT_pfAPPLY, ER_hLIST);
DllSym ST_STATUS UT_HashtableApplyArg (UT_hHASHTABLE, UT_pfAPPLYARG, 
									   void *arg, ER_hLIST);
DllSym void* UT_HashtableModify (UT_hHASHTABLE, void *key, void *newdata, 
								 ER_hLIST);
DllSym void* UT_HashtableLinLookup (UT_hHASHTABLE htable, void* arg,
									ER_hLIST elist);
DllSym void UT_HashTableCheck (UT_hHASHTABLE htable);

/* ----------------------------- ut_tern.c ----------------------------- */

typedef struct Tnode 			**UT_hTERNARY;

DllSym UT_hTERNARY UT_TernaryCreate (UT_pfHASH x, UT_pfCOMPARE y,
									 utindex_t size, ER_hLIST z);
DllSym void * UT_TernaryLookup (UT_hTERNARY, const char *key, ER_hLIST);
DllSym ST_STATUS UT_TernaryAdd (UT_hTERNARY, const char *key, void *data,
								ER_hLIST);
DllSym void UT_TernaryApply (UT_hTERNARY, UT_pfAPPLY, ER_hLIST);
DllSym void UT_TernaryApplyArg (UT_hTERNARY, UT_pfAPPLYARG, void *arg,
								ER_hLIST);

/* ----------------------------- ut_lisp.c ----------------------------- */

#ifdef va_end
DllSym ST_STATUS UT_VLispString (char* buffer, int buflen, char* format,
									va_list params);
#endif
DllSym ST_STATUS UT_LispString (char* buffer,int buflen,char* format, ...);
DllSym char* UT_LispParse (char* buffer, int maxargs,int* argc,char** argv);
DllSym UT_TOKEN UT_TokenType (char* s);
DllSym char* UT_ReadLispExpression (char* buf, int buflen, FILE *fptr);

/* ----------------------------- ut_misc.c ----------------------------- */

DllSym utindex_t UT_StringHash (const void* s);
DllSym int UT_HashStringComp (const void* data, const void* key);
DllSym int UT_HashStringSort (const void* c1, const void* c2);
DllSym void* UT_BinarySearch (void** data, utindex_t ndata,
							  UT_pfCOMPARE pfncmp, void *key, utindex_t *pos);
DllSym ST_STATUS UT_StringFields (char* buffer, char* separators,
								  int maxargs, int* argc, char** argv);
DllSym int UT_ClockGetTime (time_t *secs, time_t *nsecs);

/* ----------------------------- ut_usage.c ----------------------------- */

DllSym void UT_Usage(const char* program, const char* usage, FILE* output);
DllSym void UT_Help(const char* program, const char* usage, const char* help);

/* ----------------------------- ut_wild.c ----------------------------- */
DllSym int	UT_WildMatch (char *str, char * pattern);

#ifdef __cplusplus
}
#endif
#endif
