added MOO_LOG_STDOUT, MOO_LOG_STDERR

changed the main program to write log messages to a specified file
added moo_getuopt()/moo_getbopt()/moo_getopt()
This commit is contained in:
hyunghwan.chung
2017-11-22 04:52:45 +00:00
parent 6177cd6865
commit 7710ad99d0
76 changed files with 15675 additions and 10060 deletions

View File

@ -37,6 +37,7 @@ pkglibdir = $(libdir)
pkginclude_HEADERS = \
moo-cmn.h \
moo-opt.h \
moo-rbt.h \
moo-utl.h \
moo.h
@ -58,6 +59,8 @@ libmoo_la_SOURCES = \
heap.c \
moo.c \
obj.c \
opt-impl.h \
opt.c \
rbt.c \
sym.c \
utf8.c \

View File

@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.14.1 from Makefile.am.
# Makefile.in generated by automake 1.15 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -17,7 +17,17 @@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@ -101,18 +111,17 @@ host_triplet = @host@
bin_PROGRAMS = moo$(EXEEXT)
@ENABLE_STATIC_MODULE_FALSE@moo_DEPENDENCIES = $(am__DEPENDENCIES_3)
subdir = lib
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(srcdir)/moo-cfg.h.in $(top_srcdir)/ac/depcomp \
$(noinst_HEADERS) $(pkginclude_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/argz.m4 \
$(top_srcdir)/m4/ax_cxx_namespace.m4 \
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_namespace.m4 \
$(top_srcdir)/m4/ax_numval.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltdl.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
$(top_srcdir)/m4/ltargz.m4 $(top_srcdir)/m4/ltdl.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \
$(pkginclude_HEADERS) $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = moo-cfg.h
CONFIG_CLEAN_FILES =
@ -154,8 +163,8 @@ am_libmoo_la_OBJECTS = libmoo_la-bigint.lo libmoo_la-comp.lo \
libmoo_la-debug.lo libmoo_la-decode.lo libmoo_la-dic.lo \
libmoo_la-err.lo libmoo_la-exec.lo libmoo_la-logfmt.lo \
libmoo_la-gc.lo libmoo_la-heap.lo libmoo_la-moo.lo \
libmoo_la-obj.lo libmoo_la-rbt.lo libmoo_la-sym.lo \
libmoo_la-utf8.lo libmoo_la-utl.lo
libmoo_la-obj.lo libmoo_la-opt.lo libmoo_la-rbt.lo \
libmoo_la-sym.lo libmoo_la-utf8.lo libmoo_la-utl.lo
libmoo_la_OBJECTS = $(am_libmoo_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@ -232,6 +241,8 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/moo-cfg.h.in \
$(top_srcdir)/ac/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
pkgincludedir = $(includedir)
pkglibdir = $(libdir)
@ -239,7 +250,6 @@ ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
ARGZ_H = @ARGZ_H@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
@ -293,9 +303,11 @@ LTDLDEPS = @LTDLDEPS@
LTDLINCL = @LTDLINCL@
LTDLOPEN = @LTDLOPEN@
LTLIBOBJS = @LTLIBOBJS@
LT_ARGZ_H = @LT_ARGZ_H@
LT_CONFIG_H = @LT_CONFIG_H@
LT_DLLOADERS = @LT_DLLOADERS@
LT_DLPREOPEN = @LT_DLPREOPEN@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
@ -414,6 +426,7 @@ LDFLAGS_LIB_COMMON = $(LDFLAGS_ALL_COMMON) -version-info 1:0:0 -no-undefined
LIBADD_LIB_COMMON = $(LIBM) $(am__append_2)
pkginclude_HEADERS = \
moo-cmn.h \
moo-opt.h \
moo-rbt.h \
moo-utl.h \
moo.h
@ -434,6 +447,8 @@ libmoo_la_SOURCES = \
heap.c \
moo.c \
obj.c \
opt-impl.h \
opt.c \
rbt.c \
sym.c \
utf8.c \
@ -469,7 +484,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign lib/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@ -612,6 +626,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_la-logfmt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_la-moo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_la-obj.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_la-opt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_la-rbt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_la-sym.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_la-utf8.Plo@am__quote@
@ -726,6 +741,13 @@ libmoo_la-obj.lo: obj.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmoo_la-obj.lo `test -f 'obj.c' || echo '$(srcdir)/'`obj.c
libmoo_la-opt.lo: opt.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmoo_la-opt.lo -MD -MP -MF $(DEPDIR)/libmoo_la-opt.Tpo -c -o libmoo_la-opt.lo `test -f 'opt.c' || echo '$(srcdir)/'`opt.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmoo_la-opt.Tpo $(DEPDIR)/libmoo_la-opt.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='opt.c' object='libmoo_la-opt.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmoo_la-opt.lo `test -f 'opt.c' || echo '$(srcdir)/'`opt.c
libmoo_la-rbt.lo: rbt.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmoo_la-rbt.lo -MD -MP -MF $(DEPDIR)/libmoo_la-rbt.Tpo -c -o libmoo_la-rbt.lo `test -f 'rbt.c' || echo '$(srcdir)/'`rbt.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmoo_la-rbt.Tpo $(DEPDIR)/libmoo_la-rbt.Plo
@ -1008,6 +1030,8 @@ uninstall-am: uninstall-binPROGRAMS uninstall-pkgincludeHEADERS \
uninstall-binPROGRAMS uninstall-hook \
uninstall-pkgincludeHEADERS uninstall-pkglibLTLIBRARIES
.PRECIOUS: Makefile
install-data-hook:
@echo "#ifndef _MOO_CFG_H_" > "$(DESTDIR)$(pkgincludedir)/moo-cfg.h"

View File

@ -851,7 +851,7 @@ static int get_char (moo_t* moo)
if (n == 0)
{
return_eof:
moo->c->curinp->lxc.c = MOO_UCI_EOF;
moo->c->curinp->lxc.c = MOO_OOCI_EOF;
moo->c->curinp->lxc.l.line = moo->c->curinp->line;
moo->c->curinp->lxc.l.colm = moo->c->curinp->colm;
moo->c->curinp->lxc.l.file = moo->c->curinp->name;
@ -920,7 +920,7 @@ static int skip_comment (moo_t* moo)
do
{
GET_CHAR_TO (moo, c);
if (c == MOO_UCI_EOF) goto unterminated;
if (c == MOO_OOCI_EOF) goto unterminated;
}
while (c != '"');
@ -937,13 +937,13 @@ static int skip_comment (moo_t* moo)
do
{
GET_CHAR_TO (moo, c);
if (c == MOO_UCI_EOF) goto unterminated;
if (c == MOO_OOCI_EOF) goto unterminated;
if (c == '*')
{
check_rparen:
GET_CHAR_TO (moo, c);
if (c == MOO_UCI_EOF) goto unterminated;
if (c == MOO_OOCI_EOF) goto unterminated;
if (c == '*') goto check_rparen; /* got another * after * */
if (c == ')')
@ -970,7 +970,7 @@ static int skip_comment (moo_t* moo)
do
{
GET_CHAR_TO (moo, c);
if (c == MOO_UCI_EOF)
if (c == MOO_OOCI_EOF)
{
/* EOF on the comment line is ok for a single-line comment */
break;
@ -1018,7 +1018,7 @@ static int get_ident (moo_t* moo, moo_ooci_t char_read_ahead)
c = moo->c->lxc.c;
SET_TOKEN_TYPE (moo, MOO_IOTOK_IDENT);
if (char_read_ahead != MOO_UCI_EOF)
if (char_read_ahead != MOO_OOCI_EOF)
{
ADD_TOKEN_CHAR(moo, char_read_ahead);
}
@ -1343,7 +1343,7 @@ static int get_charlit (moo_t* moo)
*/
moo_ooci_t c = moo->c->lxc.c; /* even a new-line or white space would be taken */
if (c == MOO_UCI_EOF)
if (c == MOO_OOCI_EOF)
{
set_syntax_error (moo, MOO_SYNERR_CLTNT, LEXER_LOC(moo), MOO_NULL);
return -1;
@ -1380,7 +1380,7 @@ static int get_strlit (moo_t* moo)
ADD_TOKEN_CHAR (moo, c);
GET_CHAR_TO (moo, c);
if (c == MOO_UCI_EOF)
if (c == MOO_OOCI_EOF)
{
/* string not closed */
set_syntax_error (moo, MOO_SYNERR_STRNC, TOKEN_LOC(moo) /*&moo->c->lxc.l*/, MOO_NULL);
@ -1417,7 +1417,7 @@ static int get_string (moo_t* moo, moo_ooch_t end_char, moo_ooch_t esc_char, int
{
GET_CHAR_TO (moo, c);
if (c == MOO_UCI_EOF)
if (c == MOO_OOCI_EOF)
{
set_syntax_error (moo, MOO_SYNERR_STRNC, TOKEN_LOC(moo) /*&moo->c->lxc.l*/, MOO_NULL);
return -1;
@ -1627,7 +1627,7 @@ retry:
switch (c)
{
case MOO_UCI_EOF:
case MOO_OOCI_EOF:
{
int n;
@ -1742,7 +1742,7 @@ retry:
GET_CHAR_TO (moo, c);
switch (c)
{
case MOO_UCI_EOF:
case MOO_OOCI_EOF:
set_syntax_error (moo, MOO_SYNERR_HLTNT, LEXER_LOC(moo), MOO_NULL);
return -1;
@ -1923,7 +1923,7 @@ retry:
default:
if (is_leadidentchar(c))
{
if (get_ident(moo, MOO_UCI_EOF) <= -1) return -1;
if (get_ident(moo, MOO_OOCI_EOF) <= -1) return -1;
}
else if (is_digitchar(c))
{

View File

@ -25,6 +25,7 @@
*/
#include "moo-prv.h"
#include "moo-opt.h"
#include <stdio.h>
#include <stdlib.h>
@ -194,6 +195,8 @@ struct xtn_t
const char* source_path; /* main source file */
int vm_running;
int logfd;
#if defined(_WIN32)
HANDLE waitable_timer;
#else
@ -729,37 +732,51 @@ static void log_write (moo_t* moo, moo_oow_t mask, const moo_ooch_t* msg, moo_oo
moo_bch_t buf[256];
moo_oow_t ucslen, bcslen, msgidx;
int n;
char ts[32];
size_t tslen;
struct tm tm, *tmp;
time_t now;
xtn_t* xtn = moo_getxtn(moo);
int logfd;
if (mask & MOO_LOG_STDOUT) logfd = 1;
else if (mask & MOO_LOG_STDERR) logfd = 2;
else
{
logfd = xtn->logfd;
if (logfd <= -1) return;
}
/* TODO: beautify the log message.
* do classification based on mask. */
if (!(mask & (MOO_LOG_STDOUT | MOO_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);
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
tslen = strftime (ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %Z ", tmp);
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
if (tslen == 0)
{
strcpy (ts, "0000-00-00 00:00:00 +0000");
tslen = 25;
write_all (logfd, ts, tslen);
}
#endif
write_all (1, ts, tslen);
#if defined(MOO_OOCH_IS_UCH)
msgidx = 0;
@ -780,7 +797,7 @@ static void log_write (moo_t* moo, moo_oow_t mask, const moo_ooch_t* msg, moo_oo
MOO_ASSERT (moo, ucslen > 0); /* if this fails, the buffer size must be increased */
/* attempt to write all converted characters */
if (write_all (1, buf, bcslen) <= -1) break;
if (write_all (logfd, buf, bcslen) <= -1) break;
if (n == 0) break;
else
@ -796,7 +813,7 @@ static void log_write (moo_t* moo, moo_oow_t mask, const moo_ooch_t* msg, moo_oo
}
}
#else
write_all (1, msg, len);
write_all (logfd, msg, len);
#endif
#endif
@ -2032,6 +2049,17 @@ static void clear_sigterm (void)
}
/* ========================================================================= */
static void close_moo (moo_t* moo)
{
xtn_t* xtn = moo_getxtn(moo);
if (xtn->logfd >= 0)
{
close (xtn->logfd);
xtn->logfd = -1;
}
moo_close (moo);
}
int main (int argc, char* argv[])
{
static moo_ooch_t str_my_object[] = { 'M', 'y', 'O', 'b','j','e','c','t' }; /*TODO: make this an argument */
@ -2044,15 +2072,46 @@ int main (int argc, char* argv[])
moo_vmprim_t vmprim;
int i, xret;
moo_bci_t c;
static moo_bopt_t opt =
{
"l:",
MOO_NULL
};
const char* logfile = MOO_NULL;
setlocale (LC_ALL, "");
#if !defined(macintosh)
if (argc < 2)
{
print_usage:
fprintf (stderr, "Usage: %s filename ...\n", argv[0]);
return -1;
}
#endif
setlocale (LC_ALL, "");
while ((c = moo_getbopt (argc, argv, &opt)) != MOO_BCI_EOF)
{
switch (c)
{
case 'l':
logfile = opt.arg;
break;
case ':':
if (opt.lngopt)
fprintf (stderr, "bad argument for '%s'\n", opt.lngopt);
else
fprintf (stderr, "bad argument for '%c'\n", opt.opt);
return -1;
default:
goto print_usage;
}
}
#endif
memset (&vmprim, 0, MOO_SIZEOF(vmprim));
vmprim.dl_open = dl_open;
@ -2102,14 +2161,27 @@ int main (int argc, char* argv[])
moo_setoption (moo, MOO_LOG_MASK, &trait);
}
xtn = moo_getxtn (moo);
xtn->logfd = -1;
if (logfile)
{
xtn->logfd = open (logfile, O_CREAT | O_WRONLY | O_APPEND , 0644);
if (xtn->logfd == -1)
{
fprintf (stderr, "ERROR: cannot open %s\n", logfile);
close_moo (moo);
return -1;
}
}
if (moo_ignite(moo) <= -1)
{
moo_logbfmt (moo, MOO_LOG_ERROR, "ERROR: cannot ignite moo - [%d] %js\n", moo_geterrnum(moo), moo_geterrstr(moo));
moo_close (moo);
close_moo (moo);
return -1;
}
xtn = moo_getxtn (moo);
#if defined(macintosh)
i = 20;
@ -2117,12 +2189,11 @@ int main (int argc, char* argv[])
goto compile;
#endif
for (i = 1; i < argc; i++)
for (i = opt.ind; i < argc; i++)
{
xtn->source_path = argv[i];
compile:
if (moo_compile (moo, input_handler) <= -1)
{
if (moo->errnum == MOO_ESYNTAX)
@ -2133,35 +2204,35 @@ int main (int argc, char* argv[])
moo_getsynerr (moo, &synerr);
printf ("ERROR: ");
moo_logbfmt (moo, MOO_LOG_ERROR | MOO_LOG_STDERR, "ERROR: ");
if (synerr.loc.file)
{
#if defined(MOO_OOCH_IS_UCH)
bcslen = MOO_COUNTOF(bcs);
if (moo_convootobcstr (moo, synerr.loc.file, &ucslen, bcs, &bcslen) >= 0)
{
printf ("%.*s ", (int)bcslen, bcs);
moo_logbfmt (moo, MOO_LOG_ERROR | MOO_LOG_STDERR, "%.*s ", (int)bcslen, bcs);
}
#else
printf ("%s ", synerr.loc.file);
moo_logbfmt (moo, MOO_LOG_ERROR | MOO_LOG_STDERR, "%s ", synerr.loc.file);
#endif
}
else
{
printf ("%s ", xtn->source_path);
moo_logbfmt (moo, MOO_LOG_ERROR | MOO_LOG_STDERR, "%s ", xtn->source_path);
}
printf ("syntax error at line %lu column %lu - ",
moo_logbfmt (moo, MOO_LOG_ERROR | MOO_LOG_STDERR, "syntax error at line %lu column %lu - ",
(unsigned long int)synerr.loc.line, (unsigned long int)synerr.loc.colm);
bcslen = MOO_COUNTOF(bcs);
#if defined(MOO_OOCH_IS_UCH)
if (moo_convootobcstr (moo, moo_synerrnum_to_errstr(synerr.num), &ucslen, bcs, &bcslen) >= 0)
{
printf (" [%.*s]", (int)bcslen, bcs);
moo_logbfmt (moo, MOO_LOG_ERROR | MOO_LOG_STDERR, " [%.*s]", (int)bcslen, bcs);
}
#else
printf (" [%s]", moo_synerrnum_to_errstr(synerr.num));
moo_logbfmt (moo, MOO_LOG_ERROR | MOO_LOG_STDERR, " [%s]", moo_synerrnum_to_errstr(synerr.num));
#endif
if (synerr.tgt.len > 0)
@ -2172,21 +2243,21 @@ int main (int argc, char* argv[])
#if defined(MOO_OOCH_IS_UCH)
if (moo_convootobchars (moo, synerr.tgt.ptr, &ucslen, bcs, &bcslen) >= 0)
{
printf (" [%.*s]", (int)bcslen, bcs);
moo_logbfmt (moo, MOO_LOG_ERROR | MOO_LOG_STDERR, " [%.*s]", (int)bcslen, bcs);
}
#else
printf (" [%.*s]", (int)synerr.tgt.len, synerr.tgt.ptr);
moo_logbfmt (moo, MOO_LOG_ERROR | MOO_LOG_STDERR, " [%.*s]", (int)synerr.tgt.len, synerr.tgt.ptr);
#endif
}
printf ("\n");
fflush (stdout);
moo_logbfmt (moo, MOO_LOG_ERROR | MOO_LOG_STDERR, "\n");
}
else
{
moo_logbfmt (moo, MOO_LOG_ERROR, "ERROR: cannot compile code - [%d] %js\n", moo_geterrnum(moo), moo_geterrstr(moo));
moo_logbfmt (moo, MOO_LOG_ERROR | MOO_LOG_STDERR, "ERROR: cannot compile code - [%d] %js\n", moo_geterrnum(moo), moo_geterrstr(moo));
}
moo_close (moo);
close_moo (moo);
#if defined(USE_LTDL)
lt_dlexit ();
#endif
@ -2217,7 +2288,7 @@ int main (int argc, char* argv[])
/*moo_dumpsymtab(moo);
*moo_dumpdic(moo, moo->sysdic, "System dictionary");*/
moo_close (moo);
close_moo (moo);
#if defined(USE_LTDL)
lt_dlexit ();

View File

@ -332,13 +332,15 @@
module search path. */
#undef LT_MODULE_PATH_VAR
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR
/* Define to the shared library suffix, say, ".dylib". */
#undef LT_SHARED_EXT
/* Define to the shared archive member specification, say "(shr.o)". */
#undef LT_SHARED_LIB_MEMBER
/* enable dynamic module capability */
#undef MOO_ENABLE_DYNAMIC_MODULE
@ -576,5 +578,5 @@
/* Define so that glibc/gnulib argp.h does not typedef error_t. */
#undef __error_t_defined
/* Define to a type to use for `error_t' if it is not otherwise available. */
/* Define to a type to use for 'error_t' if it is not otherwise available. */
#undef error_t

View File

@ -407,7 +407,9 @@ struct moo_ntime_t
/* =========================================================================
* PRIMITIVE MACROS
* ========================================================================= */
#define MOO_UCI_EOF ((moo_ooci_t)-1)
#define MOO_UCI_EOF ((moo_uci_t)-1)
#define MOO_BCI_EOF ((moo_bci_t)-1)
#define MOO_OOCI_EOF ((moo_ooci_t)-1)
#define MOO_SIZEOF(x) (sizeof(x))
#define MOO_COUNTOF(x) (sizeof(x) / sizeof((x)[0]))

143
moo/lib/moo-opt.h Normal file
View File

@ -0,0 +1,143 @@
/*
* $Id$
*
Copyright (c) 2014-2017 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MOO_OPT_H_
#define _MOO_OPT_H_
#include "moo-cmn.h"
/** \file
* This file defines functions and data structures to process
* command-line arguments.
*/
typedef struct moo_uopt_t moo_uopt_t;
typedef struct moo_uopt_lng_t moo_uopt_lng_t;
struct moo_uopt_lng_t
{
const moo_uch_t* str;
moo_uci_t val;
};
struct moo_uopt_t
{
/* input */
const moo_uch_t* str; /* option string */
moo_uopt_lng_t* lng; /* long options */
/* output */
moo_uci_t opt; /* character checked for validity */
moo_uch_t* arg; /* argument associated with an option */
/* output */
const moo_uch_t* lngopt;
/* input + output */
int ind; /* index into parent argv vector */
/* input + output - internal*/
moo_uch_t* cur;
};
typedef struct moo_bopt_t moo_bopt_t;
typedef struct moo_bopt_lng_t moo_bopt_lng_t;
struct moo_bopt_lng_t
{
const moo_bch_t* str;
moo_bci_t val;
};
struct moo_bopt_t
{
/* input */
const moo_bch_t* str; /* option string */
moo_bopt_lng_t* lng; /* long options */
/* output */
moo_bci_t opt; /* character checked for validity */
moo_bch_t* arg; /* argument associated with an option */
/* output */
const moo_bch_t* lngopt;
/* input + output */
int ind; /* index into parent argv vector */
/* input + output - internal*/
moo_bch_t* cur;
};
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The moo_getopt() function processes the \a argc command-line arguments
* pointed to by \a argv as configured in \a opt. It can process two
* different option styles: a single character starting with '-', and a
* long name starting with '--'.
*
* A character in \a opt.str is treated as a single character option. Should
* it require a parameter, specify ':' after it.
*
* Two special returning option characters indicate special error conditions.
* - \b ? indicates a bad option stored in the \a opt->opt field.
* - \b : indicates a bad parameter for an option stored in the \a opt->opt field.
*
* @return an option character on success, MOO_CHAR_EOF on no more options.
*/
MOO_EXPORT moo_uci_t moo_getuopt (
int argc, /* argument count */
moo_uch_t* const* argv, /* argument array */
moo_uopt_t* opt /* option configuration */
);
MOO_EXPORT moo_bci_t moo_getbopt (
int argc, /* argument count */
moo_bch_t* const* argv, /* argument array */
moo_bopt_t* opt /* option configuration */
);
#if defined(MOO_OOCH_IS_UCH)
# define moo_opt_t moo_uopt_t
# define moo_opt_lng_t moo_uopt_lng_t
# define moo_getopt(argc,argv,opt) moo_getuopt(argc,argv,opt)
#else
# define moo_opt_t moo_bopt_t
# define moo_opt_lng_t moo_bopt_lng_t
# define moo_getopt(argc,argv,opt) moo_getbopt(argc,argv,opt)
#endif
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -456,7 +456,7 @@ MOO_EXPORT moo_rbt_pair_t* moo_rbt_update (
* // in this sample, i will append the new value to the old value
* // separated by a comma
* moo_rbt_pair_t* new_pair;
* moo_char_t comma = MOO_T(',');
* moo_ooch_t comma = MOO_T(',');
* moo_oob_t* vptr;
*
* // allocate a new pair, but without filling the actual value.
@ -467,11 +467,11 @@ MOO_EXPORT moo_rbt_pair_t* moo_rbt_update (
*
* // fill in the value space
* vptr = new_pair->vptr;
* moo_memcpy (vptr, pair->vptr, pair->vlen*MOO_SIZEOF(moo_char_t));
* vptr += pair->vlen*MOO_SIZEOF(moo_char_t);
* moo_memcpy (vptr, &comma, MOO_SIZEOF(moo_char_t));
* vptr += MOO_SIZEOF(moo_char_t);
* moo_memcpy (vptr, v->ptr, v->len*MOO_SIZEOF(moo_char_t));
* moo_memcpy (vptr, pair->vptr, pair->vlen*MOO_SIZEOF(moo_ooch_t));
* vptr += pair->vlen*MOO_SIZEOF(moo_ooch_t);
* moo_memcpy (vptr, &comma, MOO_SIZEOF(moo_ooch_t));
* vptr += MOO_SIZEOF(moo_ooch_t);
* moo_memcpy (vptr, v->ptr, v->len*MOO_SIZEOF(moo_ooch_t));
*
* // this callback requires the old pair to be destroyed
* moo_rbt_freepair (rbt, pair);
@ -485,12 +485,12 @@ MOO_EXPORT moo_rbt_pair_t* moo_rbt_update (
* {
* moo_rbt_t* s1;
* int i;
* moo_char_t* keys[] = { MOO_T("one"), MOO_T("two"), MOO_T("three") };
* moo_char_t* vals[] = { MOO_T("1"), MOO_T("2"), MOO_T("3"), MOO_T("4"), MOO_T("5") };
* moo_ooch_t* keys[] = { MOO_T("one"), MOO_T("two"), MOO_T("three") };
* moo_ooch_t* vals[] = { MOO_T("1"), MOO_T("2"), MOO_T("3"), MOO_T("4"), MOO_T("5") };
*
* s1 = moo_rbt_open (
* MOO_MMGR_GETDFL(), 0,
* MOO_SIZEOF(moo_char_t), MOO_SIZEOF(moo_char_t)
* MOO_SIZEOF(moo_ooch_t), MOO_SIZEOF(moo_ooch_t)
* ); // note error check is skipped
* moo_rbt_setstyle (s1, &style1);
*

View File

@ -240,6 +240,15 @@ MOO_EXPORT moo_bch_t* moo_rfindbchar (
moo_bch_t c
);
MOO_EXPORT moo_uch_t* moo_finducharinucstr (
const moo_uch_t* ptr,
moo_uch_t c
);
MOO_EXPORT moo_bch_t* moo_findbcharinbcstr (
const moo_bch_t* ptr,
moo_bch_t c
);
MOO_EXPORT moo_oow_t moo_countucstr (
const moo_uch_t* str
@ -261,9 +270,9 @@ MOO_EXPORT moo_oow_t moo_countbcstr (
# define moo_copyoocstr(dst,len,src) moo_copyucstr(dst,len,src)
# define moo_findoochar(ptr,len,c) moo_finduchar(ptr,len,c)
# define moo_rfindoochar(ptr,len,c) moo_rfinduchar(ptr,len,c)
# define moo_findoocharinoocstr(ptr,c) moo_finducharinucstr(ptr,c)
# define moo_countoocstr(str) moo_countucstr(str)
#else
# define moo_equaloochars(str1,str2,len) moo_equalbchars(str1,str2,len)
# define moo_compoocbcstr(str1,str2) moo_compbcstr(str1,str2)
# define moo_compoocharsbcstr(str1,len1,str2) moo_compbcharsbcstr(str1,len1,str2)
@ -275,6 +284,7 @@ MOO_EXPORT moo_oow_t moo_countbcstr (
# define moo_copyoocstr(dst,len,src) moo_copybcstr(dst,len,src)
# define moo_findoochar(ptr,len,c) moo_findbchar(ptr,len,c)
# define moo_rfindoochar(ptr,len,c) moo_rfindbchar(ptr,len,c)
# define moo_findoocharinoocstr(ptr,c) moo_findbcharinbcstr(ptr,c)
# define moo_countoocstr(str) moo_countbcstr(str)
#endif

View File

@ -1352,11 +1352,14 @@ enum moo_log_mask_t
MOO_LOG_ERROR = (1 << 3),
MOO_LOG_FATAL = (1 << 4),
MOO_LOG_MNEMONIC = (1 << 8), /* bytecode mnemonic */
MOO_LOG_GC = (1 << 9),
MOO_LOG_IC = (1 << 10), /* instruction cycle, fetch-decode-execute */
MOO_LOG_PRIMITIVE = (1 << 11),
MOO_LOG_APP = (1 << 12) /* moo applications, set by moo logging primitive */
MOO_LOG_MNEMONIC = (1 << 7), /* bytecode mnemonic */
MOO_LOG_GC = (1 << 8),
MOO_LOG_IC = (1 << 9), /* instruction cycle, fetch-decode-execute */
MOO_LOG_PRIMITIVE = (1 << 10),
MOO_LOG_APP = (1 << 11), /* moo applications, set by moo logging primitive */
MOO_LOG_STDOUT = (1 << 14), /* write log messages to stdout without timestamp. MOO_LOG_STDOUT wins over MOO_LOG_STDERR. */
MOO_LOG_STDERR = (1 << 15), /* write log messages to stderr without timestamp. */
};
typedef enum moo_log_mask_t moo_log_mask_t;

217
moo/lib/opt-impl.h Normal file
View File

@ -0,0 +1,217 @@
/* this file is supposed to be included by opt.c multiple times */
/*
* $Id$
*
Copyright (c) 2014-2017 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "moo-opt.h"
#include "moo-utl.h"
/*
* moo_getopt is based on BSD getopt.
* --------------------------------------------------------------------------
*
* Copyright (c) 1987-2002 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* A. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* B. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* C. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* --------------------------------------------------------------------------
*/
xci_t xgetopt (int argc, xch_t* const* argv, xopt_t* opt)
{
xch_t* oli; /* option letter list index */
int dbldash = 0;
opt->arg = MOO_NULL;
opt->lngopt = MOO_NULL;
if (opt->cur == MOO_NULL)
{
opt->cur = XEMSG;
opt->ind = 1;
}
if (*opt->cur == '\0')
{
/* update scanning pointer */
if (opt->ind >= argc || *(opt->cur = argv[opt->ind]) != '-')
{
/* All arguments have been processed or the current
* argument doesn't start with a dash */
opt->cur = XEMSG;
return XCI_EOF;
}
opt->cur++;
#if 0
if (*opt->cur == '\0')
{
/* - */
opt->ind++;
opt->cur = XEMSG;
return XCI_EOF;
}
#endif
if (*opt->cur == '-')
{
if (*++opt->cur == '\0')
{
/* -- */
opt->ind++;
opt->cur = XEMSG;
return XCI_EOF;
}
else
{
dbldash = 1;
}
}
}
if (dbldash && opt->lng != MOO_NULL)
{
const xopt_lng_t* o;
xch_t* end = opt->cur;
while (*end != '\0' && *end != '=') end++;
for (o = opt->lng; o->str; o++)
{
const xch_t* str = o->str;
if (*str == ':') str++;
if (xcompcharscstr(opt->cur, end - opt->cur, str) != 0) continue;
/* match */
opt->cur = XEMSG;
opt->lngopt = o->str;
/* for a long matching option, remove the leading colon */
if (opt->lngopt[0] == ':') opt->lngopt++;
if (*end == '=') opt->arg = end + 1;
if (*o->str != ':')
{
/* should not have an option argument */
if (opt->arg != MOO_NULL) return BADARG;
}
else if (opt->arg == MOO_NULL)
{
/* check if it has a remaining argument
* available */
if (argc <= ++opt->ind) return BADARG;
/* If so, the next available argument is
* taken to be an option argument */
opt->arg = argv[opt->ind];
}
opt->ind++;
return o->val;
}
/*if (*end == MOO_T('=')) *end = MOO_T('\0');*/
opt->lngopt = opt->cur;
return BADCH;
}
if ((opt->opt = *opt->cur++) == ':' ||
(oli = xfindcharincstr(opt->str, opt->opt)) == MOO_NULL)
{
/*
* if the user didn't specify '-' as an option,
* assume it means EOF.
*/
if (opt->opt == (int)'-') return XCI_EOF;
if (*opt->cur == '\0') ++opt->ind;
return BADCH;
}
if (*++oli != ':')
{
/* don't need argument */
if (*opt->cur == '\0') opt->ind++;
}
else
{
/* need an argument */
if (*opt->cur != '\0')
{
/* no white space */
opt->arg = opt->cur;
}
else if (argc <= ++opt->ind)
{
/* no arg */
opt->cur = XEMSG;
/*if (*opt->str == ':')*/ return BADARG;
/*return BADCH;*/
}
else
{
/* white space */
opt->arg = argv[opt->ind];
}
opt->cur = XEMSG;
opt->ind++;
}
return opt->opt; /* dump back option letter */
}

82
moo/lib/opt.c Normal file
View File

@ -0,0 +1,82 @@
/*
* $Id$
*
Copyright (c) 2014-2017 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "moo-opt.h"
#include "moo-utl.h"
#define BADCH '?'
#define BADARG ':'
static moo_uch_t EMSG_UCH[] = { '\0' };
static moo_bch_t EMSG_BCH[] = { '\0' };
/* ------------------------------------------------------------ */
#undef XEMSG
#undef xch_t
#undef xci_t
#undef xopt_t
#undef xopt_lng_t
#undef xgetopt
#undef xcompcharscstr
#undef xfindcharincstr
#undef XCI_EOF
#define XEMSG EMSG_UCH
#define xch_t moo_uch_t
#define xci_t moo_uci_t
#define xopt_t moo_uopt_t
#define xopt_lng_t moo_uopt_lng_t
#define xgetopt moo_getuopt
#define xcompcharscstr moo_compucharsucstr
#define xfindcharincstr moo_finducharinucstr
#define XCI_EOF MOO_BCI_EOF
#include "opt-impl.h"
/* ------------------------------------------------------------ */
#undef XEMSG
#undef xch_t
#undef xci_t
#undef xopt_t
#undef xopt_lng_t
#undef xgetopt
#undef xcompcharscstr
#undef xfindcharincstr
#undef XCI_EOF
#define XEMSG EMSG_BCH
#define xch_t moo_bch_t
#define xci_t moo_bci_t
#define xopt_t moo_bopt_t
#define xopt_lng_t moo_bopt_lng_t
#define xgetopt moo_getbopt
#define xcompcharscstr moo_compbcharsbcstr
#define xfindcharincstr moo_findbcharinbcstr
#define XCI_EOF MOO_UCI_EOF
#include "opt-impl.h"
/* ------------------------------------------------------------ */

View File

@ -268,6 +268,28 @@ moo_bch_t* moo_rfindbchar (const moo_bch_t* ptr, moo_oow_t len, moo_bch_t c)
return MOO_NULL;
}
moo_uch_t* moo_finducharinucstr (const moo_uch_t* ptr, moo_uch_t c)
{
while (*ptr != '\0')
{
if (*ptr == c) return (moo_uch_t*)ptr;
ptr++;
}
return MOO_NULL;
}
moo_bch_t* moo_findbcharinbcstr (const moo_bch_t* ptr, moo_bch_t c)
{
while (*ptr != '\0')
{
if (*ptr == c) return (moo_bch_t*)ptr;
ptr++;
}
return MOO_NULL;
}
/* ----------------------------------------------------------------------- */
int moo_concatoocstrtosbuf (moo_t* moo, const moo_ooch_t* str, int id)