fixed print_formatted() to use hcl_outfmtobj() instead of hcl_print().
added 2 new optional callbacks - vmprim.alloc_heap and vmprim.free_heap
This commit is contained in:
		@ -321,7 +321,6 @@ void hcl_seterrwithsyserr (hcl_t* hcl, int syserr)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
void hcl_getsynerr (hcl_t* hcl, hcl_synerr_t* synerr)
 | 
					void hcl_getsynerr (hcl_t* hcl, hcl_synerr_t* synerr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	HCL_ASSERT (hcl, hcl->c != HCL_NULL);
 | 
						HCL_ASSERT (hcl, hcl->c != HCL_NULL);
 | 
				
			||||||
@ -445,7 +444,6 @@ void hcl_assertfailed (hcl_t* hcl, const hcl_bch_t* expr, const hcl_bch_t* file,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	hcl_logbfmt (hcl, HCL_LOG_UNTYPED | HCL_LOG_FATAL, "ASSERTION FAILURE: %s at %s:%zu\n", expr, file, line);
 | 
						hcl_logbfmt (hcl, HCL_LOG_UNTYPED | HCL_LOG_FATAL, "ASSERTION FAILURE: %s at %s:%zu\n", expr, file, line);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(HAVE_BACKTRACE)
 | 
					#if defined(HAVE_BACKTRACE)
 | 
				
			||||||
	btsize = backtrace (btarray, HCL_COUNTOF(btarray));
 | 
						btsize = backtrace (btarray, HCL_COUNTOF(btarray));
 | 
				
			||||||
	btsyms = backtrace_symbols (btarray, btsize);
 | 
						btsyms = backtrace_symbols (btarray, btsize);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										24
									
								
								lib/hcl.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								lib/hcl.c
									
									
									
									
									
								
							@ -83,6 +83,16 @@ static void fill_bigint_tables (hcl_t* hcl)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void* alloc_heap (hcl_t* hcl, hcl_oow_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return HCL_MMGR_ALLOC(hcl->mmgr, size);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void free_heap (hcl_t* hcl, void* ptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return HCL_MMGR_FREE(hcl->mmgr, ptr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int hcl_init (hcl_t* hcl, hcl_mmgr_t* mmgr, hcl_oow_t heapsz, const hcl_vmprim_t* vmprim)
 | 
					int hcl_init (hcl_t* hcl, hcl_mmgr_t* mmgr, hcl_oow_t heapsz, const hcl_vmprim_t* vmprim)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int modtab_inited = 0;
 | 
						int modtab_inited = 0;
 | 
				
			||||||
@ -97,6 +107,8 @@ int hcl_init (hcl_t* hcl, hcl_mmgr_t* mmgr, hcl_oow_t heapsz, const hcl_vmprim_t
 | 
				
			|||||||
	hcl->mmgr = mmgr;
 | 
						hcl->mmgr = mmgr;
 | 
				
			||||||
	hcl->cmgr = hcl_getutf8cmgr();
 | 
						hcl->cmgr = hcl_getutf8cmgr();
 | 
				
			||||||
	hcl->vmprim = *vmprim;
 | 
						hcl->vmprim = *vmprim;
 | 
				
			||||||
 | 
						if (!hcl->vmprim.alloc_heap) hcl->vmprim.alloc_heap = alloc_heap;
 | 
				
			||||||
 | 
						if (!hcl->vmprim.free_heap) hcl->vmprim.free_heap = free_heap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hcl->option.log_mask = ~0u;
 | 
						hcl->option.log_mask = ~0u;
 | 
				
			||||||
	hcl->option.log_maxcapa = HCL_DFL_LOG_MAXCAPA;
 | 
						hcl->option.log_maxcapa = HCL_DFL_LOG_MAXCAPA;
 | 
				
			||||||
@ -113,19 +125,19 @@ int hcl_init (hcl_t* hcl, hcl_mmgr_t* mmgr, hcl_oow_t heapsz, const hcl_vmprim_t
 | 
				
			|||||||
	 * routine still function despite some side-effects when
 | 
						 * routine still function despite some side-effects when
 | 
				
			||||||
	 * reallocation fails */
 | 
						 * reallocation fails */
 | 
				
			||||||
	/* +1 required for consistency with put_oocs and put_ooch in logfmt.c */
 | 
						/* +1 required for consistency with put_oocs and put_ooch in logfmt.c */
 | 
				
			||||||
	hcl->log.ptr = (hcl_ooch_t*)hcl_allocmem (hcl, (hcl->log.capa + 1) * HCL_SIZEOF(*hcl->log.ptr)); 
 | 
						hcl->log.ptr = (hcl_ooch_t*)hcl_allocmem(hcl, (hcl->log.capa + 1) * HCL_SIZEOF(*hcl->log.ptr)); 
 | 
				
			||||||
	if (!hcl->log.ptr) goto oops;
 | 
						if (!hcl->log.ptr) goto oops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*hcl->permheap = hcl_makeheap (hcl, what is the best size???);
 | 
						/*hcl->permheap = hcl_makeheap (hcl, what is the best size???);
 | 
				
			||||||
	if (!hcl->curheap) goto oops; */
 | 
						if (!hcl->curheap) goto oops; */
 | 
				
			||||||
	hcl->curheap = hcl_makeheap (hcl, heapsz);
 | 
						hcl->curheap = hcl_makeheap(hcl, heapsz);
 | 
				
			||||||
	if (!hcl->curheap) goto oops;
 | 
						if (!hcl->curheap) goto oops;
 | 
				
			||||||
	hcl->newheap = hcl_makeheap (hcl, heapsz);
 | 
						hcl->newheap = hcl_makeheap(hcl, heapsz);
 | 
				
			||||||
	if (!hcl->newheap) goto oops;
 | 
						if (!hcl->newheap) goto oops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (hcl_rbt_init (&hcl->modtab, hcl, HCL_SIZEOF(hcl_ooch_t), 1) <= -1) goto oops;
 | 
						if (hcl_rbt_init(&hcl->modtab, hcl, HCL_SIZEOF(hcl_ooch_t), 1) <= -1) goto oops;
 | 
				
			||||||
	modtab_inited = 1;
 | 
						modtab_inited = 1;
 | 
				
			||||||
	hcl_rbt_setstyle (&hcl->modtab, hcl_getrbtstyle(HCL_RBT_STYLE_INLINE_COPIERS));
 | 
						hcl_rbt_setstyle(&hcl->modtab, hcl_getrbtstyle(HCL_RBT_STYLE_INLINE_COPIERS));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fill_bigint_tables (hcl);
 | 
						fill_bigint_tables (hcl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -241,7 +253,7 @@ void hcl_fini (hcl_t* hcl)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	hcl_killheap (hcl, hcl->newheap);
 | 
						hcl_killheap (hcl, hcl->newheap);
 | 
				
			||||||
	hcl_killheap (hcl, hcl->curheap);
 | 
						hcl_killheap (hcl, hcl->curheap);
 | 
				
			||||||
	hcl_killheap (hcl, hcl->permheap);
 | 
						if (hcl->permheap) hcl_killheap (hcl, hcl->permheap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (hcl->log.ptr) 
 | 
						if (hcl->log.ptr) 
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										31
									
								
								lib/hcl.h
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								lib/hcl.h
									
									
									
									
									
								
							@ -686,6 +686,14 @@ struct hcl_heap_t
 | 
				
			|||||||
/* =========================================================================
 | 
					/* =========================================================================
 | 
				
			||||||
 * VIRTUAL MACHINE PRIMITIVES
 | 
					 * VIRTUAL MACHINE PRIMITIVES
 | 
				
			||||||
 * ========================================================================= */
 | 
					 * ========================================================================= */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef void* (*hcl_alloc_heap_t) (hcl_t* hcl, hcl_oow_t size);
 | 
				
			||||||
 | 
					typedef void (*hcl_free_heap_t) (hcl_t* hcl, void* ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef void (*hcl_log_write_t) (hcl_t* hcl, int mask, const hcl_ooch_t* msg, hcl_oow_t len);
 | 
				
			||||||
 | 
					typedef void (*hcl_syserrstrb_t) (hcl_t* hcl, int syserr, hcl_bch_t* buf, hcl_oow_t len);
 | 
				
			||||||
 | 
					typedef void (*hcl_syserrstru_t) (hcl_t* hcl, int syserr, hcl_uch_t* buf, hcl_oow_t len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum hcl_vmprim_opendl_flag_t
 | 
					enum hcl_vmprim_opendl_flag_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	HCL_VMPRIM_OPENDL_PFMOD = (1 << 0)
 | 
						HCL_VMPRIM_OPENDL_PFMOD = (1 << 0)
 | 
				
			||||||
@ -696,27 +704,34 @@ typedef void* (*hcl_vmprim_dlopen_t) (hcl_t* hcl, const hcl_ooch_t* name, int fl
 | 
				
			|||||||
typedef void (*hcl_vmprim_dlclose_t) (hcl_t* hcl, void* handle);
 | 
					typedef void (*hcl_vmprim_dlclose_t) (hcl_t* hcl, void* handle);
 | 
				
			||||||
typedef void* (*hcl_vmprim_dlgetsym_t) (hcl_t* hcl, void* handle, const hcl_ooch_t* name);
 | 
					typedef void* (*hcl_vmprim_dlgetsym_t) (hcl_t* hcl, void* handle, const hcl_ooch_t* name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef void (*hcl_log_write_t) (hcl_t* hcl, int mask, const hcl_ooch_t* msg, hcl_oow_t len);
 | 
					 | 
				
			||||||
typedef void (*hcl_syserrstrb_t) (hcl_t* hcl, int syserr, hcl_bch_t* buf, hcl_oow_t len);
 | 
					 | 
				
			||||||
typedef void (*hcl_syserrstru_t) (hcl_t* hcl, int syserr, hcl_uch_t* buf, hcl_oow_t len);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef int (*hcl_vmprim_startup_t) (hcl_t* hcl);
 | 
					typedef int (*hcl_vmprim_startup_t) (hcl_t* hcl);
 | 
				
			||||||
typedef void (*hcl_vmprim_cleanup_t) (hcl_t* hcl);
 | 
					typedef void (*hcl_vmprim_cleanup_t) (hcl_t* hcl);
 | 
				
			||||||
typedef void (*hcl_vmprim_gettime_t) (hcl_t* hcl, hcl_ntime_t* now);
 | 
					typedef void (*hcl_vmprim_gettime_t) (hcl_t* hcl, hcl_ntime_t* now);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef void (*hcl_vmprim_sleep_t) (hcl_t* hcl, const hcl_ntime_t* duration);
 | 
					typedef void (*hcl_vmprim_sleep_t) (hcl_t* hcl, const hcl_ntime_t* duration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct hcl_vmprim_t
 | 
					struct hcl_vmprim_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hcl_vmprim_dlopen_t   dl_open;
 | 
						/* The alloc_heap callback function is called very earlier
 | 
				
			||||||
	hcl_vmprim_dlclose_t  dl_close;
 | 
						 * before hcl is fully initialized. so few features are availble
 | 
				
			||||||
	hcl_vmprim_dlgetsym_t dl_getsym;
 | 
						 * in this callback function. If it's not provided, the default
 | 
				
			||||||
 | 
						 * implementation is used. */
 | 
				
			||||||
 | 
						hcl_alloc_heap_t      alloc_heap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* If you customize the heap allocator by providing the alloc_heap
 | 
				
			||||||
 | 
						 * callback, you should implement the heap freer. otherwise the default
 | 
				
			||||||
 | 
						 * implementation doesn't know how to free the heap allocated by 
 | 
				
			||||||
 | 
						 * the allocator callback. */
 | 
				
			||||||
 | 
						hcl_free_heap_t       free_heap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hcl_log_write_t       log_write;
 | 
						hcl_log_write_t       log_write;
 | 
				
			||||||
	hcl_syserrstrb_t      syserrstrb;
 | 
						hcl_syserrstrb_t      syserrstrb;
 | 
				
			||||||
	hcl_syserrstru_t      syserrstru;
 | 
						hcl_syserrstru_t      syserrstru;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hcl_vmprim_dlopen_t   dl_open;
 | 
				
			||||||
 | 
						hcl_vmprim_dlclose_t  dl_close;
 | 
				
			||||||
 | 
						hcl_vmprim_dlgetsym_t dl_getsym;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hcl_vmprim_startup_t  vm_startup;
 | 
						hcl_vmprim_startup_t  vm_startup;
 | 
				
			||||||
	hcl_vmprim_cleanup_t  vm_cleanup;
 | 
						hcl_vmprim_cleanup_t  vm_cleanup;
 | 
				
			||||||
	hcl_vmprim_gettime_t  vm_gettime;
 | 
						hcl_vmprim_gettime_t  vm_gettime;
 | 
				
			||||||
 | 
				
			|||||||
@ -30,7 +30,7 @@ hcl_heap_t* hcl_makeheap (hcl_t* hcl, hcl_oow_t size)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	hcl_heap_t* heap;
 | 
						hcl_heap_t* heap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	heap = (hcl_heap_t*)HCL_MMGR_ALLOC(hcl->mmgr, HCL_SIZEOF(*heap) + size);
 | 
						heap = (hcl_heap_t*)hcl->vmprim.alloc_heap(hcl, HCL_SIZEOF(*heap) + size);
 | 
				
			||||||
	if (!heap)
 | 
						if (!heap)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		hcl_seterrnum (hcl, HCL_ESYSMEM);
 | 
							hcl_seterrnum (hcl, HCL_ESYSMEM);
 | 
				
			||||||
@ -58,7 +58,7 @@ hcl_heap_t* hcl_makeheap (hcl_t* hcl, hcl_oow_t size)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void hcl_killheap (hcl_t* hcl, hcl_heap_t* heap)
 | 
					void hcl_killheap (hcl_t* hcl, hcl_heap_t* heap)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	HCL_MMGR_FREE (hcl->mmgr, heap);
 | 
						hcl->vmprim.free_heap (hcl, heap);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void* hcl_allocheapmem (hcl_t* hcl, hcl_heap_t* heap, hcl_oow_t size)
 | 
					void* hcl_allocheapmem (hcl_t* hcl, hcl_heap_t* heap, hcl_oow_t size)
 | 
				
			||||||
 | 
				
			|||||||
@ -771,18 +771,16 @@ static HCL_INLINE int print_formatted (hcl_t* hcl, hcl_ooi_t nargs, hcl_fmtout_t
 | 
				
			|||||||
	arg = HCL_STACK_GETARG(hcl, nargs, 0);
 | 
						arg = HCL_STACK_GETARG(hcl, nargs, 0);
 | 
				
			||||||
	if (!HCL_OOP_IS_POINTER(arg) || HCL_OBJ_GET_FLAGS_TYPE(arg) != HCL_OBJ_TYPE_CHAR)
 | 
						if (!HCL_OOP_IS_POINTER(arg) || HCL_OBJ_GET_FLAGS_TYPE(arg) != HCL_OBJ_TYPE_CHAR)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
		hcl_ooi_t i;
 | 
							hcl_ooi_t i;
 | 
				
			||||||
		/* if the first argument is not a valid formatting string, 
 | 
							/* if the first argument is not a valid formatting string, 
 | 
				
			||||||
		 * print all arguments as objects */
 | 
							 * print all arguments as objects */
 | 
				
			||||||
		if (hcl_print(hcl, arg) <= -1) goto oops;
 | 
							if (hcl_outfmtobj(hcl, data->mask, arg, outbfmt) <= -1) goto oops;
 | 
				
			||||||
		for (i = 1; i < nargs; i++)
 | 
							for (i = 1; i < nargs; i++)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			arg = HCL_STACK_GETARG(hcl, nargs, i);
 | 
								arg = HCL_STACK_GETARG(hcl, nargs, i);
 | 
				
			||||||
			if (hcl_print(hcl, arg) <= -1) goto oops;
 | 
								if (hcl_outfmtobj(hcl, data->mask, arg, outbfmt) <= -1) goto oops;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fmt = HCL_OBJ_GET_CHAR_SLOT(arg);
 | 
						fmt = HCL_OBJ_GET_CHAR_SLOT(arg);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										411
									
								
								lib/main.c
									
									
									
									
									
								
							
							
						
						
									
										411
									
								
								lib/main.c
									
									
									
									
									
								
							@ -88,6 +88,7 @@
 | 
				
			|||||||
#	include <unistd.h>
 | 
					#	include <unistd.h>
 | 
				
			||||||
#	include <fcntl.h>
 | 
					#	include <fcntl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#	include <sys/mman.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(HCL_DEFAULT_PFMODPREFIX)
 | 
					#if !defined(HCL_DEFAULT_PFMODPREFIX)
 | 
				
			||||||
@ -146,14 +147,16 @@ struct xtn_t
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* ========================================================================= */
 | 
					/* ========================================================================= */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MB_1 (256UL*1024*1024)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void* sys_alloc (hcl_mmgr_t* mmgr, hcl_oow_t size)
 | 
					static void* sys_alloc (hcl_mmgr_t* mmgr, hcl_oow_t size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return malloc (size);
 | 
						return malloc(size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void* sys_realloc (hcl_mmgr_t* mmgr, void* ptr, hcl_oow_t size)
 | 
					static void* sys_realloc (hcl_mmgr_t* mmgr, void* ptr, hcl_oow_t size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return realloc (ptr, size);
 | 
						return realloc(ptr, size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void sys_free (hcl_mmgr_t* mmgr, void* ptr)
 | 
					static void sys_free (hcl_mmgr_t* mmgr, void* ptr)
 | 
				
			||||||
@ -378,7 +381,7 @@ static HCL_INLINE hcl_ooi_t close_output (hcl_t* hcl, hcl_iooutarg_t* arg)
 | 
				
			|||||||
	fp = (FILE*)arg->handle;
 | 
						fp = (FILE*)arg->handle;
 | 
				
			||||||
	HCL_ASSERT (hcl, fp != HCL_NULL);
 | 
						HCL_ASSERT (hcl, fp != HCL_NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fclose (fp);
 | 
						if (fp != stdout) fclose (fp);
 | 
				
			||||||
	arg->handle = HCL_NULL;
 | 
						arg->handle = HCL_NULL;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -395,18 +398,18 @@ static HCL_INLINE hcl_ooi_t write_output (hcl_t* hcl, hcl_iooutarg_t* arg)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	do 
 | 
						do 
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
#if defined(HCL_OOCH_IS_UCH)
 | 
						#if defined(HCL_OOCH_IS_UCH)
 | 
				
			||||||
		bcslen = HCL_COUNTOF(bcsbuf);
 | 
							bcslen = HCL_COUNTOF(bcsbuf);
 | 
				
			||||||
		ucslen = arg->len - donelen;
 | 
							ucslen = arg->len - donelen;
 | 
				
			||||||
		x = hcl_convootobchars (hcl, &arg->ptr[donelen], &ucslen, bcsbuf, &bcslen);
 | 
							x = hcl_convootobchars (hcl, &arg->ptr[donelen], &ucslen, bcsbuf, &bcslen);
 | 
				
			||||||
		if (x <= -1 && ucslen <= 0) return -1;
 | 
							if (x <= -1 && ucslen <= 0) return -1;
 | 
				
			||||||
#else
 | 
						#else
 | 
				
			||||||
		bcslen = HCL_COUNTOF(bcsbuf);
 | 
							bcslen = HCL_COUNTOF(bcsbuf);
 | 
				
			||||||
		ucslen = arg->len - donelen;
 | 
							ucslen = arg->len - donelen;
 | 
				
			||||||
		if (ucslen > bcslen) ucslen = bcslen;
 | 
							if (ucslen > bcslen) ucslen = bcslen;
 | 
				
			||||||
		else if (ucslen < bcslen) bcslen = ucslen;
 | 
							else if (ucslen < bcslen) bcslen = ucslen;
 | 
				
			||||||
		hcl_copybchars (bcsbuf, &arg->ptr[donelen], bcslen);
 | 
							hcl_copybchars (bcsbuf, &arg->ptr[donelen], bcslen);
 | 
				
			||||||
#endif
 | 
						#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (fwrite (bcsbuf, HCL_SIZEOF(bcsbuf[0]), bcslen, (FILE*)arg->handle) < bcslen)
 | 
							if (fwrite (bcsbuf, HCL_SIZEOF(bcsbuf[0]), bcslen, (FILE*)arg->handle) < bcslen)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@ -442,6 +445,212 @@ static hcl_ooi_t print_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* ========================================================================= */
 | 
					/* ========================================================================= */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void* alloc_heap (hcl_t* hcl, hcl_oow_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* It's called when HCL creates a GC heap.
 | 
				
			||||||
 | 
						 * The heap is large in size. I can use a different memory allocation
 | 
				
			||||||
 | 
						 * function instead of an ordinary malloc */
 | 
				
			||||||
 | 
						hcl_oow_t* ptr;
 | 
				
			||||||
 | 
						int flags;
 | 
				
			||||||
 | 
						hcl_oow_t actual_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB;
 | 
				
			||||||
 | 
					#if defined(MAP_UNINITIALIZED)
 | 
				
			||||||
 | 
						flags |= MAP_UNINITIALIZED;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						actual_size = HCL_SIZEOF(hcl_oow_t) + size;
 | 
				
			||||||
 | 
						actual_size = HCL_ALIGN_POW2(actual_size, 2 * 1024 * 1024);
 | 
				
			||||||
 | 
						ptr = (hcl_oow_t*)mmap(NULL, actual_size, PROT_READ | PROT_WRITE, flags, -1, 0);
 | 
				
			||||||
 | 
						if (ptr == MAP_FAILED) 
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							flags &= ~MAP_HUGETLB;
 | 
				
			||||||
 | 
							ptr = (hcl_oow_t*)mmap(NULL, actual_size, PROT_READ | PROT_WRITE, flags, -1, 0);
 | 
				
			||||||
 | 
							if (ptr == MAP_FAILED) return HCL_NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						*ptr = size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (void*)(ptr + 1);
 | 
				
			||||||
 | 
						/*return HCL_MMGR_ALLOC(hcl->mmgr, size);*/
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void free_heap (hcl_t* hcl, void* ptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						hcl_oow_t* actual_ptr;
 | 
				
			||||||
 | 
						actual_ptr = (hcl_oow_t*)ptr - 1;
 | 
				
			||||||
 | 
						munmap (actual_ptr, *actual_ptr);
 | 
				
			||||||
 | 
						/*return HCL_MMGR_FREE(hcl->mmgr, ptr);*/
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int write_all (int fd, const char* ptr, hcl_oow_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						while (len > 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							hcl_ooi_t wr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wr = write (1, ptr, len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (wr <= -1)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							#if defined(EAGAIN) && defined(EWOULDBLOCK) && (EAGAIN == EWOULDBLOCK)
 | 
				
			||||||
 | 
								if (errno == EAGAIN) continue;
 | 
				
			||||||
 | 
							#else
 | 
				
			||||||
 | 
								#	if defined(EAGAIN)
 | 
				
			||||||
 | 
								if (errno == EAGAIN) continue;
 | 
				
			||||||
 | 
								#elif defined(EWOULDBLOCK)
 | 
				
			||||||
 | 
								if (errno == EWOULDBLOCK) continue;
 | 
				
			||||||
 | 
								#endif
 | 
				
			||||||
 | 
							#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							#if defined(EINTR)
 | 
				
			||||||
 | 
								/* TODO: would this interfere with non-blocking nature of this VM? */
 | 
				
			||||||
 | 
								if (errno == EINTR) continue;
 | 
				
			||||||
 | 
							#endif
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ptr += wr;
 | 
				
			||||||
 | 
							len -= wr;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void log_write (hcl_t* hcl, int mask, const hcl_ooch_t* msg, hcl_oow_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined(_WIN32)
 | 
				
			||||||
 | 
					#	error NOT IMPLEMENTED 
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					#elif defined(macintosh)
 | 
				
			||||||
 | 
					#	error NOT IMPLEMENTED
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						hcl_bch_t buf[256];
 | 
				
			||||||
 | 
						hcl_oow_t ucslen, bcslen, msgidx;
 | 
				
			||||||
 | 
						int n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
 | 
				
			||||||
 | 
						int logfd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mask & HCL_LOG_STDERR)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/* the messages that go to STDERR don't get masked out */
 | 
				
			||||||
 | 
							logfd = 2;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (!(xtn->logmask & mask & ~HCL_LOG_ALL_LEVELS)) return;  /* check log types */
 | 
				
			||||||
 | 
							if (!(xtn->logmask & mask & ~HCL_LOG_ALL_TYPES)) return;  /* check log levels */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (mask & HCL_LOG_STDOUT) logfd = 1;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								logfd = xtn->logfd;
 | 
				
			||||||
 | 
								if (logfd <= -1) return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* TODO: beautify the log message.
 | 
				
			||||||
 | 
					 *       do classification based on mask. */
 | 
				
			||||||
 | 
						if (!(mask & (HCL_LOG_STDOUT | HCL_LOG_STDERR)))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							time_t now;
 | 
				
			||||||
 | 
							char ts[32];
 | 
				
			||||||
 | 
							size_t tslen;
 | 
				
			||||||
 | 
							struct tm tm, *tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							now = time(NULL);
 | 
				
			||||||
 | 
						#if defined(__DOS__)
 | 
				
			||||||
 | 
							tmp = localtime (&now);
 | 
				
			||||||
 | 
							tslen = strftime (ts, sizeof(ts), "%Y-%m-%d %H:%M:%S ", tmp); /* no timezone info */
 | 
				
			||||||
 | 
							if (tslen == 0) 
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								strcpy (ts, "0000-00-00 00:00:00");
 | 
				
			||||||
 | 
								tslen = 19; 
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						#else
 | 
				
			||||||
 | 
							tmp = localtime_r (&now, &tm);
 | 
				
			||||||
 | 
							#if defined(HAVE_STRFTIME_SMALL_Z)
 | 
				
			||||||
 | 
							tslen = strftime (ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %z ", tmp);
 | 
				
			||||||
 | 
							#else
 | 
				
			||||||
 | 
							tslen = strftime (ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %Z ", tmp); 
 | 
				
			||||||
 | 
							#endif
 | 
				
			||||||
 | 
							if (tslen == 0) 
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								strcpy (ts, "0000-00-00 00:00:00 +0000");
 | 
				
			||||||
 | 
								tslen = 25; 
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						#endif
 | 
				
			||||||
 | 
							write_all (logfd, ts, tslen);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (xtn->logfd_istty)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (mask & HCL_LOG_FATAL) write_all (logfd, "\x1B[1;31m", 7);
 | 
				
			||||||
 | 
							else if (mask & HCL_LOG_ERROR) write_all (logfd, "\x1B[1;32m", 7);
 | 
				
			||||||
 | 
							else if (mask & HCL_LOG_WARN) write_all (logfd, "\x1B[1;33m", 7);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(HCL_OOCH_IS_UCH)
 | 
				
			||||||
 | 
						msgidx = 0;
 | 
				
			||||||
 | 
						while (len > 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ucslen = len;
 | 
				
			||||||
 | 
							bcslen = HCL_COUNTOF(buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							n = hcl_convootobchars (hcl, &msg[msgidx], &ucslen, buf, &bcslen);
 | 
				
			||||||
 | 
							if (n == 0 || n == -2)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* n = 0: 
 | 
				
			||||||
 | 
								 *   converted all successfully 
 | 
				
			||||||
 | 
								 * n == -2: 
 | 
				
			||||||
 | 
								 *    buffer not sufficient. not all got converted yet.
 | 
				
			||||||
 | 
								 *    write what have been converted this round. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								HCL_ASSERT (hcl, ucslen > 0); /* if this fails, the buffer size must be increased */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* attempt to write all converted characters */
 | 
				
			||||||
 | 
								if (write_all (logfd, buf, bcslen) <= -1) break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (n == 0) break;
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									msgidx += ucslen;
 | 
				
			||||||
 | 
									len -= ucslen;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if (n <= -1)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* conversion error */
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						write_all (logfd, msg, len);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (xtn->logfd_istty)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (mask & (HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN)) write_all (logfd, "\x1B[0m", 4);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void syserrstrb (hcl_t* hcl, int syserr, hcl_bch_t* buf, hcl_oow_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if defined(HAVE_STRERROR_R)
 | 
				
			||||||
 | 
						strerror_r (syserr, buf, len);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						/* this is not thread safe */
 | 
				
			||||||
 | 
						hcl_copybcstr (buf, len, strerror(syserr));
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ========================================================================= */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags)
 | 
					static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if defined(USE_LTDL) || defined(USE_DLFCN)
 | 
					#if defined(USE_LTDL) || defined(USE_DLFCN)
 | 
				
			||||||
@ -671,172 +880,7 @@ static void* dl_getsym (hcl_t* hcl, void* handle, const hcl_ooch_t* name)
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int write_all (int fd, const char* ptr, hcl_oow_t len)
 | 
					/* ========================================================================= */
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	while (len > 0)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		hcl_ooi_t wr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		wr = write (1, ptr, len);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (wr <= -1)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
		#if defined(EAGAIN) && defined(EWOULDBLOCK) && (EAGAIN == EWOULDBLOCK)
 | 
					 | 
				
			||||||
			if (errno == EAGAIN) continue;
 | 
					 | 
				
			||||||
		#else
 | 
					 | 
				
			||||||
			#	if defined(EAGAIN)
 | 
					 | 
				
			||||||
			if (errno == EAGAIN) continue;
 | 
					 | 
				
			||||||
			#elif defined(EWOULDBLOCK)
 | 
					 | 
				
			||||||
			if (errno == EWOULDBLOCK) continue;
 | 
					 | 
				
			||||||
			#endif
 | 
					 | 
				
			||||||
		#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		#if defined(EINTR)
 | 
					 | 
				
			||||||
			/* TODO: would this interfere with non-blocking nature of this VM? */
 | 
					 | 
				
			||||||
			if (errno == EINTR) continue;
 | 
					 | 
				
			||||||
		#endif
 | 
					 | 
				
			||||||
			return -1;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		ptr += wr;
 | 
					 | 
				
			||||||
		len -= wr;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void log_write (hcl_t* hcl, int mask, const hcl_ooch_t* msg, hcl_oow_t len)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
#if defined(_WIN32)
 | 
					 | 
				
			||||||
#	error NOT IMPLEMENTED 
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
#elif defined(macintosh)
 | 
					 | 
				
			||||||
#	error NOT IMPLEMENTED
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
	hcl_bch_t buf[256];
 | 
					 | 
				
			||||||
	hcl_oow_t ucslen, bcslen, msgidx;
 | 
					 | 
				
			||||||
	int n;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
 | 
					 | 
				
			||||||
	int logfd;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (mask & HCL_LOG_STDERR)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		/* the messages that go to STDERR don't get masked out */
 | 
					 | 
				
			||||||
		logfd = 2;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (!(xtn->logmask & mask & ~HCL_LOG_ALL_LEVELS)) return;  /* check log types */
 | 
					 | 
				
			||||||
		if (!(xtn->logmask & mask & ~HCL_LOG_ALL_TYPES)) return;  /* check log levels */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (mask & HCL_LOG_STDOUT) logfd = 1;
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			logfd = xtn->logfd;
 | 
					 | 
				
			||||||
			if (logfd <= -1) return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* TODO: beautify the log message.
 | 
					 | 
				
			||||||
 *       do classification based on mask. */
 | 
					 | 
				
			||||||
	if (!(mask & (HCL_LOG_STDOUT | HCL_LOG_STDERR)))
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		time_t now;
 | 
					 | 
				
			||||||
		char ts[32];
 | 
					 | 
				
			||||||
		size_t tslen;
 | 
					 | 
				
			||||||
		struct tm tm, *tmp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		now = time(NULL);
 | 
					 | 
				
			||||||
	#if defined(__DOS__)
 | 
					 | 
				
			||||||
		tmp = localtime (&now);
 | 
					 | 
				
			||||||
		tslen = strftime (ts, sizeof(ts), "%Y-%m-%d %H:%M:%S ", tmp); /* no timezone info */
 | 
					 | 
				
			||||||
		if (tslen == 0) 
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			strcpy (ts, "0000-00-00 00:00:00");
 | 
					 | 
				
			||||||
			tslen = 19; 
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	#else
 | 
					 | 
				
			||||||
		tmp = localtime_r (&now, &tm);
 | 
					 | 
				
			||||||
		#if defined(HAVE_STRFTIME_SMALL_Z)
 | 
					 | 
				
			||||||
		tslen = strftime (ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %z ", tmp);
 | 
					 | 
				
			||||||
		#else
 | 
					 | 
				
			||||||
		tslen = strftime (ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %Z ", tmp); 
 | 
					 | 
				
			||||||
		#endif
 | 
					 | 
				
			||||||
		if (tslen == 0) 
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			strcpy (ts, "0000-00-00 00:00:00 +0000");
 | 
					 | 
				
			||||||
			tslen = 25; 
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	#endif
 | 
					 | 
				
			||||||
		write_all (logfd, ts, tslen);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (xtn->logfd_istty)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (mask & HCL_LOG_FATAL) write_all (logfd, "\x1B[1;31m", 7);
 | 
					 | 
				
			||||||
		else if (mask & HCL_LOG_ERROR) write_all (logfd, "\x1B[1;32m", 7);
 | 
					 | 
				
			||||||
		else if (mask & HCL_LOG_WARN) write_all (logfd, "\x1B[1;33m", 7);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(HCL_OOCH_IS_UCH)
 | 
					 | 
				
			||||||
	msgidx = 0;
 | 
					 | 
				
			||||||
	while (len > 0)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		ucslen = len;
 | 
					 | 
				
			||||||
		bcslen = HCL_COUNTOF(buf);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		n = hcl_convootobchars (hcl, &msg[msgidx], &ucslen, buf, &bcslen);
 | 
					 | 
				
			||||||
		if (n == 0 || n == -2)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			/* n = 0: 
 | 
					 | 
				
			||||||
			 *   converted all successfully 
 | 
					 | 
				
			||||||
			 * n == -2: 
 | 
					 | 
				
			||||||
			 *    buffer not sufficient. not all got converted yet.
 | 
					 | 
				
			||||||
			 *    write what have been converted this round. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			HCL_ASSERT (hcl, ucslen > 0); /* if this fails, the buffer size must be increased */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			/* attempt to write all converted characters */
 | 
					 | 
				
			||||||
			if (write_all (logfd, buf, bcslen) <= -1) break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (n == 0) break;
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				msgidx += ucslen;
 | 
					 | 
				
			||||||
				len -= ucslen;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else if (n <= -1)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			/* conversion error */
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
	write_all (logfd, msg, len);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (xtn->logfd_istty)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (mask & (HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN)) write_all (logfd, "\x1B[0m", 4);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void syserrstrb (hcl_t* hcl, int syserr, hcl_bch_t* buf, hcl_oow_t len)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
#if defined(HAVE_STRERROR_R)
 | 
					 | 
				
			||||||
	strerror_r (syserr, buf, len);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
	/* this is not thread safe */
 | 
					 | 
				
			||||||
	hcl_copybcstr (buf, len, strerror(syserr));
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int vm_startup (hcl_t* hcl)
 | 
					static int vm_startup (hcl_t* hcl)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -925,7 +969,6 @@ static int vm_startup (hcl_t* hcl)
 | 
				
			|||||||
	xtn->iothr_up = 0;
 | 
						xtn->iothr_up = 0;
 | 
				
			||||||
	/*pthread_create (&xtn->iothr, HCL_NULL, iothr_main, hcl);*/
 | 
						/*pthread_create (&xtn->iothr, HCL_NULL, iothr_main, hcl);*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
#endif /* USE_THREAD */
 | 
					#endif /* USE_THREAD */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xtn->vm_running = 1;
 | 
						xtn->vm_running = 1;
 | 
				
			||||||
@ -1435,6 +1478,7 @@ int main (int argc, char* argv[])
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		{ ":log",         'l' },
 | 
							{ ":log",         'l' },
 | 
				
			||||||
		{ ":memsize",     'm' },
 | 
							{ ":memsize",     'm' },
 | 
				
			||||||
 | 
							{ "large-pages",  '\0' },
 | 
				
			||||||
#if defined(HCL_BUILD_DEBUG)
 | 
					#if defined(HCL_BUILD_DEBUG)
 | 
				
			||||||
		{ ":debug",       '\0' }, /* NOTE: there is no short option for --debug */
 | 
							{ ":debug",       '\0' }, /* NOTE: there is no short option for --debug */
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -1448,6 +1492,7 @@ int main (int argc, char* argv[])
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	const char* logopt = HCL_NULL;
 | 
						const char* logopt = HCL_NULL;
 | 
				
			||||||
	hcl_oow_t memsize = MIN_MEMSIZE;
 | 
						hcl_oow_t memsize = MIN_MEMSIZE;
 | 
				
			||||||
 | 
						int large_pages = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(HCL_BUILD_DEBUG)
 | 
					#if defined(HCL_BUILD_DEBUG)
 | 
				
			||||||
	const char* dbgopt = HCL_NULL;
 | 
						const char* dbgopt = HCL_NULL;
 | 
				
			||||||
@ -1477,9 +1522,13 @@ int main (int argc, char* argv[])
 | 
				
			|||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case '\0':
 | 
								case '\0':
 | 
				
			||||||
				
 | 
									if (hcl_compbcstr(opt.lngopt, "large-pages") == 0)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										large_pages = 1;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			#if defined(HCL_BUILD_DEBUG)
 | 
								#if defined(HCL_BUILD_DEBUG)
 | 
				
			||||||
				if (hcl_compbcstr(opt.lngopt, "debug") == 0)
 | 
									else if (hcl_compbcstr(opt.lngopt, "debug") == 0)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					dbgopt = opt.arg;
 | 
										dbgopt = opt.arg;
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
@ -1504,19 +1553,23 @@ int main (int argc, char* argv[])
 | 
				
			|||||||
	if (opt.ind >= argc) goto print_usage;
 | 
						if (opt.ind >= argc) goto print_usage;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset (&vmprim, 0, HCL_SIZEOF(vmprim));
 | 
						memset (&vmprim, 0, HCL_SIZEOF(vmprim));
 | 
				
			||||||
 | 
						if (large_pages)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							vmprim.alloc_heap = alloc_heap;
 | 
				
			||||||
 | 
							vmprim.free_heap = free_heap;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						vmprim.log_write = log_write;
 | 
				
			||||||
 | 
						vmprim.syserrstrb = syserrstrb;
 | 
				
			||||||
	vmprim.dl_open = dl_open;
 | 
						vmprim.dl_open = dl_open;
 | 
				
			||||||
	vmprim.dl_close = dl_close;
 | 
						vmprim.dl_close = dl_close;
 | 
				
			||||||
	vmprim.dl_getsym = dl_getsym;
 | 
						vmprim.dl_getsym = dl_getsym;
 | 
				
			||||||
	vmprim.log_write = log_write;
 | 
					 | 
				
			||||||
	vmprim.syserrstrb = syserrstrb;
 | 
					 | 
				
			||||||
	vmprim.vm_startup = vm_startup;
 | 
						vmprim.vm_startup = vm_startup;
 | 
				
			||||||
	vmprim.vm_cleanup = vm_cleanup;
 | 
						vmprim.vm_cleanup = vm_cleanup;
 | 
				
			||||||
	vmprim.vm_gettime = vm_gettime;
 | 
						vmprim.vm_gettime = vm_gettime;
 | 
				
			||||||
	vmprim.vm_sleep = vm_sleep;
 | 
						vmprim.vm_sleep = vm_sleep;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hcl = hcl_open (&sys_mmgr, HCL_SIZEOF(xtn_t), 2048000lu, &vmprim, HCL_NULL);
 | 
						hcl = hcl_open (&sys_mmgr, HCL_SIZEOF(xtn_t), memsize, &vmprim, HCL_NULL);
 | 
				
			||||||
	if (!hcl)
 | 
						if (!hcl)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		printf ("cannot open hcl\n");
 | 
							printf ("cannot open hcl\n");
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user