/* maa.h -- Header file for visible libmaa functions * Created: Sun Nov 19 13:21:21 1995 by faith@dict.org * Copyright 1994-1998, 2002 Rickard E. Faith (faith@dict.org) * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #ifndef _MAA_H_ #define _MAA_H_ #include #include #ifndef __GNUC__ #define __attribute__(x) #endif /* If MAA_MAGIC is non-zero, important structures will be tagged with a magic number which will be checked for integrity at each access. This uses up more memory, and is slightly slower, but helps debugging quite a bit. */ #ifndef MAA_MAGIC #define MAA_MAGIC 1 #endif #if MAA_MAGIC #define HSH_MAGIC 0x01020304 #define HSH_MAGIC_FREED 0x10203040 #define SET_MAGIC 0x02030405 #define SET_MAGIC_FREED 0x20304050 #define LST_MAGIC 0x03040506 #define LST_MAGIC_FREED 0x30405060 #define MEM_STRINGS_MAGIC 0x23232323 #define MEM_STRINGS_MAGIC_FREED 0x32323232 #define MEM_OBJECTS_MAGIC 0x42424242 #define MEM_OBJECTS_MAGIC_FREED 0x24242424 #define ARG_MAGIC 0xfeedbead #define ARG_MAGIC_FREED 0xefdeebda #define PR_MAGIC 0x0bad7734 #define PR_MAGIC_FREED 0xb0da7743 #define SL_LIST_MAGIC 0xabcdef01 #define SL_LIST_MAGIC_FREED 0xbadcfe10 #define SL_ENTRY_MAGIC 0xacadfeed #define SL_ENTRY_MAGIC_FREED 0xcadaefde #endif /* version.c */ extern const char *maa_revision_string; /* maa.c */ #define MAA_MEMORY (3U<<30|1<<29) /* Print memory usage statistics at exit */ #define MAA_TIME (3U<<30|1<<28) /* Print timer information at exit */ #define MAA_PR (3U<<30|1<<27) /* Debug process routines */ #define MAA_SL (3U<<30|1<<26) /* Debug skip list routines */ #define MAA_PARSE (3U<<30|1<<25) /* Debug parsing */ #define MAA_SRC (3U<<30|1<<24) /* Source library */ extern void maa_init(const char *programName); extern void maa_shutdown(void); extern int maa_version_major(void); extern int maa_version_minor( void); extern int maa_version_teeny(void); extern const char *maa_version(void); /* xmalloc.c */ extern void *xmalloc(size_t size); extern void *xcalloc(size_t num, size_t size); extern void *xrealloc(void *pt, size_t size); extern void xfree(void *pt); extern char *xstrdup(const char *s); /* bit.c */ extern void bit_set(unsigned long *flags, int bit); extern void bit_clr(unsigned long *flags, int bit); extern int bit_tst(unsigned long *flags, int bit); extern int bit_cnt(unsigned long *flags); /* prime.c */ extern int prm_is_prime(unsigned int value); extern unsigned long prm_next_prime(unsigned int start); /* hash.c */ typedef void *hsh_HashTable; typedef void *hsh_Position; typedef struct hsh_Stats { unsigned long size; /* Size of table */ unsigned long resizings; /* Number of resizings */ unsigned long entries; /* Total entries in table */ unsigned long buckets_used; /* Number of hash buckets in use */ unsigned long singletons; /* Number of length one lists */ unsigned long maximum_length; /* Maximum list length */ unsigned long retrievals; /* Total number of retrievals */ unsigned long hits; /* Number of retrievals from top of a list */ unsigned long misses; /* Number of unsuccessful retrievals */ } *hsh_Stats; extern hsh_HashTable hsh_create(unsigned long (*hash)(const void *), int (*compare)(const void *, const void *)); extern void hsh_destroy(hsh_HashTable table); extern int hsh_insert(hsh_HashTable table, const void *key, const void *datum ); extern int hsh_delete(hsh_HashTable table, const void *key); extern const void *hsh_retrieve(hsh_HashTable table, const void *key); extern int hsh_iterate(hsh_HashTable table, int (*iterator)(const void *key, const void *datum)); extern int hsh_iterate_arg( hsh_HashTable table, int (*iterator)(const void *key, const void *datum, void *arg), void *arg); extern hsh_Stats hsh_get_stats(hsh_HashTable table); extern void hsh_print_stats(hsh_HashTable table, FILE *stream); extern unsigned long hsh_string_hash(const void *key); extern unsigned long hsh_pointer_hash(const void *key); extern int hsh_string_compare(const void *key1, const void *key2); extern int hsh_pointer_compare(const void *key1, const void *key2); extern void hsh_key_strings(hsh_HashTable); extern hsh_Position hsh_init_position(hsh_HashTable table); extern hsh_Position hsh_next_position(hsh_HashTable table, hsh_Position position); extern void *hsh_get_position(hsh_Position position, void **key); extern int hsh_readonly(hsh_HashTable table, int flag); #define HSH_POSITION_INIT(P,T) ((P)=hsh_init_position(T)) #define HSH_POSITION_NEXT(P,T) ((P)=hsh_next_position(T,P)) #define HSH_POSITION_OK(P) (P) #define HSH_POSITION_GET(P,K,D) ((D)=hsh_get_position(P,&K)) #define HSH_POSITION_GETKEY(P,K) (hsh_get_position(P,&K)) /* iterate over all (key, datum) pairs, (K,D), in hash table T */ #define HSH_ITERATE(T,P,K,D) \ for (HSH_POSITION_INIT((P),(T)); \ HSH_POSITION_OK(P) && (HSH_POSITION_GET((P),(K),(D)),1); \ HSH_POSITION_NEXT((P),(T))) /* iterate over all keys K, in hash table T */ #define HSH_ITERATE_KEYS(T,P,K) \ for (HSH_POSITION_INIT((P),(T)); \ HSH_POSITION_OK(P) && (HSH_POSITION_GETKEY((P),(K)),1); \ HSH_POSITION_NEXT((P),(T))) /* If the HSH_ITERATE loop is exited before all elements in the table are seen, then HSH_ITERATE_END should be called. Calling this function after complete loops does no harm. */ #define HSH_ITERATE_END(T) hsh_readonly(T,0) /* set.c */ typedef void *set_Set; typedef void *set_Position; typedef struct set_Stats{ unsigned long size; /* Size of table */ unsigned long resizings; /* Number of resizings */ unsigned long entries; /* Total entries in table */ unsigned long buckets_used; /* Number of hash buckets in use */ unsigned long singletons; /* Number of length one lists */ unsigned long maximum_length; /* Maximum list length */ unsigned long retrievals; /* Total number of retrievals */ unsigned long hits; /* Number of retrievals from top of a list */ unsigned long misses; /* Number of unsuccessful retrievals */ } *set_Stats; typedef unsigned long (*set_HashFunction)(const void *); typedef int (*set_CompareFunction)(const void *, const void *); extern set_Set set_create(set_HashFunction hash, set_CompareFunction compare); extern set_HashFunction set_get_hash(set_Set set); extern set_CompareFunction set_get_compare(set_Set set); extern void set_destroy(set_Set set); extern int set_insert(set_Set set, const void *elem); extern int set_delete(set_Set set, const void *elem); extern int set_member(set_Set set, const void *elem); extern int set_iterate(set_Set set, int (*iterator)(const void *key)); extern int set_iterate_arg(set_Set set, int (*iterator)(const void *elem, void *arg), void *arg); extern set_Set set_add(set_Set set1, set_Set set2); extern set_Set set_del(set_Set set1, set_Set set2); extern set_Set set_union(set_Set set1, set_Set set2); extern set_Set set_inter(set_Set set1, set_Set set2); extern set_Set set_diff(set_Set set1, set_Set set2); extern int set_equal(set_Set set1, set_Set set2); extern set_Stats set_get_stats(set_Set set); extern void set_print_stats(set_Set set, FILE *stream); extern int set_count(set_Set set); extern set_Position set_init_position(set_Set set); extern set_Position set_next_position(set_Set set, set_Position position); extern void *set_get_position(set_Position position); extern int set_readonly(set_Set set, int flag); #define SET_POSITION_INIT(P,S) ((P)=set_init_position(S)) #define SET_POSITION_NEXT(P,S) ((P)=set_next_position(S,P)) #define SET_POSITION_OK(P) (P) #define SET_POSITION_GET(P,E) ((E)=set_get_position(P)) /* iterate over all entries E in set S */ #define SET_ITERATE(S,P,E) \ for (SET_POSITION_INIT((P),(S)); \ SET_POSITION_OK(P) && (SET_POSITION_GET((P),(E)),1); \ SET_POSITION_NEXT((P),(S))) /* If the SET_ITERATE loop is exited before all elements in the set are seen, then SET_ITERATE_END should be called. Calling this function after complete loops does no harm. */ #define SET_ITERATE_END(S) set_readonly(S,0) /* stack.c */ typedef void *stk_Stack; extern stk_Stack stk_create(void); extern void stk_destroy(stk_Stack stack); extern void stk_push(stk_Stack stack, void *datum); extern void *stk_pop(stk_Stack stack); extern void *stk_top(stk_Stack stack); extern int stk_isempty(stk_Stack stack); /* list.c */ typedef void *lst_List; typedef void *lst_Position; extern lst_List lst_create(void); extern void lst_destroy(lst_List list); extern void lst_append(lst_List list, const void *datum); extern void lst_push(lst_List list, const void *datum); extern void *lst_pop(lst_List list ); extern void *lst_top(lst_List list ); extern void *lst_nth_get(lst_List list, unsigned int n); extern void lst_nth_set(lst_List list, unsigned int n, const void *datum); extern int lst_member(lst_List list, const void *datum); extern unsigned int lst_length(lst_List list ); extern int lst_iterate(lst_List list, int (*iterator)(const void *datum)); extern int lst_iterate_arg(lst_List list, int (*iterator)(const void *datum, void *arg), void *arg); extern void lst_truncate(lst_List list, unsigned int length); extern void lst_truncate_position(lst_List list, lst_Position position); extern lst_Position lst_init_position(lst_List list); extern lst_Position lst_last_position(lst_List list); extern lst_Position lst_next_position(lst_Position position); extern lst_Position lst_nth_position( lst_List list, unsigned int n); extern void *lst_get_position(lst_Position position); extern void lst_set_position(lst_Position position, const void *datum); extern void lst_dump(lst_List list); extern void _lst_shutdown(void); extern long int lst_total_allocated(void); #define LST_POSITION_INIT(P,L) ((P)=lst_init_position(L)) #define LST_POSITION_NEXT(P) ((P)=lst_next_position(P)) #define LST_POSITION_OK(P) (P) #define LST_POSITION_GET(P,E) ((E)=lst_get_position(P)) /* iterate over all entries E in list L */ #define LST_ITERATE(L,P,E) \ for (LST_POSITION_INIT((P),(L)); \ LST_POSITION_OK(P) && (LST_POSITION_GET((P),(E)),1); \ LST_POSITION_NEXT(P)) /* iterate over all entries in lists L1 and L2 */ #define LST_ITERATE2(L1,L2,P1,P2,E1,E2) \ for (LST_POSITION_INIT((P1),(L1)), LST_POSITION_INIT((P2),(L2)); \ LST_POSITION_OK(P1) && LST_POSITION_OK(P2) \ && (LST_POSITION_GET((P1),(E1)),LST_POSITION_GET((P2),(E2)),1); \ LST_POSITION_NEXT(P1), LST_POSITION_NEXT(P2)) /* error.c */ extern void err_set_program_name(const char *programName); extern const char *err_program_name(void); extern void err_fatal(const char *routine, const char *format, ...) __attribute__((noreturn,format(printf, 2, 3))); extern void err_fatal_errno(const char *routine, const char *format, ...) __attribute__((noreturn,format(printf, 2, 3))); extern void err_warning(const char *routine, const char *format, ...) __attribute__((format(printf, 2, 3))); extern void err_internal(const char *routine, const char *format, ...) __attribute__((noreturn,format(printf, 2, 3))); /* memory.c */ typedef void *mem_String; typedef void *mem_Object; typedef struct mem_StringStats { int count; /* Number of strings or objects */ int bytes; /* Number of bytes allocated */ } *mem_StringStats; typedef struct mem_ObjectStats { int total; /* Total objects requested */ int used; /* Total currently in use */ int reused; /* Total reused */ int size; /* Size of each object */ } *mem_ObjectStats; extern mem_String mem_create_strings(void); extern void mem_destroy_strings(mem_String info); extern const char *mem_strcpy(mem_String info, const char *string); extern const char *mem_strncpy(mem_String info, const char *string, int len); extern void mem_grow(mem_String info, const char *string, int len); extern const char *mem_finish(mem_String info); extern mem_StringStats mem_get_string_stats(mem_String info); extern void mem_print_string_stats(mem_String info, FILE *stream); extern mem_Object mem_create_objects(int size); extern void mem_destroy_objects(mem_Object info); extern void *mem_get_object(mem_Object info); extern void *mem_get_empty_object(mem_Object info); extern void mem_free_object(mem_Object info, void *obj); extern mem_ObjectStats mem_get_object_stats(mem_Object info); extern void mem_print_object_stats(mem_Object info, FILE *stream); /* string.c */ typedef void *str_Pool; typedef hsh_Position str_Position; typedef struct str_Stats { int count; /* Number of strings created */ int bytes; /* Number of bytes allocated */ int retrievals; /* Total number of retrievals */ int hits; /* Number of retrievals from top of a list */ int misses; /* Number of unsuccessful retrievals */ } *str_Stats; extern str_Pool str_pool_create(void); extern void str_pool_destroy(str_Pool pool); extern int str_pool_exists(str_Pool pool, const char *s); extern const char *str_pool_find(str_Pool pool, const char *s); extern const char *str_pool_copy(str_Pool pool, const char *s); extern const char *str_pool_copyn(str_Pool pool, const char *s, int length); extern void str_pool_grow(str_Pool pool, const char *s, int length); extern const char *str_pool_finish(str_Pool pool); extern str_Stats str_pool_get_stats(str_Pool pool); extern void str_pool_print_stats(str_Pool pool, FILE *stream); extern str_Position str_pool_init_position(str_Pool table); extern str_Position str_pool_next_position( str_Pool table, str_Position position); extern void str_pool_get_position( str_Position position, char const *const *key); #define str_pool_readonly(pool, flag) hsh_readonly ((pool), (flag)) extern int str_pool_iterate( str_Pool pool, int (*iterator)( const char *s ) ); extern int str_pool_iterate_arg( str_Pool pool, int (*iterator)( const char *s, void *arg ), void *arg ); #define STR_POSITION_INIT(P,T) ((P)=str_pool_init_position(T)) #define STR_POSITION_NEXT(P,T) ((P)=str_pool_next_position(T,P)) #define STR_POSITION_OK(P) (P) #define STR_POSITION_GET(P,K) (str_pool_get_position(P,&K), K) /* iterate over all keys (K) in string pool T */ #define STR_ITERATE(T,P,K) \ for (STR_POSITION_INIT((P),(T)); \ STR_POSITION_OK(P) && (STR_POSITION_GET((P),(K)),1); \ STR_POSITION_NEXT((P),(T))) /* If the STR_ITERATE loop is exited before all elements in the table are seen, then STR_ITERATE_END should be called. Calling this function after complete loops does no harm. */ #define STR_ITERATE_END(T) str_readonly(T,0) extern int str_exists(const char *s); extern const char *str_find(const char *s); extern const char *str_findn(const char *s, int length); extern const char *str_copy(const char *s); extern const char *str_copyn(const char *s, int length); extern void str_grow(const char *s, int length); extern const char *str_finish(void); extern const char *str_unique(const char *prefix); extern void str_destroy(void); extern str_Stats str_get_stats(void); extern void str_print_stats(FILE *stream); /* debug.c */ typedef unsigned long int dbg_Type; extern void dbg_register(dbg_Type flag, const char *name); extern void _dbg_register(dbg_Type flag, const char *name); extern void dbg_destroy(void); extern void dbg_set(const char *name); extern void dbg_set_flag(dbg_Type flag); extern void dbg_unset_flag(dbg_Type flag); extern int dbg_test(dbg_Type flag); extern void dbg_list(FILE *stream); #define PRINTF(flag,arg) if (dbg_test(flag)) { log_info arg; } /* flags.c */ typedef unsigned long int flg_Type; extern void flg_register(flg_Type flag, const char *name); extern void flg_destroy(void); extern void flg_set(const char *name); extern int flg_test(flg_Type flag); extern void flg_list(FILE *stream); extern const char *flg_name(flg_Type flag); /* timer.c */ extern void tim_start(const char *name); extern void tim_stop(const char *name); extern void tim_reset(const char *name); extern double tim_get_real(const char *name); extern double tim_get_user(const char *name); extern double tim_get_system(const char *name); extern void tim_print_timer(FILE *str, const char *name); extern void tim_print_timers(FILE *str); extern void _tim_shutdown(void); /* arg.c */ #define ARG_NO_ESCAPE 0x0001 /* Backslashed are not escape characters */ #define ARG_NO_QUOTE 0x0002 /* Don't use quote marks for quoting */ typedef void *arg_List; extern arg_List arg_create(void); extern void arg_destroy(arg_List arg); extern arg_List arg_add(arg_List arg, const char *string); extern arg_List arg_addn(arg_List arg, const char *string, int length); extern void arg_grow(arg_List arg, const char *string, int length); extern arg_List arg_finish(arg_List arg); extern const char *arg_get(arg_List arg, int item); extern int arg_count(arg_List arg); extern void arg_get_vector(arg_List arg, int *argc, char ***argv); extern arg_List arg_argify(const char *string, int quoteStyle); /* pr.c */ #define PR_USE_STDIN 0x00000001 #define PR_USE_STDOUT 0x00000002 #define PR_USE_STDERR 0x00000004 #define PR_CREATE_STDIN 0x00000010 #define PR_CREATE_STDOUT 0x00000020 #define PR_CREATE_STDERR 0x00000040 #define PR_STDERR_TO_STDOUT 0x00000100 extern int pr_open2(const char *command, void(*callback)(void), int flags, int *infd, int *outfd, int *errfd); extern int pr_open(const char *command, int flags, int *infd, int *outfd, int *errfd); extern int pr_close_nowait(int fd); extern int pr_close(int fd); extern int pr_wait(int pid); extern void _pr_shutdown(void); extern int pr_spawn(const char *command); int pr_readwrite(int in, int out, const char *inBuffer, int inLen, char *outBuffer, int outMaxLen); int pr_filter(const char *command, const char *inBuffer, int inLen, char *outBuffer, int outMaxLen); /* sl.c */ typedef void *sl_List; typedef int (*sl_Iterator)(const void *datum); typedef int (*sl_IteratorArg)(const void *datum, void *arg); extern sl_List sl_create( int (*compare)(const void *key1, const void *key2), const void *(*key)(const void *datum), const char *(*print)(const void *datum) ); extern void sl_destroy(sl_List list); extern void _sl_shutdown(void); extern void sl_insert(sl_List list, const void *datum); extern void sl_delete(sl_List list, const void *datum); extern const void *sl_find(sl_List list, const void *key); extern int sl_iterate(sl_List list, sl_Iterator f); extern int sl_iterate_arg(sl_List list, sl_IteratorArg f, void *arg); extern void _sl_dump(sl_List list); /* text.c */ extern const char * txt_soundex(const char *string); extern void txt_soundex2( const char *string, char *result /* five chars */); /* base64.c */ extern const char *b64_encode(unsigned long val); extern unsigned long b64_decode(const char *val); extern unsigned long b64_decode_buf(const char *val, size_t len); /* base26.c */ extern const char *b26_encode(unsigned long val); extern unsigned long b26_decode(const char *val); /* source.c */ typedef void *src_Type; typedef struct src_Stats { int lines_used; /* Lines used */ int lines_allocated; /* Lines allocated */ int lines_bytes; /* Bytes required to store lines */ int tokens_total; /* Tokens used */ int tokens_reused; /* Tokens reused */ int tokens_size; /* Size of a token information object */ } *src_Stats; extern void src_create(void); extern void src_destroy(void); extern const char *src_line(const char *line, int len); extern void src_new_file(const char *filename); extern void src_new_line(int line); extern void src_advance(int length); extern void src_cpp_line(const char *line, int length); extern src_Type src_get(int length); extern const char *src_filename(src_Type source); extern int src_linenumber(src_Type source); extern int src_offset(src_Type source); extern int src_length(src_Type source); extern const char *src_source_line(src_Type source); extern void src_parse_error(FILE *stream, src_Type source, const char *message); extern void src_print_error(FILE *stream, src_Type source, const char *format, ...); extern void src_print_message(FILE *str, src_Type source, const char *format, ...); extern void src_print_line(FILE *stream, src_Type source); extern src_Stats src_get_stats(void); extern void src_print_stats(FILE *stream); /* parse-concrete.c */ extern void prs_register_concrete(const char *symbol, const char *concrete); extern const char *prs_concrete(const char *symbol); extern void _prs_shutdown(void); /* log.c */ #define LOG_OPTION_FULL 1 #define LOG_OPTION_NO_FULL 2 extern void log_syslog(const char *ident); extern void log_set_facility(const char *facility); extern const char *log_get_facility(void); extern void log_option(int option); extern void log_file(const char *ident, const char *filename); extern void log_stream(const char *ident, FILE *stream); extern void log_close(void); extern void log_error_va(const char *routine, const char *format, va_list ap); extern void log_error(const char *routine, const char *format, ...); extern void log_info_va(const char *format, va_list ap); extern void log_info(const char *format, ...); #endif