adding hcl_openstd()

This commit is contained in:
2021-02-07 17:57:35 +00:00
parent ac58758da0
commit 037174ddb6
14 changed files with 1316 additions and 443 deletions

View File

@ -344,6 +344,7 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@

View File

@ -84,63 +84,17 @@ struct bb_t
hcl_bch_t* fn;
};
enum logfd_flag_t
{
LOGFD_TTY = (1 << 0),
LOGFD_OPENED_HERE = (1 << 1)
};
typedef struct xtn_t xtn_t;
struct xtn_t
{
#if defined(_WIN32)
HANDLE waitable_timer;
#endif
const char* read_path; /* main source file */
const char* print_path;
int vm_running;
struct
{
int fd;
int fd_flag; /* bitwise OR'ed fo logfd_flag_t bits */
struct
{
hcl_bch_t buf[4096];
hcl_oow_t len;
} out;
} log;
int reader_istty;
hcl_oop_t sym_errstr;
};
/* ========================================================================= */
static void* sys_alloc (hcl_mmgr_t* mmgr, hcl_oow_t size)
{
return malloc(size);
}
static void* sys_realloc (hcl_mmgr_t* mmgr, void* ptr, hcl_oow_t size)
{
return realloc(ptr, size);
}
static void sys_free (hcl_mmgr_t* mmgr, void* ptr)
{
free (ptr);
}
static hcl_mmgr_t sys_mmgr =
{
sys_alloc,
sys_realloc,
sys_free,
HCL_NULL
};
/* ========================================================================= */
@ -449,240 +403,9 @@ static int print_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg)
/* ========================================================================= */
static int write_all (int fd, const hcl_bch_t* ptr, hcl_oow_t len)
{
while (len > 0)
{
hcl_ooi_t wr;
wr = write(fd, 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 int write_log (hcl_t* hcl, int fd, const hcl_bch_t* ptr, hcl_oow_t len)
{
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
while (len > 0)
{
if (xtn->log.out.len > 0)
{
hcl_oow_t rcapa, cplen;
rcapa = HCL_COUNTOF(xtn->log.out.buf) - xtn->log.out.len;
cplen = (len >= rcapa)? rcapa: len;
HCL_MEMCPY (&xtn->log.out.buf[xtn->log.out.len], ptr, cplen);
xtn->log.out.len += cplen;
ptr += cplen;
len -= cplen;
if (xtn->log.out.len >= HCL_COUNTOF(xtn->log.out.buf))
{
int n;
n = write_all(fd, xtn->log.out.buf, xtn->log.out.len);
xtn->log.out.len = 0;
if (n <= -1) return -1;
}
}
else
{
hcl_oow_t rcapa;
rcapa = HCL_COUNTOF(xtn->log.out.buf);
if (len >= rcapa)
{
if (write_all(fd, ptr, rcapa) <= -1) return -1;
ptr += rcapa;
len -= rcapa;
}
else
{
HCL_MEMCPY (xtn->log.out.buf, ptr, len);
xtn->log.out.len += len;
ptr += len;
len -= len;
}
}
}
return 0;
}
static void flush_log (hcl_t* hcl, int fd)
{
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
if (xtn->log.out.len > 0)
{
write_all (fd, xtn->log.out.buf, xtn->log.out.len);
xtn->log.out.len = 0;
}
}
static void log_write (hcl_t* hcl, hcl_bitmask_t mask, const hcl_ooch_t* msg, hcl_oow_t len)
{
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) logfd = 2;
else if (mask & HCL_LOG_STDOUT) logfd = 1;
else
{
logfd = xtn->log.fd;
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(HCL_NULL);
#if defined(_WIN32)
tmp = localtime(&now);
tslen = strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %z ", tmp);
if (tslen == 0)
{
tslen = sprintf(ts, "%04d-%02d-%02d %02d:%02d:%02d ", tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
}
#elif defined(__OS2__)
#if defined(__WATCOMC__)
tmp = _localtime(&now, &tm);
#else
tmp = localtime(&now);
#endif
#if defined(__BORLANDC__)
/* the borland compiler doesn't handle %z properly - it showed 00 all the time */
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)
{
tslen = sprintf(ts, "%04d-%02d-%02d %02d:%02d:%02d ", tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
}
#elif defined(__DOS__)
tmp = localtime(&now);
/* since i know that %z/%Z is not available in strftime, i switch to sprintf immediately */
tslen = sprintf(ts, "%04d-%02d-%02d %02d:%02d:%02d ", tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
#else
#if defined(HAVE_LOCALTIME_R)
tmp = localtime_r(&now, &tm);
#else
tmp = localtime(&now);
#endif
#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)
{
tslen = sprintf(ts, "%04d-%02d-%02d %02d:%02d:%02d ", tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
}
#endif
write_log (hcl, logfd, ts, tslen);
}
if (logfd == xtn->log.fd && (xtn->log.fd_flag & LOGFD_TTY))
{
if (mask & HCL_LOG_FATAL) write_log (hcl, logfd, "\x1B[1;31m", 7);
else if (mask & HCL_LOG_ERROR) write_log (hcl, logfd, "\x1B[1;32m", 7);
else if (mask & HCL_LOG_WARN) write_log (hcl, 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_log(hcl, logfd, buf, bcslen) <= -1) break;
if (n == 0) break;
else
{
msgidx += ucslen;
len -= ucslen;
}
}
else if (n <= -1)
{
/* conversion error */
break;
}
}
#else
write_log (hcl, logfd, msg, len);
#endif
if (logfd == xtn->log.fd && (xtn->log.fd_flag & LOGFD_TTY))
{
if (mask & (HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN)) write_log (hcl, logfd, "\x1B[0m", 4);
}
flush_log (hcl, logfd);
}
/* ========================================================================= */
static int vm_startup (hcl_t* hcl)
{
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
#if defined(_WIN32)
xtn->waitable_timer = CreateWaitableTimer(HCL_NULL, TRUE, HCL_NULL);
#endif
xtn->vm_running = 1;
return 0;
}
@ -690,16 +413,7 @@ static int vm_startup (hcl_t* hcl)
static void vm_cleanup (hcl_t* hcl)
{
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
xtn->vm_running = 0;
#if defined(_WIN32)
if (xtn->waitable_timer)
{
CloseHandle (xtn->waitable_timer);
xtn->waitable_timer = HCL_NULL;
}
#endif
}
/*
@ -714,49 +428,26 @@ static void gc_hcl (hcl_t* hcl)
if (xtn->sym_errstr) xtn->sym_errstr = hcl_moveoop(hcl, xtn->sym_errstr);
}
static HCL_INLINE void reset_log_to_default (xtn_t* xtn)
{
#if defined(ENABLE_LOG_INITIALLY)
xtn->log.fd = 2;
xtn->log.fd_flag = 0;
#if defined(HAVE_ISATTY)
if (isatty(xtn->log.fd)) xtn->log.fd_flag |= LOGFD_TTY;
#endif
#else
xtn->log.fd = -1;
xtn->log.fd_flag = 0;
#endif
}
static void fini_hcl (hcl_t* hcl)
{
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
if ((xtn->log.fd_flag & LOGFD_OPENED_HERE) && xtn->log.fd >= 0) close (xtn->log.fd);
reset_log_to_default (xtn);
}
/* ========================================================================= */
static int handle_logopt (hcl_t* hcl, const hcl_bch_t* str)
{
xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl);
hcl_bch_t* xstr = (hcl_bch_t*)str;
hcl_bch_t* cm, * flt;
hcl_ooch_t* xstr, * cm, * flt;
hcl_bitmask_t logmask;
cm = hcl_find_bchar_in_bcstr (xstr, ',');
xstr = hcl_dupbtooochars(hcl, str, hcl_count_bcstr(str), HCL_NULL);
if (!xstr)
{
fprintf (stderr, "ERROR: out of memory in duplicating %s\n", str);
return -1;
}
cm = hcl_find_oochar_in_oocstr(xstr, ',');
if (cm)
{
/* i duplicate this string for open() below as open() doesn't
* accept a length-bounded string */
xstr = hcl_dupbchars (hcl, str, hcl_count_bcstr(str));
if (!xstr)
{
fprintf (stderr, "ERROR: out of memory in duplicating %s\n", str);
return -1;
}
cm = hcl_find_bchar_in_bcstr(xstr, ',');
cm = hcl_find_oochar_in_oocstr(xstr, ',');
*cm = '\0';
logmask = 0;
@ -764,33 +455,33 @@ static int handle_logopt (hcl_t* hcl, const hcl_bch_t* str)
{
flt = cm + 1;
cm = hcl_find_bchar_in_bcstr(flt, ',');
cm = hcl_find_oochar_in_oocstr(flt, ',');
if (cm) *cm = '\0';
if (hcl_comp_bcstr(flt, "app") == 0) logmask |= HCL_LOG_APP;
else if (hcl_comp_bcstr(flt, "compiler") == 0) logmask |= HCL_LOG_COMPILER;
else if (hcl_comp_bcstr(flt, "vm") == 0) logmask |= HCL_LOG_VM;
else if (hcl_comp_bcstr(flt, "mnemonic") == 0) logmask |= HCL_LOG_MNEMONIC;
else if (hcl_comp_bcstr(flt, "gc") == 0) logmask |= HCL_LOG_GC;
else if (hcl_comp_bcstr(flt, "ic") == 0) logmask |= HCL_LOG_IC;
else if (hcl_comp_bcstr(flt, "primitive") == 0) logmask |= HCL_LOG_PRIMITIVE;
if (hcl_comp_oocstr_bcstr(flt, "app") == 0) logmask |= HCL_LOG_APP;
else if (hcl_comp_oocstr_bcstr(flt, "compiler") == 0) logmask |= HCL_LOG_COMPILER;
else if (hcl_comp_oocstr_bcstr(flt, "vm") == 0) logmask |= HCL_LOG_VM;
else if (hcl_comp_oocstr_bcstr(flt, "mnemonic") == 0) logmask |= HCL_LOG_MNEMONIC;
else if (hcl_comp_oocstr_bcstr(flt, "gc") == 0) logmask |= HCL_LOG_GC;
else if (hcl_comp_oocstr_bcstr(flt, "ic") == 0) logmask |= HCL_LOG_IC;
else if (hcl_comp_oocstr_bcstr(flt, "primitive") == 0) logmask |= HCL_LOG_PRIMITIVE;
else if (hcl_comp_bcstr(flt, "fatal") == 0) logmask |= HCL_LOG_FATAL;
else if (hcl_comp_bcstr(flt, "error") == 0) logmask |= HCL_LOG_ERROR;
else if (hcl_comp_bcstr(flt, "warn") == 0) logmask |= HCL_LOG_WARN;
else if (hcl_comp_bcstr(flt, "info") == 0) logmask |= HCL_LOG_INFO;
else if (hcl_comp_bcstr(flt, "debug") == 0) logmask |= HCL_LOG_DEBUG;
else if (hcl_comp_oocstr_bcstr(flt, "fatal") == 0) logmask |= HCL_LOG_FATAL;
else if (hcl_comp_oocstr_bcstr(flt, "error") == 0) logmask |= HCL_LOG_ERROR;
else if (hcl_comp_oocstr_bcstr(flt, "warn") == 0) logmask |= HCL_LOG_WARN;
else if (hcl_comp_oocstr_bcstr(flt, "info") == 0) logmask |= HCL_LOG_INFO;
else if (hcl_comp_oocstr_bcstr(flt, "debug") == 0) logmask |= HCL_LOG_DEBUG;
else if (hcl_comp_bcstr(flt, "fatal+") == 0) logmask |= HCL_LOG_FATAL;
else if (hcl_comp_bcstr(flt, "error+") == 0) logmask |= HCL_LOG_FATAL | HCL_LOG_ERROR;
else if (hcl_comp_bcstr(flt, "warn+") == 0) logmask |= HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN;
else if (hcl_comp_bcstr(flt, "info+") == 0) logmask |= HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN | HCL_LOG_INFO;
else if (hcl_comp_bcstr(flt, "debug+") == 0) logmask |= HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN | HCL_LOG_INFO | HCL_LOG_DEBUG;
else if (hcl_comp_oocstr_bcstr(flt, "fatal+") == 0) logmask |= HCL_LOG_FATAL;
else if (hcl_comp_oocstr_bcstr(flt, "error+") == 0) logmask |= HCL_LOG_FATAL | HCL_LOG_ERROR;
else if (hcl_comp_oocstr_bcstr(flt, "warn+") == 0) logmask |= HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN;
else if (hcl_comp_oocstr_bcstr(flt, "info+") == 0) logmask |= HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN | HCL_LOG_INFO;
else if (hcl_comp_oocstr_bcstr(flt, "debug+") == 0) logmask |= HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN | HCL_LOG_INFO | HCL_LOG_DEBUG;
else
{
fprintf (stderr, "ERROR: unknown log option value - %s\n", flt);
if (str != xstr) hcl_freemem (hcl, xstr);
fprintf (stderr, "ERROR: invalid value - %s\n", str);
hcl_freemem (hcl, xstr);
return -1;
}
}
@ -805,24 +496,11 @@ static int handle_logopt (hcl_t* hcl, const hcl_bch_t* str)
logmask = HCL_LOG_ALL_LEVELS | HCL_LOG_ALL_TYPES;
}
#if defined(_WIN32)
xtn->log.fd = _open(xstr, _O_CREAT | _O_WRONLY | _O_APPEND | _O_BINARY , 0644);
#else
xtn->log.fd = open(xstr, O_CREAT | O_WRONLY | O_APPEND , 0644);
#endif
if (xtn->log.fd == -1)
{
fprintf (stderr, "ERROR: cannot open a log file %s\n", xstr);
if (str != xstr) hcl_freemem (hcl, xstr);
return -1;
}
xtn->log.fd_flag |= LOGFD_OPENED_HERE;
#if defined(HAVE_ISATTY)
if (isatty(xtn->log.fd)) xtn->log.fd_flag |= LOGFD_TTY;
#endif
hcl_setoption (hcl, HCL_LOG_TARGET, xstr);
hcl_freemem (hcl, xstr);
if (str != xstr) hcl_freemem (hcl, xstr);
hcl_setoption (hcl, HCL_LOG_MASK, &logmask);
return 0;
}
@ -977,7 +655,6 @@ int main (int argc, char* argv[])
{
hcl_t* hcl = HCL_NULL;
xtn_t* xtn;
hcl_vmprim_t vmprim;
hcl_cb_t hclcb;
hcl_bci_t c;
@ -1066,30 +743,14 @@ int main (int argc, char* argv[])
if (opt.ind >= argc) goto print_usage;
#endif
memset (&vmprim, 0, HCL_SIZEOF(vmprim));
if (large_pages)
{
vmprim.alloc_heap = hcl_vmprim_alloc_heap;
vmprim.free_heap = hcl_vmprim_free_heap;
}
vmprim.log_write = log_write;
vmprim.syserrstrb = hcl_vmprim_syserrstrb;
vmprim.assertfail = hcl_vmprim_assertfail;
vmprim.dl_startup = hcl_vmprim_dl_startup;
vmprim.dl_cleanup = hcl_vmprim_dl_cleanup;
vmprim.dl_open = hcl_vmprim_dl_open;
vmprim.dl_close = hcl_vmprim_dl_close;
vmprim.dl_getsym = hcl_vmprim_dl_getsym;
vmprim.vm_gettime = hcl_vmprim_vm_gettime;
vmprim.vm_sleep = hcl_vmprim_vm_sleep;
hcl = hcl_open(&sys_mmgr, HCL_SIZEOF(xtn_t), heapsize, &vmprim, HCL_NULL);
if (!hcl)
hcl = hcl_openstd(HCL_SIZEOF(xtn_t), heapsize, HCL_NULL);
if (HCL_UNLIKELY(!hcl))
{
printf ("ERROR: cannot open hcl\n");
goto oops;
}
{
hcl_oow_t tab_size;
tab_size = 5000;
@ -1113,10 +774,8 @@ int main (int argc, char* argv[])
}
xtn = (xtn_t*)hcl_getxtn(hcl);
reset_log_to_default (xtn);
memset (&hclcb, 0, HCL_SIZEOF(hclcb));
hclcb.fini = fini_hcl;
hclcb.gc = gc_hcl;
hclcb.vm_startup = vm_startup;
hclcb.vm_cleanup = vm_cleanup;