merge with ldmud distribution

This commit is contained in:
psyc://psyced.org/~lynX 2009-05-22 00:41:07 +02:00
parent 480babdac9
commit c0325c31e6
134 changed files with 16545 additions and 3006 deletions

View File

@ -1,3 +1,9 @@
2009-05-22 (lynX) (4.0.12)
+ adopted changes in LDMUD 3.3.718:
- many many many fixes
+ support for iksemel xml parser library
+ state of the art random generator
2008-07-27 (lynX) (4.0.10)
+ added ERR_TLS_NOT_DETECTED code to sys/tls.h
+ added suitable message to tls_error()

View File

@ -25,6 +25,7 @@
#define DIT_ERROR 1 /* Return the last error call chain as an array */
#define DIT_UNCAUGHT_ERROR 2 /* Return the last uncaught error call chain */
#define DIT_STR_CURRENT 3 /* Return the current call chain as a string */
#define DIT_CURRENT_DEPTH 4 /* Return the current control stack depth */
/* Indices into the array resulting from debug_info(DINFO_DATA, DID_STATUS)
*/
@ -226,8 +227,13 @@
#define TRACE_PROGRAM 2
#define TRACE_OBJECT 3
#define TRACE_LOC 4
#ifdef __EVAL_COST_TRACE__
#define TRACE_EVALCOST 5
#define TRACE_MAX 6
#else
#define TRACE_MAX 5
#endif
/* Values for entry TRACE_TYPE */

View File

@ -73,6 +73,14 @@ OPTIMIZE= $(@val_optimize@_OPTIMIZE)
# recompile.
#DEBUG = -DDEBUG # -DDEBUG_TELNET
DEBUG=
# Flags for compiling the SFMT random number generator.
SFMT_FLAGS = -fno-strict-aliasing
# for machines with sse2 support you may use:
#SFMT_FLAGS = -msse2 -fno-strict-aliasing -DHAVE_SSE2=1
# for machines with altivec support you may use:
#SFMT_FLAGS = -faltivec -fno-strict-aliasing -DHAVE_ALTIVEC=1
#
MPATH=-DMUD_LIB='"$(MUD_LIB)"' -DBINDIR='"$(BINDIR)"' -DERQ_DIR='"$(ERQ_DIR)"'
#
@ -93,7 +101,7 @@ SRC = access_check.c actions.c array.c backend.c bitstrings.c call_out.c \
interpret.c \
lex.c main.c mapping.c md5.c mempools.c mregex.c mstrings.c object.c \
otable.c\
parser.c parse.c pkg-alists.c pkg-idna.c \
parser.c parse.c pkg-alists.c pgk-iksemel.c pkg-idna.c pkg-expat.c \
pkg-mccp.c pkg-mysql.c pkg-pcre.c \
pkg-pgsql.c pkg-sqlite.c pkg-tls.c \
ptmalloc.c port.c ptrtable.c \
@ -105,13 +113,12 @@ OBJ = access_check.o actions.o array.o backend.o bitstrings.o call_out.o \
interpret.o \
lex.o main.o mapping.o md5.o mempools.o mregex.o mstrings.o object.o \
otable.o \
parser.o parse.o pkg-alists.o pkg-idna.o \
parser.o parse.o pkg-alists.o pkg-iksemel.o pkg-idna.o pkg-expat.o \
pkg-mccp.o pkg-mysql.o pkg-pcre.o \
pkg-pgsql.o pkg-sqlite.o pkg-tls.o \
ptmalloc.o port.o ptrtable.o \
random.o regexp.o sha1.o simulate.o simul_efun.o stdstrings.o \
strfuns.o structs.o sprintf.o swap.o wiz_list.o xalloc.o @ALLOCA@ \
pkg-expat.o
strfuns.o structs.o sprintf.o swap.o wiz_list.o xalloc.o @ALLOCA@
all: make-patchlevel @PROGNAME@@EXEEXT@
@ -123,7 +130,7 @@ it: @PROGNAME@@EXEEXT@
docs: @PROGNAME@@EXEEXT@
-help2man --name=@PROGNAME@ -N --help-option=--longhelp --include=../HELP --output=../@PROGNAME@.1 ./@PROGNAME@@EXEEXT@
install-all: install-driver install-headers install-utils
install: install-driver
@ -213,6 +220,9 @@ lang.c lang.h: lang.y
pcre/chartables.c : dftables@EXEEXT@
./dftables@EXEEXT@ pcre/chartables.c
random.o : random.c config.h driver.h
$(CC) $(CFLAGS) $(SFMT_FLAGS) -c random.c -o random.o
#--------------------------------------------------------
# The dependency generation uses the program 'mkdepend' and assumes GNUmake.
@ -228,11 +238,11 @@ pcre/chartables.c : dftables@EXEEXT@
depend: $(SRC) $(GENSRC)
@$(SHELL) -ec "if type mkdepend > /dev/null 2>&1; then \
echo Updating dependencies.; \
mkdepend $(SKELETON) -I. $(EXCEPT) -m -p .c:%n.o -fMakefile; \
mkdepend $(SKELETON) -I. $(EXCEPT) $(SELECT) -m -p .c:%n.o -fMakefile; \
mkdepend $(SKELETON) -I. -Ipcre -Iptmalloc $(EXCEPT) -m -p .c:%n.o -fMakefile; \
mkdepend $(SKELETON) -I. -Ipcre -Iptmalloc $(EXCEPT) $(SELECT) -m -p .c:%n.o -fMakefile; \
echo Updating dependencies in Makefile.in.; \
mkdepend $(SKELETON) -I. $(EXCEPT) -m -p .c:%n.o -fMakefile.in; \
mkdepend $(SKELETON) -I. $(EXCEPT) $(SELECT) -m -p .c:%n.o -fMakefile.in; \
mkdepend $(SKELETON) -I. -Ipcre -Iptmalloc $(EXCEPT) -m -p .c:%n.o -fMakefile.in; \
mkdepend $(SKELETON) -I. -Ipcre -Iptmalloc $(EXCEPT) $(SELECT) -m -p .c:%n.o -fMakefile.in; \
else\
echo mkdepend utility not available.; \
fi"
@ -242,8 +252,8 @@ depend: $(SRC) $(GENSRC)
depend-generic: $(SRC) $(GENSRC)
@$(SHELL) -ec "if type mkdepend > /dev/null 2>&1; then \
echo Updating dependencies in hosts/be/Makefile.; \
mkdepend $(SKELETON) -I. $(EXCEPT) -m -p .c:$$\(OBJ\)/%n.o -fhosts/be/Makefile; \
mkdepend $(SKELETON) -I. $(EXCEPT) $(SELECT) -m -p .c:$$\(OBJ\)/%n.o -fhosts/be/Makefile; \
mkdepend $(SKELETON) -I. -Ipcre -Iptmalloc $(EXCEPT) -m -p .c:$$\(OBJ\)/%n.o -fhosts/be/Makefile; \
mkdepend $(SKELETON) -I. -Ipcre -Iptmalloc $(EXCEPT) $(SELECT) -m -p .c:$$\(OBJ\)/%n.o -fhosts/be/Makefile; \
else\
echo mkdepend utility not available.; \
fi"
@ -271,20 +281,20 @@ array.o : i-svalue_cmp.h xalloc.h wiz_list.h swap.h svalue.h simulate.h \
hosts/be/be.h machine.h
backend.o : ../mudlib/sys/debug_message.h ../mudlib/sys/driver_hook.h \
xalloc.h wiz_list.h swap.h svalue.h stdstrings.h simulate.h random.h \
otable.h object.h mstrings.h mregex.h mapping.h main.h lex.h \
interpret.h heartbeat.h gcollect.h filestat.h exec.h ed.h comm.h \
closure.h call_out.h array.h actions.h backend.h my-alloca.h typedefs.h \
driver.h strfuns.h sent.h bytecode.h hash.h pkg-tls.h port.h config.h \
hosts/unix.h hosts/be/be.h machine.h
i-eval_cost.h xalloc.h wiz_list.h swap.h svalue.h stdstrings.h \
simulate.h random.h otable.h object.h mstrings.h mregex.h mapping.h \
main.h lex.h interpret.h heartbeat.h gcollect.h filestat.h exec.h ed.h \
comm.h closure.h call_out.h array.h actions.h backend.h my-alloca.h \
typedefs.h driver.h strfuns.h sent.h bytecode.h hash.h pkg-tls.h port.h \
config.h hosts/unix.h hosts/be/be.h machine.h
bitstrings.o : xalloc.h svalue.h simulate.h mstrings.h interpret.h \
bitstrings.h typedefs.h driver.h strfuns.h sent.h bytecode.h hash.h \
backend.h port.h config.h main.h hosts/unix.h hosts/be/be.h machine.h
call_out.o : ../mudlib/sys/debug_info.h xalloc.h wiz_list.h swap.h svalue.h \
strfuns.h stdstrings.h simulate.h object.h mstrings.h main.h \
interpret.h gcollect.h exec.h comm.h closure.h backend.h array.h \
call_out.o : ../mudlib/sys/debug_info.h i-eval_cost.h xalloc.h wiz_list.h \
swap.h svalue.h strfuns.h stdstrings.h simulate.h object.h mstrings.h \
main.h interpret.h gcollect.h exec.h comm.h closure.h backend.h array.h \
actions.h call_out.h typedefs.h driver.h sent.h bytecode.h hash.h \
pkg-tls.h port.h config.h hosts/unix.h hosts/be/be.h machine.h
@ -295,13 +305,13 @@ closure.o : i-svalue_cmp.h xalloc.h switch.h swap.h svalue.h structs.h \
bytecode.h port.h config.h hosts/unix.h hosts/be/be.h machine.h
comm.o : util/erq/erq.h ../mudlib/sys/input_to.h \
../mudlib/sys/driver_hook.h ../mudlib/sys/comm.h xalloc.h wiz_list.h \
swap.h svalue.h stdstrings.h simulate.h sent.h pkg-tls.h pkg-pgsql.h \
pkg-mccp.h object.h mstrings.h main.h interpret.h gcollect.h filestat.h \
exec.h ed.h closure.h array.h actions.h access_check.h comm.h \
../mudlib/sys/telnet.h my-alloca.h typedefs.h driver.h strfuns.h \
bytecode.h hash.h backend.h config.h port.h hosts/unix.h hosts/be/be.h \
machine.h
../mudlib/sys/driver_hook.h ../mudlib/sys/comm.h i-eval_cost.h xalloc.h \
wiz_list.h swap.h svalue.h stdstrings.h simulate.h sent.h pkg-tls.h \
pkg-pgsql.h pkg-mccp.h object.h mstrings.h main.h interpret.h \
gcollect.h filestat.h exec.h ed.h closure.h array.h actions.h \
access_check.h comm.h ../mudlib/sys/telnet.h my-alloca.h typedefs.h \
driver.h strfuns.h bytecode.h hash.h backend.h config.h port.h \
hosts/unix.h hosts/be/be.h machine.h
dumpstat.o : xalloc.h svalue.h structs.h stdstrings.h simulate.h ptrtable.h \
object.h mstrings.h mapping.h instrs.h filestat.h exec.h closure.h \
@ -316,14 +326,14 @@ ed.o : ../mudlib/sys/regexp.h xalloc.h svalue.h stdstrings.h simulate.h \
efuns.o : ../mudlib/sys/time.h ../mudlib/sys/strings.h \
../mudlib/sys/regexp.h ../mudlib/sys/objectinfo.h \
../mudlib/sys/driver_hook.h ../mudlib/sys/debug_info.h xalloc.h \
wiz_list.h svalue.h swap.h structs.h strfuns.h simulate.h stdstrings.h \
sha1.h random.h ptrtable.h otable.h object.h mstrings.h mregex.h md5.h \
mempools.h mapping.h main.h lex.h interpret.h heartbeat.h exec.h \
dumpstat.h comm.h closure.h call_out.h backend.h array.h actions.h \
efuns.h my-rusage.h my-alloca.h typedefs.h driver.h hash.h sent.h \
bytecode.h my-stdint.h pkg-tls.h port.h config.h hosts/unix.h \
hosts/be/be.h machine.h
../mudlib/sys/driver_hook.h ../mudlib/sys/debug_info.h i-eval_cost.h \
xalloc.h wiz_list.h svalue.h swap.h structs.h strfuns.h simulate.h \
stdstrings.h sha1.h random.h ptrtable.h otable.h object.h mstrings.h \
mregex.h md5.h mempools.h mapping.h main.h lex.h interpret.h \
heartbeat.h exec.h dumpstat.h comm.h closure.h call_out.h backend.h \
array.h actions.h efuns.h my-rusage.h my-alloca.h typedefs.h driver.h \
hash.h sent.h bytecode.h my-stdint.h pkg-tls.h port.h config.h \
hosts/unix.h hosts/be/be.h machine.h
files.o : ../mudlib/sys/files.h xalloc.h svalue.h stdstrings.h simulate.h \
mstrings.h mempools.h main.h lex.h interpret.h filestat.h comm.h \
@ -331,8 +341,8 @@ files.o : ../mudlib/sys/files.h xalloc.h svalue.h stdstrings.h simulate.h \
bytecode.h hash.h backend.h pkg-tls.h port.h config.h hosts/unix.h \
hosts/be/be.h machine.h
gcollect.o : ../mudlib/sys/driver_hook.h xalloc.h wiz_list.h swap.h \
structs.h stdstrings.h simul_efun.h simulate.h sent.h random.h \
gcollect.o : ../mudlib/sys/driver_hook.h i-eval_cost.h xalloc.h wiz_list.h \
swap.h structs.h stdstrings.h simul_efun.h simulate.h sent.h random.h \
ptrtable.h prolang.h pkg-pgsql.h parse.h otable.h object.h mstrings.h \
mregex.h mempools.h mapping.h main.h lex.h instrs.h interpret.h \
heartbeat.h filestat.h ed.h comm.h closure.h call_out.h backend.h \
@ -342,35 +352,36 @@ gcollect.o : ../mudlib/sys/driver_hook.h xalloc.h wiz_list.h swap.h \
hash.o : hash.h
heartbeat.o : ../mudlib/sys/debug_info.h xalloc.h wiz_list.h svalue.h \
strfuns.h simulate.h sent.h object.h mstrings.h interpret.h gcollect.h \
exec.h comm.h backend.h array.h actions.h heartbeat.h typedefs.h \
driver.h bytecode.h hash.h pkg-tls.h main.h port.h config.h \
heartbeat.o : ../mudlib/sys/debug_info.h i-eval_cost.h xalloc.h wiz_list.h \
svalue.h strfuns.h simulate.h sent.h object.h mstrings.h interpret.h \
gcollect.h exec.h comm.h backend.h array.h actions.h heartbeat.h \
typedefs.h driver.h bytecode.h hash.h pkg-tls.h main.h port.h config.h \
hosts/unix.h hosts/be/be.h machine.h
interpret.o : ../mudlib/sys/trace.h ../mudlib/sys/debug_info.h \
../mudlib/sys/driver_hook.h xalloc.h wiz_list.h switch.h swap.h \
svalue.h structs.h stdstrings.h simul_efun.h simulate.h prolang.h \
parse.h otable.h object.h mstrings.h mapping.h lex.h instrs.h \
heartbeat.h gcollect.h filestat.h exec.h efuns.h ed.h comm.h closure.h \
call_out.h backend.h array.h actions.h interpret.h my-alloca.h \
typedefs.h driver.h strfuns.h hash.h ptrtable.h sent.h bytecode.h \
pkg-tls.h main.h port.h config.h hosts/unix.h hosts/be/be.h machine.h
interpret.o : ../mudlib/sys/debug_info.h ../mudlib/sys/driver_hook.h \
i-eval_cost.h xalloc.h wiz_list.h switch.h swap.h svalue.h structs.h \
stdstrings.h simul_efun.h simulate.h prolang.h parse.h otable.h \
object.h mstrings.h mapping.h lex.h instrs.h heartbeat.h gcollect.h \
filestat.h exec.h efuns.h ed.h comm.h closure.h call_out.h backend.h \
array.h actions.h interpret.h my-alloca.h typedefs.h driver.h strfuns.h \
hash.h ptrtable.h sent.h bytecode.h pkg-tls.h main.h port.h config.h \
hosts/unix.h hosts/be/be.h machine.h
lex.o : efun_defs.c ../mudlib/sys/driver_hook.h xalloc.h wiz_list.h \
svalue.h strfuns.h stdstrings.h simul_efun.h simulate.h prolang.h \
patchlevel.h object.h mstrings.h mempools.h main.h lang.h interpret.h \
instrs.h hash.h gcollect.h filestat.h exec.h comm.h closure.h backend.h \
array.h lex.h my-alloca.h typedefs.h driver.h ptrtable.h sent.h \
bytecode.h pkg-tls.h port.h config.h hosts/unix.h hosts/be/be.h \
machine.h
lex.o : efun_defs.c ../mudlib/sys/driver_hook.h i-eval_cost.h xalloc.h \
wiz_list.h svalue.h strfuns.h stdstrings.h simul_efun.h simulate.h \
prolang.h patchlevel.h object.h mstrings.h mempools.h main.h lang.h \
interpret.h instrs.h hash.h gcollect.h filestat.h exec.h comm.h \
closure.h backend.h array.h lex.h my-alloca.h typedefs.h driver.h \
ptrtable.h sent.h bytecode.h pkg-tls.h port.h config.h hosts/unix.h \
hosts/be/be.h machine.h
main.o : ../mudlib/sys/regexp.h pkg-mysql.h xalloc.h wiz_list.h swap.h \
svalue.h stdstrings.h simul_efun.h simulate.h random.h pkg-tls.h \
patchlevel.h otable.h object.h mstrings.h mregex.h mempools.h mapping.h \
lex.h interpret.h gcollect.h filestat.h comm.h array.h backend.h main.h \
my-alloca.h typedefs.h driver.h strfuns.h ptrtable.h exec.h sent.h \
bytecode.h hash.h port.h config.h hosts/unix.h hosts/be/be.h machine.h
main.o : ../mudlib/sys/regexp.h i-eval_cost.h pkg-mysql.h xalloc.h \
wiz_list.h swap.h svalue.h stdstrings.h simul_efun.h simulate.h \
random.h pkg-tls.h patchlevel.h otable.h object.h mstrings.h mregex.h \
mempools.h mapping.h lex.h interpret.h gcollect.h filestat.h comm.h \
array.h backend.h main.h my-alloca.h typedefs.h driver.h strfuns.h \
ptrtable.h exec.h sent.h bytecode.h hash.h port.h config.h hosts/unix.h \
hosts/be/be.h machine.h
mapping.o : i-svalue_cmp.h xalloc.h wiz_list.h svalue.h structs.h \
simulate.h object.h mstrings.h main.h interpret.h gcollect.h closure.h \
@ -421,12 +432,12 @@ parse.o : xalloc.h wiz_list.h svalue.h stdstrings.h simulate.h object.h \
parse.h typedefs.h driver.h strfuns.h sent.h bytecode.h hash.h \
backend.h port.h config.h hosts/unix.h hosts/be/be.h machine.h
parser.o : lang.c ../mudlib/sys/driver_hook.h xalloc.h wiz_list.h switch.h \
swap.h svalue.h structs.h stdstrings.h simul_efun.h simulate.h object.h \
mstrings.h mapping.h main.h lex.h instrs.h interpret.h gcollect.h \
exec.h closure.h backend.h array.h prolang.h my-alloca.h typedefs.h \
driver.h strfuns.h hash.h ptrtable.h sent.h bytecode.h port.h config.h \
hosts/unix.h hosts/be/be.h machine.h
parser.o : lang.c ../mudlib/sys/driver_hook.h i-eval_cost.h xalloc.h \
wiz_list.h switch.h swap.h svalue.h structs.h stdstrings.h simul_efun.h \
simulate.h object.h mstrings.h mapping.h main.h lex.h instrs.h \
interpret.h gcollect.h exec.h closure.h backend.h array.h prolang.h \
my-alloca.h typedefs.h driver.h strfuns.h hash.h ptrtable.h sent.h \
bytecode.h port.h config.h hosts/unix.h hosts/be/be.h machine.h
dftables.o : pcre/maketables.c pcre/internal.h pcre/pcre.h pcre/config.h
@ -487,9 +498,10 @@ ptrtable.o : simulate.h mempools.h ptrtable.h driver.h svalue.h strfuns.h \
random.o : random.h driver.h port.h config.h hosts/unix.h hosts/be/be.h \
machine.h
regexp.o : main.h xalloc.h simulate.h interpret.h regexp.h driver.h \
typedefs.h svalue.h strfuns.h sent.h bytecode.h backend.h pkg-pcre.h \
port.h config.h pcre/pcre.h hosts/unix.h hosts/be/be.h machine.h
regexp.o : i-eval_cost.h main.h xalloc.h simulate.h regexp.h driver.h \
interpret.h typedefs.h svalue.h strfuns.h sent.h bytecode.h pkg-pcre.h \
port.h config.h backend.h pcre/pcre.h hosts/unix.h hosts/be/be.h \
machine.h
sha1.o : sha1.h my-stdint.h driver.h port.h config.h hosts/unix.h \
hosts/be/be.h machine.h
@ -502,12 +514,12 @@ simul_efun.o : xalloc.h swap.h svalue.h stdstrings.h simulate.h prolang.h \
simulate.o : ../mudlib/sys/rtlimits.h ../mudlib/sys/regexp.h \
../mudlib/sys/files.h ../mudlib/sys/driver_hook.h \
../mudlib/sys/debug_info.h xalloc.h wiz_list.h svalue.h swap.h \
structs.h strfuns.h stdstrings.h simul_efun.h sent.h prolang.h \
../mudlib/sys/debug_info.h i-eval_cost.h xalloc.h wiz_list.h svalue.h \
swap.h structs.h strfuns.h stdstrings.h simul_efun.h sent.h prolang.h \
pkg-sqlite.h pkg-tls.h otable.h object.h mstrings.h mregex.h mempools.h \
mapping.h main.h lex.h interpret.h heartbeat.h gcollect.h filestat.h \
ed.h comm.h closure.h call_out.h backend.h array.h actions.h simulate.h \
my-alloca.h typedefs.h driver.h hash.h exec.h ptrtable.h bytecode.h \
mapping.h main.h lex.h heartbeat.h gcollect.h filestat.h ed.h comm.h \
closure.h call_out.h backend.h array.h actions.h simulate.h my-alloca.h \
typedefs.h driver.h interpret.h hash.h exec.h ptrtable.h bytecode.h \
port.h config.h hosts/unix.h hosts/be/be.h machine.h
sprintf.o : xalloc.h swap.h svalue.h structs.h stdstrings.h simul_efun.h \

View File

@ -496,12 +496,20 @@ remove_shadow_actions (object_t *shadow, object_t *target)
*/
{
#ifdef USE_INVENTORIES
# ifdef USE_INVENTORIES
object_t *item;
#endif
# endif
object_t *shadowing;
/* Get the real underlying object, just as add_action does. */
while ((target->flags & O_SHADOW)
&& NULL != (shadowing = O_GET_SHADOW(target)->shadowing))
{
target = shadowing;
}
remove_shadow_action_sent(shadow, target);
#ifdef USE_INVENTORIES
# ifdef USE_INVENTORIES
for (item = target->contains; item; item = item->next_inv)
{
if (shadow != item)
@ -517,7 +525,7 @@ remove_shadow_actions (object_t *shadow, object_t *target)
remove_shadow_action_sent(shadow, item);
}
}
#endif
# endif
} /* remove_shadow_actions() */
#endif
@ -1248,7 +1256,7 @@ execute_command (char *str, object_t *ob)
/* Save the current context */
save_command_context(&context);
context.rt.last = rt_context;
rt_context = (rt_context_t *)&context;
rt_context = (rt_context_t *)&context.rt;
/* Default settings */
command_giver = ob;
@ -1423,8 +1431,8 @@ e_add_action (svalue_t *func, svalue_t *cmd, p_int flag)
if ((size_t)(-flag) >= mstrsize(p->verb))
{
free_action_sent(p);
errorf("Bad arg 3 to add_action(): value %ld larger than verb '%s'.\n"
, (long)flag, get_txt(p->verb));
errorf("Bad arg 3 to add_action(): value %"PRIdPINT" larger than verb '%s'.\n"
, flag, get_txt(p->verb));
/* NOTREACHED */
return MY_TRUE;
}
@ -1437,8 +1445,8 @@ e_add_action (svalue_t *func, svalue_t *cmd, p_int flag)
else
{
free_action_sent(p);
errorf("Bad arg 3 to add_action(): value %ld too big.\n"
, (long)flag);
errorf("Bad arg 3 to add_action(): value %"PRIdPINT" too big.\n"
, flag);
/* NOTREACHED */
return MY_TRUE;
}
@ -1613,7 +1621,8 @@ f_execute_command (svalue_t *sp)
len = mstrsize(argp->u.str);
if (len >= sizeof(buf) - 1)
errorf("Command too long: '%.200s...'\n", get_txt(argp->u.str));
errorf("Command too long (size: %zu): '%.200s...'\n",
len, get_txt(argp->u.str));
strncpy(buf, get_txt(argp->u.str), len);
buf[len+1] = '\0';
@ -1940,7 +1949,7 @@ f_remove_action (svalue_t *sp)
*/
{
object_t *ob;
object_t *ob, *shadow_ob;
string_t *verb;
sentence_t **sentp;
action_t *s;
@ -1969,14 +1978,33 @@ f_remove_action (svalue_t *sp)
efun_gen_arg_error(1, sp[-1].type, sp);
/* NOTREACHED */
}
/* Now search and remove the sentence */
rc = 0;
sentp = &ob->sent;
ob = current_object;
shadow_ob = NULL;
/* Look for the underlying object, just as add_action does. */
if (ob->flags & O_SHADOW && O_GET_SHADOW(ob)->shadowing)
{
object_t *shadowing;
shadow_ob = ob;
while ((ob->flags & O_SHADOW)
&& NULL != (shadowing = O_GET_SHADOW(ob)->shadowing))
{
ob = shadowing;
}
}
/* Now search and remove the sentence */
while ( NULL != (s = (action_t *)*sentp) )
{
if (!SENT_IS_INTERNAL((*sentp)->type) && s->ob == ob && (!verb || s->verb == verb))
if (!SENT_IS_INTERNAL((*sentp)->type) && s->ob == ob
&& (!verb || s->verb == verb)
&& (!shadow_ob || s->shadow_ob == shadow_ob))
{
#ifdef CHECK_OBJECT_REF
if (sentp == &ob->sent)
@ -2281,7 +2309,7 @@ f_disable_commands (svalue_t *sp)
return sp;
if (d_flag > 1) {
debug_message("%s Disable commands %s (ref %ld)\n"
debug_message("%s Disable commands %s (ref %"PRIdPINT")\n"
, time_stamp(), get_txt(current_object->name)
, current_object->ref);
}
@ -2311,7 +2339,7 @@ f_enable_commands (svalue_t *sp)
return sp;
if (d_flag > 1) {
debug_message("%s Enable commands %s (ref %ld)\n"
debug_message("%s Enable commands %s (ref %"PRIdPINT")\n"
, time_stamp(), get_txt(current_object->name)
, current_object->ref);
}
@ -2545,8 +2573,8 @@ f_set_modify_command (svalue_t *sp)
else
{
if (sp->u.number != -1)
errorf("Bad num arg 1 to set_modify_command(): got %ld, "
"expected 0 or -1\n", sp->u.number);
errorf("Bad num arg 1 to set_modify_command(): got %"PRIdPINT
", expected 0 or -1\n", sp->u.number);
if (old) ref_object(old, "set_modify_command");
}
}

View File

@ -63,7 +63,7 @@
#include "array.h"
#include "backend.h"
#include "closure.h" /* closure_cmp(), closure_eq() */
#include "interpret.h" /* for the efuns */
#include "interpret.h"
#include "main.h"
#include "mapping.h"
#include "mempools.h"
@ -133,7 +133,7 @@ _allocate_array(mp_int n MTRACE_DECL)
svalue_t *svp;
if (n < 0 || (max_array_size && (size_t)n > max_array_size))
errorf("Illegal array size: %ld.\n", n);
errorf("Illegal array size: %"PRIdMPINT".\n", n);
if (n == 0) {
p = ref_array(&null_vector);
@ -145,10 +145,11 @@ _allocate_array(mp_int n MTRACE_DECL)
p = ALLOC_VECTOR(n);
if (!p) {
#ifndef MALLOC_TRACE
(*allocate_array_error_handler)("Out of memory: array[%ld]\n", n);
(*allocate_array_error_handler)
("Out of memory: array[%"PRIdMPINT"]\n", n);
#else
(*allocate_array_error_handler)
("(%s:%d) Out of memory: array[%ld]\n"
("(%s:%d) Out of memory: array[%"PRIdMPINT"]\n"
MTRACE_PASS, n);
#endif
return 0;
@ -191,7 +192,7 @@ _allocate_array_unlimited(mp_int n MTRACE_DECL)
svalue_t *svp;
if (n < 0)
errorf("Illegal array size: %ld.\n", n);
errorf("Illegal array size: %"PRIdMPINT".\n", n);
if (n == 0) {
p = ref_array(&null_vector);
@ -204,10 +205,10 @@ _allocate_array_unlimited(mp_int n MTRACE_DECL)
if (!p) {
#ifndef MALLOC_TRACE
(*allocate_array_error_handler)
("Out of memory: unlimited array[%ld]\n", n);
("Out of memory: unlimited array[%"PRIdMPINT"]\n", n);
#else
(*allocate_array_error_handler)
("(%s:%d) Out of memory: unlimited array[%ld]\n"
("(%s:%d) Out of memory: unlimited array[%"PRIdMPINT"]\n"
MTRACE_PASS, n);
#endif
return 0;
@ -247,7 +248,7 @@ _allocate_uninit_array (mp_int n MTRACE_DECL)
vector_t *p;
if (n < 0 || (max_array_size && (size_t)n > max_array_size))
errorf("Illegal array size: %ld.\n", n);
errorf("Illegal array size: %"PRIdMPINT".\n", n);
if (n == 0) {
p = ref_array(&null_vector);
@ -260,10 +261,10 @@ _allocate_uninit_array (mp_int n MTRACE_DECL)
if (!p) {
#ifndef MALLOC_TRACE
(*allocate_array_error_handler)
("Out of memory: uninited array[%ld]\n", n);
("Out of memory: uninited array[%"PRIdMPINT"]\n", n);
#else
(*allocate_array_error_handler)
("(%s:%d) Out of memory: uninited array[%ld]\n"
("(%s:%d) Out of memory: uninited array[%"PRIdMPINT"]\n"
MTRACE_PASS, n);
#endif
return 0;
@ -293,7 +294,8 @@ _free_vector (vector_t *p)
#ifdef DEBUG
if (p->ref > 0)
fatal("Vector with %ld refs passed to _free_vector()\n", p->ref);
fatal("Vector with %"PRIdPINT" refs passed to _free_vector()\n",
p->ref);
if (p == &null_vector)
fatal("Tried to free the zero-size shared vector.\n");
#endif
@ -1860,7 +1862,7 @@ v_allocate (svalue_t *sp, int num_arg)
size = svp->u.number;
if (size < 0 || (max_array_size && (size_t)size > max_array_size))
errorf("Illegal array size: %ld\n", (long)size);
errorf("Illegal array size: %"PRIdPINT"\n", size);
if (size == 0 && dim < num_dim-1)
errorf("Only the last dimension can have empty arrays.\n");
@ -2186,7 +2188,8 @@ x_map_array (svalue_t *sp, int num_arg)
res = allocate_array(cnt);
if (!res)
errorf("(map_array) Out of memory: array[%ld] for result\n", cnt);
errorf("(map_array) Out of memory: array[%"PRIdMPINT
"] for result\n", cnt);
push_array(inter_sp, res); /* In case of errors */
for (w = arr->item, x = res->item; --cnt >= 0; w++, x++)
@ -2224,7 +2227,8 @@ x_map_array (svalue_t *sp, int num_arg)
res = allocate_array(cnt);
if (!res)
errorf("(map_array) Out of memory: array[%ld] for result\n", cnt);
errorf("(map_array) Out of memory: array[%"PRIdMPINT
"] for result\n", cnt);
push_array(inter_sp, res); /* In case of errors */
/* Loop through arr and res, mapping the values from arr */

View File

@ -7,49 +7,6 @@
#include "typedefs.h"
#include "svalue.h"
/* --- Macros --- */
/* vector_t *ref_array(vector_t *a)
* Add another ref to array <a> and return the vector <a>.
*/
#define ref_array(a) ((a)->ref++, (a))
/* void free_array(vector_t *a)
* Subtract one ref from array <a>, and free the array fully if
* the refcount reaches zero.
*/
#define free_array(a) MACRO( if (--((a)->ref) <= 0) _free_vector(a); )
/* p_int deref_array(vector_t *a)
* Subtract one ref from array <a>, but don't check if it needs to
* be freed. Result is the number of refs left.
*/
#define deref_array(a) (--(a)->ref)
/* See array.c for a description of what the following macros do. */
/* Helper for LOCAL_VECn() */
#ifdef DEBUG
# define VEC_DEBUGREF(ref) ref,
#else
# define VEC_DEBUGREF(ref)
#endif
#include "svalue.h"
#define VEC_HEAD(size) size, 1, VEC_DEBUGREF(1) NULL
#define VEC_SIZE(v) ((v)->size)
#define LOCAL_VEC1(name, type1) \
struct { vector_t v; } name \
= { { VEC_HEAD(1), { { type1, { 0 } } } } }
#define LOCAL_VEC2(name, type1, type2) \
struct { vector_t v; svalue_t item[1]; } name \
= { { VEC_HEAD(2), { { type1, { 0 } } } }, { { type2, { 0 } } } }
/* --- Types --- */
@ -70,6 +27,30 @@ struct vector_s {
};
/* --- Macros --- */
/* See array.c for a description of what the following macros do. */
/* Helper for LOCAL_VECn() */
#ifdef DEBUG
# define VEC_DEBUGREF(ref) ref,
#else
# define VEC_DEBUGREF(ref)
#endif
#define VEC_HEAD(size) size, 1, VEC_DEBUGREF(1) NULL
#define VEC_SIZE(v) ((v)->size)
#define LOCAL_VEC1(name, type1) \
struct { vector_t v; } name \
= { { VEC_HEAD(1), { { type1, { 0 } } } } }
#define LOCAL_VEC2(name, type1, type2) \
struct { vector_t v; svalue_t item[1]; } name \
= { { VEC_HEAD(2), { { type1, { 0 } } } }, { { type2, { 0 } } } }
/* --- Variables --- */
extern vector_t null_vector;
@ -77,6 +58,7 @@ extern vector_t null_vector;
extern int num_arrays;
extern void (*allocate_array_error_handler) (const char *, ...);
/* --- Prototypes --- */
#if defined(MALLOC_TRACE)
@ -134,4 +116,33 @@ extern void clear_array_size (void);
extern void count_array_size (vector_t *vec);
#endif
/* --- static helper functions --- */
/* vector_t *ref_array(vector_t *a)
* Add another ref to array <a> and return the vector <a>.
*/
static INLINE vector_t* ref_array(vector_t *a) {
++a->ref;
return a;
}
/* void free_array(vector_t *a)
* Subtract one ref from array <a>, and free the array fully if
* the refcount reaches zero.
*/
static INLINE void free_array(vector_t *a) {
if (--(a->ref) <= 0)
_free_vector(a);
}
/* p_int deref_array(vector_t *a)
* Subtract one ref from array <a>, but don't check if it needs to
* be freed. Result is the number of refs left.
*/
static INLINE p_int deref_array(vector_t *a) {
return --a->ref;
}
#endif /* ARRAY_H__ */

View File

@ -74,6 +74,8 @@
#include "wiz_list.h"
#include "xalloc.h"
#include "i-eval_cost.h"
#include "../mudlib/sys/driver_hook.h"
#include "../mudlib/sys/debug_message.h"
@ -122,9 +124,9 @@ uint num_last_data_cleaned = 0;
/* Number of object data-cleaned in last process_objects().
*/
statistic_t stat_last_processed = { 0 };
statistic_t stat_last_data_cleaned = { 0 };
statistic_t stat_in_list = { 0 };
statistic_t stat_last_processed = { 0, 0, 0.0 };
statistic_t stat_last_data_cleaned = { 0, 0, 0.0 };
statistic_t stat_in_list = { 0, 0, 0.0 };
/* Decaying average number of objects processed and objects in the list.
*/
@ -151,12 +153,12 @@ Bool mud_is_up = MY_FALSE;
*/
#endif
statistic_t stat_load = { 0 };
statistic_t stat_load = { 0, 0, 0.0 };
/* The load average (player commands/second), weighted over the
* last period of time.
*/
statistic_t stat_compile = { 0 };
statistic_t stat_compile = { 0, 0, 0.0 };
/* The average of compiled lines/second, weighted over the last period
* of time.
*/
@ -337,7 +339,7 @@ handle_usr1 (int sig UNUSED)
#ifndef RETSIGTYPE_VOID
return 0;
#endif
} /* handle_usr1() */
} /* handle_usr2() */
/*-------------------------------------------------------------------------*/
static RETSIGTYPE
@ -614,7 +616,7 @@ backend (void)
/* puts("Handling outgoing connections."); */
check_for_out_connections();
} else
extra_jobs_to_do = MY_FALSE;
extra_jobs_to_do = MY_FALSE;
} /* if (extra_jobs_to_do */
@ -841,8 +843,9 @@ void check_alarm (void)
}
else if (curtime - last_alarm_time > 15)
{
debug_message("%s Last alarm was %ld seconds ago - restarting it.\n"
, time_stamp(), curtime - last_alarm_time);
debug_message("%s Last alarm was %"PRIdMPINT" seconds ago "
"- restarting it.\n",
time_stamp(), curtime - last_alarm_time);
alarm(0); /* stop alarm in case it is still alive, but just slow */
comm_time_to_call_heart_beat = MY_TRUE;
@ -931,7 +934,7 @@ static Bool did_swap;
error_recovery_info.rt.last = rt_context;
error_recovery_info.rt.type = ERROR_RECOVERY_BACKEND;
rt_context = (rt_context_t *)&error_recovery_info;
rt_context = (rt_context_t *)&error_recovery_info.rt;
if (setjmp(error_recovery_info.con.text))
{

View File

@ -64,10 +64,10 @@ last_bit (string_t *str)
*/
{
mp_int pos;
long len;
char * cstr;
int c;
mp_int pos;
long len;
const char * cstr;
int c;
pos = -1;
@ -624,7 +624,7 @@ f_count_bits (svalue_t *sp)
} /* f_count_bits() */
/*-------------------------------------------------------------------------*/
static INLINE void
static void
copy_bits ( string_t * dest, p_int deststart
, string_t * src, p_int srcstart
, p_int len

View File

@ -232,7 +232,7 @@ typedef bytecode_t * bytecode_p;
RSTORE_2BYTE(p,_us);)
#else
# error "Unsupported size of short."
#endif
#endif /* SIZEOF_SHORT */
#if SIZEOF_LONG == 4
# define GET_LONG(d,p) GET_4BYTE(d,p)
@ -256,7 +256,7 @@ typedef bytecode_t * bytecode_p;
RSTORE_4BYTE(p,_ui);)
#else
# error "Unsupported size of long."
#endif
#endif /* SIZEOF_LONG */
#define LOAD_INT16(d,p) LOAD_2BYTE(d,p)
@ -280,7 +280,7 @@ typedef bytecode_t * bytecode_p;
# define LOAD_INT32(d,p) LOAD_2BYTE(d,p)
#endif
#endif
#endif /* CHAR_BIT */
#ifndef GET_CODE
# error "No bytecode type defined."

View File

@ -46,6 +46,8 @@
#include "wiz_list.h"
#include "xalloc.h"
#include "i-eval_cost.h"
#include "../mudlib/sys/debug_info.h"
/*-------------------------------------------------------------------------*/
@ -262,7 +264,7 @@ call_out (void)
error_recovery_info.rt.last = rt_context;
error_recovery_info.rt.type = ERROR_RECOVERY_BACKEND;
rt_context = (rt_context_t *)&error_recovery_info;
rt_context = (rt_context_t *)&error_recovery_info.rt;
if (setjmp(error_recovery_info.con.text))
{

View File

@ -344,6 +344,9 @@ static work_area_t current
/* Forward declarations */
static void lambda_error VARPROT((const char *error_str, ...), printf, 1, 2) NORETURN;
static void lambda_cerror(const char *s) FORMATDEBUG(printf,1,0) NORETURN;
static void lambda_cerrorl(const char *s1, const char *s2 UNUSED, int line1 UNUSED,
int line2 UNUSED) NORETURN FORMATDEBUG(printf,1,0);
static void free_symbols(void);
static Bool is_lvalue (svalue_t *argp, int index_lvalue);
static void compile_lvalue(svalue_t *, int);
@ -939,7 +942,7 @@ replace_program_lambda_adjust (replace_ob_t *r_ob)
error_recovery_info.rt.last = rt_context;
error_recovery_info.rt.type = ERROR_RECOVERY_BACKEND;
rt_context = (rt_context_t *)&error_recovery_info;
rt_context = (rt_context_t *)&error_recovery_info.rt;
if (setjmp(error_recovery_info.con.text))
{
bytecode_p p;
@ -1347,8 +1350,9 @@ realloc_values (void)
new_values = xalloc(new_max * sizeof(*new_values));
if (!new_values)
lambda_error("Out of memory (%lu bytes) for %ld new values\n"
, new_max, new_max * sizeof(*new_values));
lambda_error("Out of memory (%"PRIdMPINT
" bytes) for %"PRIdMPINT" new values\n",
new_max, new_max * sizeof(*new_values));
current.values_left += current.value_max;
memcpy( (current.valuep = new_values + current.value_max)
@ -1380,7 +1384,8 @@ realloc_code (void)
new_max = current.code_max * 2;
new_code = rexalloc(current.code, (size_t)new_max);
if (!new_code)
lambda_error("Out of memory (%ld bytes) for new code\n", new_max);
lambda_error("Out of memory (%"PRIdMPINT" bytes) for new code\n",
new_max);
current.code_left += current.code_max;
current.code_max = new_max;
@ -1595,7 +1600,7 @@ make_symbol (string_t *name)
if (!symp) {
current.symbol_max /= 2;
xfree(sym);
lambda_error("Out of memory (%ld bytes) for symbol table\n"
lambda_error("Out of memory (%"PRIdMPINT" bytes) for symbol table\n"
, current.symbol_max);
}
current.symbol_mask = i = current.symbol_max - (long)sizeof sym;
@ -5200,8 +5205,8 @@ lambda (vector_t *args, svalue_t *block, object_t *origin)
current.code_left = CODE_BUFFER_START_SIZE-3;
current.levels_left = MAX_LAMBDA_LEVELS;
if ( !(current.code = current.codep = xalloc((size_t)current.code_max)) )
lambda_error("Out of memory (%ld bytes) for initial codebuffer\n"
, current.code_max);
lambda_error("Out of memory (%"PRIdMPINT
" bytes) for initial codebuffer\n", current.code_max);
/* Store the lambda code header */
STORE_UINT8(current.codep, 0); /* dummy for num values */
@ -5212,8 +5217,9 @@ lambda (vector_t *args, svalue_t *block, object_t *origin)
if ( !(current.values =
xalloc(current.value_max * sizeof current.values[0])) )
{
lambda_error("Out of memory (%lu bytes) for initial value buffer\n"
, current.value_max * sizeof current.values[0]);
lambda_error("Out of memory (%"PRIdMPINT
" bytes) for initial value buffer\n",
current.value_max * sizeof current.values[0]);
}
current.valuep = current.values + current.value_max;

View File

@ -9,6 +9,10 @@
#include "svalue.h"
#endif /* USE_NEW_INLINES */
/* In case offsetof() is not a compiler builtin include stddef.h which
* supplies a define as fallback. Needed for LAMBDA_VALUE_OFFSET */
#include <stddef.h>
/* --- Types --- */
/* --- struct lambda_s: ---

File diff suppressed because it is too large Load Diff

View File

@ -156,6 +156,10 @@ struct input_to_s {
*
* When changing struct members, take care that you don't introduce
* unnecessary padding.
*
* If the CBool members should ever be changed to C99's _Bool, take care of
* checking who is relying on a specific size (e.g. some printf())
*
*/
struct interactive_s {
@ -416,7 +420,7 @@ extern void add_message VARPROT((const char *, ...), printf, 1, 2);
extern void flush_all_player_mess(void);
extern Bool get_message(char *buff, size_t *len);
extern void remove_interactive(object_t *ob, Bool force);
extern void set_noecho(interactive_t *i, char noecho, Bool local_change);
extern void set_noecho(interactive_t *i, char noecho, Bool local_change, Bool external);
extern int find_no_bang (interactive_t *ip);
extern Bool call_function_interactive(interactive_t *i, char *str, size_t len);
extern void remove_all_players(void);

View File

@ -14,6 +14,9 @@
#include "config.h"
/* Include the portability headers */
#include "port.h"
/* TODO: Some TODO defines */
/* NO_NEGATIVE_RANGES: If defined, assignments to negative ranges
@ -46,17 +49,26 @@
# define GC_SUPPORT 1
#endif
/* Do some of the selected packages require special treatment? */
/* SQLite in the threadsafe mode needs a normal malloc() */
#if defined(SBRK_OK) && defined(USE_SQLITE)
# undef SBRK_OK
#endif
/* ptmalloc only works correctly with SBRK_OK right now. */
#ifdef MALLOC_ptmalloc
# ifndef SBRK_OK
# define SBRK_OK
# endif
#else // no ptmalloc
/* SQLite in the threadsafe mode needs a normal malloc() if the allocator is
* not ptmalloc*/
# if defined(SBRK_OK) && defined(USE_SQLITE) && defined(SQLITE3_USES_PTHREADS)
# undef SBRK_OK
# endif
/* PTHREADS need a normal malloc() if the allocator is not ptmalloc */
# if defined(SBRK_OK) && defined(USE_PTHREADS)
# undef SBRK_OK
# endif
#endif // MALLOC_ptmalloc
/* PTHREADS need a normal malloc() */
#if defined(SBRK_OK) && (defined(USE_PTHREADS) || defined(SQLITE3_USES_PTHREADS))
# undef SBRK_OK
#endif
/* When we have allocation tracing, the allocator annotates every
* allocation with the source filename and line where the allocation
@ -131,9 +143,6 @@
# define __IPV6__
#endif
/* Include the portability headers */
#include "port.h"
/* TODO: this ctype-stuff might go into lex.h (impl in efun_defs.c) */
#define _MCTe 0x01 /* escaped character in save/restore object. */
#define _MCTd 0x02 /* numeric digit */
@ -166,4 +175,10 @@ extern unsigned char _my_ctype[];
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif /* MIN */
/* For the use of mudlib/sys/debug_info.h.
*/
#ifdef EVAL_COST_TRACE
#define __EVAL_COST_TRACE__
#endif
#endif /* DRIVER_H__ */

View File

@ -346,7 +346,7 @@ dumpstat (string_t *fname)
overhead += sizeof (object_t);
fprintf(f, "%-20s %5ld (%5ld) ref %2ld %s "
fprintf(f, "%-20s %5"PRIdMPINT" (%5"PRIdMPINT") ref %2"PRIdPINT" %s "
, get_txt(ob->name)
, compsize + overhead, totalsize + overhead
, ob->ref
@ -360,14 +360,15 @@ dumpstat (string_t *fname)
fprintf(f, "-- ");
if (ob->gigaticks)
fprintf(f, " (%lu%09lu)", ob->gigaticks, ob->ticks);
fprintf(f, " (%"PRIuMPINT"%09"PRIuMPINT")",
(mp_uint)ob->gigaticks, (mp_uint)ob->ticks);
else
fprintf(f, " (%lu)", ob->ticks);
fprintf(f, " (%"PRIuMPINT")", (mp_uint)ob->ticks);
fprintf(f, " %s",
swapstrings[(O_PROG_SWAPPED(ob)?1:0) | (O_VAR_SWAPPED(ob)?2:0)]
);
tm = localtime((time_t *)&ob->load_time);
strftime(timest, sizeof(timest)-1, "%Y.%m.%d-%H:%M:%S", tm);
strftime(timest, sizeof(timest), "%Y.%m.%d-%H:%M:%S", tm);
fprintf(f, " %s\n", timest);
}
fclose(f);
@ -406,7 +407,7 @@ dumpstat_dest(string_t *fname)
if (!(ob->flags & O_DESTRUCTED)) /* TODO: Can't happen */
continue;
#endif
fprintf(f, "%-20s ref %2ld NEW\n"
fprintf(f, "%-20s ref %2"PRIdPINT" NEW\n"
, get_txt(ob->name)
, ob->ref
);
@ -418,7 +419,7 @@ dumpstat_dest(string_t *fname)
if (!(ob->flags & O_DESTRUCTED)) /* TODO: Can't happen */
continue;
#endif
fprintf(f, "%-20s ref %2ld\n"
fprintf(f, "%-20s ref %2"PRIdPINT"\n"
, get_txt(ob->name)
, ob->ref
);

View File

@ -362,7 +362,7 @@ static void count_blanks(int line);
static void _count_blanks(char *str, int blanks);
static LINE *getptr(int num);
static void putcntl(char c);
static void prntln(char *str, int vflg, int lin);
static void prntln(char *str, Bool vflg, int lin);
static regexp_t *optpat(void);
/*-------------------------------------------------------------------------*/
@ -2917,6 +2917,7 @@ docmd (Bool glob)
free_mstring(fptr);
return err;
}
free_mstring(fptr);
P_FCHANGED = TRUE;
break;
@ -3257,8 +3258,12 @@ clear_ed_buffer_refs (ed_buffer_t *b)
{
object_t *ob;
if (b->fname)
clear_string_ref(b->fname);
if (b->exit_fn)
{
clear_string_ref(b->exit_fn);
if ( NULL != (ob = b->exit_ob) )
{
if (ob->flags & O_DESTRUCTED)

File diff suppressed because it is too large Load Diff

View File

@ -76,21 +76,26 @@ extern svalue_t *f_localtime (svalue_t *sp);
extern svalue_t *f_blueprint (svalue_t *sp);
extern svalue_t *v_clones (svalue_t *sp, int num_args);
extern svalue_t *v_object_info (svalue_t *sp, int num_args);
extern svalue_t *f_present_clone (svalue_t *sp);
extern svalue_t *v_present_clone (svalue_t *sp, int num_arg);
extern svalue_t *f_to_object(svalue_t *sp);
extern svalue_t *f_set_is_wizard(svalue_t *sp); /* optional */
extern svalue_t *tell_room(svalue_t *sp);
extern svalue_t *f_ctime(svalue_t *);
extern svalue_t *v_strftime(svalue_t *, int num_arg);
extern svalue_t *v_debug_info(svalue_t *sp, int num_arg);
extern svalue_t *f_rusage(svalue_t *sp);
extern svalue_t *f_random(svalue_t *);
extern svalue_t *f_shutdown(svalue_t *sp);
extern svalue_t *f_time(svalue_t *);
extern svalue_t *f_utime(svalue_t *);
extern svalue_t *f_mktime(svalue_t *);
extern svalue_t *f_strftime(svalue_t *);
extern svalue_t *f_strptime(svalue_t *);
extern svalue_t *f_mktime(svalue_t *);
extern svalue_t *f_utime(svalue_t *);
#ifdef GC_SUPPORT
extern void clear_ref_from_efuns(void);
extern void count_ref_from_efuns(void);
#endif /* GC_SUPPORT */
#endif /* EFUNS_H__ */

View File

@ -46,7 +46,7 @@ extern int lstat(const char *, struct stat *);
#ifdef SunOS4
# if !defined (__GNUC__) || __GNUC__ < 2 || __GNUC__ == 2 && __GNUC_MINOR__ < 7
extern int lstat(CONST char *, struct stat *);
extern int lstat (CONST char *, struct stat *);
# endif
extern int fchmod(int, int);
#endif
@ -74,10 +74,6 @@ extern int fchmod(int, int);
#include "../mudlib/sys/files.h"
/* TODO: The move/copy code is a derivate of the GNU fileutils. Rewrite
* TODO:: it, replace it by the BSD code, or put the driver under the GPL.
*/
/*-------------------------------------------------------------------------*/
static Bool
isdir (const char *path)
@ -115,95 +111,81 @@ copy_file (const char *from, const char *to, int mode)
*/
{
int ifd;
int ofd;
char buf[1024 * 8];
int len; /* Number of bytes read into `buf'. */
if (unlink(to) && errno != ENOENT)
int fromfd, tofd;
ssize_t count;
char buf[4096];
fromfd = ixopen(from, O_RDONLY);
if (fromfd < 0)
{
debug_message("copy_file(): cannot remove `%s'\n", to);
debug_message("copy_file(): can't open '%s': %s\n", from, strerror(errno));
return 1;
}
/* We have to unlink 'to', because it may be a symlink.
O_CREAT won't remove that. */
if (unlink(to) < 0 && errno != ENOENT)
{
debug_message("copy_file(): can't unlink '%s': %s\n", to, strerror(errno));
close(fromfd);
return 1;
}
tofd = ixopen3(to, O_WRONLY|O_CREAT|O_TRUNC, mode);
if (tofd < 0)
{
debug_message("copy_file(): can't open '%s': %s\n", to, strerror(errno));
close(fromfd);
return 1;
}
ifd = ixopen3(from, O_RDONLY | O_BINARY, 0);
if (ifd < 0)
#ifdef HAVE_FCHMOD
/* We have given the file mode to ixopen3, this is just to counter umask.
So don't worry if this fchmod fails. */
fchmod(tofd, mode);
#endif
do
{
debug_message("copy_file(): %s: open failed\n", from);
return errno;
}
ofd = ixopen3(to, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600);
if (ofd < 0)
{
debug_message("copy_file(): %s: open failed\n", to);
close(ifd);
return 1;
}
#ifdef HAVE_FCHMOD
if (fchmod(ofd, mode))
{
debug_message("copy_file(): %s: fchmod failed\n", to);
close(ifd);
close(ofd);
unlink(to);
return 1;
}
#endif
ssize_t written;
count = read(fromfd, buf, sizeof(buf));
if (count < 0)
{
debug_message("copy_file(): can't read from '%s': %s\n", from, strerror(errno));
close(fromfd);
close(tofd);
unlink(to);
return 1;
}
written = 0;
while (written < count)
{
ssize_t len;
len = write(tofd, buf + written, count - written);
if (len <= 0)
{
debug_message("copy_file(): can't write to '%s': %s\n", to, strerror(errno));
close(fromfd);
close(tofd);
unlink(to);
return 1;
}
written += len;
}
} while (count > 0);
FCOUNT_READ(from);
FCOUNT_WRITE(to);
while ((len = read(ifd, buf, sizeof (buf))) > 0)
{
int wrote = 0;
char *bp = buf;
do
{
wrote = write(ofd, bp, len);
if (wrote < 0)
{
debug_message("copy_file(): %s: write failed\n", to);
close(ifd);
close(ofd);
unlink(to);
return 1;
}
bp += wrote;
len -= wrote;
} while (len > 0);
}
if (len < 0)
{
debug_message("copy_file(): %s: read failed\n", from);
close(ifd);
close(ofd);
unlink(to);
return 1;
}
if (close (ifd) < 0)
{
debug_message("copy_file(): %s: close failed\n", from);
close(ofd);
return 1;
}
if (close (ofd) < 0)
{
debug_message("copy_file(): %s: close failed\n", to);
return 1;
}
close(fromfd);
close(tofd);
#ifndef HAVE_FCHMOD
if (chmod (to, mode))
{
debug_message("copy_file(): %s: chmod failed\n", to);
return 1;
}
chmod(to, mode);
#endif
return 0;
@ -218,80 +200,55 @@ move_file (const char *from, const char *to)
*/
{
struct stat to_stats, from_stats;
if (lstat(from, &from_stats) != 0)
struct stat fromstat, tostat;
if (lstat(from, &fromstat) < 0)
{
debug_message("move_file(): %s: lstat failed\n", from);
debug_message("move_file(): can't lstat '%s': %s\n", from, strerror(errno));
return 1;
}
if (lstat (to, &to_stats) == 0)
if (!lstat(to, &tostat))
{
if (from_stats.st_dev == to_stats.st_dev
&& from_stats.st_ino == to_stats.st_ino)
if (fromstat.st_dev == tostat.st_dev
&& fromstat.st_ino == tostat.st_ino)
{
debug_message("move_file(): '%s' and '%s' are the same file\n", from, to);
/* Same file. */
debug_message("move_file(): '%s' and '%s' are the same.\n", from, to);
return 1;
}
if (S_ISDIR (to_stats.st_mode))
if (S_ISDIR(tostat.st_mode))
{
debug_message("move_file(): %s: cannot overwrite directory\n", to);
debug_message("move_file(): destination '%s' is a directory.\n", to);
return 1;
}
}
if (rename(from, to))
{
if (errno == EXDEV)
{
if (!S_ISREG(fromstat.st_mode))
{
debug_message("move_file(): can't move '%s' across filesystems: Not a regular file.\n", to);
return 1;
}
if (copy_file(from, to, fromstat.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)))
return 1;
unlink(from);
}
else
{
debug_message("move_file(): can't rename '%s' to '%s': %s\n", to, from, strerror(errno));
return 1;
}
}
else if (errno != ENOENT)
{
perror("do_move");
debug_message("move_file(): %s: unknown error\n", to);
return 1;
}
#ifndef RENAME_HANDLES_DIRECTORIES
/* old SYSV */
if (isdir(from))
{
char cmd_buf[3*MAXPATHLEN+1];
if (strchr(from, '\'') || strchr(to, '\''))
return 0;
sprintf(cmd_buf, "/usr/lib/mv_dir '%s' '%s'", from, to);
return system(cmd_buf);
}
else
#endif /* RENAME_HANDLES_DIRECTORIES */
if (rename (from, to) == 0)
{
FCOUNT_DEL(from);
return 0;
}
if (errno != EXDEV)
{
debug_message("move_file(): cannot move '%s' to '%s'\n", from, to);
return 1;
}
/* rename failed on cross-filesystem link. Copy the file instead. */
if (!S_ISREG(from_stats.st_mode))
{
debug_message("move_file(): cannot move '%s' across filesystems: "
"Not a regular file\n", from);
return 1;
}
if (copy_file(from, to, from_stats.st_mode & 0777))
return 1;
if (unlink(from))
{
debug_message("move_file(): cannot remove '%s'\n", from);
return 1;
}
FCOUNT_DEL(from);
return 0;
} /* move_file() */
@ -1750,7 +1707,7 @@ f_write_file (svalue_t *sp)
break;
if (sp->u.number & 1)
if (remove(get_txt(file)))
if (remove(get_txt(file)) && errno != ENOENT)
{
perror("write_file (remove)");
errorf("Could not remove %s: errno %d.\n", get_txt(file), errno);

View File

@ -657,7 +657,7 @@ object first_inventory(object|string default: F_THIS_OBJECT);
object next_inventory(object default: F_THIS_OBJECT);
void move_object(object|string, object|string);
object present(object|string, void|int|object, void|object);
object present_clone(object|string, object default: F_THIS_OBJECT); /* PRELIMINARY */
object present_clone(object|string, object|int|void, int|void);
#ifdef USE_STRUCTS
void say(string|mixed *|object|mapping|struct, void|object|object *);
#else

View File

@ -94,6 +94,7 @@
#include "closure.h"
#include "comm.h"
#include "ed.h"
#include "efuns.h"
#include "filestat.h"
#include "heartbeat.h"
#include "interpret.h"
@ -124,6 +125,8 @@
#include "wiz_list.h"
#include "xalloc.h"
#include "i-eval_cost.h"
#include "../mudlib/sys/driver_hook.h"
/*-------------------------------------------------------------------------*/
@ -2094,6 +2097,7 @@ garbage_collection(void)
mstring_clear_refs();
clear_ref_from_wiz_list();
clear_ref_from_call_outs();
clear_ref_from_efuns();
#if defined(USE_PARSE_COMMAND)
clear_parse_refs();
#endif
@ -2313,6 +2317,7 @@ garbage_collection(void)
count_ref_from_wiz_list();
count_ref_from_call_outs();
count_ref_from_efuns();
if (master_ob)
master_ob->ref++;

View File

@ -57,6 +57,8 @@
#include "wiz_list.h"
#include "xalloc.h"
#include "i-eval_cost.h"
#include "../mudlib/sys/debug_info.h"
/*-------------------------------------------------------------------------*/
@ -165,7 +167,7 @@ call_heart_beat (void)
error_recovery_info.rt.last = rt_context;
error_recovery_info.rt.type = ERROR_RECOVERY_BACKEND;
rt_context = (rt_context_t *)&error_recovery_info;
rt_context = (rt_context_t *)&error_recovery_info.rt;
if (setjmp(error_recovery_info.con.text))
{

82
src/i-eval_cost.h Normal file
View File

@ -0,0 +1,82 @@
/*---------------------------------------------------------------------------
* Eval Cost functions.
*
*---------------------------------------------------------------------------
*/
#ifndef I_EVAL_COST__
#define I_EVAL_COST__
#include "driver.h"
#include "interpret.h"
/*-------------------------------------------------------------------------*/
static INLINE Bool
add_eval_cost_n (int32 added_cost, uint repetitions)
/* Increase the evaluation cost by <added_cost>*<repetitions>. Return TRUE if
* this would exceed max_eval_cost, return FALSE if not.
*
* Passing <repetitions> explicitely guards against situations where
* <added_cost>*<repetitions> itself would overflow.
*
* To safeguard the driver against ridiculous executions, the actual eval_cost
* is capped at max_eval_cost+1.
*/
{
if (repetitions == 0)
return MY_FALSE;
if (max_eval_cost)
{
/* Test the evaluation cost against the limit.
* eval_cost < 0 signify a wrap-around - unlikely, but with these crazy
* wizards everything is possible.
*/
if (eval_cost >= max_eval_cost || eval_cost < 0)
return MY_TRUE;
if (max_eval_cost - eval_cost < added_cost
|| (int32)((max_eval_cost - eval_cost) / repetitions) < added_cost
)
{
total_evalcost += max_eval_cost - eval_cost + 1;
eval_cost = max_eval_cost+1;
return MY_TRUE;
}
}
eval_cost += added_cost * repetitions;
total_evalcost += added_cost * repetitions;
return MY_FALSE;
} /* add_eval_cost_n() */
/*-------------------------------------------------------------------------*/
/* --- Macros --- */
/* Increase the eval cost for a non-repetitive action.
*/
#define add_eval_cost(cost) add_eval_cost_n(cost, 1)
/* Reset the evaluation cost/time counter.
*/
#define CLEAR_EVAL_COST (assigned_eval_cost = eval_cost = 0)
/* Check if the current evaluation took too long
*/
#define EVALUATION_TOO_LONG() \
(max_eval_cost && (eval_cost >= max_eval_cost || eval_cost < 0))
/* Return the amount of remaining evaluation costs, or MAX_INT if there
* is no real maximum.
*/
#define GET_REMAINING_EVAL_COST() \
( max_eval_cost ? ((eval_cost >= max_eval_cost || eval_cost < 0) ? 0 : (max_eval_cost - eval_cost)) : INT32_MAX)
/***************************************************************************/
#endif /* I_EVAL_COST__ */

View File

@ -37,7 +37,7 @@ svalue_cmp (svalue_t *left, svalue_t *right)
*/
{
register int d;
register p_int d;
if ( 0 != (d = left->type - right->type) ) return d;

File diff suppressed because it is too large Load Diff

View File

@ -78,23 +78,28 @@ struct control_stack {
* TODO: This should be mirrored in the current_object global variable,
* TODO:: to avoid accesses to wrong functions/variables.
*/
#ifdef EVAL_COST_TRACE
int32 eval_cost;
/* The eval cost at that moment. */
#endif
};
/* --- Macros --- */
/* a general error handler structure. head is assigned as payload to an
* T_LVALUE svalue of type T_ERROR_HANDLER and pushed onto the value stack.
* If the stack is unrolled during runtime errors the error_handler function
* is called and frees buff. */
typedef struct errorhandler_s {
svalue_t head; /* The T_ERROR_HANDLER structure */
char * buff; /* The allocated buffer to free. */
} errorhandler_t;
#define MAX_SHIFT ((sizeof(p_int) << 3) - 1)
/* --- Constants --- */
static const short MAX_SHIFT = (sizeof(p_int) << 3) - 1;
/* The maximally useful shift (left or right) of a number in LPC.
*/
/* Reset the evaluation cost/time counter.
*/
#define CLEAR_EVAL_COST (assigned_eval_cost = eval_cost = 0)
/* Check if the current evaluation took too long
*/
#define EVALUATION_TOO_LONG() \
(max_eval_cost && (eval_cost >= max_eval_cost || eval_cost < 0))
/* --- Variables --- */
extern program_t *current_prog;
@ -108,12 +113,11 @@ extern svalue_t *current_variables;
extern int32 eval_cost;
extern int32 assigned_eval_cost;
extern svalue_t apply_return_value;
extern svalue_t catch_value;
extern svalue_t last_indexing_protector;
#ifdef APPLY_CACHE_STAT
extern p_int apply_cache_hit;
extern p_int apply_cache_miss;
extern p_uint apply_cache_hit;
extern p_uint apply_cache_miss;
#endif
extern unsigned long total_evalcost;
@ -138,7 +142,8 @@ extern void push_control_stack(svalue_t *sp, bytecode_p pc, svalue_t *fp);
extern void pop_control_stack(void);
extern struct longjump_s *push_error_context(svalue_t *sp, int catch_flags);
extern void pop_error_context (void);
extern svalue_t *pull_error_context (svalue_t *sp);
extern svalue_t *pull_error_context (svalue_t *sp, svalue_t *msg);
extern void transfer_error_message (svalue_t *v, rt_context_t *rt);
extern Bool destructed_object_ref (svalue_t *svp);
extern void free_object_svalue(svalue_t *v);
extern void zero_object_svalue(svalue_t *v);
@ -156,6 +161,11 @@ extern void push_svalue(svalue_t *v);
extern void push_svalue_block(int num, svalue_t *v);
extern svalue_t *pop_n_elems (int n, svalue_t *sp);
extern void pop_stack(void);
extern void push_apply_value(void);
extern void pop_apply_value (void);
extern void push_referenced_mapping(mapping_t *m);
extern svalue_t *push_error_handler(void (*errorhandler)(svalue_t *), svalue_t *arg);
extern void *xalloc_with_error_handler(size_t size);
extern void init_interpret(void);
extern const char *typename(int type);
@ -170,8 +180,7 @@ extern void vefun_exp_arg_error (int arg, long expected, int got, svalue_t *sp)
extern Bool privilege_violation(string_t *what, svalue_t *arg, svalue_t *sp);
extern Bool privilege_violation2(string_t *what, svalue_t *arg, svalue_t *arg2, svalue_t *sp);
extern Bool privilege_violation4(string_t *what, object_t *whom, string_t *how_str, int how_num, svalue_t *sp);
extern void push_apply_value(void);
extern void pop_apply_value (void);
extern svalue_t *sapply_int(string_t *fun, object_t *ob, int num_arg, Bool b_ign_prot, Bool b_use_default);
#define sapply(f,o,n) sapply_int(f,o,n, MY_FALSE, MY_TRUE)
#define sapply_ign_prot(f,o,n) sapply_int(f,o,n, MY_TRUE, MY_TRUE)
@ -182,7 +191,11 @@ extern string_t *collect_trace(strbuf_t * sbuf, vector_t ** rvec);
extern string_t *dump_trace(Bool how, vector_t **rvec);
extern int get_line_number_if_any(string_t **name);
extern void reset_machine(Bool first);
extern svalue_t *secure_apply(string_t *fun, object_t *ob, int num_arg);
extern void secure_apply_error(svalue_t *save_sp, struct control_stack *save_csp, Bool clear_costs);
extern svalue_t *secure_apply_ob(string_t *fun, object_t *ob, int num_arg, Bool external);
#define secure_apply(fun, ob, num_arg) secure_apply_ob(fun, ob, num_arg, MY_FALSE)
#define secure_callback(fun, ob, num_arg) secure_apply_ob(fun, ob, num_arg, MY_TRUE)
extern svalue_t *apply_master_ob(string_t *fun, int num_arg, Bool external);
#define apply_master(fun, num_arg) apply_master_ob(fun, num_arg, MY_FALSE)
#define callback_master(fun, num_arg) apply_master_ob(fun, num_arg, MY_TRUE)
@ -198,12 +211,9 @@ extern void int_call_lambda(svalue_t *lsvp, int num_arg, Bool allowRefs);
extern inherit_t *adjust_variable_offsets(const inherit_t *inheritp, const program_t *prog, const object_t *obj);
extern void free_interpreter_temporaries(void);
extern void invalidate_apply_low_cache(void);
extern void push_referenced_mapping(mapping_t *m);
extern void push_error_handler(void (*errorhandler)(svalue_t *), svalue_t *arg);
extern void m_indices_filter (svalue_t *key, svalue_t *data, void *extra);
extern void m_values_filter (svalue_t *key, svalue_t *data, void *extra);
extern void m_unmake_filter ( svalue_t *key, svalue_t *data, void *extra);
extern int last_instructions(int length, Bool verbose, svalue_t **svpp);
extern svalue_t *v_apply (svalue_t *sp, int num_arg);
extern svalue_t *v_funcall (svalue_t *sp, int num_arg);
extern svalue_t *v_call_direct_resolved (svalue_t *sp, int num_arg);
@ -212,7 +222,6 @@ extern svalue_t *f_caller_stack_depth (svalue_t *sp);
extern svalue_t *f_caller_stack (svalue_t *sp);
extern svalue_t *f_get_eval_cost (svalue_t *sp);
extern svalue_t *f_previous_object (svalue_t *sp);
extern svalue_t *f_last_instructions(svalue_t *sp);
extern svalue_t *f_set_this_object (svalue_t *sp);
extern svalue_t *f_trace(svalue_t *sp);
extern svalue_t *f_traceprefix(svalue_t *sp);
@ -222,7 +231,8 @@ extern Bool opcdump(string_t *fname);
#endif
#ifdef TRACE_CODE
extern int last_instructions(int length, int verbose, svalue_t **svpp);
extern svalue_t *f_last_instructions(svalue_t *sp);
extern int last_instructions(int length, Bool verbose, svalue_t **svpp);
#endif
#ifdef DEBUG
@ -240,5 +250,6 @@ extern void clear_interpreter_refs(void);
extern void count_interpreter_refs(void);
#endif
extern int control_stack_depth(void);
#endif /* INTERPRET_H__ */

View File

@ -62,6 +62,8 @@
#include "wiz_list.h" /* wizlist_name[] */
#include "xalloc.h"
#include "i-eval_cost.h"
#include "../mudlib/sys/driver_hook.h"
/* TODO: Implement the # and ## operators. With this, #define X(a) (a + "a")
@ -795,24 +797,27 @@ init_lexer(void)
sprintf(mtext, "%d", ERQ_MAX_REPLY);
add_permanent_define("__ERQ_MAX_REPLY__", -1, string_copy(mtext), MY_FALSE);
#endif
sprintf(mtext, "%ld", (long)max_malloced);
sprintf(mtext, "%"PRIdMPINT, max_malloced);
add_permanent_define("__MAX_MALLOC__", -1, string_copy(mtext), MY_FALSE);
sprintf(mtext, "%ld", (long)def_eval_cost);
sprintf(mtext, "%"PRId32, def_eval_cost);
add_permanent_define("__MAX_EVAL_COST__", -1, string_copy(mtext), MY_FALSE);
sprintf(mtext, "%ld", (long)CATCH_RESERVED_COST);
add_permanent_define("__CATCH_EVAL_COST__", -1, string_copy(mtext), MY_FALSE);
sprintf(mtext, "%ld", (long)MASTER_RESERVED_COST);
add_permanent_define("__MASTER_EVAL_COST__", -1, string_copy(mtext), MY_FALSE);
sprintf(mtext, "%ld", (long)time_to_reset);
sprintf(mtext, "%ld", time_to_reset);
add_permanent_define("__RESET_TIME__", -1, string_copy(mtext), MY_FALSE);
sprintf(mtext, "%ld", (long)time_to_cleanup);
sprintf(mtext, "%ld", time_to_cleanup);
add_permanent_define("__CLEANUP_TIME__", -1, string_copy(mtext), MY_FALSE);
sprintf(mtext, "%ld", (long)alarm_time);
sprintf(mtext, "%ld", alarm_time);
add_permanent_define("__ALARM_TIME__", -1, string_copy(mtext), MY_FALSE);
sprintf(mtext, "%ld", (long)heart_beat_interval);
sprintf(mtext, "%ld", heart_beat_interval);
add_permanent_define("__HEART_BEAT_INTERVAL__", -1, string_copy(mtext), MY_FALSE);
if (synch_heart_beats)
add_permanent_define("__SYNCHRONOUS_HEART_BEAT__", -1, string_copy("1"), MY_FALSE);
#ifdef EVAL_COST_TRACE
add_permanent_define("__EVAL_COST_TRACE__", -1, string_copy("1"), MY_FALSE);
#endif
#ifdef MSDOS_FS
add_permanent_define("__MSDOS_FS__", -1, string_copy("1"), MY_FALSE);
#endif
@ -834,6 +839,9 @@ init_lexer(void)
#ifdef USE_SQLITE
add_permanent_define("__SQLITE__", -1, string_copy("1"), MY_FALSE);
#endif
#ifdef USE_IKSEMEL
add_permanent_define("__XML_DOM__", -1, string_copy("1"), MY_FALSE);
#endif
#ifdef USE_EXPAT
add_permanent_define("__EXPAT__", -1, string_copy("1"), MY_FALSE);
#endif
@ -892,15 +900,15 @@ init_lexer(void)
add_permanent_define("__WIZLIST__", -1, string_copy(mtext), MY_FALSE);
}
sprintf(mtext, "(%ld)", PINT_MAX);
sprintf(mtext, "(%"PRIdPINT")", PINT_MAX);
add_permanent_define("__INT_MAX__", -1, string_copy(mtext), MY_FALSE);
sprintf(mtext, "(%ld)", PINT_MIN);
sprintf(mtext, "(%"PRIdPINT")", PINT_MIN);
add_permanent_define("__INT_MIN__", -1, string_copy(mtext), MY_FALSE);
sprintf(mtext, "(%g)", DBL_MAX);
add_permanent_define("__FLOAT_MAX__", -1, string_copy(mtext), MY_FALSE);
sprintf(mtext, "(%g)", DBL_MIN);
add_permanent_define("__FLOAT_MIN__", -1, string_copy(mtext), MY_FALSE);
sprintf(mtext, "%ld", get_current_time());
sprintf(mtext, "%"PRIdMPINT, get_current_time());
add_permanent_define("__BOOT_TIME__", -1, string_copy(mtext), MY_FALSE);
/* Add the permanent macro definitions given on the commandline */
@ -1925,8 +1933,8 @@ make_global_identifier (char *s, int n)
{
ip = xalloc(sizeof(ident_t));
if (!ip) {
yyerrorf("Out of memory: identifier (%lu bytes)"
, (unsigned long) sizeof(ident_t));
yyerrorf("Out of memory: identifier (%zu bytes)",
sizeof(ident_t));
return NULL;
}
ip->name = ref_mstring(q->name);
@ -2079,8 +2087,8 @@ realloc_defbuf (void)
defbuf_len <<= 1;
}
if (comp_flag)
fprintf(stderr, "%s (reallocating defbuf from %ld (%ld left) to %ld) "
, time_stamp(), (long)old_defbuf_len, (long)(old_outp-defbuf)
fprintf(stderr, "%s (reallocating defbuf from %zu (%td left) to %lu) "
, time_stamp(), old_defbuf_len, (ptrdiff_t)(old_outp-defbuf)
, defbuf_len);
defbuf = xalloc(defbuf_len);
memcpy(defbuf+defbuf_len-old_defbuf_len, old_defbuf, old_defbuf_len);
@ -2604,10 +2612,12 @@ add_auto_include (const char * obj_file, const char *cur_file, Bool sys_include)
if (auto_include_string != NULL)
{
/* The auto include string is handled like a normal include */
current_loc.line++; /* Make sure to restore to line 1 */
if (cur_file != NULL) /* Otherwise we already are at line 1 */
current_loc.line++; /* Make sure to restore to line 1 */
(void)start_new_include(-1, auto_include_string
, current_loc.file->name, "auto include", ')');
current_loc.line++; /* Make sure to start at line 1 */
if (cur_file == NULL) /* Otherwise #include will increment it */
current_loc.line++; /* Make sure to start at line 1 */
}
} /* add_auto_include() */
@ -3664,6 +3674,8 @@ parse_numeric_escape (char * cp, unsigned char * p_char)
/* strtol() gets the sign bit wrong,
* strtoul() isn't portable enough.
* TODO: strtoul should be portable enough today... Re-check if we
* TODO::require C99.
*/
num_digits = 2;
l = 0;
@ -3680,7 +3692,10 @@ parse_numeric_escape (char * cp, unsigned char * p_char)
/* Parse a normal number from here */
l = c - '0';
if (l < 0 || l > base)
/* l is unsigned. So any c smaller than '0' will be wrapped into
* positive values and be larger then base as well. Therefore an
* additional comparison of l < 0 is not explicitly needed here. */
if (l > base)
{
yywarn("Character constant used with no valid digits");
return NULL;
@ -3933,8 +3948,8 @@ add_lex_string (char *str, size_t slen)
new = mstr_add_txt(last_lex_string, str, slen);
if (!new)
{
lexerrorf("Out of memory for string concatenation (%lu bytes)"
, (unsigned long)len1+slen);
lexerrorf("Out of memory for string concatenation (%zu bytes)",
len1+slen);
}
free_mstring(last_lex_string);
last_lex_string = make_tabled(new);
@ -3961,8 +3976,8 @@ string (char *str, size_t slen)
last_lex_string = new_n_tabled(str, slen);
if (!last_lex_string)
{
lexerrorf("Out of memory for string literal (%lu bytes)"
, (unsigned long)slen);
lexerrorf("Out of memory for string literal (%zu bytes)",
slen);
}
}
return L_STRING;
@ -4233,7 +4248,7 @@ closure (char *in_yyp)
} /* closure() */
/*-------------------------------------------------------------------------*/
static INLINE char *
static char *
handle_preprocessor_statement (char * in_yyp)
/* The lexer has found a preprocessor statement (<newline>#), an <in_yyp>
@ -4647,18 +4662,6 @@ yylex1 (void)
current_loc = p->loc;
if (!was_string_source)
current_loc.line++;
else
{
/* 'string' includes are supposed to be inline
* so correct the line number information to take out
* the assumed newlines.
* This has to be done after store_include_end()
* since that function may remove all line number
* information since the start of the include.
*/
current_loc.line -= 1;
store_line_number_backward(1);
}
yyin = p->yyin;
saved_char = p->saved_char;
@ -7774,7 +7777,7 @@ show_lexer_status (strbuf_t * sbuf, Bool verbose UNUSED)
sum += 2 * DEFMAX; /* for the buffers in _expand_define() */
if (sbuf)
strbuf_addf(sbuf, "Lexer structures\t\t\t %9lu\n", sum);
strbuf_addf(sbuf, "Lexer structures\t\t\t %9zu\n", sum);
return sum;
} /* show_lexer_status() */
@ -7814,7 +7817,7 @@ count_lex_refs (void)
count_ident_refs(id);
for (id2 = id->inferior; id2 != NULL; id2 = id2->next)
{
count_ident_refs(id);
count_ident_refs(id2);
}
}
}

View File

@ -240,7 +240,7 @@ struct inline_fun
extern struct lpc_predef_s * lpc_predefs;
extern int total_lines;
extern source_loc_t current_loc;
extern int pragma_strict_types;
extern Bool pragma_strict_types;
extern Bool pragma_use_local_scopes;
extern Bool pragma_save_types;
extern Bool pragma_combine_strings;

View File

@ -76,6 +76,12 @@
#include "pkg-mysql.h"
#endif
#ifdef USE_IKSEMEL
#include "pkg-iksemel.h"
#endif
#include "i-eval_cost.h"
#include "../mudlib/sys/regexp.h"
/*-------------------------------------------------------------------------*/
@ -110,8 +116,6 @@ Bool share_variables = MY_FALSE; /* Clones are initialized from their
Bool allow_filename_spaces = MY_FALSE; /* Allow spaces in filenames */
static uint32 random_seed = 0; /* The seed for the pseudo-random generator. */
static char * hostname = NULL;
static char * hostaddr = NULL;
/* Hostname and -addr given on the commandline. They are passed as
@ -269,6 +273,7 @@ main (int argc, char **argv)
boot_time = (mp_int)time(NULL);
setlocale(LC_CTYPE, ""); /* Use the locale defined in the LANG env var */
setlocale(LC_TIME, "");
get_stack_direction();
mb_init();
init_interpret();
@ -278,9 +283,15 @@ main (int argc, char **argv)
put_number(&const1, 1);
current_time = get_current_time();
random_seed = (uint32)current_time;
seed_random(random_seed);
// Set prng_device_name to the default //
prng_device_name = strdup(PRNG_DEFAULT_DEVICE);
// init PRG by the default device (/dev/urandom)
// if --random-seed or --randomdevice is given on the command-line it
// will re-seeded later.
seed_random(prng_device_name);
do {
dummy_current_object_for_loads = NULL_object;
#ifdef DEBUG
@ -437,15 +448,6 @@ main (int argc, char **argv)
for (i = 0; i < (int)(sizeof avg_consts / sizeof avg_consts[0]); i++)
avg_consts[i] = exp(- i / 900.0);
#ifdef USE_LDMUD_COMPATIBILITY
# ifdef VERBOSE
printf("%s Random seed: 0x%lx\n"
, time_stamp(), (unsigned long)random_seed);
# endif
debug_message("%s Random seed: 0x%lx\n"
, time_stamp(), (unsigned long)random_seed);
#endif
#ifdef USE_MYSQL
if (!pkg_mysql_init())
{
@ -454,6 +456,10 @@ main (int argc, char **argv)
}
#endif
#ifdef USE_IKSEMEL
pkg_iksemel_init();
#endif
/* If the master_name hasn't been set, select a sensible default */
if ('\0' == master_name[0])
{
@ -1064,6 +1070,7 @@ typedef enum OptNumber {
, cNoHeart /* --no-heart */
, cNoPreload /* --no-preload */
, cPidFile /* --pidfile */
, cRandomdevice /* --randomdevice */
, cRandomSeed /* --random-seed */
, cRegexp /* --regexp */
, cResetTime /* --reset-time */
@ -1506,6 +1513,16 @@ static Option aOptions[]
, " Use <pathname> as the directory where your certificate revocation lists reside.\n"
" If relative, <pathname> is interpreted relative to <mudlib>.\n"
}
, { 0, "tls-crlfile", cTLScrlfile, MY_TRUE
, " --tls-crlfile <pathname>\n"
, " Use <pathname> as the filename holding your certificate revocation lists.\n"
" If relative, <pathname> is interpreted relative to <mudlib>.\n"
}
, { 0, "tls-crldirectory", cTLScrldir, MY_TRUE
, " --tls-crldirectory <pathname>\n"
, " Use <pathname> as the directory where your certificate revocation lists reside.\n"
" If relative, <pathname> is interpreted relative to <mudlib>.\n"
}
#endif /* USE_TLS */
, { 0, "wizlist-file", cWizlistFile, MY_TRUE
@ -1527,6 +1544,13 @@ static Option aOptions[]
" Write the pid of the driver process into <filename>.\n"
}
, { 0, "randomdevice", cRandomdevice, MY_TRUE
, " --randomdevice <filename>\n"
, " --randomdevice <filename>\n"
" Determines the source of the seed for the random number generator.\n"
" (tries /dev/urandom by default and uses system clock as fallback)\n"
}
, { 0, "random-seed", cRandomSeed, MY_TRUE
, " --random-seed <num>\n"
, " --random-seed <num>\n"
@ -1820,6 +1844,9 @@ options (void)
#ifdef HAS_IDN
, "idna supported\n"
#endif
#ifdef USE_IKSEMEL
, "iksemel supported\n"
#endif
#ifdef USE_IPV6
, "IPv6 supported\n"
#endif
@ -2556,33 +2583,38 @@ eval_arg (int eOption, const char * pValue)
}
new_mudlib = 1;
#ifndef USE_LDMUD_COMPATIBILITY
debug_message("%s Sandboxing myself into %s\n",
debug_message("%s Entering my %s sandbox\n",
time_stamp(), pValue);
#endif
break;
#if 1 /* def USE_DEBUG_LOG */
case cDebugFile:
#ifdef USE_DEBUG_LOG
if (debug_file != NULL)
free(debug_file);
debug_file = strdup(pValue);
#else
debug_message("%s Ignoring --debug-file option\n"
/* " This function has been disabled at compile time.\n"
" Please remove it from your scripts.\n" */
, time_stamp());
debug_message("%s Ignoring --debug-file option\n", time_stamp());
#endif
break;
#endif
case cRandomdevice:
// sets prng_device_name to some file/device and re-seeds the PRNG
// from it.
if (prng_device_name != NULL)
free(prng_device_name);
prng_device_name = strdup(pValue);
seed_random(prng_device_name);
break;
case cRandomSeed:
// seeds PRG with given value
#ifdef HAVE_STRTOUL
random_seed = strtoul(pValue, (char **)0, 0);
seed_random_from_int(strtoul(pValue, (char **)0, 0));
#else
random_seed = (uint32)strtol(pValue, (char **)0, 0);
seed_random_from_int((uint32)strtol(pValue, (char **)0, 0));
#endif
seed_random(random_seed);
break;
case cReserved:
@ -2687,6 +2719,16 @@ eval_arg (int eOption, const char * pValue)
}
gcollect_outfd = default_gcollect_outfd;
break;
case cTLScrlfile:
if (tls_crlfile != NULL)
free(tls_crlfile);
tls_crlfile = strdup(pValue);
break;
case cTLScrldir:
if (tls_crldirectory != NULL)
free(tls_crldirectory);
tls_crldirectory = strdup(pValue);
break;
#endif
case cOptions:

View File

@ -61,7 +61,7 @@ extern int exit_code;
extern int main(int argc, char **argv);
extern void initialize_master_uid(void);
extern void debug_message(const char *, ...) FORMATDEBUG(printf, 1, 2);
extern void vdebug_message(const char *, va_list);
extern void vdebug_message(const char *, va_list) FORMATDEBUG(printf, 1, 0);
extern void write_X (int d, unsigned char i);
extern void write_x(int d, p_uint i);

View File

@ -485,7 +485,7 @@ static int curr_lpc_type_size = 0;
/* Forward declarations */
static void yyerror(const char *);
static void yyerror(const char *) NORETURN;
static int yylex(void);
int yyparse(void);
int ungetc(int c, FILE *f);
@ -496,7 +496,7 @@ static const char *ctype(int);
#ifndef toupper
int toupper(int);
#endif
static int fatal(const char *str);
static void fatal(const char *str) NORETURN;
static int cond_get_exp(int);
/*-------------------------------------------------------------------------*/
@ -517,7 +517,7 @@ mystrdup (const char *str)
}
/*-------------------------------------------------------------------------*/
static int
static void
fatal (const char *str)
/* Print <str> on stderr, flush stdout and exit the program with
@ -528,8 +528,6 @@ fatal (const char *str)
fprintf(stderr, "%s", str);
fflush(stdout);
exit(1);
/* NOTREACHED */
return 0;
}
/*-------------------------------------------------------------------------*/

View File

@ -15,6 +15,11 @@
* TODO:: The pool is not absolutely required, but would reduce overhead if
* TODO:: MALLOC_TRACE is in effect.
*
* TODO: Check if the use of mp_int is reasonable for values for num_values
* TODO::and num_entries (which are in the struct p_int). And check as
* TODO::the wild mixture of mp_int, p_int, size_t (and maybe still int?)
* TODO::used for iterating over mapping structures.
*
* Mappings, or 'associative arrays', are similar to normal arrays, with
* the principal difference that they can use every value to index their
* stored data, whereas arrays only index with integer values. On the
@ -370,7 +375,8 @@ get_new_hash ( mapping_t *m, mp_int hash_size)
*
* Return the new structure, or NULL when out of memory.
*/
/* TODO: hash_size of mp_int seems unnecessarily large to me, because
* TODO::mappings can only have p_int values? */
{
mapping_hash_t *hm;
map_chain_t **mcp;
@ -439,7 +445,8 @@ get_new_mapping ( wiz_list_t * user, mp_int num_values
*
* Return the new mapping, or NULL when out of memory.
*/
/* TODO: hash_size of mp_int seems unnecessarily large to me, because
* TODO::mappings can only have p_int values? */
{
mapping_cond_t *cm;
mapping_hash_t *hm;
@ -588,7 +595,8 @@ _free_mapping (mapping_t *m, Bool no_data)
fatal("No wizlist pointer for mapping");
if (!no_data && m->ref > 0)
fatal("Mapping with %ld refs passed to _free_mapping().\n", m->ref);
fatal("Mapping with %"PRIdPINT" refs passed to _free_mapping().\n",
m->ref);
#endif
num_mappings--;
@ -624,11 +632,11 @@ _free_mapping (mapping_t *m, Bool no_data)
if ( NULL != (hm = m->hash) )
{
map_chain_t **mcp, *mc, *next;
int i;
p_int i;
#ifdef DEBUG
if (hm->ref)
fatal("Ref count in freed hash mapping: %ld\n", hm->ref);
fatal("Ref count in freed hash mapping: %"PRIdPINT"\n", hm->ref);
#endif
LOG_SUB("free_mapping hash", SIZEOF_MH(hm));
m->user->mapping_total -= SIZEOF_MH(hm);
@ -694,8 +702,9 @@ free_protector_mapping (mapping_t *m)
}
#endif
dump_trace(MY_FALSE, NULL);
printf("%s free_protector_mapping() : no hash %s\n"
/* printf("%s free_protector_mapping() : no hash %s\n"
, time_stamp(), m->hash ? "reference" : "part");
*/
free_mapping(m);
}
#endif /* DEBUG */
@ -980,13 +989,14 @@ static svalue_t local_const0;
}
if (max_mapping_size && msize > (mp_int)max_mapping_size)
{
errorf("Illegal mapping size: %ld elements (%ld x %ld)\n"
, msize, (long)MAP_SIZE(m)+1, (long)m->num_values);
errorf("Illegal mapping size: %"PRIdMPINT" elements (%"
PRIdPINT" x %"PRIdPINT")\n"
, msize, MAP_SIZE(m)+1, m->num_values);
return NULL;
}
if (max_mapping_keys && MAP_SIZE(m) > (mp_int)max_mapping_keys)
{
errorf("Illegal mapping size: %ld entries\n", msize+1);
errorf("Illegal mapping size: %"PRIdMPINT" entries\n", msize+1);
return NULL;
}
}
@ -1188,7 +1198,7 @@ check_map_for_destr (mapping_t *m)
*/
{
int num_values;
p_int num_values;
mapping_cond_t *cm;
mapping_hash_t *hm;
@ -1210,7 +1220,7 @@ check_map_for_destr (mapping_t *m)
if (destructed_object_ref(entry))
{
int i;
p_int i;
svalue_t * data = COND_DATA(cm, ix, num_values);
/* Destructed key: remove the whole entry */
@ -1450,6 +1460,7 @@ resize_mapping (mapping_t *m, mp_int new_width)
mapping_hash_t * hm, *hm2 = NULL;
mapping_cond_t * cm, *cm2 = NULL;
mp_int common_width; /* == min(num_values, new_width) */
p_int num_entries;
/* Set the width variables */
if (m->num_values >= new_width)
@ -1469,12 +1480,14 @@ resize_mapping (mapping_t *m, mp_int new_width)
&& (SSIZE_MAX - sizeof(map_chain_t)) / new_width < sizeof(svalue_t))
)
{
errorf("Mapping width too big (%ld)\n", new_width);
errorf("Mapping width too big (%"PRIdMPINT")\n", new_width);
/* NOTREACHED */
return NULL;
}
}
num_entries = m->num_entries;
/* Get the target mapping without a hash, but with a condensed block
* big enough to hold all entries.
@ -1490,7 +1503,7 @@ resize_mapping (mapping_t *m, mp_int new_width)
m2 = get_new_mapping(current_object->user, new_width, 0, cm_size);
if (!m2)
{
outofmem(sizeof *m2 + sizeof(svalue_t) * m->num_entries * new_width
outofmem(sizeof *m2 + (mp_int)sizeof(svalue_t) * m->num_entries * new_width
, "result mapping base structure");
/* NOTREACHED */
return NULL;
@ -1531,39 +1544,42 @@ resize_mapping (mapping_t *m, mp_int new_width)
map_chain_t *last = NULL, *mc, *mc2;
for (mc = *mcp++; mc; mc = mc->next)
{
svalue_t *src, *dest;
p_int i;
mc2 = new_map_chain(m2);
if (!mc2)
if(destructed_object_ref(&(mc->data[0])))
num_entries--;
else
{
xfree(hm2);
outofmem(SIZEOF_MCH(mc, new_width), "hash link");
/* NOTREACHED */
return NULL;
svalue_t *src, *dest;
p_int i;
mc2 = new_map_chain(m2);
if (!mc2)
{
xfree(hm2);
outofmem(SIZEOF_MCH(mc, new_width), "hash link");
/* NOTREACHED */
return NULL;
}
/* Copy the key and the common values */
for (src = &(mc->data[0]), dest = &(mc2->data[0]), i = common_width
; i >= 0
; --i, src++, dest++)
{
assign_svalue_no_free(dest, src);
}
/* Zero out any extraneous values */
for (dest = &(mc2->data[common_width+1]), i = new_width - common_width
; i > 0
; --i, dest++)
{
put_number(dest, 0);
}
mc2->next = last;
last = mc2;
}
/* Copy the key and the common values */
for (src = &(mc->data[0]), dest = &(mc2->data[0]), i = common_width
; i >= 0
; --i, src++, dest++)
{
assign_svalue_no_free(dest, src);
}
/* Zero out any extraneous values */
for (dest = &(mc2->data[common_width+1]), i = new_width - common_width
; i > 0
; --i, dest++)
{
put_number(dest, 0);
}
mc2->next = last;
last = mc2;
}
*mcp2++ = last;
} while (--size);
@ -1595,7 +1611,24 @@ resize_mapping (mapping_t *m, mp_int new_width)
; src_ix < cm->size
; src_ix++, src_key++)
{
if (src_key->type != T_INVALID)
if (src_key->type == T_INVALID)
; /* Do nothing */
else if (destructed_object_ref(src_key))
{
/* We have to fill the space.
* (Alternatively we could decrease m->cond->size.)
*/
p_int i;
num_entries--;
dest_key->type = T_INVALID;
dest_key++;
for (i = new_width; i > 0; i--, dest_data++)
put_number(dest_data, 0);
}
else
{
p_int i;
@ -1616,7 +1649,7 @@ resize_mapping (mapping_t *m, mp_int new_width)
/* --- Finalize the basis structure ---
*/
m2->num_entries = m->num_entries;
m2->num_entries = num_entries;
/* That's it. */
return m2;
@ -1671,8 +1704,9 @@ add_mapping (mapping_t *m1, mapping_t *m2)
return copy_mapping(m1);
}
errorf("Mappings to be added are of different width: %ld vs. %ld\n"
, (long)num_values, (long)m2->num_values);
errorf("Mappings to be added are of different width: %"PRIdMPINT
" vs. %"PRIdPINT"\n",
num_values, m2->num_values);
}
@ -1730,7 +1764,8 @@ add_mapping (mapping_t *m1, mapping_t *m2)
; cm1_ix < cm1size && cm2_ix < cm2size
; NOOP )
{
int cmp, i;
int cmp;
p_int i;
if (src1_key->type == T_INVALID
|| destructed_object_ref(src1_key)
@ -1793,7 +1828,7 @@ add_mapping (mapping_t *m1, mapping_t *m2)
for ( ; cm1_ix < cm1size; cm1_ix++, src1_key++)
{
svalue_t *data = COND_DATA(cm1, cm1_ix, num_values);
int i;
p_int i;
if (src1_key->type != T_INVALID
&& !destructed_object_ref(src1_key))
@ -1811,7 +1846,7 @@ add_mapping (mapping_t *m1, mapping_t *m2)
for ( ; cm2_ix < cm2size; cm2_ix++, src2_key++)
{
svalue_t *data = COND_DATA(cm2, cm2_ix, num_values);
int i;
p_int i;
if (src2_key->type != T_INVALID
&& !destructed_object_ref(src2_key))
@ -1834,7 +1869,7 @@ add_mapping (mapping_t *m1, mapping_t *m2)
for ( ; (p_int)num_entries < cm3size; num_entries++)
{
int i;
p_int i;
dest_key->type = T_INVALID; dest_key++;
@ -1864,7 +1899,7 @@ add_mapping (mapping_t *m1, mapping_t *m2)
for (mc = *mcp++; mc; mc = mc->next)
{
svalue_t * src, * dest;
int i;
p_int i;
src = &(mc->data[0]);
dest = get_map_lvalue_unchecked(m3, src);
@ -1894,7 +1929,7 @@ add_mapping (mapping_t *m1, mapping_t *m2)
for (mc = *mcp++; mc; mc = mc->next)
{
svalue_t * src, * dest;
int i;
p_int i;
src = &(mc->data[0]);
dest = get_map_lvalue_unchecked(m3, src);
@ -2060,7 +2095,8 @@ compact_mapping (mapping_t *m, Bool force)
cm = m->cond;
if (hm && hm->ref) {
fatal("compact_mapping(): remaining protector ref count %ld!\n", hm->ref);
fatal("compact_mapping(): remaining protector ref count %"
PRIdPINT"!\n", hm->ref);
}
/* Test if the mapping is dirty at all.
@ -2184,7 +2220,7 @@ compact_mapping (mapping_t *m, Bool force)
if (last_hash)
{
p_int d = svalue_cmp(&(mcp->data[0]), &(last_hash->data[0]));
int d = svalue_cmp(&(mcp->data[0]), &(last_hash->data[0]));
if (d < 0) {
last_hash->next = hook1;
@ -2260,7 +2296,7 @@ compact_mapping (mapping_t *m, Bool force)
{
/* Sort the next runlength elements onto out1 */
while (1) {
p_int d = svalue_cmp(&(hook1->data[0]), &(hook2->data[0]));
int d = svalue_cmp(&(hook1->data[0]), &(hook2->data[0]));
if (d > 0)
{
@ -2352,7 +2388,7 @@ compact_mapping (mapping_t *m, Bool force)
map_chain_t *temp;
svalue_t *src;
int i;
p_int i;
*dest_key++ = hook1->data[0];
@ -2367,7 +2403,7 @@ compact_mapping (mapping_t *m, Bool force)
{
/* Take entry from the old condensed part */
int i;
p_int i;
*dest_key++ = *src_key++;
@ -2389,7 +2425,7 @@ compact_mapping (mapping_t *m, Bool force)
{
if (src_key->type != T_INVALID)
{
int i;
p_int i;
*dest_key++ = *src_key++;
@ -2412,7 +2448,7 @@ compact_mapping (mapping_t *m, Bool force)
{
map_chain_t *temp;
svalue_t *src;
int i;
p_int i;
*dest_key++ = hook1->data[0];
@ -2553,7 +2589,7 @@ mapping_overhead (mapping_t *m)
*/
struct set_mapping_user_locals
{
int num_values; /* Number of values per key */
p_int num_values; /* Number of values per key */
object_t *owner; /* Owner to set */
svalue_t **hairy;
/* Next free entry in the array of keys which need manual tweaking */
@ -2575,7 +2611,7 @@ set_mapping_user_filter (svalue_t *key, svalue_t *data, void *extra)
*/
{
int i;
p_int i;
struct set_mapping_user_locals *locals;
object_t *owner;
@ -2608,7 +2644,7 @@ set_mapping_user (mapping_t *m, object_t *owner)
*/
{
int num_values;
p_int num_values;
mp_int total;
wiz_list_t *user;
struct set_mapping_user_locals locals;
@ -2958,12 +2994,12 @@ clean_stale_mappings (void)
{
#ifdef VERBOSE
fprintf(stderr, "%s Unable to compact stale mapping: Out of memory "
"for new condensed block (%ld bytes).\n"
, time_stamp(), (long)size);
"for new condensed block (%zu bytes).\n"
, time_stamp(), size);
#endif
debug_message("%s Unable to compact stale mapping: Out of memory "
"for new condensed block (%ld bytes).\n"
, time_stamp(), (long)size);
"for new condensed block (%zu bytes).\n"
, time_stamp(), size);
/* No use in even trying to compact the much bigger data
* block either.
@ -3085,19 +3121,20 @@ f_m_allocate (svalue_t *sp)
p_int width = sp[0].u.number;
if (size < 0)
errorf("Illegal mapping size: %ld\n", size);
errorf("Illegal mapping size: %"PRIdPINT"\n", size);
if (width < 0)
errorf("Illegal mapping width: %ld\n", width);
errorf("Illegal mapping width: %"PRIdPINT"\n", width);
if (max_mapping_size
&& size * (1 + width) > (p_int)max_mapping_size)
errorf("Illegal mapping size: %ld elements (%ld x %ld).\n"
, size * (1+width)
, size, width);
errorf("Illegal mapping size: %"PRIdMPINT
" elements (%"PRIdPINT" x %"PRIdPINT").\n",
(mp_int)size * (1+width),
size, width);
if (max_mapping_keys
&& size > (p_int)max_mapping_keys)
errorf("Illegal mapping size: %ld entries.\n", size);
errorf("Illegal mapping size: %"PRIdPINT" entries.\n", size);
sp--;
@ -3107,7 +3144,8 @@ f_m_allocate (svalue_t *sp)
/* sp points to a number-typed svalue, so freeing won't
* be a problem.
*/
errorf("Out of memory for mapping[%ld,%ld].\n", size, width);
errorf("Out of memory for mapping[%"PRIdPINT",%"PRIdPINT"].\n",
size, width);
/* NOTREACHED */
}
sp->type = T_MAPPING;
@ -3135,7 +3173,7 @@ v_m_add (svalue_t *sp, int num_arg)
mapping_t *m;
svalue_t *argp;
svalue_t *entry;
int num_values;
p_int num_values;
argp = sp - num_arg + 1;
m = argp->u.map;
@ -3214,7 +3252,7 @@ m_indices (mapping_t *m)
mp_int size;
check_map_for_destr(m);
size = (mp_int)MAP_SIZE(m);
size = MAP_SIZE(m);
v = allocate_array(size); /* might cause error */
svp = v->item;
walk_mapping(m, m_indices_filter, &svp);
@ -3267,8 +3305,8 @@ f_m_values (svalue_t *sp)
mapping_t *m;
vector_t *v;
struct mvf_info vip;
mp_int size;
int num;
p_int size;
p_int num;
/* Get and check the arguments */
num = sp->u.number;
@ -3277,12 +3315,12 @@ f_m_values (svalue_t *sp)
m = sp->u.map;
if (num < 0 || num >= m->num_values)
errorf("Illegal index %d to m_values(): should be in 0..%ld.\n"
, num, (long)m->num_values-1);
errorf("Illegal index %"PRIdPINT" to m_values(): should be in 0..%"
PRIdPINT".\n", num, m->num_values-1);
/* Get the size of the mapping */
check_map_for_destr(m);
size = (mp_int)MAP_SIZE(m);
size = MAP_SIZE(m);
if (size > 0 && m->num_values < 1)
errorf("m_values() applied on mapping with no values.\n");
@ -3311,7 +3349,7 @@ add_to_mapping_filter (svalue_t *key, svalue_t *data, void *extra)
{
svalue_t *data2;
int i;
p_int i;
data2 = get_map_lvalue_unchecked((mapping_t *)extra, key);
if (!data2)
@ -3378,8 +3416,9 @@ add_to_mapping (mapping_t *m1, mapping_t *m2)
}
else
{
errorf("Mappings to be added are of different width: %ld vs. %ld\n"
, (long)m1->num_values, (long)m2->num_values);
errorf("Mappings to be added are of different width: %"PRIdPINT
" vs. %"PRIdPINT"\n",
m1->num_values, m2->num_values);
return;
}
}
@ -3452,9 +3491,9 @@ map_intersect_filter (svalue_t *key, svalue_t *data UNUSED, void *extra)
src = get_map_value(m, key);
if (src != &const0)
{
int num_values = m->num_values;
p_int num_values = m->num_values;
svalue_t * dest;
int j;
p_int j;
dest = get_map_lvalue(rc, key);
if (!dest)
@ -3488,9 +3527,9 @@ map_intersect (mapping_t *m, svalue_t * val)
if (val->type == T_POINTER)
{
vector_t * vec = val->u.vec;
size_t vecsize = VEC_SIZE(vec);
int num_values = m->num_values;
size_t i;
p_int vecsize = VEC_SIZE(vec);
p_int num_values = m->num_values;
p_int i;
rc = allocate_mapping(vecsize, num_values);
if (!rc)
@ -3507,7 +3546,7 @@ map_intersect (mapping_t *m, svalue_t * val)
if (src != &const0)
{
svalue_t * dest;
int j;
p_int j;
dest = get_map_lvalue(rc, &vec->item[i]);
if (!dest)
@ -3525,7 +3564,7 @@ map_intersect (mapping_t *m, svalue_t * val)
else if (val->type == T_MAPPING)
{
mapping_t * map = val->u.map;
int num_values = m->num_values;
p_int num_values = m->num_values;
struct map_intersect_s data;
rc = allocate_mapping(MAP_SIZE(map), num_values);
@ -3566,12 +3605,12 @@ map_intersect_array (vector_t *vec, mapping_t *map)
{
Bool *flags; /* The result from match_arrays() */
size_t result_size; /* Size of the result array */
p_int result_size; /* Size of the result array */
vector_t *result; /* Result array */
svalue_t *dest; /* Pointer for storing the result elements */
size_t i;
p_int i;
size_t vec_size = VEC_SIZE(vec);
p_int vec_size = VEC_SIZE(vec);
/* Handle empty arrays */
@ -3615,7 +3654,7 @@ map_intersect_array (vector_t *vec, mapping_t *map)
xfree(flags);
free_mapping(map);
free_array(vec);
errorf("Illegal array size: %lu.\n", (unsigned long)result_size);
errorf("Illegal array size: %"PRIdPINT".\n", result_size);
}
result = allocate_array(result_size);
@ -3810,7 +3849,7 @@ v_walk_mapping (svalue_t *sp, int num_arg)
callback_t cb;
int error_index;
mapping_t *m; /* Mapping to walk */
int num_values; /* Number of values per entry */
p_int num_values; /* Number of values per entry */
svalue_t *read_pointer; /* Prepared mapping values */
mp_int i;
@ -3848,7 +3887,7 @@ v_walk_mapping (svalue_t *sp, int num_arg)
*/
while (--i >= 0)
{
int j;
p_int j;
svalue_t *sp2, *data;
if (!callback_object(&cb))
@ -3916,12 +3955,12 @@ x_filter_mapping (svalue_t *sp, int num_arg, Bool bFull)
mapping_t *m; /* Mapping to filter */
int error_index;
callback_t cb;
int num_values; /* Width of the mapping */
p_int num_values; /* Width of the mapping */
vector_t *dvec; /* Values of one key */
svalue_t *dvec_sp; /* Stackentry of dvec */
svalue_t *read_pointer; /* Prepared mapping values */
svalue_t *v;
int i, j;
p_int i, j;
/* Locate the arguments on the stack and extract them */
arg = sp - num_arg + 1;
@ -4144,11 +4183,11 @@ x_map_mapping (svalue_t *sp, int num_arg, Bool bFull)
svalue_t *arg; /* Begin of arguments on the stack */
mapping_t *arg_m; /* Mapping to map */
mapping_t *m; /* Result mapping */
int num_values; /* Width of the mapping */
p_int num_values; /* Width of the mapping */
vector_t *vec; /* Indices of m */
svalue_t *dvec_sp; /* Stackentry of dvec */
vector_t *dvec; /* Values of one key */
long i;
p_int i;
svalue_t *key;
callback_t cb;
int error_index;
@ -4204,7 +4243,7 @@ x_map_mapping (svalue_t *sp, int num_arg, Bool bFull)
dvec_sp = sp;
}
m = allocate_mapping((i = (long)VEC_SIZE(vec)), 1);
m = allocate_mapping((i = VEC_SIZE(vec)), 1);
if (!m)
{
inter_sp = sp;
@ -4255,7 +4294,7 @@ x_map_mapping (svalue_t *sp, int num_arg, Bool bFull)
}
else
{
int j;
p_int j;
svalue_t *svp;
v = get_map_value(arg_m, key);
@ -4334,7 +4373,7 @@ v_m_contains (svalue_t *sp, int num_arg)
* int m_contains(mixed &data1, ..., &dataN, map, key)
*
* If the mapping contains the key map, the corresponding values
* are assigned to the data arguments, which massed be passed by
* are assigned to the data arguments, which must be passed by
* reference, and 1 is returned. If key is not in map, 0 is
* returned and the data args are left unchanged.
* It is possible to use this function for a 0-value mapping, in
@ -4352,8 +4391,8 @@ v_m_contains (svalue_t *sp, int num_arg)
if (sp[-1].type != T_MAPPING)
vefun_arg_error(num_arg-1, T_MAPPING, sp[-1].type, sp);
if (sp[-1].u.map->num_values != num_arg - 2)
errorf("Not enough lvalues: given %ld, required %ld.\n"
, (long)num_arg-2, (long)sp[-1].u.map->num_values);
errorf("Not enough lvalues: given %d, required %"PRIdPINT".\n",
num_arg-2, sp[-1].u.map->num_values);
item = get_map_value(sp[-1].u.map, sp);
if (item == &const0)
@ -4411,8 +4450,8 @@ f_m_entry (svalue_t *sp)
data = get_map_value(sp[-1].u.map, sp);
if (&const0 != data)
{
int num_values = sp[-1].u.map->num_values;
int i;
p_int num_values = sp[-1].u.map->num_values;
p_int i;
rc = allocate_array(num_values);
@ -4450,7 +4489,7 @@ f_m_reallocate (svalue_t *sp)
*/
{
int new_width; /* Requested width of the target mapping */
p_int new_width; /* Requested width of the target mapping */
mapping_t *m; /* Argument mapping */
mapping_t *new_m; /* New mapping */
@ -4458,7 +4497,7 @@ f_m_reallocate (svalue_t *sp)
new_width = sp->u.number;
if (new_width < 0)
{
errorf("Illegal width to m_reallocate(): %ld\n", (long)new_width);
errorf("Illegal width to m_reallocate(): %"PRIdPINT"\n", new_width);
/* NOTREACHED */
return sp;
}
@ -4549,26 +4588,28 @@ v_mkmapping (svalue_t *sp, int num_arg)
if (sp[-num_arg+1].type == T_POINTER)
{
long i, length, num_values;
int i, num_values; /* contains num_arg, which is int */
p_int length; /* VEC_SIZE, array sizes */
svalue_t *key;
/* Check the arguments and set length to the size of
* the shortest array.
*/
length = LONG_MAX;
length = PINT_MAX;
for (i = -num_arg; ++i <= 0; )
{
if ( sp[i].type != T_POINTER )
vefun_arg_error(i+num_arg, T_POINTER, sp[i].type, sp);
if (length > (long)VEC_SIZE(sp[i].u.vec))
length = (long)VEC_SIZE(sp[i].u.vec);
if (length > VEC_SIZE(sp[i].u.vec))
length = VEC_SIZE(sp[i].u.vec);
}
if (max_mapping_size && length * num_arg > (p_int)max_mapping_size)
errorf("Illegal mapping size: %ld elements (%ld x %ld)\n"
, length * num_arg, length, (long)num_arg);
if (max_mapping_size && (mp_int)length * num_arg > (mp_int)max_mapping_size)
errorf("Illegal mapping size: %"PRIdMPINT
" elements (%"PRIdPINT" x %d)\n"
, (mp_int)length * num_arg, length, num_arg);
if (max_mapping_keys && length > (p_int)max_mapping_keys)
errorf("Illegal mapping size: %ld entries\n", length);
errorf("Illegal mapping size: %"PRIdPINT" entries\n", length);
/* Allocate the mapping */
num_values = num_arg - 1;
@ -4635,14 +4676,14 @@ f_unmkmapping (svalue_t *sp)
vector_t *v;
struct mvf_info vip;
mp_int size;
int i;
p_int i;
/* Get the arguments */
m = sp->u.map;
/* Determine the size of the mapping and allocate the result vector */
check_map_for_destr(m);
size = (mp_int)MAP_SIZE(m);
size = MAP_SIZE(m);
v = allocate_array(m->num_values+1);
/* Allocate the sub vectors */
@ -4680,7 +4721,7 @@ f_widthof (svalue_t *sp)
*/
{
int width;
p_int width;
if (sp->type == T_NUMBER && sp->u.number == 0)
return sp;

View File

@ -266,12 +266,12 @@ mb_status (strbuf_t * sbuf, Bool verbose)
{
strbuf_add(sbuf, "\nMemory Buffers:\n");
strbuf_add(sbuf, "---------------\n");
strbuf_addf(sbuf, "File data: %8lu\n", membuffers[mbFile].size);
strbuf_addf(sbuf, "Swap buffer: %8lu\n", membuffers[mbSwap].size);
strbuf_addf(sbuf, "File data: %8zu\n", membuffers[mbFile].size);
strbuf_addf(sbuf, "Swap buffer: %8zu\n", membuffers[mbSwap].size);
}
else
{
strbuf_addf(sbuf, "Memory buffers:\t\t\t\t %9lu\n", res);
strbuf_addf(sbuf, "Memory buffers:\t\t\t\t %9zu\n", res);
}
return res;

View File

@ -421,6 +421,22 @@ rx_compile_pcre (string_t * expr, int opt, Bool from_ed, regdata_t * rdata)
errorf("pcre: %s\n", pErrmsg);
return 0;
}
/* We have to ensure to have an initialized pHints structure for
setting the recursion limit later on */
if (pHints == NULL)
{
pcre_malloc_err = "allocating memory for pHints section in regexp";
pHints = (pcre_extra *)pcre_xalloc(sizeof(pcre_extra));
if (pHints == NULL)
{
if (from_ed)
add_message("pcre: Could not allocate memory for pHints\n");
else
errorf("pcre: Could not allocate memory for pHints\n");
return 0;
}
pHints->flags = 0;
}
{
int rc;
@ -685,18 +701,28 @@ rx_exec (regexp_t *pRegexp, string_t * string, size_t start)
if (prog->opt & RE_NOTEMPTY) pcre_opt |= PCRE_NOTEMPTY;
pHints = prog->pHints;
if (pHints && max_eval_cost)
{
pHints->flags |= PCRE_EXTRA_MATCH_LIMIT;
if (max_eval_cost > eval_cost + 1)
pHints->match_limit = max_eval_cost - eval_cost - 1;
else
pHints->match_limit = 1;
}
else if (pHints)
{
pHints->flags &= ~PCRE_EXTRA_MATCH_LIMIT;
}
/* If LD_PCRE_RECURSION_LIMIT is defined we set a limit for match. If
* PCRE_EXTRA_MATCH_LIMIT_RECURSION is defined, we have a new libpcre,
* which supports limiting the recursions. Otherwise we have to limit
* the no of calls to match().
* TODO: Instead of the conditional compilation we should update the
* TODO::built-in pcre package.
*/
#ifdef LD_PCRE_RECURSION_LIMIT
#ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
pHints->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
pHints->match_limit_recursion = LD_PCRE_RECURSION_LIMIT;
#else
pHints->flags |= PCRE_EXTRA_MATCH_LIMIT;
pHints->match_limit = LD_PCRE_RECURSION_LIMIT;
#endif /* PCRE_EXTRA_MATCH_LIMIT_RECURSION */
#else /* LD_PCRE_RECURSION_LIMIT */
#ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
pHints->flags &= ~PCRE_EXTRA_MATCH_LIMIT_RECURSION
#else
pHints->flags &= ~PCRE_EXTRA_MATCH_LIMIT;
#endif /* PCRE_EXTRA_MATCH_LIMIT_RECURSION */
#endif /* LD_PCRE_RECURSION_LIMIT */
rc = pcre_exec( prog->pProg, pHints
, get_txt(string), mstrsize(string), start, pcre_opt
@ -748,18 +774,28 @@ rx_exec_str (regexp_t *pRegexp, char * string, char * start)
if (prog->opt & RE_NOTEMPTY) pcre_opt |= PCRE_NOTEMPTY;
pHints = prog->pHints;
if (pHints && max_eval_cost)
{
pHints->flags |= PCRE_EXTRA_MATCH_LIMIT;
if (max_eval_cost > eval_cost + 1)
pHints->match_limit = max_eval_cost - eval_cost - 1;
else
pHints->match_limit = 1;
}
else if (pHints)
{
pHints->flags &= ~PCRE_EXTRA_MATCH_LIMIT;
}
/* If LD_PCRE_RECURSION_LIMIT is defined we set a limit for match. If
* PCRE_EXTRA_MATCH_LIMIT_RECURSION is defined, we have a new libpcre,
* which supports limiting the recursions. Otherwise we have to limit
* the no of calls to match().
* TODO: Instead of the conditional compilation we should update the
* TODO::built-in pcre package.
*/
#ifdef LD_PCRE_RECURSION_LIMIT
#ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
pHints->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
pHints->match_limit_recursion = LD_PCRE_RECURSION_LIMIT;
#else
pHints->flags |= PCRE_EXTRA_MATCH_LIMIT;
pHints->match_limit = LD_PCRE_RECURSION_LIMIT;
#endif /* PCRE_EXTRA_MATCH_LIMIT_RECURSION */
#else /* LD_PCRE_RECURSION_LIMIT */
#ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
pHints->flags &= ~PCRE_EXTRA_MATCH_LIMIT_RECURSION
#else
pHints->flags &= ~PCRE_EXTRA_MATCH_LIMIT;
#endif /* PCRE_EXTRA_MATCH_LIMIT_RECURSION */
#endif /* LD_PCRE_RECURSION_LIMIT */
rc = pcre_exec( prog->pProg, pHints
, start, strlen(start), string - start, pcre_opt
@ -1172,12 +1208,13 @@ rxcache_status (strbuf_t *sbuf, Bool verbose)
{
strbuf_add(sbuf, "\nRegexp cache status:\n");
strbuf_add(sbuf, "--------------------\n");
strbuf_addf(sbuf, "Expressions in cache: %lu (%.1f%%)\n"
strbuf_addf(sbuf, "Expressions in cache: %"PRIu32" (%.1f%%)\n"
, iNumXEntries, 100.0 * (float)iNumXEntries / RXCACHE_TABLE);
strbuf_addf(sbuf, "Memory allocated: %lu\n", iXSizeAlloc);
strbuf_addf(sbuf, "Memory allocated: %"PRIu32"\n", iXSizeAlloc);
iNumXReq = iNumXRequests ? iNumXRequests : 1;
strbuf_addf(sbuf
, "Requests: %lu - Found: %lu (%.1f%%) - Coll: %lu (%.1f%% req/%.1f%% entries)\n"
, "Requests: %"PRIu32" - Found: %"PRIu32" (%.1f%%) - "
"Coll: %"PRIu32" (%.1f%% req/%.1f%% entries)\n"
, iNumXRequests, iNumXFound, 100.0 * (float)iNumXFound/(float)iNumXReq
, iNumXCollisions, 100.0 * (float)iNumXCollisions/(float)iNumXReq
, 100.0 * (float)iNumXCollisions/(iNumXEntries ? iNumXEntries : 1)
@ -1185,7 +1222,8 @@ rxcache_status (strbuf_t *sbuf, Bool verbose)
}
else
{
strbuf_addf(sbuf, "Regexp cache:\t\t\t%8ld %9lu\n", iNumXEntries, iXSizeAlloc);
strbuf_addf(sbuf, "Regexp cache:\t\t\t%8"PRId32" %9"PRIu32"\n",
iNumXEntries, iXSizeAlloc);
}
return iXSizeAlloc;

View File

@ -111,7 +111,7 @@ static string_t ** stringtable = NULL;
* This does include the memory by the string management structures.
*/
static mp_uint mstr_tabled = 0;
static mp_uint mstr_tabled_count = 0;
/* Number of distinct strings in the string table.
*/
@ -128,14 +128,14 @@ static mp_uint mstr_added = 0;
*/
static mp_uint mstr_deleted = 0;
/* Number of distinct strings delete from the string table.
/* Number of distinct strings deleted from the string table.
*/
static mp_uint mstr_collisions = 0;
/* Number of collisions when adding a new distinct string.
*/
static mp_uint mstr_untabled = 0;
static mp_uint mstr_untabled_count = 0;
/* Number of distinct untabled strings.
*/
@ -180,7 +180,7 @@ unsigned long stNumTabledCheckedSearch = 0;
/*-------------------------------------------------------------------------*/
static INLINE whash_t
hash_string (const char * const s, size_t size)
hash_string_inl (const char * const s, size_t size)
/* Compute the hash for string <s> of length <size> and return it.
* The result will always be non-zero.
@ -193,7 +193,13 @@ hash_string (const char * const s, size_t size)
if (!hash)
hash = 1 << (sizeof (hash) * CHAR_BIT - 1);
return hash;
} /* hash_string() */
} /* hash_string_inl() */
whash_t
hash_string (const char * const s, size_t size)
{
return hash_string_inl(s, size);
}
/*-------------------------------------------------------------------------*/
static INLINE whash_t
@ -204,7 +210,7 @@ get_hash (string_t * pStr)
{
if (!pStr->hash)
pStr->hash = hash_string(pStr->txt, pStr->size);
pStr->hash = hash_string_inl(pStr->txt, pStr->size);
return pStr->hash;
} /* get_hash() */
@ -363,7 +369,7 @@ make_new_tabled (const char * const pTxt, size_t size, whash_t hash MTRACE_DECL)
msize = mstr_mem_size(string);
mstr_used++;
mstr_used_size += msize;
mstr_tabled++;
mstr_tabled_count++;
mstr_tabled_size += msize;
}
@ -409,7 +415,7 @@ mstring_alloc_string (size_t iSize MTRACE_DECL)
msize = mstr_mem_size(string);
mstr_used++;
mstr_used_size += msize;
mstr_untabled++;
mstr_untabled_count++;
mstr_untabled_size += msize;
}
@ -486,7 +492,7 @@ mstring_new_tabled (const char * const pTxt MTRACE_DECL)
string_t * string;
size = strlen(pTxt);
hash = hash_string(pTxt, size);
hash = hash_string_inl(pTxt, size);
/* Check if the string has already been tabled */
string = find_and_move(pTxt, size, hash);
@ -516,7 +522,7 @@ mstring_new_n_tabled (const char * const pTxt, size_t size MTRACE_DECL)
whash_t hash;
string_t * string;
hash = hash_string(pTxt, size);
hash = hash_string_inl(pTxt, size);
/* Check if the string has already been tabled */
string = find_and_move(pTxt, size, hash);
@ -581,10 +587,10 @@ table_string (string_t * pStr MTRACE_DECL)
pStr->next = stringtable[idx];
stringtable[idx] = pStr;
mstr_tabled++;
mstr_tabled_count++;
mstr_tabled_size += msize;
mstr_untabled--;
mstr_untabled_count--;
mstr_untabled_size -= msize;
string = pStr;
@ -792,7 +798,7 @@ mstring_find_tabled_str (const char * const pTxt, size_t size)
{
whash_t hash;
hash = hash_string(pTxt, size);
hash = hash_string_inl(pTxt, size);
return find_and_move(pTxt, size, hash);
} /* mstring_find_tabled_str() */
@ -831,7 +837,7 @@ mstring_free (string_t *s)
int idx;
mstr_tabled--;
mstr_tabled_count--;
mstr_tabled_size -= msize;
idx = HashToIndex(get_hash(s));
@ -853,7 +859,7 @@ mstring_free (string_t *s)
{
/* An untabled string */
mstr_untabled--;
mstr_untabled_count--;
mstr_untabled_size -= msize;
}
@ -861,36 +867,6 @@ mstring_free (string_t *s)
xfree(s);
} /* mstring_free() */
/*-------------------------------------------------------------------------*/
string_t *
mstring_ref ( string_t * str)
/* Aliased to: ref_mstring_safe(s)
*
* Increment the refcount for string <str> and return the ref'ed string.
* In contrast to macro ref_mstring(), this function can handle arguments
* with sideeffects.
*/
{
return ref_mstring(str);
} /* mstring_ref() */
/*-------------------------------------------------------------------------*/
unsigned long
mstring_deref ( string_t * str)
/* Aliased to: deref_mstring_safe(s)
*
* Decrement the refcount for string <str> and return the new refcount.
* In contrast to macro deref_mstring(), this function can handle arguments
* with sideeffects.
*/
{
return deref_mstring(str);
} /* mstring_deref() */
/*-------------------------------------------------------------------------*/
Bool
mstring_equal(string_t * const pStr1, string_t * const pStr2)
@ -1048,12 +1024,13 @@ mstring_mstr_n_str ( const string_t * const pStr, size_t start
size_t left;
char first;
if (start >= mstrsize(pStr))
if (start > mstrsize(pStr))
return NULL;
/* Initialize 'characters remaining' and 'current position' */
left = mstrsize(pStr) - start;
cp = get_txt(pStr)+start;
/* remove the const qualifier temporarily when calling get_txt(). */
cp = get_txt((string_t *const)pStr)+start;
/* Special case: strstr("text", "") */
if (len == 0)
@ -1099,12 +1076,12 @@ mstring_mstr_rn_str ( const string_t * const pStr, size_t start
size_t left;
char first;
if (start >= mstrsize(pStr))
if (start > mstrsize(pStr))
return NULL;
/* Initialize 'characters remaining' and 'current position' */
left = mstrsize(pStr) - start;
cp = get_txt(pStr)+start;
cp = get_txt((string_t *const)pStr)+start;
/* Special case: strrstr("text", "") */
if (len == 0)
@ -1119,7 +1096,7 @@ mstring_mstr_rn_str ( const string_t * const pStr, size_t start
&& 0 == memcmp(cp, pTxt, len)
)
return cp;
} while (cp != get_txt(pStr));
} while (cp != get_txt((string_t *const)pStr));
return NULL;
} /* mstring_mstr_n_str() */
@ -1146,7 +1123,7 @@ mstring_add_slash (const string_t *str MTRACE_DECL)
{
txt = get_txt(tmp);
*txt = '/';
memcpy(txt+1, get_txt(str), mstrsize(str));
memcpy(txt+1, get_txt((string_t *const)str), mstrsize(str));
}
return tmp;
} /* mstring_add_slash() */
@ -1234,7 +1211,7 @@ mstring_cvt_progname (const string_t *str MTRACE_DECL)
const char * txt, *p;
char *txt2;
txt = get_txt(str);
txt = get_txt((string_t *const)str);
len = mstrsize(str);
p = strrchr(txt, '.');
@ -1287,8 +1264,8 @@ mstring_add (const string_t *left, const string_t *right MTRACE_DECL)
char * txt;
txt = get_txt(tmp);
memcpy(txt, get_txt(left), lleft);
memcpy(txt+lleft, get_txt(right), lright);
memcpy(txt, get_txt((string_t *const)left), lleft);
memcpy(txt+lleft, get_txt((string_t *const)right), lright);
}
return tmp;
} /* mstring_add() */
@ -1317,7 +1294,7 @@ mstring_add_txt (const string_t *left, const char *right, size_t len MTRACE_DECL
if (tmp)
{
txt = get_txt(tmp);
memcpy(txt, get_txt(left), lleft);
memcpy(txt, get_txt((string_t *const)left), lleft);
memcpy(txt+lleft, right, len);
}
return tmp;
@ -1348,7 +1325,7 @@ mstring_add_to_txt (const char *left, size_t len, const string_t *right MTRACE_D
{
txt = get_txt(tmp);
memcpy(txt, left, len);
memcpy(txt+len, get_txt(right), lright);
memcpy(txt+len, get_txt((string_t *const)right), lright);
}
return tmp;
} /* mstring_add_to_txt() */
@ -1432,7 +1409,7 @@ mstring_repeat (const string_t *base, size_t num MTRACE_DECL)
char * txt = get_txt(result);
/* Seed result[] with one copy of the string */
memcpy(txt, get_txt(base), len);
memcpy(txt, get_txt((string_t *const)base), len);
/* Repeatedly double the string in result */
curlen = len;
@ -1506,7 +1483,7 @@ mstring_extract (const string_t *str, size_t start, long end MTRACE_DECL)
result = mstring_alloc_string(reslen MTRACE_PASS);
if (result && reslen)
{
memcpy(get_txt(result), get_txt(str)+start, reslen);
memcpy(get_txt(result), get_txt((string_t *const)str)+start, reslen);
}
return result;
} /* mstring_extract() */
@ -1524,8 +1501,8 @@ mstring_prefixed (const string_t *p, const string_t *s)
const char *pp, *ps;
size_t lp, ls;
lp = mstrsize(p); pp = get_txt(p);
ls = mstrsize(s); ps = get_txt(s);
lp = mstrsize(p); pp = get_txt((string_t *const)p);
ls = mstrsize(s); ps = get_txt((string_t *const)s);
for (; lp > 0 && ls > 0; lp--, ls--)
{
@ -1549,9 +1526,9 @@ mstring_chr (const string_t *p, char c)
{
char *pp;
pp = memchr(get_txt(p), c, mstrsize(p));
pp = memchr(get_txt((string_t *const)p), c, mstrsize(p));
if (pp != NULL)
return pp - get_txt(p);
return pp - get_txt((string_t *const)p);
return -1;
} /* mstring_chr() */
@ -1676,9 +1653,9 @@ mstring_gc_table (void)
next = this->next;
}
mstr_untabled++;
mstr_untabled_count++;
mstr_untabled_size += mstr_mem_size(this);
mstr_tabled--;
mstr_tabled_count--;
mstr_tabled_size += mstr_mem_size(this);
mstr_deleted++;
@ -1715,10 +1692,10 @@ add_string_status (strbuf_t *sbuf, Bool verbose)
mp_uint distinct_overhead;
stringtable_size = HTABLE_SIZE * sizeof(string_t *);
distinct_strings = mstr_tabled + mstr_untabled;
distinct_strings = mstr_tabled_count + mstr_untabled_count;
distinct_size = mstr_tabled_size + mstr_untabled_size;
distinct_overhead = mstr_tabled * STR_OVERHEAD
+ mstr_untabled * STR_OVERHEAD;
distinct_overhead = mstr_tabled_count * STR_OVERHEAD
+ mstr_untabled_count * STR_OVERHEAD;
if (!verbose)
{
@ -1748,20 +1725,20 @@ add_string_status (strbuf_t *sbuf, Bool verbose)
, distinct_overhead + stringtable_size
);
strbuf_addf(sbuf, " - tabled\t%9lu %9lu (%9lu+%9lu)\n"
, mstr_tabled
, mstr_tabled_count
, mstr_tabled_size + stringtable_size
, mstr_tabled_size
? mstr_tabled_size - mstr_tabled * STR_OVERHEAD
? mstr_tabled_size - mstr_tabled_count * STR_OVERHEAD
: 0
, mstr_tabled * STR_OVERHEAD + stringtable_size
, mstr_tabled_count * STR_OVERHEAD + stringtable_size
);
strbuf_addf(sbuf, " - untabled\t%9lu %9lu (%9lu+%9lu)\n"
, mstr_untabled
, mstr_untabled_count
, mstr_untabled_size
, mstr_untabled_size
? mstr_untabled_size - mstr_untabled * STR_OVERHEAD
? mstr_untabled_size - mstr_untabled_count * STR_OVERHEAD
: 0
, mstr_untabled * STR_OVERHEAD
, mstr_untabled_count * STR_OVERHEAD
);
strbuf_addf(sbuf, "\nSpace required vs. 'regular C' string implementation: "
"%lu%% with, %lu%% without overhead.\n"
@ -1782,7 +1759,7 @@ add_string_status (strbuf_t *sbuf, Bool verbose)
, (float)mstr_searchlen_byvalue / (float)mstr_searches_byvalue
);
strbuf_addf(sbuf, "Hash chains used: %lu of %lu (%.1f%%)\n"
, mstr_chains, HTABLE_SIZE
, mstr_chains, (unsigned long)HTABLE_SIZE
, 100.0 * (float)mstr_chains / (float)HTABLE_SIZE
);
strbuf_addf(sbuf, "Distinct strings added: %lu "
@ -1847,9 +1824,9 @@ string_dinfo_status (svalue_t *svp, int value)
ST_NUMBER(DID_ST_STR_DELETED, mstr_deleted);
ST_NUMBER(DID_ST_STR_COLLISIONS, mstr_collisions);
ST_NUMBER(DID_ST_UNTABLED, mstr_untabled);
ST_NUMBER(DID_ST_UNTABLED, mstr_untabled_count);
ST_NUMBER(DID_ST_UNTABLED_SIZE, mstr_untabled_size);
ST_NUMBER(DID_ST_TABLED, mstr_tabled);
ST_NUMBER(DID_ST_TABLED, mstr_tabled_count);
ST_NUMBER(DID_ST_TABLED_SIZE, mstr_tabled_size);
ST_NUMBER(DID_ST_STR_SEARCHES, mstr_searches);

View File

@ -65,6 +65,7 @@ extern mp_uint mstr_used_size;
/* --- Prototypes --- */
extern void mstring_init (void);
extern whash_t hash_string (const char * const s, size_t size);
extern whash_t mstring_get_hash (string_t * pStr);
extern string_t * mstring_alloc_string (size_t iSize MTRACE_DECL);
extern string_t * mstring_new_string (const char * const pTxt MTRACE_DECL);
@ -84,8 +85,6 @@ extern int mstring_compare( string_t * const pStr1
extern Bool mstring_equal( string_t * const pStr1
, string_t * const pStr2);
extern void mstring_free (string_t *s);
extern string_t * mstring_ref ( string_t * str);
extern unsigned long mstring_deref ( string_t * str);
extern const char * mstring_mstr_n_str(const string_t * const pStr, size_t start, const char * const pTxt, size_t len);
extern const char * mstring_mstr_rn_str(const string_t * const pStr, size_t start, const char * const pTxt, size_t len);
extern string_t * mstring_add_slash (const string_t *str MTRACE_DECL);
@ -116,110 +115,140 @@ extern void string_dinfo_status(svalue_t *svp, int value);
/* --- Inline functions and macros --- */
#define mstr_mem_size(s) \
(sizeof(string_t) + (s)->size)
/* size_t mstr_mem_size(string_t * s)
* The amount of memory used to hold all this strings' data.
static INLINE size_t mstr_mem_size(const string_t * const s)
__attribute__((nonnull(1)))
__attribute__((pure));
static INLINE size_t mstr_mem_size(const string_t * const s)
/* The amount of memory used to hold all this strings' data.
* Used only to keep the statistics up to date.
*/
{
return sizeof(string_t) + s->size;
}
#define mstr_hash(s) \
( (s)->hash )
/* whash_t mstr_hash(string_t * s)
* Return the hash value of string <s>, which is 0 if the
static INLINE whash_t mstr_hash(const string_t * const s)
__attribute__((nonnull(1)))
__attribute__((pure));
static INLINE whash_t mstr_hash(const string_t * const s)
/* Return the hash value of string <s>, which is 0 if the
* hash hasn't been computed yet.
*/
{
return s->hash;
}
#define mstr_singular(s) \
(! ((s)->info.tabled || (s)->info.ref != 1) )
/* Bool mstr_singular(string_t *s)
* Return FALSE if string<s> has multiple users, ie. is tabled
* or has more than one reference.
static INLINE Bool mstr_singular(const string_t * const s)
__attribute__((nonnull(1)))
__attribute__((pure));
static INLINE Bool mstr_singular(const string_t * const s)
/* Return FALSE if string<s> has multiple users, ie. is tabled
* or has more than one reference.
*/
{
return ! (s->info.tabled || s->info.ref != 1);
}
#define mstr_untabled(s) \
(!(s)->info.tabled)
/* Bool mstr_untabled (string_t *s)
* Return TRUE if string <s> is not tabled.
* The argument must not have sideeffects!
static INLINE Bool mstr_untabled(const string_t * const s)
__attribute__((nonnull(1)))
__attribute__((pure));
static INLINE Bool mstr_untabled(const string_t * const s)
/* Return TRUE if string <s> is not tabled.
*/
{
return !(s->info.tabled);
}
#define mstr_tabled(s) \
((s)->info.tabled)
/* Bool mstr_tabled (string_t *s)
* Return TRUE if string <s> is tabled - directly or indirectly.
* The argument must not have sideeffects!
static INLINE Bool mstr_tabled(const string_t * const s)
__attribute__((nonnull(1)))
__attribute__((pure));
static INLINE Bool mstr_tabled(const string_t * const s)
/* Return TRUE if string <s> is tabled - directly or indirectly.
*/
{
return s->info.tabled;
}
#define mstrsize(s) \
((s)->size)
/* size_t mstrsize(string_t *s)
* Return the size (length) of the string <s>.
static INLINE size_t mstrsize(const string_t * const s)
__attribute__((nonnull(1)))
__attribute__((pure));
static INLINE size_t mstrsize(const string_t * const s)
/* Return the size (length) of the string <s>.
*/
{
return s->size;
}
#define ref_mstring(s) \
(mstr_used++, mstr_used_size += mstr_mem_size(s), (s)->info.ref ? ++((s)->info.ref) : 0, (s))
#define ref_mstring_safe(s) mstring_ref(s)
/* string_t * ref_mstring (string_t *s)
* string_t * ref_mstring_safe (string_t *s)
* Increment the refcount for string <s> and return the ref'ed string.
* The argument <s> to ref_mstring() must not have sideeffects!
static INLINE string_t *ref_mstring(string_t *const s) __attribute__((nonnull(1)));
static INLINE string_t *ref_mstring(string_t *const s)
/* Increment the refcount for string <s> and return the ref'ed string.
*/
{
mstr_used++;
mstr_used_size += mstr_mem_size(s);
if (s->info.ref)
++(s->info.ref);
return s;
}
#define deref_mstring(s) \
(mstr_used--, mstr_used_size -= mstr_mem_size(s), (s)->info.ref ? --((s)->info.ref) : (s)->info.ref)
#define deref_mstring_safe(s) mstring_deref(s)
/* int deref_mstring (string_t *s)
* int deref_mstring_safe (string_t *s)
* Decrement the refcount for string <s> and return the new count.
* The argument <s> to deref_mstring() must not have sideeffects!
static INLINE unsigned int deref_mstring(string_t *const s) __attribute__((nonnull(1)));
static INLINE unsigned int deref_mstring(string_t *const s)
/* Decrement the refcount for string <s> and return the new count.
*/
{
mstr_used--;
mstr_used_size -= mstr_mem_size(s);
if (s->info.ref)
--(s->info.ref);
return s->info.ref;
}
#define free_mstring(s) \
MACRO(string_t * fmsttmp = s; if (fmsttmp != NULL) { if (fmsttmp->info.ref == 1) { mstring_free(fmsttmp); } else deref_mstring(fmsttmp); } )
/* void free_mstring(s)
*
* Decrement the refcount for string <s>, and if it reaches 0,
* deallocate <s> altogether.
static INLINE void free_mstring(string_t *const s) __attribute__((nonnull(1)));
static INLINE void free_mstring(string_t *const s)
/* Decrement the refcount for string <s>, and if it reaches 0,
* deallocate <s> altogether.
* TODO: check if s can really be NULL or should be allowed to be.
*/
{
if (s != NULL)
{
if (s->info.ref == 1)
{
mstring_free(s);
}
else
deref_mstring(s);
}
}
#define get_txt(s) \
((s)->txt)
/* char * get_txt (string_t *s)
*
* Return a pointer to the actual string text of string <s>.
* There is at least one '\0' terminating the string text.
static INLINE char *get_txt(string_t *const s)
__attribute__((nonnull(1)))
__attribute__((pure));
static INLINE char *get_txt(string_t *const s)
/* Return a pointer to the actual string text of string <s>.
* There is at least one '\0' terminating the string text.
* BTW: It is a pity that it can't be const char *get_txt().
*/
{
return s->txt;
}
#define extract_cstr(d,s,l) \
MACRO(strncpy((d), get_txt(s), (l)-1); \
if ((l) > mstrsize(s)) \
d[mstrsize(s)] = '\0'; \
else \
d[(l)-1] = '\0'; \
)
/* void extract_cstr (char * d, string_t *s, size_t l)
*
* Extract the C string from <s> (that is: all characters up to the
* first '\0' resp the end of the string) and copy it into buffer <d>
* of size <l>. The macro makes sure that the string is terminated
* with a '\0'
static INLINE void extract_cstr(char *d, const string_t *const s, size_t l)
__attribute__((nonnull(1,2)));
static INLINE void extract_cstr(char *d, const string_t *const s, size_t l)
/* Extract the C string from <s> (that is: all characters up to the
* first '\0' resp the end of the string) and copy it into buffer <d>
* of size <l>. The macro makes sure that the string is terminated
* with a '\0'
*/
{
strncpy(d, get_txt((string_t*)s), l-1);
if (l > mstrsize(s))
d[mstrsize(s)] = '\0';
else
d[l-1] = '\0';
}
/* A handful of shorthands for commonly used functions */

View File

@ -39,7 +39,7 @@
extern int getpagesize();
# endif
# if defined(sun) || defined(ultrix)
extern int getrusage(int, struct rusage *);
extern int getrusage (int, struct rusage *);
# endif
#else /* !HAVE_GETRUSAGE */

File diff suppressed because it is too large Load Diff

View File

@ -189,7 +189,7 @@ struct replace_ob_s
# define ref_object(o,from) (\
(o)->ref++,\
d_flag > 1 ? printf("Add ref to object %s: %ld (%s) %s %d\n" \
d_flag > 1 ? printf("Add ref to object %s: %"PRIdPINT" (%s) %s %d\n" \
, get_txt((o)->name), (o)->ref, from, __FILE__, __LINE__) : 0, \
(o))
@ -233,7 +233,7 @@ struct replace_ob_s
object_t * tmp_ = o; \
if (tmp_->ref == 2) dest_last_ref_gone = MY_TRUE; \
tmp_->ref--;\
if (d_flag > 1) printf("Sub ref from object %s: %ld (%s) %s %d\n"\
if (d_flag > 1) printf("Sub ref from object %s: %"PRIdPINT" (%s) %s %d\n"\
, get_txt(tmp_->name), tmp_->ref, from, __FILE__, __LINE__);\
if (tmp_->ref <= 0) dealloc_object(tmp_); \
)
@ -242,7 +242,7 @@ struct replace_ob_s
object_t * tmp_ = o; \
if (tmp_->ref == 2) dest_last_ref_gone = MY_TRUE; \
tmp_->ref--;\
if (d_flag > 1) printf("Sub ref from object %s: %ld (%s) %s %d\n"\
if (d_flag > 1) printf("Sub ref from object %s: %"PRIdPINT" (%s) %s %d\n"\
, get_txt(tmp_->name), tmp_->ref, from, __FILE__, __LINE__);\
if (tmp_->ref <= 0) dealloc_object(tmp_, __FILE__, __LINE__); \
)
@ -262,7 +262,7 @@ struct replace_ob_s
#else
# define deref_object(o,from) (--(o)->ref, \
d_flag > 1 ? printf("Sub ref from object %s: %ld (%s)\n" \
d_flag > 1 ? printf("Sub ref from object %s: %"PRIdPINT" (%s)\n" \
, get_txt((o)->name), (o)->ref, from) : 0)
#endif
@ -321,7 +321,7 @@ extern void dealloc_object(object_t *);
extern void dealloc_object(object_t *, const char * file, int line);
#endif
extern object_t *get_empty_object(int num_var);
extern void init_object_variables (object_t *ob);
extern void init_object_variables (object_t *ob, object_t *templ);
extern svalue_t *v_function_exists(svalue_t *sp, int num_arg);
extern svalue_t *f_functionlist(svalue_t *sp);

View File

@ -51,10 +51,10 @@
#if !( (OTABLE_SIZE) & (OTABLE_SIZE)-1 )
# define ObjHash(s) (mstr_get_hash(s) & ((OTABLE_SIZE)-1) )
# define ObjHashStr(s,len) (whashmem(s, len, MSTRING_HASH_LENGTH) & ((OTABLE_SIZE)-1) )
# define ObjHashStr(s,len) (hash_string(s, len) & ((OTABLE_SIZE)-1) )
#else
# define ObjHash(s) (mstr_get_hash(s) % OTABLE_SIZE)
# define ObjHashStr(s,len) (whashmem(s, len, MSTRING_HASH_LENGTH) % OTABLE_SIZE)
# define ObjHashStr(s,len) (hash_string(s, len) % OTABLE_SIZE)
#endif
/* Hash the string <s> and compute the appropriate table index
*/

View File

@ -216,7 +216,7 @@ f_idna_stringprep (svalue_t *sp)
{
errorf("stringprep(): Error %s", stringprep_strerror(ret));
/* NOTREACHED */
}
}
else
{
// free the string argument

560
src/pkg-iksemel.c Normal file
View File

@ -0,0 +1,560 @@
/*------------------------------------------------------------------
* iksemel Efuns
*
*------------------------------------------------------------------
* This file holds the efuns interfacing with iksemel and provides
* functions for handling xml files and converting them between
* mappings and xml data strings.
*
* efun: xml_
*------------------------------------------------------------------
*/
#include "driver.h"
#ifdef USE_IKSEMEL
#include <iksemel.h>
#include "array.h"
#include "xalloc.h"
#include "mapping.h"
#include "mstrings.h"
#include "simulate.h"
#include "interpret.h"
#include "pkg-iksemel.h"
#include "typedefs.h"
#include "../mudlib/sys/xml.h"
typedef struct attribute_walk_extra_s attribute_walk_extra_t;
/* This structure is used to walk all attributes as well as for error handling.
* In case an error happens, this structure is called too.
*/
struct attribute_walk_extra_s
{
iks *node;
int size;
char *tag_name;
};
/* This structure is used for error handling. In case of an error our handler
* called with a pointer ot this structure.
*/
struct xml_cleanup_s
{
svalue_t head; /* push_error_handler saves the link to our handler here. */
iks *node;
iksparser *parser;
};
void *
iksemel_alloc(size_t size)
{
return xalloc(size);
}
void
iksemel_free(void *ptr)
{
xfree(ptr);
}
void
add_string_to_mapping(mapping_t *map, char *skey, char *svalue)
/*
* Adds a string value under the given key to the given mapping. In case the
* value already exists, it is overriden.
*/
{
svalue_t key;
svalue_t *value;
/* change the c string into an string_t */
put_c_string(&key, skey);
/* get or insert key */
value = get_map_lvalue(map, &key);
/* free the string_t again */
free_svalue(&key);
/* free maybe existing value (should not happen, i hope) */
free_svalue(value);
/* change the value of the key to the given value */
put_c_string(value, svalue);
}
void
parse_node(svalue_t *result, iks *node)
/*
* Parses the xml DOM starting at node and returns the information on the
* stack.
*/
{
int i = 0;
int num_attributes = 0;
int num_children = 0;
iks *attribute;
iks *child;
vector_t *root = NULL;
vector_t *children = NULL;
mapping_t *attributes = NULL;
/* lets figure out if the node is cdata or another tag */
switch (iks_type(node))
{
case IKS_NONE:
case IKS_ATTRIBUTE:
/* we ignore those, as they will not occure for us */
return;
case IKS_CDATA:
/* Add the string as result, and return */
put_c_n_string(result, iks_cdata(node), iks_cdata_size(node));
return;
case IKS_TAG:
break;
}
/* We have a tag here, so allocate a tag array with three elements
* (name, contents and attributes)
*/
memsafe(root = allocate_array(XML_TAG_SIZE), sizeof(*root), "new tag array");
/* Put the array as result */
put_array(result, root);
/* add name to array */
put_c_string(&root->item[XML_TAG_NAME], iks_name(node));
/* check if the node has any children */
child = iks_child(node);
if (child != NULL)
{
do
{
++num_children;
}
while ((child = iks_next(child)));
}
if (0 < num_children)
{
/* children need to stay in the right order, so we create another
* for them
*/
memsafe(children = allocate_array(num_children), sizeof(*children)
, "new tag contents array");
/* Add the array of all children to the node */
put_array(&root->item[XML_TAG_CONTENTS], children);
/* get the first child */
child = iks_child(node);
do
{
/* recurse here cause the child can be a string or another node */
parse_node(&children->item[i++], child);
}
while ((child = iks_next(child)));
}
/* Finally, lets handle the attributes, we need to find out how many
* attributes the node has, to allocate enough memory for them. If
* no attributes exist, the part in the array will be empty */
attribute = iks_attrib(node);
if (attribute != NULL)
{
do
{
++num_attributes;
}
while ((attribute = iks_next(attribute)));
}
if (0 < num_attributes)
{
/* allocate new mapping */
memsafe(attributes = allocate_mapping(num_attributes, 1), sizeof(*attributes)
, "new attributes mapping");
/* add the attributes to the array */
put_mapping(&root->item[XML_TAG_ATTRIBUTES], attributes);
/* get the first one */
attribute = iks_attrib(node);
do
{
add_string_to_mapping(attributes, iks_name(attribute), iks_cdata(attribute));
}
while ((attribute = iks_next(attribute)));
}
}
void
walk_attribute_mapping(svalue_t *key, svalue_t *val, void *pextra)
/*
* Callback for walk_mapping() used in generate_xml_node to add iks
* attribute nodes to the node given in the pextra.
*/
{
char *ckey;
attribute_walk_extra_t *extra = pextra;
if (key->type == T_STRING)
{
ckey = get_txt(key->u.str);
}
else
{
errorf("Bad argument 1 to xml_generate(): expected string for attribute key of tag '%s'.\n"
, extra->tag_name);
/* NOTREACHED */
return;
}
if (val->type == T_STRING)
{
memsafe(iks_insert_attrib(extra->node, ckey, get_txt(val->u.str))
, sizeof(*ckey), "new iksemel attribute");
}
else
{
errorf("Bad argument 1 to xml_generate(): expected string for value of attribute '%s' of tag '%s'.\n"
, ckey, extra->tag_name);
}
}
static void
xml_cleanup(svalue_t * arg)
/*
* Takes care, that the node without parent (root node) is correctly freed in
* case of an error and at the end of the f_generate_xml().
*/
{
struct xml_cleanup_s * data;
data = (struct xml_cleanup_s *)arg;
if (data->node)
{
iks_delete(data->node);
}
if (data->parser)
{
iks_parser_delete(data->parser);
}
xfree(data);
} /* xml_cleanup() */
iks *
generate_xml_node(vector_t *vnode, iks *parent)
/*
* Generates a new iks node from the given array structure with the three
* elements (name, contents, attributes) and adds the node to the parent,
* or in case this is empty, simply returns it. The contents element may
* contain other tags, so recursion may occur.
*/
{
iks *node;
svalue_t *element;
char *name;
struct xml_cleanup_s * rec_data;
if ((mp_int) VEC_SIZE(vnode) != 3)
{
errorf("Bad arg 1 to xml_generate(): tag is not an array with 3 "
"elements.\n");
/* NOTREACHED */
return NULL;
}
/* get the name, as this is essential */
element = &vnode->item[XML_TAG_NAME];
if (element->type != T_STRING)
{
errorf("Bad arg 1 to xml_generate(): first element of tag array not a "
"string.\n");
/* NOTREACHED */
return NULL;
}
/* get the name */
name = get_txt(element->u.str);
/* depending whether there is a parent or not, we start the structure
* or add the node to the given one */
if (parent == NULL)
{
memsafe(node = iks_new(name), 30, "new iksemel node");
rec_data = xalloc(sizeof(*rec_data));
if (rec_data == NULL)
{
iks_delete(node);
errorf("generate_xml() Out of memory: (%lu bytes) for cleanup structure\n"
, (unsigned long) sizeof(*rec_data));
/* NOTREACHED */
return NULL;
}
rec_data->node = node;
rec_data->parser = NULL;
push_error_handler(xml_cleanup, &(rec_data->head));
}
else
{
memsafe(node = iks_insert(parent, name), 30, "insert new iksemel node");
}
/* now handle the attributes of this one */
element = &vnode->item[XML_TAG_ATTRIBUTES];
/* this might be absent */
if (element->type == T_MAPPING)
{
attribute_walk_extra_t extra;
extra.node = node;
extra.size = element->u.map->num_values;
extra.tag_name = name;
/* walk the mapping and add all attributes */
walk_mapping(element->u.map, &walk_attribute_mapping, &extra);
}
else if (element->type != T_NUMBER || element->u.number != 0)
{
errorf("Bad arg 1 to xml_generate(): second element of tag array not "
"NULL/mapping.\n");
/* NOTREACHED */
return NULL;
}
/* now check, if the node has a contents */
element = &vnode->item[XML_TAG_CONTENTS];
/* this might even be absent */
if (element->type == T_POINTER)
{
int size;
int i;
vector_t *contents;
/* get the vector */
contents = element->u.vec;
/* get its size */
size = (mp_int)VEC_SIZE(contents);
for (i = 0; i < size; i++)
{
element = &contents->item[i];
if (element->type == T_STRING)
{
/* found a cdata */
memsafe(iks_insert_cdata(node, get_txt(element->u.str), mstrsize(element->u.str))
, mstrsize(element->u.str)
, "new iksemel node cdata");
}
else if (element->type == T_POINTER)
{
/* found a sub tag, as iks_insert will handle the insert we do
* not have anything to do with the result
*/
generate_xml_node(element->u.vec, node);
}
}
}
else if (element->type != T_NUMBER || element->u.number != 0)
{
errorf("Bad arg 1 to xml_generate(): third element of tag array not "
"NULL/array.\n");
/* NOTREACHED */
return NULL;
}
return node;
}
void
pkg_iksemel_init()
{
iks_set_mem_funcs(iksemel_alloc, iksemel_free);
}
/*=========================================================================*/
/* EFUNS */
/*-------------------------------------------------------------------------*/
svalue_t *
f_xml_generate(svalue_t *sp)
/* EFUN xml_generate()
*
* string xml_generate(mixed *xml)
*
* Converts the given <xml> array into an XML conform string, if
* possible. The <xml> argument array must have the same structure
* as xml_parse returns.
*
* In case the parameter does not follow these rules, errors are raised.
* The method returns a valid XML string otherwise.
*/
{
char *xml_string;
iks *node;
vector_t *root;
/* get the root of the structure to be used */
root = sp->u.vec;
/* start generating the tree */
node = generate_xml_node(root, NULL);
/* At this point generate_xml_node() had
put an error handler on the stack.
*/
/* Clean up and return result */
free_svalue(sp);
/* get the xml string out of the stack */
memsafe(xml_string = iks_string(iks_stack(node), node)
, sizeof(*xml_string), "new xml string from node");
/* send the xml string back onto the stack */
put_c_string(sp, xml_string);
/* clean up, this will free the root node too, as it calls our error handler */
pop_stack();
return sp;
}
svalue_t *
f_xml_parse(svalue_t * sp)
/* EFUN xml_parse()
*
* mixed * xml_parse(string xml_text)
*
* Parses the given string <xml> as a XML conform string. The string must
* have only one root tag, subsequent root tags are ignored.
*
* If the xml string is correct, an array is of three elements is
* returned, where as the following indices are defined:
*
* string XML_TAG_NAME
* The name of the XML tag.
*
* mixed * XML_TAG_CONTENTS
* The contents of this xml tag as array. This array may
* contain either strings, or arrags of sub-tags again with
* three elements (see example)
*
* If the xml tag does not contain anything, the element is
* set 0.
*
* mapping XML_TAG_ATTRIBUTES
* All attributes given to the XML tag as mapping where the key
* is the attribute name and the value is its string value.
*
* If the xml tag does not contain any attributes, this element
* is set 0.
*
* If the XML string is not well formed, or there is not enough memory to
* parse the whole XML structure into the array an error is raised. In case
* the XML string can't be parsed, cause it is not valid XML, 0 is returned.
*/
{
struct xml_cleanup_s * rec_data;
int err;
memsafe(rec_data = xalloc(sizeof(*rec_data)), sizeof(*rec_data), "xml cleanup structure");
rec_data->node = NULL;
rec_data->parser = NULL;
push_error_handler(xml_cleanup, &(rec_data->head));
/* TODO: This can be implemented more efficient using the SAX interface. */
memsafe(rec_data->parser = iks_dom_new(&(rec_data->node)), 50, "new iksemel parser");
err = iks_parse(rec_data->parser, get_txt(sp->u.str), mstrsize(sp->u.str), 1);
switch (err)
{
case IKS_OK:
break;
case IKS_NOMEM:
errorf("Out of memory.\n");
/* NOTREACHED */
return sp;
case IKS_BADXML:
errorf("Bad arg 1 to xml_parse(): XML document not well formed (error "
"in line %ld, byte %ld).\n", iks_nr_lines(rec_data->parser)
, iks_nr_bytes(rec_data->parser));
/* NOTREACHED */
return sp;
case IKS_HOOK:
/* actually only used for a sax parser? */
break;
}
/* we no longer need the string */
free_svalue(sp);
/* set 0 to always have a valid return */
put_number(sp, 0);
if (rec_data->node != NULL)
{
/* tree contains the tree now, this will put the resulting a */
parse_node(sp, rec_data->node);
}
else
{
/* There was no XML tag or the tag was not closed properly. */
errorf("Bad arg 1 to xml_parse(): XML document not well formed (premature end "
"at line %ld, byte %ld).\n", iks_nr_lines(rec_data->parser)
, iks_nr_bytes(rec_data->parser));
}
/* At the end, be nice and remove the rest
using our error handler. */
pop_stack();
return sp;
}
#endif /* USE_IKSEMEL */

19
src/pkg-iksemel.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef PKG_IKSEMEL_H__
#define PKG_IKSEMEL_H__ 1
#include "driver.h"
#ifdef USE_IKSEMEL
#ifndef HAS_IKSEMEL
#error "pkg-iksemel configured even though the machine doesn't support iksemel."
#endif
/* --- Prototypes --- */
void pkg_iksemel_init();
#endif /* USE_IKSEMEL */
#endif /* PKG_IKSEMEL_H__ */

View File

@ -381,15 +381,17 @@ f_db_conv_string (svalue_t *sp)
char *buff;
s = sp->u.str;
buff = alloca(mstrsize(s)*2 +1);
buff = xalloc(mstrsize(s)*2 +1);
if ( !buff )
{
errorf("Out of memory.\n");
errorf("Out of memory (%zu bytes) in db_conv_string().\n",
mstrsize(s)*2 + 1);
/* NOTREACHED */
return sp;
}
mysql_escape_string(buff, get_txt(s), strlen(get_txt(s)) );
xfree(buff);
free_string_svalue(sp);
put_c_string(sp, buff);
return sp;

View File

@ -22,6 +22,10 @@
/* Error code to be returned if too many backtracks are detected.
*/
#ifdef PCRE_ERROR_RECURSIONLIMIT
#define RE_ERROR_BACKTRACK PCRE_ERROR_RECURSIONLIMIT
#else
#define RE_ERROR_BACKTRACK PCRE_ERROR_MATCHLIMIT
#endif
#endif /* PKG_PCRE_H_ */

View File

@ -74,7 +74,7 @@ struct sqlite_dbs_s
/* The list of database connections.
*/
static sqlite_dbs_t *head = NULL;
/*-------------------------------------------------------------------------*/
static sqlite_dbs_t *
find_db (object_t * obj)
@ -150,29 +150,83 @@ remove_db(sqlite_dbs_t *db)
/*-------------------------------------------------------------------------*/
static int
my_sqlite3_authorizer(void * data, int what, const char* arg1, const char* arg2,
my_sqlite3_authorizer (void * data, int what, const char* arg1, const char* arg2,
const char* dbname, const char* view)
/* Callback function for SQLite to handle authorizations.
*/
{
/* TODO: Check them via privilege_violation resp. valid_write.
(Don't know, whether sqlite can handle longjmps out of
its code in case of an error...)
*/
struct error_recovery_info error_recovery_info;
svalue_t *save_sp, sarg1, sarg2;
struct control_stack *save_csp;
int val;
switch(what)
{
case SQLITE_PRAGMA:
if(!strcasecmp(arg1, "synchronous"))
return SQLITE_OK;
return SQLITE_DENY;
/* PRAGMA name [ = value ]
* PRAGMA function(arg)
*
* arg1: name/function
* arg2: value/arg
* dbname/view: NULL
*/
error_recovery_info.rt.last = rt_context;
error_recovery_info.rt.type = ERROR_RECOVERY_APPLY;
rt_context = (rt_context_t *)&error_recovery_info;
save_sp = inter_sp;
save_csp = csp;
sarg1.type = T_INVALID;
sarg2.type = T_INVALID;
if (setjmp(error_recovery_info.con.text))
{
secure_apply_error(save_sp, save_csp, MY_FALSE);
val = SQLITE_DENY;
}
else
{
if(arg1)
put_c_string(&sarg1, arg1);
else
put_number(&sarg1, 0);
if(arg2)
put_c_string(&sarg2, arg2);
else
put_number(&sarg2, 0);
if(privilege_violation2(STR_SQLITE_PRAGMA, &sarg1, &sarg2, inter_sp))
val = SQLITE_OK;
else
val = SQLITE_DENY;
}
free_svalue(&sarg1);
sarg1.type = T_INVALID;
free_svalue(&sarg2);
sarg2.type = T_INVALID;
rt_context = error_recovery_info.rt.last;
return val;
case SQLITE_ATTACH:
case SQLITE_DETACH:
/* ATTACH "filename" AS "dbname"
*
* arg1: filename
* arg2, dbname, view: NULL
*/
/* SQLite3 doesn't allow the filename to be changed,
* but at least we must convert an absolute pathname
* to a relative one. So we have to deactivate it...
*/
return SQLITE_DENY;
default:
return SQLITE_OK;
}
@ -323,13 +377,13 @@ v_sl_exec (svalue_t * sp, int num_arg)
db = find_db (current_object);
if (!db)
errorf("The current object doesn't have a database open.\n");
/* To increase the efficiency of SQLite by avoid re-parsing of statements,
* these prepared (precompiled) statement objects should be cached and
* re-used whenever the command string is the same. The placeholder syntax
* of SQLite is defined at http://www.sqlite.org/c3ref/bind_blob.html
* See also http://about.psyc.eu/SQL -lynX 2008
*/
/* To increase the efficiency of SQLite by avoid re-parsing of statements,
* these prepared (precompiled) statement objects should be cached and
* re-used whenever the command string is the same. The placeholder syntax
* of SQLite is defined at http://www.sqlite.org/c3ref/bind_blob.html
* See also http://about.psyc.eu/SQL -lynX 2008
*/
err = sqlite3_prepare(db->db, get_txt(argp->u.str), mstrsize(argp->u.str),
&stmt, &tail);
if(err)
@ -380,8 +434,7 @@ v_sl_exec (svalue_t * sp, int num_arg)
rec_data->rows = NULL;
rec_data->stmt = stmt;
push_error_handler(sl_exec_cleanup, &(rec_data->head));
sp = inter_sp;
sp = push_error_handler(sl_exec_cleanup, &(rec_data->head));
while((err = sqlite3_step(stmt)) == SQLITE_ROW)
{

View File

@ -19,6 +19,7 @@
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <locale.h>
#include <time.h>
#include "backend.h"
@ -86,24 +87,30 @@ get_current_time (void)
/*-------------------------------------------------------------------------*/
char *
time_string (mp_int t)
/* Return a textual representation of the time <t>. */
time_fstring (mp_int t, const char* str, Bool localized)
/* Return a textual representation of the time <t> according to the format
* string <str>. Doesn't cache because it would be necessary to
* save the format string and compare.
* If localized is true, this function sets the locale according to the
* environment variable before calling strftime and resets it afterwards.
* TODO: It would be nicer to allocate the result buffer dynamically
* TODO::for using longer format strings. */
{
static char result[80];
struct tm *tm;
mp_int last_time = -1;
if (t != last_time)
{
time_t ti = (time_t)t;
last_time = t;
tm = localtime(&ti);
strftime(result, sizeof(result)-1, "%a %b %d %H:%M:%S %Y", tm);
static char result[512];
struct tm *tm; // broken-down time struct
time_t ti = (time_t)t;
tm = localtime(&ti);
if (!localized) {
setlocale(LC_TIME, "C");
strftime(result, sizeof(result)-1, str, tm);
setlocale(LC_TIME, "");
}
else
strftime(result, sizeof(result)-1, str, tm);
return result;
} /* time_string() */
} /* time_fstring() */
/*-------------------------------------------------------------------------*/
char *
@ -115,18 +122,13 @@ utime_string (mp_int t, mp_int ut)
static char result[80];
struct tm *tm;
size_t len;
mp_int last_t = -1, last_ut = -1;
if (t != last_t || ut != last_ut)
{
time_t ti = (time_t)t;
last_t= t;
last_ut= ut;
tm = localtime(&ti);
len = strftime(result, sizeof(result)-1, "%a %b %d %H:%M:%S:", tm);
sprintf(result+len, "%06ld", ut);
strftime(result+len+6, sizeof(result)-7-len, " %Y", tm);
}
time_t ti = (time_t)t;
tm = localtime(&ti);
len = strftime(result, sizeof(result)-1, "%a %b %d %H:%M:%S:", tm);
sprintf(result+len, "%06"PRIdMPINT, ut);
strftime(result+len+6, sizeof(result)-7-len, " %Y", tm);
return result;
} /* utime_string() */
@ -154,8 +156,8 @@ time_stamp (void)
time_t ti = (time_t)t;
last_time = t;
tm = localtime(&ti);
strftime( current_time_stamp, sizeof(current_time_stamp)-1
, "%Y.%m.%d %H:%M:%S", tm);
strftime( current_time_stamp, sizeof(current_time_stamp),
"%Y.%m.%d %H:%M:%S", tm);
}
return current_time_stamp;
} /* time_stamp() */

View File

@ -87,12 +87,7 @@ extern int errno;
#if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H)
# include <memory.h>
#endif
#if 0
/* TODO: Obsoleted by limits.h+floats.h - remove this and the config check */
#ifdef HAVE_VALUES_H
# include <values.h>
#endif
#endif
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
@ -121,35 +116,6 @@ extern int errno;
# include <sys/param.h>
#endif
/*------------------------------------------------------------------
* Limits for less-standard integral types:
*
* LONGLONG_MIN, LONGLONG_MAX, ULONGLONG_MAX
* TODO: Add SIZEOF_SIZET to configure, and SIZET_limits here.
* TODO:: Then use SIZET_limits in smalloc::smalloc().
*/
#if defined(HAVE_LONG_LONG) && !defined(LONGLONG_MIN)
# if defined(LONG_LONG_MAX)
# define LONGLONG_MIN LONG_LONG_MIN
# define LONGLONG_MAX LONG_LONG_MAX
# define ULONGLONG_MAX ULONG_LONG_MAX
# elif SIZEOF_LONG_LONG == 8
# define LONGLONG_MIN (-9223372036854775807LL - 1)
# define LONGLONG_MAX (9223372036854775807LL)
# define ULONGLONG_MAX (0xffffffffffffffffULL)
# elif SIZEOF_LONG_LONG == SIZEOF_LONG
# define LONGLONG_MIN LONG_MIN
# define LONGLONG_MAX LONG_MAX
# define ULONGLONG_MAX ULONG_MAX
# elif SIZEOF_LONG_LONG == SIZEOF_INT
# define LONGLONG_MIN INT_MIN
# define LONGLONG_MAX INT_MAX
# define ULONGLONG_MAX UINT_MAX
# endif
#endif
/*------------------------------------------------------------------
* Define some macros:
* CHAR_BIT number of bits in a char, if not defined already.
@ -184,31 +150,35 @@ extern int errno;
# endif
#endif
#if defined(__GNUC__) && __GNUC__ >= 2 && (__GNUC_MINOR__ > 6 || __GNUC__ > 2)
# define NORETURN __attribute__ ((noreturn))
# define UNUSED __attribute__ ((unused))
/* some handy gcc attributes, but define everything to nothing if any other
* compiler ist used. Additional attributes maybe used in the driver are:
always_inline, const, deprecated, format_arg, nonnull, pure, returns_twice,
unused, warn_unused_result.
*/
#if defined(__GNUC__)
# define MALLOC __attribute__((malloc))
# define NORETURN __attribute__((noreturn))
# define UNUSED __attribute__((unused))
# define FORMATDEBUG(f,a,b) __attribute__((format (f,a,b)))
#elif defined(__MWERKS__)
# define __attribute__(x) /*NOTHING*/
# define NORETURN
# define UNUSED
#else
# define NORETURN
# define UNUSED
#endif
#if defined(__GNUC__) && __GNUC__ >= 3
# define MALLOC __attribute__ ((malloc))
#else
# define MALLOC
#endif
#ifdef __GNUC__
# define FORMATDEBUG(f,a,b) __attribute__ ((format (f,a,b)))
# define FORMATDEBUG(f,a,b)
#else
# define __attribute__(x) /*NOTHING*/
# define NORETURN
# define UNUSED
# define MALLOC
# define FORMATDEBUG(f,a,b)
#endif
#define VARPROT(proto,like,form,var) proto FORMATDEBUG(like,form,var)
// TODO: autoconf defines inline to some suitable keyword if the compiler does
// not understand inline itself. Just use inline in code?
#if defined(HAS_INLINE) && !defined(NO_INLINES)
# define INLINE inline
/* configure made sure that 'inline' expands to the proper attribute */
@ -234,102 +204,284 @@ extern int errno;
#define MSDOS_FS
#endif
/*------------------------------------------------------------------
* Test for C99-compatible data types
* TODO: check if we can remove these checks once (if?) we require a C99
* compliant build environment.
*/
#if defined(HAVE_INTTYPES_H)
/* C99 compliant inttypes.h. */
# include <inttypes.h>
#endif
#if defined(HAVE_STDINT_H)
/* C99 compliant stdint.h available
* Usually it gets included also in inttypes.h, but it doesn't hurt to
* include it specifically. */
# include <stdint.h>
#endif
/* If stdint.h or inttypes.h don't have int8_t, int16_t, int32_t, int64_t,
* uint8_t, uint16_t, uint32_t, uint64_t, intmax_t, uintmax_t, intptr_t,
* or uintmax_t, autoconf will have them defined to a suitable type now.
* If Autoconf did not find suitable types, there is probably no sense in
* searching them ourself.
*/
#if !defined(HAVE_INTPTR_T) && !defined(intptr_t)
/* If there is no intptr_t in stdint.h and autoconf did not find a
* suitable type, we're out of luck (because in this case we are unlikely
* to find one). */
# error Autoconf did not find an integer type with same size as a pointer
Thats it.
#endif
#if !defined(INT32_MAX) && !defined(int32_t)
# error Autoconf did not find an integer type with exactly 32 bits.
Thats it.
#endif
/* If mode_t, off_t, pid_t, size_t or ssize_t are not defined by the standard
* headers on this system, autoconf will have them defined as well.
*/
/*------------------------------------------------------------------
* Limits for less-standard integral types:
*
* LONGLONG_MIN, LONGLONG_MAX, ULONGLONG_MAX
* TODO: Add SIZEOF_SIZET to configure, and SIZET_limits here.
* TODO:: Then use SIZET_limits in smalloc::smalloc().
*/
#if defined(HAVE_LONG_LONG) && !defined(LONGLONG_MIN)
# if defined(LONG_LONG_MAX)
# define LONGLONG_MIN LONG_LONG_MIN
# define LONGLONG_MAX LONG_LONG_MAX
# define ULONGLONG_MAX ULONG_LONG_MAX
# elif SIZEOF_LONG_LONG == 8
# define LONGLONG_MIN (-9223372036854775807LL - 1)
# define LONGLONG_MAX (9223372036854775807LL)
# define ULONGLONG_MAX (0xffffffffffffffffULL)
# elif SIZEOF_LONG_LONG == SIZEOF_LONG
# define LONGLONG_MIN LONG_MIN
# define LONGLONG_MAX LONG_MAX
# define ULONGLONG_MAX ULONG_MAX
# elif SIZEOF_LONG_LONG == SIZEOF_INT
# define LONGLONG_MIN INT_MIN
# define LONGLONG_MAX INT_MAX
# define ULONGLONG_MAX UINT_MAX
# endif
#endif
/*------------------------------------------------------------------
* Integral types:
* Bool, SBool, CBool: boolean type, sized as int/short/char.
* Bool, SBool, CBool: boolean type, sized as _Bool or int, short, char.
* p_int : an integer that has the same size as a pointer
* ph_int : an integer that has half the size of a pointer
* mp_int : an integer that has at least the size of a pointer
* int32 : an integer with 32 bits
* PTRTYPE: a type to use with constant pointer arithmetic.
* The unsigned versions use 'uint' instead of 'int'.
* Additionally to the type themselves we define format specifiers for
* printing our types with sprintf() (PRN*) and scanning them with sscanf()
* (SCN*).
* Changes here must be reflected in my-limits.h .
* TODO: Add a type 'u/schar', '(u/s)int8' and '(u/s)int16'., unless not already
* TODO:: defined by STDC.
* TODO: inttypes.h, stdint.h, limits.h have many interesting types...
* Additional integral types from stdint.h/inttypes.h are available (s. above)
* TODO: check, if it is feasible to use the C99 data types instead of our own
* TODO::names in the future.
*/
/* p_int : an integer that has the same size as a pointer */
#define SIZEOF_PINT SIZEOF_CHAR_P
#if SIZEOF_LONG == SIZEOF_CHAR_P
typedef long p_int;
typedef unsigned long p_uint;
# define PINT_MIN LONG_MIN
# define PINT_MAX LONG_MAX
# define PUINT_MAX ULONG_MAX
#elif SIZEOF_INT == SIZEOF_CHAR_P
typedef int p_int;
typedef unsigned int p_uint;
# define PINT_MIN INT_MIN
# define PINT_MAX INT_MAX
# define PUINT_MAX UINT_MAX
#elif defined(HAVE_LONG_LONG) && SIZEOF_LONG_LONG == SIZEOF_CHAR_P
typedef long long p_int;
typedef unsigned long long p_uint;
# define PINT_MIN LONGLONG_MIN
# define PINT_MAX LONGLONG_MAX
# define PUINT_MAX ULONGLONG_MAX
#if defined(HAVE_INTPTR_T) && SIZEOF_INT != SIZEOF_CHAR_P
/* just use intptr_t
* BUT! glibc on ILP32 platforms unfortunately defines intptr_t as int,
* not as long. While this doesn't change things in principle, because they
* have equal size, gcc will output a bunch of warnings on
* sprintf("%ld",p_int) because %ld is the wrong format specifier for int.
* Therefore this little hack, which uses intptr_t for the time being
* only if sizeof(int) != sizeof(char*) (because then intptr_t cannot be
* an int). As it is not guaranteed that p_int will always be a long or
* have the size of a long, this %ld for outputting p_int are anyway a
* problem.
* TODO: As soon, as all the %ld for p_int are replaced, this hack should
* TODO::be removed!
*/
typedef intptr_t p_int;
typedef uintptr_t p_uint;
# define PINT_MIN INTPTR_MIN
# define PINT_MAX INTPTR_MAX
# define PUINT_MAX UINTPTR_MAX
# define SIZEOF_PINT SIZEOF_INTPTR_T
# define PRIdPINT PRIdPTR
# define PRIuPINT PRIuPTR
# define PRIxPINT PRIxPTR
# define SCNdPINT SCNdPTR
# define SCNuPINT SCNuPTR
# define SCNxPINT SCNxPTR
# ifdef __PRIPTR_PREFIX
# define PRI_PINT_PREFIX __PRIPTR_PREFIX
# else
/* ugly - it is a pity that the format specifiers are standardized but not
* the length modifier. But we need one for sprintf.c. *sigh* */
# if SIZEOF_INTPTR_T == SIZEOF_LONG
# define PRI_PINT_PREFIX "l"
# elif SIZEOF_INTPTR_T == SIZEOF_INT
# define PRI_PINT_PREFIX
# elif HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
# define PRI_PINT_PREFIX "ll"
# else
# error Could not find a length modifier for intptr_t.
Thats it.
# endif
# endif
#else
#error cannot find an integer type with same size as a pointer
Thats it.
#endif
/* autoconf will have some type defined to intptr_t, but it won't define the
* limits and we won't have SIZEOF_INTPTR_T available. Therefore we have to
* search ourselves the old way.
* TODO: remove once C99 support is required */
# define SIZEOF_PINT SIZEOF_CHAR_P
# if SIZEOF_LONG == SIZEOF_CHAR_P
typedef long p_int;
typedef unsigned long p_uint;
# define PINT_MIN LONG_MIN
# define PINT_MAX LONG_MAX
# define PUINT_MAX ULONG_MAX
# define PRI_PINT_PREFIX "l"
# elif SIZEOF_INT == SIZEOF_CHAR_P
typedef int p_int;
typedef unsigned int p_uint;
# define PINT_MIN INT_MIN
# define PINT_MAX INT_MAX
# define PUINT_MAX UINT_MAX
# define PRI_PINT_PREFIX
# elif defined(HAVE_LONG_LONG) && SIZEOF_LONG_LONG == SIZEOF_CHAR_P
typedef long long p_int;
typedef unsigned long long p_uint;
# define PINT_MIN LONGLONG_MIN
# define PINT_MAX LONGLONG_MAX
# define PUINT_MAX ULONGLONG_MAX
# define PRI_PINT_PREFIX "ll"
# else
/* nearly impossible (s. intptr_t check above, but better safe than
* sorry. */
# error cannot find an integer type with same size as a pointer
Thats it.
# endif
# define PRIdPINT PRI_PINT_PREFIX "d"
# define PRIuPINT PRI_PINT_PREFIX "u"
# define PRIxPINT PRI_PINT_PREFIX "x"
# define SCNdPINT PRI_PINT_PREFIX "d"
# define SCNuPINT PRI_PINT_PREFIX "u"
# define SCNxPINT PRI_PINT_PREFIX "x"
#endif // HAVE_INTPTR_T
/* ph_int : an integer that has half the size of a pointer */
/* ph_int : an integer that has half the size of a pointer.
* Unfortuntately C99 has nothing like this and therefore we have to find our
* own.
*/
#if SIZEOF_CHAR_P == SIZEOF_INT * 2
typedef int ph_int;
typedef unsigned int ph_uint;
# define PHINT_MIN INT_MIN
# define PHINT_MAX INT_MAX
# define PHUINT_MAX UINT_MAX
# define PRI_PHINT_PREFIX
#elif SIZEOF_CHAR_P == SIZEOF_SHORT * 2
typedef short ph_int;
typedef unsigned short ph_uint;
# define PHINT_MIN SHRT_MIN
# define PHINT_MAX SHRT_MAX
# define PHUINT_MAX USHRT_MAX
# define PRI_PHINT_PREFIX "h"
#elif SIZEOF_CHAR_P == SIZEOF_LONG * 2
typedef long ph_int;
typedef unsigned long ph_uint;
# define PHINT_MIN LONG_MIN
# define PHINT_MAX LONG_MAX
# define PHUINT_MAX ULONG_MAX
# define PRI_PHINT_PREFIX "l"
#else
# if SIZEOF_CHAR_P == 4
/* short is assumed to be always 2 bytes. */
/* TODO: This is a dangerous assumption. */
typedef short ph_int;
typedef unsigned short ph_uint;
# define PHINT_MIN SHORT_MIN
# define PHINT_MAX SHORT_MAX
# define PHUINT_MAX USHORT_MAX
# endif
# error Cannot find an integer of half the size of a pointer.
Thats it.
#endif
#define PRIdPHINT PRI_PHINT_PREFIX "d"
#define PRIuPHINT PRI_PHINT_PREFIX "u"
#define PRIxPHINT PRI_PHINT_PREFIX "x"
#define SCNdPHINT PRI_PHINT_PREFIX "d"
#define SCNuPHINT PRI_PHINT_PREFIX "u"
#define SCNxPHINT PRI_PHINT_PREFIX "x"
/* mp_int : an integer that has at least the size of a pointer */
/* mp_int : an integer that has at least the size of a pointer
* TODO: use intmax_t intstead once the driver does not assume mp_ints to be
* TODO::longs? */
typedef p_int mp_int;
typedef p_uint mp_uint;
typedef p_uint mp_uint;
#define MPINT_MIN PINT_MIN
#define MPINT_MAX PINT_MAX
#define MPUINT_MAX PUINT_MAX
#define PRIdMPINT PRIdPINT
#define PRIuMPINT PRIuPINT
#define PRIxMPINT PRIxPINT
#define SCNdMPINT PRIdPINT
#define SCNuMPINT PRIuPINT
#define SCNxMPINT PRIxPINT
#ifndef __BEOS__
/* int32 : an integer with 32 bits. */
/* TODO: Add a configuration check for 'int32' typedef */
# if SIZEOF_LONG == 4
# if !defined(_AIX)
typedef long int32;
# endif
typedef unsigned long uint32;
# else
# if SIZEOF_INT == 4
typedef int int32;
typedef unsigned int uint32;
# endif
/* int32 : an integer with 32 bits.
TODO: just use (u)int32_t instead of (u)int32. */
typedef int32_t int32;
typedef uint32_t uint32;
# ifndef PRId32
/* unfortunately there seems to be no PRId32 from inttypes.h or alike.
TODO: Once we require C99, we can get rid of the this stuff */
# if !defined(CHAR_BIT) || CHAR_BIT != 8
# error CHAR_BIT does not exist or is != 8 which is currently not supported!
Thats it.
# endif
/* now sizeof(int32) has to be sizeof(char) * 4 == 4. */
# if SIZEOF_INT == 4
# define __PRId32PREFIX
# elif SIZEOF_LONG == 4
# define __PRId32PREFIX "l"
# elif SIZEOF_SHORT == 4
# define __PRIx32PREFIX "h"
# else
# error Could not find length modifier for (u)int32
Thats it.
# endif
# define PRId32 __PRId32PREFIX "d"
# define PRIu32 __PRId32PREFIX "u"
# define PRIx32 __PRId32PREFIX "x"
# endif /* PRId32 */
#endif /* __BEOS__ */
/* Boolean datatype and values */
typedef int Bool; /* naming it 'bool' clashes on some machines... */
/* type to use with constant pointer arithmetic. */
#define PTRTYPE char *
/* Boolean datatype and values */
#ifdef HAVE_STDBOOL_H
# include <stdbool.h>
#else
# ifndef HAVE__BOOL
/* _Bool is not available - typedef our own with int.
* naming it 'bool' clashes on some machines... */
typedef int _Bool;
# endif
/* define true and false as stdbool.h does. */
# define false 0
# define true 1
# define __bool_true_false_are_defined 1
#endif // HAVE_STDBOOL_H
/* _Bool looks strange and we anyway used Bool until now. */
typedef _Bool Bool;
/* TODO: check if these two can be merged with Bool */
typedef short SBool;
typedef char CBool;
#define MY_TRUE (1)
#define MY_FALSE (0)
#define MY_TRUE (true)
#define MY_FALSE (false)
/* TODO: This should go into my-malloc.h? */
#ifdef FREE_RETURNS_VOID
@ -340,17 +492,11 @@ typedef char CBool;
# define FREE_RETURN return 1;
#endif
#define PTRTYPE char *
/*------------------------------------------------------------------
* Provide functions, types and defines missing from the system headers.
*/
#ifndef HAVE_SSIZE_T
typedef signed long ssize_t;
#endif
#ifndef HAVE_MEMCPY
/* The following 'implementation' is suitable for throwing away a value,
but not to using it; the cast to return int is likely to show a warning
@ -427,7 +573,8 @@ typedef signed long ssize_t;
extern char current_time_stamp[];
extern mp_int get_current_time(void);
extern char * time_string(mp_int);
extern char * time_fstring(mp_int t, const char* str, Bool localized)
FORMATDEBUG(strftime,2,0);
extern char * utime_string(mp_int, mp_int);
extern char * time_stamp(void);
extern char *xmemmem(const char *, size_t, const char *, size_t);

File diff suppressed because it is too large Load Diff

View File

@ -127,7 +127,7 @@ find_add_pointer (struct pointer_table *ptable, void *pointer, Bool bAdd)
*/
{
mp_int key; /* The <pointer> as a normal int */
p_uint key; /* The <pointer> as a normal int */
int hash; /* hash computed from <key> aka <pointer> */
int mask; /* mask for <hash> in to <usage_p> */
char *usage_p; /* First usage vector byte for entry <hash> */
@ -135,7 +135,7 @@ find_add_pointer (struct pointer_table *ptable, void *pointer, Bool bAdd)
struct pointer_record *new; /* New record to add */
struct pointer_record **insert; /* Pointer to hashed table entry */
key = (mp_int)pointer;
key = (p_uint)pointer;
/* Compute the hash value, and the index and mask for
* the usage vector
@ -214,8 +214,8 @@ find_add_pointer (struct pointer_table *ptable, void *pointer, Bool bAdd)
table = mempool_alloc(ptable->pool, sizeof *table);
if (!table)
errorf("(pointertable) Out of memory (%lu bytes pooled) "
"for subtable.\n", (unsigned long) sizeof *table);
errorf("(pointertable) Out of memory (%zu bytes pooled) "
"for subtable.\n", sizeof *table);
*insert = (struct pointer_record *)table;
memset(table->used, 0, sizeof table->used);
@ -247,8 +247,8 @@ find_add_pointer (struct pointer_table *ptable, void *pointer, Bool bAdd)
usage_p[0] |= mask;
new = mempool_alloc(ptable->pool, sizeof *new);
if (!new)
errorf("(pointertable) Out of memory (%lu bytes pooled) for "
"new entry.\n", (unsigned long) sizeof *new);
errorf("(pointertable) Out of memory (%zu bytes pooled) for "
"new entry.\n", sizeof *new);
*insert = new;
new->key = key;
new->next = old;

View File

@ -1,274 +1,120 @@
/*---------------------------------------------------------------------------
* Gamedriver: Random Generator 'Mersenne Twister'
/*------------------------------------------------------------------
* Wrapper for the 'SIMD oriented Fast Mersenne Twister.
*
* A C-program for MT19937, with initialization improved 2002/2/10.
* Coded by Takuji Nishimura and Makoto Matsumoto.
* This is a faster version by taking Shawn Cokus's optimization,
* Matthe Bellew's simplification, Isaku Wada's real version.
*
* Before using, initialize the state by using init_genrand(seed)
* or init_by_array(init_key, key_length).
*
* Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
* 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.
*
* 3. The names of its contributors may not 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 COPYRIGHT OWNER 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.
*
* Any feedback is very welcome.
* http://www.math.keio.ac.jp/matumoto/emt.html
* email: matumoto@math.keio.ac.jp
*---------------------------------------------------------------------------
* SFMT was developed by Mutsuo Saito and Makoto Matsumoto,
* Hiroshima University,
* http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html)
* SFMT was integrated to LDMud by Zesstra@MorgenGrauen (http://mg.mud.de)
*------------------------------------------------------------------
*/
#include "driver.h"
#include "random.h"
#include "backend.h"
/* Period parameters */
#define N 624
#define M 397
#define MATRIX_A 0x9908b0dfUL /* constant vector a */
#define UMASK 0x80000000UL /* most significant w-r bits */
#define LMASK 0x7fffffffUL /* least significant r bits */
#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
/* This is included on purpose so that the compiler may inline some functions.
* They are anyway never used anywhere else, all other parts of the driver use
* only the wrapper functions in this file.
*/
#include "random/SFMT.c"
static unsigned long state[N]; /* the array for the state vector */
static int left = 1;
static int initf = 0;
static unsigned long *next;
const unsigned int INIT_ARRAY_SIZE = 156U; // 4*156 == 624 bytes
/* initializes state[N] with a seed */
void init_genrand(unsigned long s)
{
int j;
state[0]= s & 0xffffffffUL;
for (j=1; j<N; j++) {
state[j] = (1812433253UL * (state[j-1] ^ (state[j-1] >> 30)) + j);
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
/* In the previous versions, MSBs of the seed affect */
/* only MSBs of the array state[]. */
/* 2002/01/09 modified by Makoto Matsumoto */
state[j] &= 0xffffffffUL; /* for >32 bit machines */
}
left = 1; initf = 1;
}
/* initialize by an array with array-length */
/* init_key is the array for initializing keys */
/* key_length is its length */
/* slight change for C++, 2004/2/26 */
void init_by_array(unsigned long init_key[], int key_length)
{
int i, j, k;
init_genrand(19650218UL);
i=1; j=0;
k = (N>key_length ? N : key_length);
for (; k; k--) {
state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1664525UL))
+ init_key[j] + j; /* non linear */
state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
i++; j++;
if (i>=N) { state[0] = state[N-1]; i=1; }
if (j>=key_length) j=0;
}
for (k=N-1; k; k--) {
state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL))
- i; /* non linear */
state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
i++;
if (i>=N) { state[0] = state[N-1]; i=1; }
}
state[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
left = 1; initf = 1;
}
static void next_state(void)
{
unsigned long *p=state;
int j;
/* if init_genrand() has not been called, */
/* a default initial seed is used */
if (initf==0) init_genrand(5489UL);
left = N;
next = state;
for (j=N-M+1; --j; p++)
*p = p[M] ^ TWIST(p[0], p[1]);
for (j=M; --j; p++)
*p = p[M-N] ^ TWIST(p[0], p[1]);
*p = p[M-N] ^ TWIST(p[0], state[0]);
}
/* generates a random number on [0,0xffffffff]-interval */
unsigned long genrand_int32(void)
{
unsigned long y;
if (--left == 0) next_state();
y = *next++;
/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680UL;
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
return y;
}
#if 0
/** LDMud doesn't use the following functions - yet. **/
/* generates a random number on [0,0x7fffffff]-interval */
long genrand_int31(void)
{
unsigned long y;
if (--left == 0) next_state();
y = *next++;
/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680UL;
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
return (long)(y>>1);
}
/* generates a random number on [0,1]-real-interval */
double genrand_real1(void)
{
unsigned long y;
if (--left == 0) next_state();
y = *next++;
/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680UL;
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
return (double)y * (1.0/4294967295.0);
/* divided by 2^32-1 */
}
/* generates a random number on [0,1)-real-interval */
double genrand_real2(void)
{
unsigned long y;
if (--left == 0) next_state();
y = *next++;
/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680UL;
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
return (double)y * (1.0/4294967296.0);
/* divided by 2^32 */
}
/* generates a random number on (0,1)-real-interval */
double genrand_real3(void)
{
unsigned long y;
if (--left == 0) next_state();
y = *next++;
/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680UL;
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
return ((double)y + 0.5) * (1.0/4294967296.0);
/* divided by 2^32 */
}
/* generates a random number on [0,1) with 53-bit resolution*/
double genrand_res53(void)
{
unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6;
return(a*67108864.0+b)*(1.0/9007199254740992.0);
}
/* These real versions are due to Isaku Wada, 2002/01/09 added */
#endif
// Name of the device/file to seed the PRNG from
char * prng_device_name = NULL;
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* Driver interface functions */
/*-------------------------------------------------------------------------*/
void
seed_random (uint32 seed)
/* Initialize the generator */
{
unsigned long init[4];
init[0] = seed & 0xFFF;
init[1] = (seed >>= 8) & 0xFFF;
init[2] = (seed >>= 8) & 0xFFF;
init[3] = (seed >>= 8) & 0xFFF;
init_by_array(init, 4);
} /* seed_random() */
/*-------------------------------------------------------------------------*/
uint32
random_number (uint32 n)
/* random_number() is in random.h to be inlined. */
/* Return a random number in the range 0..n-1.
*
* The MT FAQ suggests:
* If the application is not sensitive to the rounding off error, then please
* multiply N to [0,1)-real uniform random numbers and take the integer part
* (this is sufficient for most applications).
*
* I use the appropriate functions from the SFMT to generate random numbers on
* the [0,1) interval and multiply with N.
*/
#if SIZEOF_LONG == SIZEOF_CHAR_P
uint64_t random_number(uint64_t n) {
return genrand_res53() * n;
}
#elif SIZEOF_INT == SIZEOF_CHAR_P
uint32_t random_number(uint32 n) {
return genrand_real2() * n;
}
#else
#error We currently do not yet support a 128 bit integer type used as \
svalue number type.
#endif
void seed_random_from_int (uint32_t seed)
/* Initialize the generator */
{
return genrand_int32() * (1.0/4294967296.0) * n;
/*
* Since most compilers compute the constant when it is compiled, so this
* code runs with the same speed with the standard C codes, and portability
* and readability are better.
*/
} /* random_number() */
#ifdef USE_LDMUD_COMPATIBILITY
# ifdef VERBOSE
printf("%s Seeding PRNG with: 0x%lx\n"
, time_stamp(), (unsigned long)seed);
# endif
debug_message("%s Seeding PRNG with: 0x%lx\n"
, time_stamp(), (unsigned long)seed);
#endif
init_gen_rand(seed);
} /* seed_random_from_int() */
/*-------------------------------------------------------------------------*/
void
seed_random(const char *filename)
/* Opens the file given by filename and reads 156 uint32_t (624
* bytes) from it (most often the file is probably /dev/urandom or
* /dev/random). If successful the random number generator will be seeded
* by an array of 624 bytes. Otherwise the driver clock will be used as
* fallback.
*/
{
FILE *seedsrc = NULL; // Filepointer
// If we got a NULL pointer or an empty string, don't try to open some
// device/file.
if (filename != NULL && strlen(filename))
seedsrc = fopen(filename,"rb");
// if we have a file descriptor try to get a suitable amount of 32-bit
// values from a file (right now 156 uint32_t / 624 bytes)
if (seedsrc) {
uint32_t seeddata[INIT_ARRAY_SIZE];
size_t count = fread( seeddata, sizeof(uint32), INIT_ARRAY_SIZE,
seedsrc );
fclose(seedsrc);
if( count == INIT_ARRAY_SIZE ) {
init_by_array(seeddata, INIT_ARRAY_SIZE ); // seed PRNG
#ifdef USE_LDMUD_COMPATIBILITY
# ifdef VERBOSE
printf("%s Seeding PRNG from %s.\n", time_stamp(),
filename);
# endif
debug_message("%s Seeding PRNG from %s.\n", time_stamp(),
filename);
#endif
return;
} // if (count == INIT_ARRAY_SIZE)
} // if (seedsrc)
// Fall-back: driver clock
#ifdef USE_LDMUD_COMPATIBILITY
# ifdef VERBOSE
printf("%s Seeding PRNG with current driver time\n"
, time_stamp());
# endif
debug_message("%s Seeding PRNG with current driver time\n"
, time_stamp());
#endif
seed_random_from_int((uint32_t)current_time);
} /* seed_random() */
/***************************************************************************/

View File

@ -2,8 +2,28 @@
#define RANDOM_H__ 1
#include "driver.h"
// SFTM expects MEXP to contain the desired period length
#ifdef RANDOM_PERIOD_LENGTH
#define MEXP RANDOM_PERIOD_LENGTH
#endif
extern uint32 random_number(uint32 n);
extern void seed_random(uint32 seed);
#include "random/SFMT.h"
#define PRNG_DEFAULT_DEVICE "/dev/urandom"
// device/file to read seed for the PRNG from
extern char * prng_device_name;
/* --- Prototypes --- */
extern void seed_random_from_int(uint32_t seed);
extern void seed_random(const char *filename);
#if SIZEOF_LONG == SIZEOF_CHAR_P
uint64_t random_number(uint64_t n);
#elif SIZEOF_INT == SIZEOF_CHAR_P
uint32_t random_number(uint32_t n);
#else
#error We currently do not yes support a 128 bit integer type used as \
svalue number type.
#endif
#endif /* RANDOM_H__ */

55
src/random/CHANGE-LOG.txt Normal file
View File

@ -0,0 +1,55 @@
ver 1.3.3
-------
change condition compile of do_recursion in SFMT.c
ver 1.3.2
-------
bug fix to_res53_mix and genrand_res53_mix.
ver 1.3.1
-------
gcc compile option changed form -O9 to -O3.
add functions genrand_res53_mix and to_res53_mix.
bug fix about definition of ALWAYS_INLINE.
add new definition PRE_ALWAYS for MSC.
ver 1.3
-------
bug fixed: -DONLY64 without -DBIG_ENIAN64 had been generating
wrong sequence.
bug fixed: There is no documentation about BIG_ENDIAN64.
add automatic endian check by __BIG_ENDIAN__ predefined macro.
bug fixed: change == in check.sh to =
add SFMT-params216091.h
add AltiVec parameter format for systems which are not osx.
change Makefile for systems which are not osx and support AltiVec.
change sample2 of howto-compile for Free BSD.
change source files for BORLANDC and Visual Studio.
change period certification code more smart.
add params directory.
ver 1.2.1
-------
Fix typo in SFMT-alti.c SFMT-sse2.c
marge SFMT-alti.c and SFMT-alti.h into SFMT-alti.h
marge SFMT-sse2.c and SFMT-sse2.h into SFMT-sse2.h
This version is not released.
ver 1.2
-------
Support many periods: 2^{607}, 2^{1279}, 2^{2281}, 2^{4253}, 2^{11213},
2^{19937}, 2^{44497}, 2^{86243}, 2^{132049}
Fix typo in LICENSE.txt.
Add cast to vec_perm for SFMT-alti.c, SFMT-alti64.c.
combine source codes.
ver 1.1
-------
The period certification method is changed from constant to function.
The convert functions from 32-bit and 64-bit integer to double are added.
The documentation is changed.
Sample programs are added.
ver 1.0
-------
The first version.

21
src/random/FILES.txt Normal file
View File

@ -0,0 +1,21 @@
This archive contails following directories and files.
TOP DIRECTORY
FILES.txt: This file.
LICENSE.txt: License file.
CHANGE-LOG.txt: Change log file.
SFMT.h: Header file.
SFMT-params.h: parameter file which controls various Mersenne expornent
params607.h: parameters for period of 2^{607}-1
params1279.h: parameters for period of 2^{1279}-1
params2281.h: parameters for period of 2^{2281}-1
params4253.h: parameters for period of 2^{4253}-1
params11213.h: parameters for period of 2^{11213}-1
params19937.h: parameters for period of 2^{19937}-1
params44497.h: parameters for period of 2^{44497}-1
params86243.h: parameters for period of 2^{86243}-1
params132049.h: parameters for period of 2^{132049}-1
params216091.h: parameters for period of 2^{216091}-1
SFMT.c: C code for standard C (c99) and unix like systems.
SFMT-alti.h: C code optimized for PowerPC AltiVec.
SFMT-sse2.h: C code optimized for intel SSE2.

32
src/random/LICENSE.txt Normal file
View File

@ -0,0 +1,32 @@
This License covers the the files in this subdirectory of the LDMud
source (src/random/).
Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
University. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* 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.
* Neither the name of the Hiroshima University 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 COPYRIGHT
OWNER 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.

10
src/random/README.LDMUD Normal file
View File

@ -0,0 +1,10 @@
This is SFMT-1.3.3, stripped down to what is required by the LDMud gamedriver.
Additionally the 'public' function were made static as well because they are
probably not used without the wrapper. Therefore, their declarations have been
commented out.
The small inline functions from SFMT.h were moved to SFMT.c for the same
reason.
The files README.txt and LICENSE.txt tell you where to get the complete package.

22
src/random/README.txt Normal file
View File

@ -0,0 +1,22 @@
=================================================================
SFMT ver. 1.3.3
SIMD oriented Fast Mersenne Twister(SFMT)
Mutsuo Saito (Hiroshima University) and
Makoto Matsumoto (Hiroshima University)
Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
University. All rights reserved.
The (modified) BSD License is applied to this software, see LICENSE.txt
=================================================================
To see documents, see html/index.html.
To make test program, see html/howto-compile.html
If you want to redistribute and/or change source files, see LICENSE.txt.
When you change these files and redistribute them, PLEASE write your
e-mail address in redistribution and write to contact YOU first if
users of your changed source encounter troubles.

156
src/random/SFMT-alti.h Normal file
View File

@ -0,0 +1,156 @@
/**
* @file SFMT-alti.h
*
* @brief SIMD oriented Fast Mersenne Twister(SFMT)
* pseudorandom number generator
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (Hiroshima University)
*
* Copyright (C) 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University. All rights reserved.
*
* The new BSD License is applied to this software.
* see LICENSE.txt
*/
#ifndef SFMT_ALTI_H
#define SFMT_ALTI_H
inline static vector unsigned int vec_recursion(vector unsigned int a,
vector unsigned int b,
vector unsigned int c,
vector unsigned int d)
ALWAYSINLINE;
/**
* This function represents the recursion formula in AltiVec and BIG ENDIAN.
* @param a a 128-bit part of the interal state array
* @param b a 128-bit part of the interal state array
* @param c a 128-bit part of the interal state array
* @param d a 128-bit part of the interal state array
* @return output
*/
inline static vector unsigned int vec_recursion(vector unsigned int a,
vector unsigned int b,
vector unsigned int c,
vector unsigned int d) {
const vector unsigned int sl1 = ALTI_SL1;
const vector unsigned int sr1 = ALTI_SR1;
#ifdef ONLY64
const vector unsigned int mask = ALTI_MSK64;
const vector unsigned char perm_sl = ALTI_SL2_PERM64;
const vector unsigned char perm_sr = ALTI_SR2_PERM64;
#else
const vector unsigned int mask = ALTI_MSK;
const vector unsigned char perm_sl = ALTI_SL2_PERM;
const vector unsigned char perm_sr = ALTI_SR2_PERM;
#endif
vector unsigned int v, w, x, y, z;
x = vec_perm(a, (vector unsigned int)perm_sl, perm_sl);
v = a;
y = vec_sr(b, sr1);
z = vec_perm(c, (vector unsigned int)perm_sr, perm_sr);
w = vec_sl(d, sl1);
z = vec_xor(z, w);
y = vec_and(y, mask);
v = vec_xor(v, x);
z = vec_xor(z, y);
z = vec_xor(z, v);
return z;
}
/**
* This function fills the internal state array with pseudorandom
* integers.
*/
inline static void gen_rand_all(void) {
int i;
vector unsigned int r, r1, r2;
r1 = sfmt[N - 2].s;
r2 = sfmt[N - 1].s;
for (i = 0; i < N - POS1; i++) {
r = vec_recursion(sfmt[i].s, sfmt[i + POS1].s, r1, r2);
sfmt[i].s = r;
r1 = r2;
r2 = r;
}
for (; i < N; i++) {
r = vec_recursion(sfmt[i].s, sfmt[i + POS1 - N].s, r1, r2);
sfmt[i].s = r;
r1 = r2;
r2 = r;
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
*
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pesudorandom numbers to be generated.
*/
inline static void gen_rand_array(w128_t *array, int size) {
int i, j;
vector unsigned int r, r1, r2;
r1 = sfmt[N - 2].s;
r2 = sfmt[N - 1].s;
for (i = 0; i < N - POS1; i++) {
r = vec_recursion(sfmt[i].s, sfmt[i + POS1].s, r1, r2);
array[i].s = r;
r1 = r2;
r2 = r;
}
for (; i < N; i++) {
r = vec_recursion(sfmt[i].s, array[i + POS1 - N].s, r1, r2);
array[i].s = r;
r1 = r2;
r2 = r;
}
/* main loop */
for (; i < size - N; i++) {
r = vec_recursion(array[i - N].s, array[i + POS1 - N].s, r1, r2);
array[i].s = r;
r1 = r2;
r2 = r;
}
for (j = 0; j < 2 * N - size; j++) {
sfmt[j].s = array[j + size - N].s;
}
for (; i < size; i++) {
r = vec_recursion(array[i - N].s, array[i + POS1 - N].s, r1, r2);
array[i].s = r;
sfmt[j++].s = r;
r1 = r2;
r2 = r;
}
}
#ifndef ONLY64
#if defined(__APPLE__)
#define ALTI_SWAP (vector unsigned char) \
(4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11)
#else
#define ALTI_SWAP {4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11}
#endif
/**
* This function swaps high and low 32-bit of 64-bit integers in user
* specified array.
*
* @param array an 128-bit array to be swaped.
* @param size size of 128-bit array.
*/
inline static void swap(w128_t *array, int size) {
int i;
const vector unsigned char perm = ALTI_SWAP;
for (i = 0; i < size; i++) {
array[i].s = vec_perm(array[i].s, (vector unsigned int)perm, perm);
}
}
#endif
#endif

97
src/random/SFMT-params.h Normal file
View File

@ -0,0 +1,97 @@
#ifndef SFMT_PARAMS_H
#define SFMT_PARAMS_H
#if !defined(MEXP)
#ifdef __GNUC__
#warning "MEXP is not defined. I assume MEXP is 19937."
#endif
#define MEXP 19937
#endif
/*-----------------
BASIC DEFINITIONS
-----------------*/
/** Mersenne Exponent. The period of the sequence
* is a multiple of 2^MEXP-1.
* #define MEXP 19937 */
/** SFMT generator has an internal state array of 128-bit integers,
* and N is its size. */
#define N (MEXP / 128 + 1)
/** N32 is the size of internal state array when regarded as an array
* of 32-bit integers.*/
#define N32 (N * 4)
/** N64 is the size of internal state array when regarded as an array
* of 64-bit integers.*/
#define N64 (N * 2)
/*----------------------
the parameters of SFMT
following definitions are in paramsXXXX.h file.
----------------------*/
/** the pick up position of the array.
#define POS1 122
*/
/** the parameter of shift left as four 32-bit registers.
#define SL1 18
*/
/** the parameter of shift left as one 128-bit register.
* The 128-bit integer is shifted by (SL2 * 8) bits.
#define SL2 1
*/
/** the parameter of shift right as four 32-bit registers.
#define SR1 11
*/
/** the parameter of shift right as one 128-bit register.
* The 128-bit integer is shifted by (SL2 * 8) bits.
#define SR2 1
*/
/** A bitmask, used in the recursion. These parameters are introduced
* to break symmetry of SIMD.
#define MSK1 0xdfffffefU
#define MSK2 0xddfecb7fU
#define MSK3 0xbffaffffU
#define MSK4 0xbffffff6U
*/
/** These definitions are part of a 128-bit period certification vector.
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0x00000000U
#define PARITY4 0xc98e126aU
*/
#if MEXP == 607
#include "SFMT-params607.h"
#elif MEXP == 1279
#include "SFMT-params1279.h"
#elif MEXP == 2281
#include "SFMT-params2281.h"
#elif MEXP == 4253
#include "SFMT-params4253.h"
#elif MEXP == 11213
#include "SFMT-params11213.h"
#elif MEXP == 19937
#include "SFMT-params19937.h"
#elif MEXP == 44497
#include "SFMT-params44497.h"
#elif MEXP == 86243
#include "SFMT-params86243.h"
#elif MEXP == 132049
#include "SFMT-params132049.h"
#elif MEXP == 216091
#include "SFMT-params216091.h"
#else
#ifdef __GNUC__
#error "MEXP is not valid."
#undef MEXP
#else
#undef MEXP
#endif
#endif
#endif /* SFMT_PARAMS_H */

View File

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS11213_H
#define SFMT_PARAMS11213_H
#define POS1 68
#define SL1 14
#define SL2 3
#define SR1 7
#define SR2 3
#define MSK1 0xeffff7fbU
#define MSK2 0xffffffefU
#define MSK3 0xdfdfbfffU
#define MSK4 0x7fffdbfdU
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0xe8148000U
#define PARITY4 0xd0c7afa3U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define ALTI_SR2_PERM \
(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
#define ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
#endif /* For OSX */
#define IDSTR "SFMT-11213:68-14-3-7-3:effff7fb-ffffffef-dfdfbfff-7fffdbfd"
#endif /* SFMT_PARAMS11213_H */

View File

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS1279_H
#define SFMT_PARAMS1279_H
#define POS1 7
#define SL1 14
#define SL2 3
#define SR1 5
#define SR2 1
#define MSK1 0xf7fefffdU
#define MSK2 0x7fefcfffU
#define MSK3 0xaff3ef3fU
#define MSK4 0xb5ffff7fU
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0x00000000U
#define PARITY4 0x20000000U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define IDSTR "SFMT-1279:7-14-3-5-1:f7fefffd-7fefcfff-aff3ef3f-b5ffff7f"
#endif /* SFMT_PARAMS1279_H */

View File

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS132049_H
#define SFMT_PARAMS132049_H
#define POS1 110
#define SL1 19
#define SL2 1
#define SR1 21
#define SR2 1
#define MSK1 0xffffbb5fU
#define MSK2 0xfb6ebf95U
#define MSK3 0xfffefffaU
#define MSK4 0xcff77fffU
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0xcb520000U
#define PARITY4 0xc7e91c7dU
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
#define ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
#define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define IDSTR "SFMT-132049:110-19-1-21-1:ffffbb5f-fb6ebf95-fffefffa-cff77fff"
#endif /* SFMT_PARAMS132049_H */

View File

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS19937_H
#define SFMT_PARAMS19937_H
#define POS1 122
#define SL1 18
#define SL2 1
#define SR1 11
#define SR2 1
#define MSK1 0xdfffffefU
#define MSK2 0xddfecb7fU
#define MSK3 0xbffaffffU
#define MSK4 0xbffffff6U
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0x00000000U
#define PARITY4 0x13c9e684U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
#define ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
#define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define IDSTR "SFMT-19937:122-18-1-11-1:dfffffef-ddfecb7f-bffaffff-bffffff6"
#endif /* SFMT_PARAMS19937_H */

View File

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS216091_H
#define SFMT_PARAMS216091_H
#define POS1 627
#define SL1 11
#define SL2 3
#define SR1 10
#define SR2 1
#define MSK1 0xbff7bff7U
#define MSK2 0xbfffffffU
#define MSK3 0xbffffa7fU
#define MSK4 0xffddfbfbU
#define PARITY1 0xf8000001U
#define PARITY2 0x89e80709U
#define PARITY3 0x3bd2b64bU
#define PARITY4 0x0c64b1e4U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define IDSTR "SFMT-216091:627-11-3-10-1:bff7bff7-bfffffff-bffffa7f-ffddfbfb"
#endif /* SFMT_PARAMS216091_H */

View File

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS2281_H
#define SFMT_PARAMS2281_H
#define POS1 12
#define SL1 19
#define SL2 1
#define SR1 5
#define SR2 1
#define MSK1 0xbff7ffbfU
#define MSK2 0xfdfffffeU
#define MSK3 0xf7ffef7fU
#define MSK4 0xf2f7cbbfU
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0x00000000U
#define PARITY4 0x41dfa600U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
#define ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
#define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define IDSTR "SFMT-2281:12-19-1-5-1:bff7ffbf-fdfffffe-f7ffef7f-f2f7cbbf"
#endif /* SFMT_PARAMS2281_H */

View File

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS4253_H
#define SFMT_PARAMS4253_H
#define POS1 17
#define SL1 20
#define SL2 1
#define SR1 7
#define SR2 1
#define MSK1 0x9f7bffffU
#define MSK2 0x9fffff5fU
#define MSK3 0x3efffffbU
#define MSK4 0xfffff7bbU
#define PARITY1 0xa8000001U
#define PARITY2 0xaf5390a3U
#define PARITY3 0xb740b3f8U
#define PARITY4 0x6c11486dU
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
#define ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
#define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define IDSTR "SFMT-4253:17-20-1-7-1:9f7bffff-9fffff5f-3efffffb-fffff7bb"
#endif /* SFMT_PARAMS4253_H */

View File

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS44497_H
#define SFMT_PARAMS44497_H
#define POS1 330
#define SL1 5
#define SL2 3
#define SR1 9
#define SR2 3
#define MSK1 0xeffffffbU
#define MSK2 0xdfbebfffU
#define MSK3 0xbfbf7befU
#define MSK4 0x9ffd7bffU
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0xa3ac4000U
#define PARITY4 0xecc1327aU
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define ALTI_SR2_PERM \
(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
#define ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
#endif /* For OSX */
#define IDSTR "SFMT-44497:330-5-3-9-3:effffffb-dfbebfff-bfbf7bef-9ffd7bff"
#endif /* SFMT_PARAMS44497_H */

View File

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS607_H
#define SFMT_PARAMS607_H
#define POS1 2
#define SL1 15
#define SL2 3
#define SR1 13
#define SR2 3
#define MSK1 0xfdff37ffU
#define MSK2 0xef7f3f7dU
#define MSK3 0xff777b7dU
#define MSK4 0x7ff7fb2fU
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0x00000000U
#define PARITY4 0x5986f054U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define ALTI_SR2_PERM \
(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
#define ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
#endif /* For OSX */
#define IDSTR "SFMT-607:2-15-3-13-3:fdff37ff-ef7f3f7d-ff777b7d-7ff7fb2f"
#endif /* SFMT_PARAMS607_H */

View File

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS86243_H
#define SFMT_PARAMS86243_H
#define POS1 366
#define SL1 6
#define SL2 7
#define SR1 19
#define SR2 1
#define MSK1 0xfdbffbffU
#define MSK2 0xbff7ff3fU
#define MSK3 0xfd77efffU
#define MSK4 0xbf9ff3ffU
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0x00000000U
#define PARITY4 0xe9528d85U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(25,25,25,25,3,25,25,25,7,0,1,2,11,4,5,6)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(7,25,25,25,25,25,25,25,15,0,1,2,3,4,5,6)
#define ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {25,25,25,25,3,25,25,25,7,0,1,2,11,4,5,6}
#define ALTI_SL2_PERM64 {7,25,25,25,25,25,25,25,15,0,1,2,3,4,5,6}
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define IDSTR "SFMT-86243:366-6-7-19-1:fdbffbff-bff7ff3f-fd77efff-bf9ff3ff"
#endif /* SFMT_PARAMS86243_H */

121
src/random/SFMT-sse2.h Normal file
View File

@ -0,0 +1,121 @@
/**
* @file SFMT-sse2.h
* @brief SIMD oriented Fast Mersenne Twister(SFMT) for Intel SSE2
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (Hiroshima University)
*
* @note We assume LITTLE ENDIAN in this file
*
* Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University. All rights reserved.
*
* The new BSD License is applied to this software, see LICENSE.txt
*/
#ifndef SFMT_SSE2_H
#define SFMT_SSE2_H
PRE_ALWAYS static __m128i mm_recursion(__m128i *a, __m128i *b, __m128i c,
__m128i d, __m128i mask) ALWAYSINLINE;
/**
* This function represents the recursion formula.
* @param a a 128-bit part of the interal state array
* @param b a 128-bit part of the interal state array
* @param c a 128-bit part of the interal state array
* @param d a 128-bit part of the interal state array
* @param mask 128-bit mask
* @return output
*/
PRE_ALWAYS static __m128i mm_recursion(__m128i *a, __m128i *b,
__m128i c, __m128i d, __m128i mask) {
__m128i v, x, y, z;
x = _mm_load_si128(a);
y = _mm_srli_epi32(*b, SR1);
z = _mm_srli_si128(c, SR2);
v = _mm_slli_epi32(d, SL1);
z = _mm_xor_si128(z, x);
z = _mm_xor_si128(z, v);
x = _mm_slli_si128(x, SL2);
y = _mm_and_si128(y, mask);
z = _mm_xor_si128(z, x);
z = _mm_xor_si128(z, y);
return z;
}
/**
* This function fills the internal state array with pseudorandom
* integers.
*/
inline static void gen_rand_all(void) {
int i;
__m128i r, r1, r2, mask;
mask = _mm_set_epi32(MSK4, MSK3, MSK2, MSK1);
r1 = _mm_load_si128(&sfmt[N - 2].si);
r2 = _mm_load_si128(&sfmt[N - 1].si);
for (i = 0; i < N - POS1; i++) {
r = mm_recursion(&sfmt[i].si, &sfmt[i + POS1].si, r1, r2, mask);
_mm_store_si128(&sfmt[i].si, r);
r1 = r2;
r2 = r;
}
for (; i < N; i++) {
r = mm_recursion(&sfmt[i].si, &sfmt[i + POS1 - N].si, r1, r2, mask);
_mm_store_si128(&sfmt[i].si, r);
r1 = r2;
r2 = r;
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
*
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pesudorandom numbers to be generated.
*/
inline static void gen_rand_array(w128_t *array, int size) {
int i, j;
__m128i r, r1, r2, mask;
mask = _mm_set_epi32(MSK4, MSK3, MSK2, MSK1);
r1 = _mm_load_si128(&sfmt[N - 2].si);
r2 = _mm_load_si128(&sfmt[N - 1].si);
for (i = 0; i < N - POS1; i++) {
r = mm_recursion(&sfmt[i].si, &sfmt[i + POS1].si, r1, r2, mask);
_mm_store_si128(&array[i].si, r);
r1 = r2;
r2 = r;
}
for (; i < N; i++) {
r = mm_recursion(&sfmt[i].si, &array[i + POS1 - N].si, r1, r2, mask);
_mm_store_si128(&array[i].si, r);
r1 = r2;
r2 = r;
}
/* main loop */
for (; i < size - N; i++) {
r = mm_recursion(&array[i - N].si, &array[i + POS1 - N].si, r1, r2,
mask);
_mm_store_si128(&array[i].si, r);
r1 = r2;
r2 = r;
}
for (j = 0; j < 2 * N - size; j++) {
r = _mm_load_si128(&array[j + size - N].si);
_mm_store_si128(&sfmt[j].si, r);
}
for (; i < size; i++) {
r = mm_recursion(&array[i - N].si, &array[i + POS1 - N].si, r1, r2,
mask);
_mm_store_si128(&array[i].si, r);
_mm_store_si128(&sfmt[j++].si, r);
r1 = r2;
r2 = r;
}
}
#endif

694
src/random/SFMT.c Normal file
View File

@ -0,0 +1,694 @@
/**
* @file SFMT.c
* @brief SIMD oriented Fast Mersenne Twister(SFMT)
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (Hiroshima University)
*
* Copyright (C) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University. All rights reserved.
*
* The new BSD License is applied to this software, see LICENSE.txt
*/
#include <string.h>
#include <assert.h>
#include "SFMT.h"
#include "SFMT-params.h"
#if defined(__BIG_ENDIAN__) && !defined(__amd64) && !defined(BIG_ENDIAN64)
#define BIG_ENDIAN64 1
#endif
#if defined(HAVE_ALTIVEC) && !defined(BIG_ENDIAN64)
#define BIG_ENDIAN64 1
#endif
#if defined(ONLY64) && !defined(BIG_ENDIAN64)
#if defined(__GNUC__)
#error "-DONLY64 must be specified with -DBIG_ENDIAN64"
#endif
#undef ONLY64
#endif
/*------------------------------------------------------
128-bit SIMD data type for Altivec, SSE2 or standard C
------------------------------------------------------*/
#if defined(HAVE_ALTIVEC)
#if !defined(__APPLE__)
#include <altivec.h>
#endif
/** 128-bit data structure */
union W128_T {
vector unsigned int s;
uint32_t u[4];
};
/** 128-bit data type */
typedef union W128_T w128_t;
#elif defined(HAVE_SSE2)
#include <emmintrin.h>
/** 128-bit data structure */
union W128_T {
__m128i si;
uint32_t u[4];
};
/** 128-bit data type */
typedef union W128_T w128_t;
#else
/** 128-bit data structure */
struct W128_T {
uint32_t u[4];
};
/** 128-bit data type */
typedef struct W128_T w128_t;
#endif
/*--------------------------------------
FILE GLOBAL VARIABLES
internal state, index counter and flag
--------------------------------------*/
/** the 128-bit internal state array */
static w128_t sfmt[N];
/** the 32bit integer pointer to the 128-bit internal state array */
static uint32_t *psfmt32 = &sfmt[0].u[0];
#if !defined(BIG_ENDIAN64) || defined(ONLY64)
/** the 64bit integer pointer to the 128-bit internal state array */
static uint64_t *psfmt64 = (uint64_t *)&sfmt[0].u[0];
#endif
/** index counter to the 32-bit internal state array */
static int idx;
/** a flag: it is 0 if and only if the internal state is not yet
* initialized. */
static int initialized = 0;
/** a parity check vector which certificate the period of 2^{MEXP} */
static uint32_t parity[4] = {PARITY1, PARITY2, PARITY3, PARITY4};
/*----------------
STATIC FUNCTIONS
----------------*/
inline static int idxof(int i);
inline static void rshift128(w128_t *out, w128_t const *in, int shift);
inline static void lshift128(w128_t *out, w128_t const *in, int shift);
inline static void gen_rand_all(void);
inline static void gen_rand_array(w128_t *array, int size);
inline static uint32_t func1(uint32_t x);
inline static uint32_t func2(uint32_t x);
static void period_certification(void);
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
inline static void swap(w128_t *array, int size);
#endif
#if defined(HAVE_ALTIVEC)
#include "SFMT-alti.h"
#elif defined(HAVE_SSE2)
#include "SFMT-sse2.h"
#endif
/**
* This function simulate a 64-bit index of LITTLE ENDIAN
* in BIG ENDIAN machine.
*/
#ifdef ONLY64
inline static int idxof(int i) {
return i ^ 1;
}
#else
inline static int idxof(int i) {
return i;
}
#endif
/**
* This function simulates SIMD 128-bit right shift by the standard C.
* The 128-bit integer given in in is shifted by (shift * 8) bits.
* This function simulates the LITTLE ENDIAN SIMD.
* @param out the output of this function
* @param in the 128-bit data to be shifted
* @param shift the shift value
*/
#ifdef ONLY64
inline static void rshift128(w128_t *out, w128_t const *in, int shift) {
uint64_t th, tl, oh, ol;
th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
oh = th >> (shift * 8);
ol = tl >> (shift * 8);
ol |= th << (64 - shift * 8);
out->u[0] = (uint32_t)(ol >> 32);
out->u[1] = (uint32_t)ol;
out->u[2] = (uint32_t)(oh >> 32);
out->u[3] = (uint32_t)oh;
}
#else
inline static void rshift128(w128_t *out, w128_t const *in, int shift) {
uint64_t th, tl, oh, ol;
th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
oh = th >> (shift * 8);
ol = tl >> (shift * 8);
ol |= th << (64 - shift * 8);
out->u[1] = (uint32_t)(ol >> 32);
out->u[0] = (uint32_t)ol;
out->u[3] = (uint32_t)(oh >> 32);
out->u[2] = (uint32_t)oh;
}
#endif
/**
* This function simulates SIMD 128-bit left shift by the standard C.
* The 128-bit integer given in in is shifted by (shift * 8) bits.
* This function simulates the LITTLE ENDIAN SIMD.
* @param out the output of this function
* @param in the 128-bit data to be shifted
* @param shift the shift value
*/
#ifdef ONLY64
inline static void lshift128(w128_t *out, w128_t const *in, int shift) {
uint64_t th, tl, oh, ol;
th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
oh = th << (shift * 8);
ol = tl << (shift * 8);
oh |= tl >> (64 - shift * 8);
out->u[0] = (uint32_t)(ol >> 32);
out->u[1] = (uint32_t)ol;
out->u[2] = (uint32_t)(oh >> 32);
out->u[3] = (uint32_t)oh;
}
#else
inline static void lshift128(w128_t *out, w128_t const *in, int shift) {
uint64_t th, tl, oh, ol;
th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
oh = th << (shift * 8);
ol = tl << (shift * 8);
oh |= tl >> (64 - shift * 8);
out->u[1] = (uint32_t)(ol >> 32);
out->u[0] = (uint32_t)ol;
out->u[3] = (uint32_t)(oh >> 32);
out->u[2] = (uint32_t)oh;
}
#endif
/**
* This function represents the recursion formula.
* @param r output
* @param a a 128-bit part of the internal state array
* @param b a 128-bit part of the internal state array
* @param c a 128-bit part of the internal state array
* @param d a 128-bit part of the internal state array
*/
#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
#ifdef ONLY64
inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
w128_t *d) {
w128_t x;
w128_t y;
lshift128(&x, a, SL2);
rshift128(&y, c, SR2);
r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK2) ^ y.u[0]
^ (d->u[0] << SL1);
r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK1) ^ y.u[1]
^ (d->u[1] << SL1);
r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK4) ^ y.u[2]
^ (d->u[2] << SL1);
r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK3) ^ y.u[3]
^ (d->u[3] << SL1);
}
#else
inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
w128_t *d) {
w128_t x;
w128_t y;
lshift128(&x, a, SL2);
rshift128(&y, c, SR2);
r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK1) ^ y.u[0]
^ (d->u[0] << SL1);
r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK2) ^ y.u[1]
^ (d->u[1] << SL1);
r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK3) ^ y.u[2]
^ (d->u[2] << SL1);
r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK4) ^ y.u[3]
^ (d->u[3] << SL1);
}
#endif
#endif
#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
/**
* This function fills the internal state array with pseudorandom
* integers.
*/
inline static void gen_rand_all(void) {
int i;
w128_t *r1, *r2;
r1 = &sfmt[N - 2];
r2 = &sfmt[N - 1];
for (i = 0; i < N - POS1; i++) {
do_recursion(&sfmt[i], &sfmt[i], &sfmt[i + POS1], r1, r2);
r1 = r2;
r2 = &sfmt[i];
}
for (; i < N; i++) {
do_recursion(&sfmt[i], &sfmt[i], &sfmt[i + POS1 - N], r1, r2);
r1 = r2;
r2 = &sfmt[i];
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
*
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pseudorandom numbers to be generated.
*/
inline static void gen_rand_array(w128_t *array, int size) {
int i, j;
w128_t *r1, *r2;
r1 = &sfmt[N - 2];
r2 = &sfmt[N - 1];
for (i = 0; i < N - POS1; i++) {
do_recursion(&array[i], &sfmt[i], &sfmt[i + POS1], r1, r2);
r1 = r2;
r2 = &array[i];
}
for (; i < N; i++) {
do_recursion(&array[i], &sfmt[i], &array[i + POS1 - N], r1, r2);
r1 = r2;
r2 = &array[i];
}
for (; i < size - N; i++) {
do_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2);
r1 = r2;
r2 = &array[i];
}
for (j = 0; j < 2 * N - size; j++) {
sfmt[j] = array[j + size - N];
}
for (; i < size; i++, j++) {
do_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2);
r1 = r2;
r2 = &array[i];
sfmt[j] = array[i];
}
}
#endif
#if defined(BIG_ENDIAN64) && !defined(ONLY64) && !defined(HAVE_ALTIVEC)
inline static void swap(w128_t *array, int size) {
int i;
uint32_t x, y;
for (i = 0; i < size; i++) {
x = array[i].u[0];
y = array[i].u[2];
array[i].u[0] = array[i].u[1];
array[i].u[2] = array[i].u[3];
array[i].u[1] = x;
array[i].u[3] = y;
}
}
#endif
/**
* This function represents a function used in the initialization
* by init_by_array
* @param x 32-bit integer
* @return 32-bit integer
*/
static uint32_t func1(uint32_t x) {
return (x ^ (x >> 27)) * (uint32_t)1664525UL;
}
/**
* This function represents a function used in the initialization
* by init_by_array
* @param x 32-bit integer
* @return 32-bit integer
*/
static uint32_t func2(uint32_t x) {
return (x ^ (x >> 27)) * (uint32_t)1566083941UL;
}
/**
* This function certificate the period of 2^{MEXP}
*/
static void period_certification(void) {
int inner = 0;
int i, j;
uint32_t work;
for (i = 0; i < 4; i++)
inner ^= psfmt32[idxof(i)] & parity[i];
for (i = 16; i > 0; i >>= 1)
inner ^= inner >> i;
inner &= 1;
/* check OK */
if (inner == 1) {
return;
}
/* check NG, and modification */
for (i = 0; i < 4; i++) {
work = 1;
for (j = 0; j < 32; j++) {
if ((work & parity[i]) != 0) {
psfmt32[idxof(i)] ^= work;
return;
}
work = work << 1;
}
}
}
/*----------------
PUBLIC FUNCTIONS
----------------*/
/**
* This function returns the identification string.
* The string shows the word size, the Mersenne exponent,
* and all parameters of this generator.
*/
static INLINE const char *get_idstring(void) {
return IDSTR;
}
/**
* This function returns the minimum size of array used for \b
* fill_array32() function.
* @return minimum size of array used for fill_array32() function.
*/
static INLINE int get_min_array_size32(void) {
return N32;
}
/**
* This function returns the minimum size of array used for \b
* fill_array64() function.
* @return minimum size of array used for fill_array64() function.
*/
static INLINE int get_min_array_size64(void) {
return N64;
}
#ifndef ONLY64
/**
* This function generates and returns 32-bit pseudorandom number.
* init_gen_rand or init_by_array must be called before this function.
* @return 32-bit pseudorandom number
*/
static INLINE uint32_t gen_rand32(void) {
uint32_t r;
assert(initialized);
if (idx >= N32) {
gen_rand_all();
idx = 0;
}
r = psfmt32[idx++];
return r;
}
#endif
/**
* This function generates and returns 64-bit pseudorandom number.
* init_gen_rand or init_by_array must be called before this function.
* The function gen_rand64 should not be called after gen_rand32,
* unless an initialization is again executed.
* @return 64-bit pseudorandom number
*/
static INLINE uint64_t gen_rand64(void) {
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
uint32_t r1, r2;
#else
uint64_t r;
#endif
assert(initialized);
assert(idx % 2 == 0);
if (idx >= N32) {
gen_rand_all();
idx = 0;
}
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
r1 = psfmt32[idx];
r2 = psfmt32[idx + 1];
idx += 2;
return ((uint64_t)r2 << 32) | r1;
#else
r = psfmt64[idx / 2];
idx += 2;
return r;
#endif
}
#ifndef ONLY64
/**
* This function generates pseudorandom 32-bit integers in the
* specified array[] by one call. The number of pseudorandom integers
* is specified by the argument size, which must be at least 624 and a
* multiple of four. The generation by this function is much faster
* than the following gen_rand function.
*
* For initialization, init_gen_rand or init_by_array must be called
* before the first call of this function. This function can not be
* used after calling gen_rand function, without initialization.
*
* @param array an array where pseudorandom 32-bit integers are filled
* by this function. The pointer to the array must be \b "aligned"
* (namely, must be a multiple of 16) in the SIMD version, since it
* refers to the address of a 128-bit integer. In the standard C
* version, the pointer is arbitrary.
*
* @param size the number of 32-bit pseudorandom integers to be
* generated. size must be a multiple of 4, and greater than or equal
* to (MEXP / 128 + 1) * 4.
*
* @note \b memalign or \b posix_memalign is available to get aligned
* memory. Mac OSX doesn't have these functions, but \b malloc of OSX
* returns the pointer to the aligned memory block.
*/
static INLINE void fill_array32(uint32_t *array, int size) {
assert(initialized);
assert(idx == N32);
assert(size % 4 == 0);
assert(size >= N32);
gen_rand_array((w128_t *)array, size / 4);
idx = N32;
}
#endif
/**
* This function generates pseudorandom 64-bit integers in the
* specified array[] by one call. The number of pseudorandom integers
* is specified by the argument size, which must be at least 312 and a
* multiple of two. The generation by this function is much faster
* than the following gen_rand function.
*
* For initialization, init_gen_rand or init_by_array must be called
* before the first call of this function. This function can not be
* used after calling gen_rand function, without initialization.
*
* @param array an array where pseudorandom 64-bit integers are filled
* by this function. The pointer to the array must be "aligned"
* (namely, must be a multiple of 16) in the SIMD version, since it
* refers to the address of a 128-bit integer. In the standard C
* version, the pointer is arbitrary.
*
* @param size the number of 64-bit pseudorandom integers to be
* generated. size must be a multiple of 2, and greater than or equal
* to (MEXP / 128 + 1) * 2
*
* @note \b memalign or \b posix_memalign is available to get aligned
* memory. Mac OSX doesn't have these functions, but \b malloc of OSX
* returns the pointer to the aligned memory block.
*/
static INLINE void fill_array64(uint64_t *array, int size) {
assert(initialized);
assert(idx == N32);
assert(size % 2 == 0);
assert(size >= N64);
gen_rand_array((w128_t *)array, size / 2);
idx = N32;
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
swap((w128_t *)array, size /2);
#endif
}
/**
* This function initializes the internal state array with a 32-bit
* integer seed.
*
* @param seed a 32-bit integer used as the seed.
*/
static void init_gen_rand(uint32_t seed) {
int i;
psfmt32[idxof(0)] = seed;
for (i = 1; i < N32; i++) {
psfmt32[idxof(i)] = 1812433253UL * (psfmt32[idxof(i - 1)]
^ (psfmt32[idxof(i - 1)] >> 30))
+ i;
}
idx = N32;
period_certification();
initialized = 1;
}
/**
* This function initializes the internal state array,
* with an array of 32-bit integers used as the seeds
* @param init_key the array of 32-bit integers, used as a seed.
* @param key_length the length of init_key.
*/
static void init_by_array(uint32_t *init_key, int key_length) {
int i, j, count;
uint32_t r;
int lag;
int mid;
int size = N * 4;
if (size >= 623) {
lag = 11;
} else if (size >= 68) {
lag = 7;
} else if (size >= 39) {
lag = 5;
} else {
lag = 3;
}
mid = (size - lag) / 2;
memset(sfmt, 0x8b, sizeof(sfmt));
if (key_length + 1 > N32) {
count = key_length + 1;
} else {
count = N32;
}
r = func1(psfmt32[idxof(0)] ^ psfmt32[idxof(mid)]
^ psfmt32[idxof(N32 - 1)]);
psfmt32[idxof(mid)] += r;
r += key_length;
psfmt32[idxof(mid + lag)] += r;
psfmt32[idxof(0)] = r;
count--;
for (i = 1, j = 0; (j < count) && (j < key_length); j++) {
r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)]
^ psfmt32[idxof((i + N32 - 1) % N32)]);
psfmt32[idxof((i + mid) % N32)] += r;
r += init_key[j] + i;
psfmt32[idxof((i + mid + lag) % N32)] += r;
psfmt32[idxof(i)] = r;
i = (i + 1) % N32;
}
for (; j < count; j++) {
r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)]
^ psfmt32[idxof((i + N32 - 1) % N32)]);
psfmt32[idxof((i + mid) % N32)] += r;
r += i;
psfmt32[idxof((i + mid + lag) % N32)] += r;
psfmt32[idxof(i)] = r;
i = (i + 1) % N32;
}
for (j = 0; j < N32; j++) {
r = func2(psfmt32[idxof(i)] + psfmt32[idxof((i + mid) % N32)]
+ psfmt32[idxof((i + N32 - 1) % N32)]);
psfmt32[idxof((i + mid) % N32)] ^= r;
r -= i;
psfmt32[idxof((i + mid + lag) % N32)] ^= r;
psfmt32[idxof(i)] = r;
i = (i + 1) % N32;
}
idx = N32;
period_certification();
initialized = 1;
}
/* These real versions are due to Isaku Wada */
/** generates a random number on [0,1]-real-interval */
inline static double to_real1(uint32_t v)
{
return v * (1.0/4294967295.0);
/* divided by 2^32-1 */
}
/** generates a random number on [0,1]-real-interval */
inline static double genrand_real1(void)
{
return to_real1(gen_rand32());
}
/** generates a random number on [0,1)-real-interval */
inline static double to_real2(uint32_t v)
{
return v * (1.0/4294967296.0);
/* divided by 2^32 */
}
/** generates a random number on [0,1)-real-interval */
inline static double genrand_real2(void)
{
return to_real2(gen_rand32());
}
/** generates a random number on (0,1)-real-interval */
inline static double to_real3(uint32_t v)
{
return (((double)v) + 0.5)*(1.0/4294967296.0);
/* divided by 2^32 */
}
/** generates a random number on (0,1)-real-interval */
inline static double genrand_real3(void)
{
return to_real3(gen_rand32());
}
/** These real versions are due to Isaku Wada */
/** generates a random number on [0,1) with 53-bit resolution*/
inline static double to_res53(uint64_t v)
{
return v * (1.0/18446744073709551616.0L);
}
/** generates a random number on [0,1) with 53-bit resolution from two
* 32 bit integers */
inline static double to_res53_mix(uint32_t x, uint32_t y)
{
return to_res53(x | ((uint64_t)y << 32));
}
/** generates a random number on [0,1) with 53-bit resolution
*/
inline static double genrand_res53(void)
{
return to_res53(gen_rand64());
}
/** generates a random number on [0,1) with 53-bit resolution
using 32bit integer.
*/
inline static double genrand_res53_mix(void)
{
uint32_t x, y;
x = gen_rand32();
y = gen_rand32();
return to_res53_mix(x, y);
}

87
src/random/SFMT.h Normal file
View File

@ -0,0 +1,87 @@
/**
* @file SFMT.h
*
* @brief SIMD oriented Fast Mersenne Twister(SFMT) pseudorandom
* number generator
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (Hiroshima University)
*
* Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University. All rights reserved.
*
* The new BSD License is applied to this software.
* see LICENSE.txt
*
* @note We assume that your system has inttypes.h. If your system
* doesn't have inttypes.h, you have to typedef uint32_t and uint64_t,
* and you have to define PRIu64 and PRIx64 in this file as follows:
* @verbatim
typedef unsigned int uint32_t
typedef unsigned long long uint64_t
#define PRIu64 "llu"
#define PRIx64 "llx"
@endverbatim
* uint32_t must be exactly 32-bit unsigned integer type (no more, no
* less), and uint64_t must be exactly 64-bit unsigned integer type.
* PRIu64 and PRIx64 are used for printf function to print 64-bit
* unsigned int and 64-bit unsigned int in hexadecimal format.
*/
#ifndef SFMT_H
#define SFMT_H
#include <stdio.h>
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
#include <inttypes.h>
#elif defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned int uint32_t;
typedef unsigned __int64 uint64_t;
#define inline __inline
#else
#include <inttypes.h>
#if defined(__GNUC__)
#define inline __inline__
#endif
#endif
#ifndef PRIu64
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define PRIu64 "I64u"
#define PRIx64 "I64x"
#else
#define PRIu64 "llu"
#define PRIx64 "llx"
#endif
#endif
#if defined(__GNUC__)
#define ALWAYSINLINE __attribute__((always_inline))
#else
#define ALWAYSINLINE
#endif
#if defined(_MSC_VER)
#if _MSC_VER >= 1200
#define PRE_ALWAYS __forceinline
#else
#define PRE_ALWAYS inline
#endif
#else
#define PRE_ALWAYS inline
#endif
/* these are not needed in public
uint32_t gen_rand32(void);
uint64_t gen_rand64(void);
void fill_array32(uint32_t *array, int size);
void fill_array64(uint64_t *array, int size);
void init_gen_rand(uint32_t seed);
void init_by_array(uint32_t *init_key, int key_length);
const char *get_idstring(void);
int get_min_array_size32(void);
int get_min_array_size64(void);
*/
#endif

View File

@ -45,13 +45,14 @@
#include <ctype.h>
#include "regexp.h"
#include "interpret.h" /* eval_cost */
#include "simulate.h"
#include "xalloc.h"
#ifdef DEBUG
#include "main.h"
#endif
#include "i-eval_cost.h"
/*-------------------------------------------------------------------------*/
/* The "internal use only" fields in regexp.h are present to pass info from
@ -215,7 +216,7 @@ static void reginsert (char op, unsigned char *opnd);
static unsigned char *reg (Bool paren, int *flagp);
static int regtry(regexp*, char *);
static int regmatch(unsigned char *);
static Bool regmatch(unsigned char *);
static int regrepeat(unsigned char *);
#ifdef DEBUG
@ -1162,9 +1163,7 @@ regmatch (unsigned char *prog)
/* Couldn't or didn't -- back up. */
no--;
reginput = save + no;
eval_cost ++;
total_evalcost++;
if (EVALUATION_TOO_LONG())
if (add_eval_cost(1))
return RE_ERROR_BACKTRACK;
}
return RE_NOMATCH;

View File

@ -63,6 +63,9 @@ enable_use_json=yes
# compile expat xml & xmpp parser in, if available
enable_use_expat=no
# compile iksemel parser in, if available
enable_use_iksemel=no
# compile DNS SRV support in, if available
enable_use_srv=yes

View File

@ -200,6 +200,18 @@ assert_simul_efun_object (void)
/* Get the name(s) of the simul_efun object. */
svp = apply_master(STR_GET_SEFUN, 0);
/* If a simul_efun_object appears during the GET_SEFUN call, it
* might have been due to a recursive get_simul_efun() call which may
* have gotten an old backup copy. This can lead to hard-to-debug
* variable and function definition inconsistencies.
*/
if (simul_efun_object)
{
printf("%s simul_efun object appeared while asking for it.\n", time_stamp());
return MY_TRUE;
}
if (svp == NULL)
{
printf("%s No simul_efun\n", time_stamp());

View File

@ -44,7 +44,6 @@
#include "filestat.h"
#include "gcollect.h"
#include "heartbeat.h"
#include "interpret.h"
#include "lex.h"
#include "main.h"
#include "mapping.h"
@ -72,6 +71,8 @@
#include "wiz_list.h"
#include "xalloc.h"
#include "i-eval_cost.h"
#include "../mudlib/sys/debug_info.h"
#include "../mudlib/sys/driver_hook.h"
#include "../mudlib/sys/files.h"
@ -145,7 +146,7 @@ struct error_recovery_info toplevel_context
};
rt_context_t * rt_context
= (rt_context_t *)&toplevel_context;
= (rt_context_t *)&toplevel_context.rt;
/*-------------------------------------------------------------------------*/
@ -392,9 +393,10 @@ catch_instruction ( int flags, uint offset
* the global <catch_value>.
*/
svalue_t *sp;
svalue_t catch_value;
/* Remove the catch context and get the old stackpointer setting */
sp = pull_error_context(INTER_SP);
sp = pull_error_context(INTER_SP, &catch_value);
/* beware of errors after set_this_object() */
current_object = csp->ob;
@ -407,7 +409,6 @@ catch_instruction ( int flags, uint offset
/* Push the catch return value */
*(++sp) = catch_value;
catch_value.type = T_INVALID;
*i_sp = (volatile svalue_t *)sp;
@ -436,8 +437,9 @@ catch_instruction ( int flags, uint offset
if (max_eval_cost && eval_cost >= max_eval_cost)
{
errorf("Not enough eval time left for catch(): required %ld, available %ld\n"
, (long)reserve_cost, (long)(max_eval_cost - eval_cost + reserve_cost)
errorf("Not enough eval time left for catch(): required %"PRId32
", available %"PRId32"\n", reserve_cost,
(max_eval_cost - eval_cost + reserve_cost)
);
/* NOTREACHED */
return MY_TRUE;
@ -809,7 +811,12 @@ errorf (const char *fmt, ...)
string_t * str = new_mstring(emsg_buf);
if (NULL != str)
put_string(&catch_value, str);
{
svalue_t stmp;
put_string(&stmp, str);
transfer_error_message(&stmp, rt);
}
else
{
error_caught = MY_FALSE;
@ -933,7 +940,7 @@ errorf (const char *fmt, ...)
if (curobj)
{
line_number = get_line_number_if_any(&file);
debug_message("%s program: %s, object: %s line %ld\n"
debug_message("%s program: %s, object: %s line %"PRIdMPINT"\n"
, ts, get_txt(file), get_txt(curobj->name)
, line_number);
if (current_prog && num_error < 3)
@ -954,7 +961,7 @@ errorf (const char *fmt, ...)
printf("%s error in function call: %s", ts, emsg_buf+1);
if (curobj)
{
printf("%s program: %s, object: %s line %ld\n"
printf("%s program: %s, object: %s line %"PRIdMPINT"\n"
, ts, get_txt(file), get_txt(curobj->name)
, line_number
);
@ -1191,7 +1198,7 @@ errorf (const char *fmt, ...)
if (O_SET_INTERACTIVE(i, current_interactive)
&& i->noecho & NOECHO_STALE)
{
set_noecho(i, 0, MY_FALSE);
set_noecho(i, 0, MY_FALSE, MY_FALSE);
}
}
@ -1285,7 +1292,7 @@ warnf (char *fmt, ...)
if (curobj)
{
line_number = get_line_number_if_any(&file);
debug_message("%s program: %s, object: %s line %ld\n"
debug_message("%s program: %s, object: %s line %"PRIdMPINT"\n"
, ts, get_txt(file), get_txt(curobj->name)
, line_number);
}
@ -1368,21 +1375,21 @@ parse_error (Bool warning, const char *error_file, int line, const char *what
/*-------------------------------------------------------------------------*/
void
throw_error()
throw_error (svalue_t *v)
/* The second part of the efun throw(): the caller stored the message
* into catch_value, now our job is to do the proper longjmp.
/* The efun throw(). We have to save the message <v> in the
* error context and then do the proper longjmp. <v> is freed.
*/
{
unroll_context_stack();
if (rt_context->type >= ERROR_RECOVERY_CATCH)
{
transfer_error_message(v, rt_context);
longjmp(((struct error_recovery_info *)rt_context)->con.text, 1);
fatal("Throw_error failed!");
}
free_svalue(&catch_value);
catch_value.type = T_INVALID;
free_svalue(v);
errorf("Throw with no catch.\n");
} /* throw_error() */
@ -1452,8 +1459,8 @@ push_give_uid_error_context (object_t *ob)
if (!ecp)
{
destruct(ob);
errorf("Out of memory (%lu bytes) for new object '%s' uids\n"
, (unsigned long) sizeof(*ecp), get_txt(ob->name));
errorf("Out of memory (%zu bytes) for new object '%s' uids\n"
, sizeof(*ecp), get_txt(ob->name));
}
ecp->new_object = ob;
push_error_handler(give_uid_error_handler, &(ecp->head));
@ -1751,8 +1758,8 @@ load_object_error(const char *msg, const char *name, namechain_t *chain)
/* Make a local copy of the message so as not to leak memory */
buf = alloca(strbuf_length(&sbuf)+1);
if (!buf)
errorf("Out of stack memory (%lu bytes)\n"
, (unsigned long) strlen(sbuf.buf)+1);
errorf("Out of stack memory (%zu bytes)\n"
, strlen(sbuf.buf)+1);
strbuf_copy(&sbuf, buf);
strbuf_free(&sbuf);
@ -1793,9 +1800,9 @@ load_object (const char *lname, Bool create_super, int depth
int fd;
object_t *ob;
object_t *save_command_giver = command_giver;
int i;
long i;
struct stat c_st;
int name_length;
size_t name_length;
char *name; /* Copy of <lname> */
char *fname; /* Filename for <name> */
program_t *prog;
@ -1806,6 +1813,16 @@ load_object (const char *lname, Bool create_super, int depth
fatal("Improper filename '%s' passed to load_object()\n", lname);
#endif
/* Empty lnames may lead to a driver crash in enter_object_hash() if there
* exists a file '.c' in the root of the mudlib.
*/
name_length = strlen(lname);
if (name_length < 1) {
load_object_error("Illegal file to load (empty filename)", lname, chain);
/* NOTREACHED */
}
/* It could be that the passed filename is one of an already loaded
* object. In that case, simply return that object.
*/
@ -1818,12 +1835,17 @@ load_object (const char *lname, Bool create_super, int depth
/* We need two copies of <lname>: one to construct the filename in,
* the second because lname might be a buffer which is deleted
* during the compilation process.
* The memory is allocated in one chunk for both strings and an error
* handler is pushed on the stack (additionally is needed: memory for '/'
* and '\0 (sizeof("/")) and '/', '\0', '.' and 'c' (sizeof("/.c"))).
*/
name_length = strlen(lname);
name = alloca(name_length+2);
fname = alloca(name_length+4);
if (!name || !fname)
fatal("Stack overflow in load_object()");
name = xalloc_with_error_handler(2 * name_length + sizeof("/") +
sizeof("/.c"));
fname = name + name_length + sizeof("/") + 1;
if (!name)
errorf("Out of memory (%zu bytes) in load_object() for temporary name "
"buffers.\n", 2*name_length + sizeof("/") + sizeof("/.c"));
if (!compat_mode)
*name++ = '/'; /* Add and hide a leading '/' */
strcpy(name, lname);
@ -1854,6 +1876,7 @@ load_object (const char *lname, Bool create_super, int depth
*/
errorf("Out of memory: unswap object '%s'\n", get_txt(ob->name));
#endif
pop_stack(); /* free error handler */
return ob;
}
}
@ -1921,6 +1944,7 @@ load_object (const char *lname, Bool create_super, int depth
ob->flags &= ~O_CLONE;
ob->flags |= O_REPLACED;
}
pop_stack(); /* free error handler */
return ob;
}
}
@ -1943,6 +1967,7 @@ load_object (const char *lname, Bool create_super, int depth
ob->flags &= ~O_CLONE;
ob->flags |= O_REPLACED;
}
pop_stack(); /* free error handler */
return ob;
}
fname[name_length] = '.';
@ -1974,6 +1999,7 @@ load_object (const char *lname, Bool create_super, int depth
ob = lookup_object_hash_str((char *)name);
if (ob)
{
pop_stack(); /* free error handler */
return ob;
}
@ -2105,7 +2131,7 @@ load_object (const char *lname, Bool create_super, int depth
#ifdef CHECK_OBJECT_STAT
if (check_object_stat)
{
fprintf(stderr, "DEBUG: OSTAT: (%ld:%ld) load( %p '%s') name: %ld -> (%ld:%ld)\n"
fprintf(stderr, "DEBUG: OSTAT: (%ld:%ld) load( %p '%s') name: %zu -> (%ld:%ld)\n"
, tot_alloc_object, tot_alloc_object_size, ob, ob->name ? get_txt(ob->name) : "<null>"
, mstrsize(ob->name)
, tot_alloc_object
@ -2162,7 +2188,7 @@ load_object (const char *lname, Bool create_super, int depth
{
/* The master object is loaded with no current object */
current_object = NULL;
init_object_variables(ob);
init_object_variables(ob, NULL);
reset_object(ob, create_super ? H_CREATE_SUPER : H_CREATE_OB);
/* If the master inherits anything -Ugh- we have to have
@ -2173,7 +2199,7 @@ load_object (const char *lname, Bool create_super, int depth
else
{
current_object = save_current;
init_object_variables(ob);
init_object_variables(ob, NULL);
reset_object(ob, create_super ? H_CREATE_SUPER : H_CREATE_OB);
}
}
@ -2181,6 +2207,9 @@ load_object (const char *lname, Bool create_super, int depth
if ( !(ob->flags & O_DESTRUCTED))
ob->flags |= O_WILL_CLEAN_UP;
/* free the error handler with the buffer for name and fname. */
pop_stack();
/* Restore the command giver */
command_giver = check_object(save_command_giver);
@ -2194,8 +2223,8 @@ load_object (const char *lname, Bool create_super, int depth
#if 0 && defined(CHECK_OBJECT_REF)
if (strchr(get_txt(ob->name), '#') == NULL)
printf("DEBUG: new_object(%p '%s') ref %ld flags %x\n"
, ob, get_txt(ob->name), (long)ob->ref, ob->flags);
printf("DEBUG: new_object(%p '%s') ref %"PRIdPINT" flags %x\n"
, ob, get_txt(ob->name), ob->ref, ob->flags);
#endif
return ob;
} /* load_object() */
@ -2358,7 +2387,7 @@ clone_object (string_t *str1)
#ifdef CHECK_OBJECT_STAT
if (check_object_stat)
{
fprintf(stderr, "DEBUG: OSTAT: (%ld:%ld) clone( %p '%s') name: %ld -> (%ld:%ld)\n"
fprintf(stderr, "DEBUG: OSTAT: (%ld:%ld) clone( %p '%s') name: %zu -> (%ld:%ld)\n"
, tot_alloc_object, tot_alloc_object_size, new_ob, new_ob->name ? get_txt(new_ob->name) : "<null>"
, mstrsize(new_ob->name)
, tot_alloc_object
@ -2389,7 +2418,7 @@ clone_object (string_t *str1)
push_ref_object(inter_sp, ob, "clone_object");
push_ref_string(inter_sp, new_ob->name);
give_uid_to_object(new_ob, H_CLONE_UIDS, 2);
init_object_variables(new_ob);
init_object_variables(new_ob, ob);
reset_object(new_ob, H_CREATE_CLONE);
command_giver = check_object(save_command_giver);
@ -2513,7 +2542,7 @@ destruct_object (svalue_t *v)
if (d_flag)
{
debug_message("%s destruct_object: %s (ref %ld)\n"
debug_message("%s destruct_object: %s (ref %"PRIdPINT")\n"
, time_stamp(), get_txt(ob->name), ob->ref);
}
@ -2831,7 +2860,8 @@ check_object_shadow (object_t *ob, object_shadow_t *sh)
if ((sh->flags & O_DESTRUCTED) != (ob->flags & O_DESTRUCTED)
|| sh->sent != ob->sent
)
fatal("DEBUG: Obj %p '%s': ref %ld, flags %x, sent %p; shadow ref %ld, flags %x, sent %p\n"
fatal("DEBUG: Obj %p '%s': ref %"PRIdPINT", flags %x, sent %p;"
"shadow ref %"PRIdPINT", flags %x, sent %p\n"
, ob, get_txt(ob->name), ob->ref, ob->flags, ob->sent
, sh->ref, sh->flags, sh->sent
);
@ -2874,7 +2904,7 @@ update_object_sent(object_t *obj, sentence_t *new_sent)
break;
if (sh == NULL)
{
fatal("DEBUG: Obj %p '%s': ref %ld, flags %x, sent %p; no shadow found\n"
fatal("DEBUG: Obj %p '%s': ref %"PRIdPINT", flags %x, sent %p; no shadow found\n"
, obj, get_txt(obj->name), obj->ref, obj->flags, obj->sent
);
}
@ -2916,7 +2946,7 @@ remove_object (object_t *ob
#endif
if (d_flag > 1)
{
debug_message("%s remove_object: object %s (ref %ld)\n"
debug_message("%s remove_object: object %s (ref %"PRIdPINT")\n"
, time_stamp(), get_txt(ob->name), ob->ref);
}
@ -3260,20 +3290,22 @@ status_parse (strbuf_t * sbuf, char * buff)
if (!verbose)
{
#ifdef USE_ACTIONS
strbuf_addf(sbuf, "Actions:\t\t\t%8ld %9ld\n"
strbuf_addf(sbuf, "Actions:\t\t\t%8"PRIdPINT" %9"PRIdPINT"\n"
, alloc_action_sent
, alloc_action_sent * sizeof (action_t));
#endif
#ifdef USE_SHADOWS
strbuf_addf(sbuf, "Shadows:\t\t\t%8ld %9ld\n"
strbuf_addf(sbuf, "Shadows:\t\t\t%8"PRIdPINT" %9"PRIdPINT"\n"
, alloc_shadow_sent
, alloc_shadow_sent * sizeof (shadow_t));
#endif
strbuf_addf(sbuf, "Objects:\t\t\t%8ld %9d (%lu destructed; %ld swapped: %ld Kbytes)\n"
strbuf_addf(sbuf, "Objects:\t\t\t%8ld %9ld (%ld destructed;"
" %"PRIdMPINT" swapped: %"PRIdMPINT" Kbytes)\n"
, tot_alloc_object, tot_alloc_object_size
, num_destructed
, num_destructed
, num_vb_swapped, total_vb_bytes_swapped / 1024);
strbuf_addf(sbuf, "Prog blocks:\t\t\t%8ld %9ld (%ld swapped: %ld Kbytes)\n"
strbuf_addf(sbuf, "Prog blocks:\t\t\t%8"PRIdMPINT" %9"PRIdMPINT
" (%"PRIdMPINT" swapped: %"PRIdMPINT" Kbytes)\n"
, total_num_prog_blocks + num_swapped - num_unswapped
, total_prog_block_size + total_bytes_swapped
- total_bytes_unswapped
@ -3281,21 +3313,22 @@ status_parse (strbuf_t * sbuf, char * buff)
, (total_bytes_swapped - total_bytes_unswapped) / 1024);
strbuf_addf(sbuf, "Arrays:\t\t\t\t%8ld %9ld\n"
, (long)num_arrays, total_array_size() );
strbuf_addf(sbuf, "Mappings:\t\t\t%8ld %9ld (%ld hybrid, %ld hash)\n"
strbuf_addf(sbuf, "Mappings:\t\t\t%8"PRIdMPINT" %9"PRIdMPINT
" (%"PRIdMPINT" hybrid, %"PRIdMPINT" hash)\n"
, num_mappings, total_mapping_size()
, num_dirty_mappings, num_hash_mappings
);
strbuf_addf(sbuf, "Memory reserved:\t\t\t %9d\n", res);
strbuf_addf(sbuf, "Memory reserved:\t\t\t %9zu\n", res);
}
if (verbose) {
/* TODO: Add these numbers to the debug_info statistics. */
strbuf_add(sbuf, "\nVM Execution:\n");
strbuf_add(sbuf, "-------------\n");
strbuf_addf(sbuf
, "Last: %7lu ticks, %3ld.%06ld s\n"
"Average: %7.0lf ticks, %10.6lf s\n"
, "Last: %10lu ticks, %3ld.%06ld s\n"
"Average: %10.0lf ticks, %10.6lf s\n"
, last_total_evalcost
, last_eval_duration.tv_sec, last_eval_duration.tv_usec
, last_eval_duration.tv_sec, (long)last_eval_duration.tv_usec
, stat_total_evalcost.weighted_avg
, stat_eval_duration.weighted_avg / 1000000.0
);
@ -3309,14 +3342,14 @@ status_parse (strbuf_t * sbuf, char * buff)
strbuf_add(sbuf, "\nNetwork IO:\n");
strbuf_add(sbuf, "-----------\n");
strbuf_addf(sbuf
, "In: Packets: %7lu - Sum: %7lu - "
, "In: Packets: %10lu - Sum: %10lu - "
"Average packet size: %7.2f\n"
, inet_packets_in
, inet_volume_in
, inet_packets_in ? (float)inet_volume_in/(float)inet_packets_in : 0.0
);
strbuf_addf(sbuf
, "Out: Packets: %7lu - Sum: %7lu - "
, "Out: Packets: %10lu - Sum: %10lu - "
"Average packet size: %7.2f\n"
" Calls to add_message: %lu\n"
, inet_packets
@ -3329,10 +3362,10 @@ status_parse (strbuf_t * sbuf, char * buff)
strbuf_add(sbuf, "\nApply Cache:\n");
strbuf_add(sbuf, "------------\n");
strbuf_addf(sbuf
, "Calls to apply_low: %7lu\n"
"Cache hits: %7lu (%.2f%%)\n"
, (unsigned long)(apply_cache_hit+apply_cache_miss)
, (unsigned long)apply_cache_hit
, "Calls to apply_low: %10"PRIuPINT"\n"
"Cache hits: %10"PRIuPINT" (%.2f%%)\n"
, (apply_cache_hit+apply_cache_miss)
, apply_cache_hit
, 100.*(float)apply_cache_hit/
(float)(apply_cache_hit+apply_cache_miss) );
#endif
@ -3349,70 +3382,70 @@ status_parse (strbuf_t * sbuf, char * buff)
if (verbose)
{
#ifdef DEBUG
long count;
unsigned long count;
object_t *ob;
#endif
strbuf_add(sbuf, "\nObject status:\n");
strbuf_add(sbuf, "--------------\n");
strbuf_addf(sbuf, "Objects total:\t\t\t %8ld\n"
, (long)tot_alloc_object);
, tot_alloc_object);
#ifndef DEBUG
strbuf_addf(sbuf, "Objects in list:\t\t %8ld\n"
, (long)num_listed_objs);
strbuf_addf(sbuf, "Objects in list:\t\t %8lu\n"
, (unsigned long)num_listed_objs);
strbuf_addf(sbuf, "Objects newly destructed:\t\t %8ld\n"
, (long)num_newly_destructed);
, num_newly_destructed);
strbuf_addf(sbuf, "Objects destructed:\t\t %8ld\n"
, (long)num_destructed);
, num_destructed);
#else
for (count = 0, ob = obj_list; ob != NULL; ob = ob->next_all)
count++;
if (count != (long)num_listed_objs)
{
debug_message("DEBUG: num_listed_objs mismatch: listed %ld, counted %ld\n"
, (long)num_listed_objs, count);
strbuf_addf(sbuf, "Objects in list:\t\t %8ld (counted %ld)\n"
, (long)num_listed_objs, count);
debug_message("DEBUG: num_listed_objs mismatch: listed %lu, counted %lu\n"
, (unsigned long)num_listed_objs, count);
strbuf_addf(sbuf, "Objects in list:\t\t %8lu (counted %lu)\n"
, (unsigned long)num_listed_objs, count);
}
else
strbuf_addf(sbuf, "Objects in list:\t\t %8ld\n"
, (long)num_listed_objs);
strbuf_addf(sbuf, "Objects in list:\t\t %8lu\n"
, (unsigned long)num_listed_objs);
for (count = 0, ob = newly_destructed_objs; ob != NULL; ob = ob->next_all)
count++;
if (count != num_newly_destructed)
{
debug_message("DEBUG: num_newly_destructed mismatch: listed %ld, counted %ld\n"
, (long)num_newly_destructed, count);
strbuf_addf(sbuf, "Objects newly destructed:\t\t %8ld (counted %ld)\n"
, (long)num_newly_destructed, count);
debug_message("DEBUG: num_newly_destructed mismatch: listed %ld, counted %lu\n"
, num_newly_destructed, count);
strbuf_addf(sbuf, "Objects newly destructed:\t\t %8ld (counted %lu)\n"
, num_newly_destructed, count);
}
else
strbuf_addf(sbuf, "Objects newly destructed:\t %8ld\n"
, (long)num_newly_destructed);
, num_newly_destructed);
for (count = 0, ob = destructed_objs; ob != NULL; ob = ob->next_all)
count++;
if (count != num_destructed)
{
debug_message("DEBUG: num_destructed mismatch: listed %ld, counted %ld\n"
, (long)num_destructed, count);
strbuf_addf(sbuf, "Objects destructed:\t\t %8ld (counted %ld)\n"
, (long)num_destructed, count);
debug_message("DEBUG: num_destructed mismatch: listed %ld, counted %lu\n"
, num_destructed, count);
strbuf_addf(sbuf, "Objects destructed:\t\t %8ld (counted %lu)\n"
, num_destructed, count);
}
else
strbuf_addf(sbuf, "Objects destructed:\t\t %8ld\n"
, (long)num_destructed);
, num_destructed);
#endif
strbuf_addf(sbuf, "Objects processed in last cycle: "
"%8ld (%5.1lf%% - avg. %5.1lf%%)\n"
, (long)num_last_processed
"%8lu (%5.1lf%% - avg. %5.1lf%%)\n"
, (unsigned long)num_last_processed
, (float)num_last_processed / (float)num_listed_objs * 100.0
, 100.0 * relate_statistics(stat_last_processed, stat_in_list)
);
#ifdef NEW_CLEANUP
strbuf_addf(sbuf, "Objects data-cleaned in last cycle: "
"%5ld (%5.1lf%% - avg. %5.1lf : %5.1lf%%)\n"
, (long)num_last_data_cleaned
"%5lu (%5.1lf%% - avg. %5.1lf : %5.1lf%%)\n"
, (unsigned long)num_last_data_cleaned
, (double)num_last_data_cleaned / (double)num_listed_objs * 100.0
, stat_last_data_cleaned.weighted_avg
, 100.0 * relate_statistics(stat_last_data_cleaned, stat_in_list)
@ -3445,7 +3478,7 @@ status_parse (strbuf_t * sbuf, char * buff)
#endif
other += num_simul_efun * sizeof(function_t);
other += interpreter_overhead();
strbuf_addf(sbuf, "Other structures\t\t\t %9lu\n", other);
strbuf_addf(sbuf, "Other structures\t\t\t %9zu\n", other);
tot += other;
}
tot += mb_status(sbuf, verbose);
@ -3454,7 +3487,7 @@ status_parse (strbuf_t * sbuf, char * buff)
if (!verbose) {
strbuf_add(sbuf, "\t\t\t\t\t ---------\n");
strbuf_add(sbuf, "Total:\t\t\t\t\t ");
strbuf_addf(sbuf, "%9d\n", tot);
strbuf_addf(sbuf, "%9zu\n", tot);
}
return MY_TRUE;
}
@ -4446,12 +4479,12 @@ print_svalue (svalue_t *arg)
else if (arg->type == T_OBJECT)
add_message("OBJ(%s)", get_txt(arg->u.ob->name));
else if (arg->type == T_NUMBER)
add_message("%ld", arg->u.number);
add_message("%"PRIdPINT, arg->u.number);
else if (arg->type == T_FLOAT)
{
char buff[120];
sprintf(buff, "%g", READ_DOUBLE( arg ) );
snprintf(buff, sizeof(buff), "%g", READ_DOUBLE( arg ) );
add_message(buff);
}
else if (arg->type == T_POINTER)
@ -4461,7 +4494,7 @@ print_svalue (svalue_t *arg)
else if (arg->type == T_CLOSURE)
add_message("<CLOSURE>");
else
add_message("<OTHER:%d>", arg->type);
add_message("<OTHER:%"PRIdPHINT">", arg->type);
} /* print_svalue() */
/*=========================================================================*/
@ -4899,7 +4932,7 @@ f_set_driver_hook (svalue_t *sp)
if (n < 0 || n >= NUM_DRIVER_HOOKS)
{
errorf("Bad hook number: %ld, expected 0..%ld\n"
errorf("Bad hook number: %"PRIdPINT", expected 0..%ld\n"
, n, (long)NUM_DRIVER_HOOKS-1);
/* NOTREACHED */
return sp;
@ -4930,9 +4963,9 @@ f_set_driver_hook (svalue_t *sp)
&& sp->u.number != RE_TRADITIONAL
)
{
errorf("Bad value for hook %ld: got 0x%lx, expected RE_PCRE (0x%lx) "
"or RE_TRADITIONAL (0x%lx).\n"
, n, (long)sp->u.number
errorf("Bad value for hook %"PRIdPINT": got 0x%"PRIxPINT
", expected RE_PCRE (0x%lx) or RE_TRADITIONAL (0x%lx).\n"
, n, sp->u.number
, (long)RE_PCRE, (long)RE_TRADITIONAL
);
break;
@ -4941,7 +4974,7 @@ f_set_driver_hook (svalue_t *sp)
}
else
{
errorf("Bad value for hook %ld: got number, expected %s or 0.\n"
errorf("Bad value for hook %"PRIdPINT": got number, expected %s or 0.\n"
, n
, efun_arg_typename(hook_type_map[n]));
break;
@ -4953,7 +4986,7 @@ f_set_driver_hook (svalue_t *sp)
string_t *str;
if ( !((1 << T_STRING) & hook_type_map[n]) )
errorf("Bad value for hook %ld: got string, expected %s.\n"
errorf("Bad value for hook %"PRIdPINT": got string, expected %s.\n"
, n
, efun_arg_typename(hook_type_map[n]));
@ -4969,7 +5002,7 @@ f_set_driver_hook (svalue_t *sp)
if (!sp->u.map->num_values
|| sp->u.map->ref != 1 /* add_to_mapping() could zero num_values */)
{
errorf("Bad value for hook %ld: mapping is empty "
errorf("Bad value for hook %"PRIdPINT": mapping is empty "
"or has other references.\n", n);
return sp;
}
@ -5009,7 +5042,7 @@ f_set_driver_hook (svalue_t *sp)
}
else if (!CLOSURE_IS_LFUN(sp->x.closure_type))
{
errorf("Bad value for hook %ld: unbound lambda or "
errorf("Bad value for hook %"PRIdPINT": unbound lambda or "
"lfun closure expected.\n", n);
}
/* FALLTHROUGH */
@ -5018,7 +5051,7 @@ f_set_driver_hook (svalue_t *sp)
default_test:
if ( !((1 << sp->type) & hook_type_map[n]) )
{
errorf("Bad value for hook %ld: got %s, expected %s.\n"
errorf("Bad value for hook %"PRIdPINT": got %s, expected %s.\n"
, n, typename(sp->type), efun_arg_typename(hook_type_map[n]));
break; /* flow control hint */
}
@ -5166,7 +5199,7 @@ set_single_limit ( struct limits_context_s * result
}
}
else if (val != LIMIT_KEEP)
errorf("Illegal %s value: %ld\n", limitnames[limit], val);
errorf("Illegal %s value: %"PRIdPINT"\n", limitnames[limit], val);
}
} /* set_single_limit() */
@ -5213,14 +5246,14 @@ extract_limits ( struct limits_context_s * result
for (i = 0; i < num - 1; i += 2)
{
int limit;
p_int limit;
if (svp[i].type != T_NUMBER)
errorf("Illegal limit value: got a %s, expected a number\n"
, typename(svp[i].type));
limit = (int)svp[i].u.number;
limit = svp[i].u.number;
if (limit < 0 || limit >= LIMIT_MAX)
errorf("Illegal limit tag: %ld\n", (long)limit);
errorf("Illegal limit tag: %"PRIdPINT"\n", limit);
set_single_limit(result, limit, svp+i+1);
}
@ -5305,7 +5338,7 @@ v_limited (svalue_t * sp, int num_arg)
limits.max_file = 0;
limits.use_cost = 1; /* smallest we can do */
}
else if (argp[1].type == T_POINTER)
else if (argp[1].type == T_POINTER && VEC_SIZE(argp[1].u.vec) < INT_MAX)
{
extract_limits(&limits, argp[1].u.vec->item
, (int)VEC_SIZE(argp[1].u.vec)
@ -5363,7 +5396,7 @@ v_limited (svalue_t * sp, int num_arg)
/* Save the current runtime limits and set the new ones */
save_limits_context(&context);
context.rt.last = rt_context;
rt_context = (rt_context_t *)&context;
rt_context = (rt_context_t *)&context.rt;
max_eval_cost = limits.max_eval ? limits.max_eval + eval_cost : 0;
/* Make sure that we get the requested amount of ticks, but remember
@ -5437,7 +5470,7 @@ v_set_limits (svalue_t * sp, int num_arg)
argp = sp - num_arg + 1;
if (num_arg == 1 && argp->type == T_POINTER)
if (num_arg == 1 && argp->type == T_POINTER && VEC_SIZE(argp->u.vec) < INT_MAX)
extract_limits(&limits, argp->u.vec->item, (int)VEC_SIZE(argp->u.vec)
, MY_FALSE);
else if (num_arg % 2 == 0)

View File

@ -229,8 +229,8 @@ extern mp_int current_error_line_number;
extern vector_t *uncaught_error_trace;
extern vector_t *current_error_trace;
extern int game_is_being_shut_down;
extern int master_will_be_updated;
extern Bool game_is_being_shut_down;
extern Bool master_will_be_updated;
/* --- Prototypes --- */
@ -280,7 +280,7 @@ extern void dinfo_data_status(svalue_t * svp, int value);
extern void warnf VARPROT((char *, ...), printf, 1, 2);
extern void errorf VARPROT((const char *, ...), printf, 1, 2) NORETURN;
extern void fatal VARPROT((const char *, ...), printf, 1, 2) NORETURN;
extern void throw_error(void);
extern void throw_error(svalue_t *v) NORETURN;
extern char *limit_error_format(char *fixed_fmt, size_t fixed_fmt_len, const char *fmt);
extern Bool legal_path(const char *path);
extern Bool check_no_parentdirs(const char *path);

View File

@ -180,7 +180,7 @@
* Small free blocks:
*
* The M_SIZE field in fact holds the offset to the slab holding this
* block.
* block (this also holds true for the small allocated blocks).
*
* The first word of the user area holds the 'next' link of the free
* list, which is NULL for the last block in the list.
@ -508,7 +508,7 @@ struct slabentry_s
unsigned long numBlocks; /* Desired number of blocks per slab. */
};
#define INIT_SLABENTRY { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
#define INIT_SLABENTRY { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
#define INIT_SLABENTRY2 INIT_SLABENTRY, INIT_SLABENTRY
#define INIT_SLABENTRY4 INIT_SLABENTRY2, INIT_SLABENTRY2
#define INIT_SLABENTRY8 INIT_SLABENTRY4, INIT_SLABENTRY4
@ -569,20 +569,20 @@ static t_stat perm_alloc_stat = {0,0};
* figure is a subset of {small,large}_alloc_stat.
*/
static long malloc_increment_size_calls = 0;
static unsigned long malloc_increment_size_calls = 0;
/* Number of calls to malloc_increment_size().
*/
static long malloc_increment_size_success = 0;
static unsigned long malloc_increment_size_success = 0;
/* Number of successfull calls to malloc_increment_size().
*/
static long malloc_increment_size_total = 0;
static unsigned long malloc_increment_size_total = 0;
/* Total memory allocated through to malloc_increment_size().
*/
#ifdef USE_AVL_FREELIST
static long num_avl_nodes = 0;
static unsigned long num_avl_nodes = 0;
/* Number of nodes in the AVL tree managing the large free blocks.
*/
#endif /* USE_AVL_FREELIST */
@ -729,7 +729,7 @@ mem_mark_permanent (POINTER p)
if (q[-M_OVERHEAD] & M_GC_FREE)
{
q[-M_OVERHEAD] &= ~M_GC_FREE;
count_up(perm_alloc_stat, mem_block_total_size(q));
count_up(&perm_alloc_stat, mem_block_total_size(q));
}
} /* mem_mark_permanent() */
@ -746,7 +746,7 @@ mem_mark_collectable (POINTER p)
if (!(q[-M_OVERHEAD] & M_GC_FREE))
{
q[-M_OVERHEAD] |= (M_REF|M_GC_FREE);
count_back(perm_alloc_stat, mem_block_total_size(q));
count_back(&perm_alloc_stat, mem_block_total_size(q));
}
} /* mem_mark_collectable() */
@ -904,40 +904,42 @@ mem_dump_data (strbuf_t *sbuf)
# define dump_stat(str,stat) strbuf_addf(sbuf, str,stat.counter,stat.size)
strbuf_add(sbuf, "Type Count Space (bytes)\n");
dump_stat("xallocs: %8u %10lu\n\n", xalloc_st);
dump_stat("sbrk requests: %8u %10lu (a)\n",sbrk_st);
dump_stat("large blocks: %8u %10lu (b)\n",l_alloc);
dump_stat("xallocs: %8lu %10lu\n\n", xalloc_st);
dump_stat("sbrk requests: %8lu %10lu (a)\n",sbrk_st);
dump_stat("large blocks: %8lu %10lu (b)\n",l_alloc);
strbuf_addf(sbuf
, "large net avail: %10ld\n"
, "large net avail: %10lu\n"
, l_alloc.size - l_alloc.counter * ML_OVERHEAD * SINT
);
dump_stat("large free blocks: %8u %10lu (c)\n",l_free);
dump_stat("large wasted: %8u %10lu (d)\n\n",l_wasted);
dump_stat("small slabs: %8u %10lu (e)\n",s_slab);
dump_stat("small blocks: %8u %10lu (f)\n",s_alloc);
dump_stat("large free blocks: %8lu %10lu (c)\n",l_free);
dump_stat("large wasted: %8lu %10lu (d)\n\n",l_wasted);
dump_stat("small slabs: %8lu %10lu (e)\n",s_slab);
dump_stat("small blocks: %8lu %10lu (f)\n",s_alloc);
strbuf_addf(sbuf
, "small net avail: %10d\n"
, "small net avail: %10lu\n"
, s_alloc.size - s_alloc.counter * M_OVERHEAD * SINT
);
dump_stat("small free blocks: %8u %10lu (g)\n",s_free);
dump_stat("small free slabs: %8u %10lu \n",s_free_slab);
dump_stat("small free blocks: %8lu %10lu (g)\n",s_free);
dump_stat("small free slabs: %8lu %10lu \n",s_free_slab);
strbuf_addf(sbuf
, "small overhead: %10lu (h)\n"
, s_overhead
);
dump_stat("\npermanent blocks: %8u %10lu\n", perm_st);
dump_stat("\npermanent blocks: %8lu %10lu\n", perm_st);
#ifdef SBRK_OK
dump_stat("clib allocations: %8u %10lu\n", clib_st);
dump_stat("clib allocations: %8lu %10lu\n", clib_st);
#else
strbuf_addf(sbuf, "clib allocations: n/a n/a\n");
#endif
strbuf_add(sbuf, "\n");
#ifdef USE_AVL_FREELIST
strbuf_addf(sbuf, "AVL nodes: %8u -\n", num_avl_nodes);
strbuf_addf(sbuf, "AVL nodes: %8lu -\n", num_avl_nodes);
strbuf_add(sbuf, "\n");
#endif /* USE_AVL_FREELIST */
#undef dump_stat
strbuf_addf(sbuf,
"malloc_increment_size: calls %lu success %lu total %lu\n\n",
malloc_increment_size_calls,
@ -979,7 +981,7 @@ mem_dump_extdata (strbuf_t *sbuf)
{
#ifdef MALLOC_EXT_STATISTICS
int i;
unsigned int i;
strbuf_add(sbuf,
"Detailed Block Statistics:\n\n"
@ -1513,8 +1515,8 @@ free_slab (mslab_t * slab, int ix)
{
ulog2f("slaballoc: deallocate slab %x [%d]\n", slab, ix);
slabtable[ix].numSlabs--;
count_back(small_slab_stat, SLAB_SIZE(slab, ix));
count_back_n(small_free_stat, slabtable[ix].numBlocks, slab->size);
count_back(&small_slab_stat, SLAB_SIZE(slab, ix));
count_back_n(&small_free_stat, slabtable[ix].numBlocks, slab->size);
#ifdef MALLOC_EXT_STATISTICS
extstats[SIZE_INDEX(slab->size)].cur_free -= slabtable[ix].numBlocks;
extstats[EXTSTAT_SLABS].cur_free--;
@ -1591,7 +1593,7 @@ mem_alloc (size_t size)
ulog2f(" %d bytes -> [%d]\n", size, ix);
/* Update statistics */
count_up(small_alloc_stat,size);
count_up(&small_alloc_stat,size);
#ifdef MALLOC_EXT_STATISTICS
extstats[SIZE_INDEX(size)].num_xalloc++;
@ -1612,7 +1614,7 @@ mem_alloc (size_t size)
block = slab->freeList;
slab->freeList = BLOCK_NEXT(slab->freeList);
count_back(small_free_stat, slab->size);
count_back(&small_free_stat, slab->size);
#ifdef MALLOC_EXT_STATISTICS
extstats[ix].cur_free--;
@ -1701,7 +1703,7 @@ mem_alloc (size_t size)
}
slabtable[ix].numFreeSlabs--;
count_back(small_slab_free_stat, SLAB_SIZE(slab, ix));
count_back(&small_slab_free_stat, SLAB_SIZE(slab, ix));
#ifdef MALLOC_EXT_STATISTICS
extstats[EXTSTAT_SLABS].cur_free--;
#endif /* MALLOC_EXT_STATISTICS */
@ -1733,8 +1735,8 @@ mem_alloc (size_t size)
slab->size = size;
slabtable[ix].numSlabs++;
count_up(small_slab_stat, slabSize);
count_up_n(small_free_stat, numObjects, size);
count_up(&small_slab_stat, slabSize);
count_up_n(&small_free_stat, numObjects, size);
#ifdef MALLOC_EXT_STATISTICS
extstats[ix].cur_free += numObjects;
extstats[EXTSTAT_SLABS].num_xalloc++;
@ -1781,7 +1783,7 @@ mem_alloc (size_t size)
MADVISE(block, orig_size);
count_back(small_free_stat, size);
count_back(&small_free_stat, size);
#ifdef MALLOC_EXT_STATISTICS
extstats[ix].cur_free--;
#endif /* MALLOC_EXT_STATISTICS */
@ -1870,7 +1872,7 @@ sfree (POINTER ptr)
/* It's a small block: put it into the slab's free list */
slab = (mslab_t*)(block - (block[M_SIZE] & M_MASK));
count_back(small_alloc_stat, slab->size);
count_back(&small_alloc_stat, slab->size);
ix = SIZE_INDEX(slab->size);
ulog4f("slaballoc: -> slab %x [%d], freelist %x, %d free\n"
@ -1886,31 +1888,28 @@ sfree (POINTER ptr)
if (slab->magic == sfmagic[ix % NELEM(sfmagic)])
{
in_malloc = 0;
fatal("mem_free: block %lx size %lu (user %lx) freed in free slab %lx\n"
, (unsigned long)block, (unsigned long)(ix * SINT)
, (unsigned long)ptr, (unsigned long) slab);
fatal("mem_free: block %p size %"PRIuPINT" (user %p) freed in free slab %p\n"
, block, (ix * SINT), ptr, slab);
}
if (slab->magic != samagic[ix % NELEM(samagic)])
{
in_malloc = 0;
fatal("mem_free: block %p magic match failed for slab %lx: "
"size %lu, expected %lx, found %lx\n"
, block, (unsigned long)slab
, (unsigned long)(ix * SINT), samagic[ix], slab->magic);
fatal("mem_free: block %p magic match failed for slab %p: "
"size %"PRIuPINT", expected %"PRIuPINT", found %"PRIuPINT"\n"
, block, slab, (ix * SINT), (p_uint)samagic[ix], slab->magic);
}
if (block[M_MAGIC] == sfmagic[ix % NELEM(sfmagic)])
{
in_malloc = 0;
fatal("mem_free: block %lx size %lu (user %lx) freed twice\n"
, (unsigned long)block, (unsigned long)(ix * SINT)
, (unsigned long)ptr);
fatal("mem_free: block %p size %"PRIuPINT" (user %p) freed twice\n"
, block, (ix * SINT), ptr);
}
if (block[M_MAGIC] != samagic[ix % NELEM(samagic)])
{
in_malloc = 0;
fatal("mem_free: block %p magic match failed: "
"size %lu, expected %lx, found %lx\n"
, block, (unsigned long)(ix * SINT), samagic[ix], block[M_MAGIC]);
"size %"PRIuPINT", expected %"PRIuPINT", found %"PRIuPINT"\n"
, block, (ix * SINT), (p_uint)samagic[ix], block[M_MAGIC]);
}
#endif
@ -1933,7 +1932,7 @@ sfree (POINTER ptr)
slab->freeList = block;
slab->numAllocated--;
count_up(small_free_stat, slab->size);
count_up(&small_free_stat, slab->size);
/* If this slab is not the fresh slab, handle possible list movements.
*/
@ -1993,7 +1992,7 @@ sfree (POINTER ptr)
slabtable[ix].firstFree = slab;
slabtable[ix].numFreeSlabs++;
count_up(small_slab_free_stat, SLAB_SIZE(slab, ix));
count_up(&small_slab_free_stat, SLAB_SIZE(slab, ix));
#ifdef MALLOC_EXT_STATISTICS
extstats[EXTSTAT_SLABS].cur_alloc--;
extstats[EXTSTAT_SLABS].cur_free++;
@ -2131,6 +2130,7 @@ static struct free_block dummy =
#ifdef USE_AVL_FREELIST
, /* prev */ 0, /* next */ 0
#endif /* USE_AVL_FREELIST */
, /* align_dummy */ 0
};
struct free_block dummy2 =
@ -2139,6 +2139,7 @@ static struct free_block dummy =
#ifdef USE_AVL_FREELIST
, /* prev */ 0, /* next */ 0
#endif /* USE_AVL_FREELIST */
, /* align_dummy */ 0
};
static struct free_block *free_tree = &dummy2;
@ -2278,7 +2279,8 @@ check_free_block (void *m)
if (!contains(free_tree, (struct free_block *)(p+size+T_OVERHEAD)) )
{
in_malloc = 0;
fatal("not found\n");
fatal("Memory at %p, size: %"PRIuPINT" (user: %p) was not found in the free_tree\n",
p, size, m);
}
}
return 0;
@ -2305,16 +2307,14 @@ remove_from_free_list (word_t *ptr)
{
in_malloc = 0;
fatal("remove_from_free_list: block %p, "
"magic match failed: expected %lx, "
"found %lx\n"
, ptr
, (unsigned long)LFMAGIC
, (unsigned long)ptr[M_MAGIC]
"magic match failed: expected %"PRIuPINT", "
"found %"PRIuPINT"\n"
, ptr, (p_uint)LFMAGIC, ptr[M_MAGIC]
);
}
#endif
p = (struct free_block *)(ptr+M_OVERHEAD);
count_back(large_free_stat, p->size);
count_back(&large_free_stat, p->size);
#ifdef MALLOC_EXT_STATISTICS
extstats[EXTSTAT_LARGE].cur_free--;
#endif /* MALLOC_EXT_STATISTICS */
@ -2338,7 +2338,9 @@ remove_from_free_list (word_t *ptr)
#ifdef DEBUG
if (p->parent)
{
fatal("(remove_from_free_list) Node %p (size %ld) is the AVL tree root, but has a parent\n", p, (long)p->size);
fatal("(remove_from_free_list) Node %p (size %"PRIuPINT
") is the AVL tree root, but has a parent\n",
p, p->size);
}
#endif
free_tree = p->next;
@ -2348,7 +2350,9 @@ remove_from_free_list (word_t *ptr)
#ifdef DEBUG
if (!p->parent)
{
fatal("(remove_from_free_list) Node %p (size %ld) has neither a parent nor is it the AVL tree root.\n", p, (long)p->size);
fatal("(remove_from_free_list) Node %p (size %"PRIuPINT
") has neither a parent nor is it the AVL tree root.\n",
p, p->size);
}
#endif
if (p->parent->left == p)
@ -2703,7 +2707,7 @@ add_to_free_list (word_t *ptr)
* register choice
*/
r = (struct free_block *)(ptr+M_OVERHEAD);
count_up(large_free_stat, size);
count_up(&large_free_stat, size);
#ifdef MALLOC_EXT_STATISTICS
extstats[EXTSTAT_LARGE].cur_free++;
extstat_update_max(extstats+EXTSTAT_LARGE);
@ -3344,7 +3348,7 @@ found_fit:
{
mark_block(ptr+size);
*(ptr+size) &= ~M_GC_FREE; /* Hands off, GC! */
count_up(large_wasted_stat, (*(ptr+size) & M_MASK) * SINT);
count_up(&large_wasted_stat, (*(ptr+size) & M_MASK) * SINT);
}
else
# endif
@ -3360,7 +3364,7 @@ found_fit:
/* The block at ptr is all ours */
mark_block(ptr);
count_up(large_alloc_stat, size);
count_up(&large_alloc_stat, size);
#ifdef MALLOC_EXT_STATISTICS
extstats[EXTSTAT_LARGE].num_xalloc++;
extstats[EXTSTAT_LARGE].cur_alloc++;
@ -3388,7 +3392,7 @@ large_free (char *ptr)
p = (word_t *) ptr;
p -= M_OVERHEAD;
size = p[M_LSIZE];
count_back(large_alloc_stat, size);
count_back(&large_alloc_stat, size);
#ifdef MALLOC_EXT_STATISTICS
extstats[EXTSTAT_LARGE].num_xfree++;
extstats[EXTSTAT_LARGE].cur_alloc--;
@ -3398,19 +3402,17 @@ large_free (char *ptr)
if (p[M_MAGIC] == LFMAGIC)
{
in_malloc = 0;
fatal("large_free: block %lx size %lu, (user %lx) freed twice\n"
, (unsigned long)p, (unsigned long)(size * SINT)
, (unsigned long)ptr);
fatal("large_free: block %p size %"PRIuPINT", (user %p) freed twice\n"
, p, (size * SINT), ptr);
}
if (p[M_MAGIC] != LAMAGIC)
{
in_malloc = 0;
fatal("large_free(%p): block %p magic match failed: size %lu, "
"expected %lx, found %lx\n"
, ptr, p
, (unsigned long)(size * SINT)
, (unsigned long)LAMAGIC
, (unsigned long)p[M_MAGIC]
fatal("large_free(%p): block %p magic match failed: size %"PRIuPINT", "
"expected %"PRIuPINT", found %"PRIuPINT"\n"
, ptr, p, (size * SINT)
, (p_uint)LAMAGIC
, p[M_MAGIC]
);
}
#endif
@ -3460,7 +3462,7 @@ esbrk (word_t size, size_t * pExtra)
}
*heap_start = 2;
*(heap_start+1) = PREV_BLOCK | M_MASK;
count_up(large_wasted_stat, 2*SINT);
count_up(&large_wasted_stat, 2*SINT);
assert_stack_gap();
}
@ -3468,7 +3470,7 @@ esbrk (word_t size, size_t * pExtra)
if ((int)brk((char *)heap_end + size) == -1)
return NULL;
count_up(sbrk_stat, size);
count_up(&sbrk_stat, size);
heap_end = (word_t*)((char *)heap_end + size);
heap_end[-1] = THIS_BLOCK | M_MASK;
heap_end[-2] = M_MASK;
@ -3535,7 +3537,7 @@ esbrk (word_t size, size_t * pExtra)
/* We can join with the existing heap */
p[overhead] &= ~PREV_BLOCK;
overlap = SINT;
count_back(large_wasted_stat, overlap);
count_back(&large_wasted_stat, overlap);
}
else
{
@ -3559,7 +3561,7 @@ esbrk (word_t size, size_t * pExtra)
heap_end = (word_t *)(block + size);
block -= overhead;
overlap = overhead * SINT;
count_back(large_wasted_stat, overlap);
count_back(&large_wasted_stat, overlap);
}
else
{
@ -3594,7 +3596,7 @@ esbrk (word_t size, size_t * pExtra)
/* Our block directly follows the one we found */
block -= overhead;
overlap += overhead * SINT;
count_back(large_wasted_stat, overhead * SINT);
count_back(&large_wasted_stat, overhead * SINT);
}
else
{
@ -3619,7 +3621,7 @@ esbrk (word_t size, size_t * pExtra)
/* Our block directly preceedes the next one */
*(next+1) &= ~PREV_BLOCK;
overlap += overhead * SINT;
count_back(large_wasted_stat, overhead * SINT);
count_back(&large_wasted_stat, overhead * SINT);
}
else
{
@ -3630,8 +3632,8 @@ esbrk (word_t size, size_t * pExtra)
}
}
count_up(sbrk_stat, size);
count_up(large_wasted_stat, overhead * SINT);
count_up(&sbrk_stat, size);
count_up(&large_wasted_stat, overhead * SINT);
*pExtra = overlap;
return block + SINT;
@ -3681,7 +3683,7 @@ mem_increment_size (void *vp, size_t size)
start[M_LSIZE] += wsize;
malloc_increment_size_success++;
malloc_increment_size_total += (start2 - start) - M_OVERHEAD;
count_add(large_alloc_stat, wsize);
count_add(&large_alloc_stat, wsize);
return start2+M_LSIZE;
}
@ -3699,7 +3701,7 @@ mem_increment_size (void *vp, size_t size)
start[M_LSIZE] += wsize;
malloc_increment_size_success++;
malloc_increment_size_total += (start2 - start) - M_OVERHEAD;
count_add(large_alloc_stat, wsize);
count_add(&large_alloc_stat, wsize);
return start2+M_LSIZE;
}
@ -3859,8 +3861,8 @@ mem_clear_ref_flags (void)
if (p + *p > heap_end)
{
in_malloc = 0;
fatal("pointer larger than brk: %p + %lx = %p > %p\n"
, p, *p, p + *p , last);
fatal("pointer larger than brk: %p + %"PRIuPINT" = %p > %p\n"
, p, (p_uint)(*p), p + *p , last);
}
p += *p;
}
@ -3950,7 +3952,7 @@ mem_free_unrefed_slab_memory ( const char * tag
{
/* Unref'd small blocks are definitely lost */
success++;
count_back(xalloc_stat, slab->size - (T_OVERHEAD * SINT));
count_back(&xalloc_stat, slab->size - (T_OVERHEAD * SINT));
dprintf2(gcollect_outfd, "freeing small block 0x%x (user 0x%x)"
, (p_uint)p, (p_uint)(p+M_OVERHEAD));
#ifdef MALLOC_TRACE
@ -4007,7 +4009,7 @@ mem_free_unrefed_memory (void)
word_t size2, flags2;
success++;
count_back(xalloc_stat, mem_block_size(p+ML_OVERHEAD));
count_back(&xalloc_stat, mem_block_size(p+ML_OVERHEAD));
#if defined(MALLOC_TRACE) || defined(MALLOC_LPC_TRACE)
dprintf1(gcollect_outfd, "freeing large block 0x%x", (p_uint)p);
#endif
@ -4319,7 +4321,7 @@ mem_consolidate (Bool force)
while (NULL != (slab = slabtable[ix].firstFree))
{
slabtable[ix].firstFree = slab->next;
count_back(small_slab_free_stat, SLAB_SIZE(slab, ix));
count_back(&small_slab_free_stat, SLAB_SIZE(slab, ix));
free_slab(slab, ix);
}
slabtable[ix].numFreeSlabs = 0;
@ -4343,7 +4345,7 @@ mem_consolidate (Bool force)
else
slabtable[ix].firstFree = NULL;
slabtable[ix].numFreeSlabs--;
count_back(small_slab_free_stat, SLAB_SIZE(slab, ix));
count_back(&small_slab_free_stat, SLAB_SIZE(slab, ix));
free_slab(slab, ix);
}
#ifdef DEBUG_MALLOC_ALLOCS

View File

@ -695,7 +695,7 @@ mem_mark_permanent (POINTER p)
if (q[-M_OVERHEAD] & M_GC_FREE)
{
q[-M_OVERHEAD] &= ~M_GC_FREE;
count_up(perm_alloc_stat, mem_block_total_size(q));
count_up(&perm_alloc_stat, mem_block_total_size(q));
}
} /* mem_mark_permanent() */
@ -712,7 +712,7 @@ mem_mark_collectable (POINTER p)
if (!(q[-M_OVERHEAD] & M_GC_FREE))
{
q[-M_OVERHEAD] |= (M_REF|M_GC_FREE);
count_back(perm_alloc_stat, mem_block_total_size(q));
count_back(&perm_alloc_stat, mem_block_total_size(q));
}
} /* mem_mark_collectable() */
@ -832,6 +832,8 @@ mem_dump_data (strbuf_t *sbuf)
strbuf_add(sbuf, "\n");
#endif /* USE_AVL_FREELIST */
#undef dump_stat
strbuf_addf(sbuf,
"malloc_increment_size: calls %lu success %lu total %lu\n\n",
malloc_increment_size_calls,
@ -1111,7 +1113,7 @@ UNLINK_SMALL_FREE (word_t * block)
next[M_PLINK(next[M_SIZE] & M_MASK)] = (word_t)prev | flag;
prev[M_LINK] = (word_t) next;
}
count_back(small_free_stat, bsize * SINT);
count_back(&small_free_stat, bsize * SINT);
} /* UNLINK_SMALL_FREE() */
@ -1159,7 +1161,7 @@ void MAKE_SMALL_FREE (word_t *block, word_t bsize)
block[M_PLINK(bsize)-1] = bsize;
sfltable[ix] = block;
count_up(small_free_stat, bsize * SINT);
count_up(&small_free_stat, bsize * SINT);
#ifdef MALLOC_CHECK
block[M_MAGIC] = sfmagic[SIZE_MOD_INDEX(bsize * SINT, sfmagic)];
@ -1482,7 +1484,7 @@ mem_alloc (size_t size)
size = (size+M_OVERHEAD*SINT+SINT-1) & ~(SINT-1);
/* Update statistics */
count_up(small_alloc_stat,size);
count_up(&small_alloc_stat,size);
#ifdef MALLOC_EXT_STATISTICS
extstats[SIZE_INDEX(size)].num_xalloc++;
extstats[SIZE_INDEX(size)].cur_alloc++;
@ -1558,7 +1560,7 @@ mem_alloc (size_t size)
/* Just modify the size and move the .prev pointer
* and size field.
*/
count_back(small_free_stat, bsize * SINT);
count_back(&small_free_stat, bsize * SINT);
this[M_SIZE] &= (PREV_BLOCK|M_DEFRAG);
this[M_SIZE] |= rsize | (THIS_BLOCK|M_REF);
@ -1569,7 +1571,7 @@ mem_alloc (size_t size)
this[M_MAGIC] = sfmagic[SIZE_MOD_INDEX(rsize*SINT, sfmagic)];
#endif
count_up(small_free_stat, rsize * SINT);
count_up(&small_free_stat, rsize * SINT);
}
/* Split off the allocated small block from the end
@ -1717,8 +1719,8 @@ mem_alloc (size_t size)
*new_chunk = (word_t)last_small_chunk;
last_small_chunk = new_chunk++;
count_up(small_chunk_stat, new_chunk[-ML_OVERHEAD-1] * SINT);
count_up(small_chunk_wasted, SINT*(M_OVERHEAD+1));
count_up(&small_chunk_stat, new_chunk[-ML_OVERHEAD-1] * SINT);
count_up(&small_chunk_wasted, SINT*(M_OVERHEAD+1));
small_chunk_size = SMALL_CHUNK_SIZE;
@ -1782,7 +1784,7 @@ sfree (POINTER ptr)
/* It's a small block: put it back into the free list */
count_back(small_alloc_stat, bsize * SINT);
count_back(&small_alloc_stat, bsize * SINT);
i -= SMALL_BLOCK_MIN + T_OVERHEAD;
#ifdef MALLOC_EXT_STATISTICS
@ -2104,7 +2106,7 @@ remove_from_free_list (word_t *ptr)
}
#endif
p = (struct free_block *)(ptr+M_OVERHEAD);
count_back(large_free_stat, p->size);
count_back(&large_free_stat, p->size);
#ifdef MALLOC_EXT_STATISTICS
extstats[SMALL_BLOCK_NUM+1].cur_free--;
#endif /* MALLOC_EXT_STATISTICS */
@ -2493,7 +2495,7 @@ add_to_free_list (word_t *ptr)
* register choice
*/
r = (struct free_block *)(ptr+M_OVERHEAD);
count_up(large_free_stat, size);
count_up(&large_free_stat, size);
#ifdef MALLOC_EXT_STATISTICS
extstats[SMALL_BLOCK_NUM+1].cur_free++;
extstat_update_max(extstats+SMALL_BLOCK_NUM+1);
@ -3131,7 +3133,7 @@ found_fit:
{
mark_block(ptr+size);
*(ptr+size) &= ~M_GC_FREE; /* Hands off, GC! */
count_up(large_wasted_stat, (*(ptr+size) & M_MASK) * SINT);
count_up(&large_wasted_stat, (*(ptr+size) & M_MASK) * SINT);
}
else
# endif
@ -3147,7 +3149,7 @@ found_fit:
/* The block at ptr is all ours */
mark_block(ptr);
count_up(large_alloc_stat, size);
count_up(&large_alloc_stat, size);
#ifdef MALLOC_EXT_STATISTICS
extstats[SMALL_BLOCK_NUM+1].num_xalloc++;
extstats[SMALL_BLOCK_NUM+1].cur_alloc++;
@ -3175,7 +3177,7 @@ large_free (char *ptr)
p = (word_t *) ptr;
p -= M_OVERHEAD;
size = p[M_LSIZE];
count_back(large_alloc_stat, size);
count_back(&large_alloc_stat, size);
#ifdef MALLOC_EXT_STATISTICS
extstats[SMALL_BLOCK_NUM+1].num_xfree++;
extstats[SMALL_BLOCK_NUM+1].cur_alloc--;
@ -3247,7 +3249,7 @@ esbrk (word_t size, size_t * pExtra)
}
*heap_start = 2;
*(heap_start+1) = PREV_BLOCK | M_MASK;
count_up(large_wasted_stat, 2*SINT);
count_up(&large_wasted_stat, 2*SINT);
assert_stack_gap();
}
@ -3255,7 +3257,7 @@ esbrk (word_t size, size_t * pExtra)
if ((int)brk((char *)heap_end + size) == -1)
return NULL;
count_up(sbrk_stat, size);
count_up(&sbrk_stat, size);
heap_end = (word_t*)((char *)heap_end + size);
heap_end[-1] = THIS_BLOCK | M_MASK;
heap_end[-2] = M_MASK;
@ -3321,7 +3323,7 @@ esbrk (word_t size, size_t * pExtra)
/* We can join with the existing heap */
p[overhead] &= ~PREV_BLOCK;
overlap = SINT;
count_back(large_wasted_stat, overlap);
count_back(&large_wasted_stat, overlap);
}
else
{
@ -3345,7 +3347,7 @@ esbrk (word_t size, size_t * pExtra)
heap_end = (word_t *)(block + size);
block -= overhead;
overlap = overhead * SINT;
count_back(large_wasted_stat, overlap);
count_back(&large_wasted_stat, overlap);
}
else
{
@ -3380,7 +3382,7 @@ esbrk (word_t size, size_t * pExtra)
/* Our block directly follows the one we found */
block -= overhead;
overlap += overhead * SINT;
count_back(large_wasted_stat, overhead * SINT);
count_back(&large_wasted_stat, overhead * SINT);
}
else
{
@ -3405,7 +3407,7 @@ esbrk (word_t size, size_t * pExtra)
/* Our block directly preceedes the next one */
*(next+1) &= ~PREV_BLOCK;
overlap += overhead * SINT;
count_back(large_wasted_stat, overhead * SINT);
count_back(&large_wasted_stat, overhead * SINT);
}
else
{
@ -3416,8 +3418,8 @@ esbrk (word_t size, size_t * pExtra)
}
}
count_up(sbrk_stat, size);
count_up(large_wasted_stat, overhead * SINT);
count_up(&sbrk_stat, size);
count_up(&large_wasted_stat, overhead * SINT);
*pExtra = overlap;
return block + SINT;
@ -3477,7 +3479,7 @@ mem_increment_size (void *vp, size_t size)
malloc_increment_size_success++;
malloc_increment_size_total += (start2 - start) - M_OVERHEAD;
count_add(small_alloc_stat, wsize * SINT);
count_add(&small_alloc_stat, wsize * SINT);
#ifdef MALLOC_EXT_STATISTICS
extstats[SIZE_INDEX(old_size * SINT)].cur_alloc--;
@ -3504,7 +3506,7 @@ mem_increment_size (void *vp, size_t size)
malloc_increment_size_success++;
malloc_increment_size_total += (start2 - start) - M_OVERHEAD;
count_add(small_alloc_stat, wsize * SINT);
count_add(&small_alloc_stat, wsize * SINT);
#ifdef MALLOC_EXT_STATISTICS
extstats[SIZE_INDEX(old_size * SINT)].cur_alloc--;
@ -3536,7 +3538,7 @@ mem_increment_size (void *vp, size_t size)
start[M_LSIZE] += wsize;
malloc_increment_size_success++;
malloc_increment_size_total += (start2 - start) - M_OVERHEAD;
count_add(large_alloc_stat, wsize);
count_add(&large_alloc_stat, wsize);
return start2+M_LSIZE;
}
@ -3554,7 +3556,7 @@ mem_increment_size (void *vp, size_t size)
start[M_LSIZE] += wsize;
malloc_increment_size_success++;
malloc_increment_size_total += (start2 - start) - M_OVERHEAD;
count_add(large_alloc_stat, wsize);
count_add(&large_alloc_stat, wsize);
return start2+M_LSIZE;
}
@ -3745,7 +3747,7 @@ mem_free_unrefed_memory (void)
word_t size2, flags2;
success++;
count_back(xalloc_stat, mem_block_size(p+ML_OVERHEAD));
count_back(&xalloc_stat, mem_block_size(p+ML_OVERHEAD));
#if defined(MALLOC_TRACE) || defined(MALLOC_LPC_TRACE)
dprintf1(gcollect_outfd, "freeing large block 0x%x", (p_uint)p);
#endif
@ -3793,7 +3795,7 @@ mem_free_unrefed_memory (void)
{
/* Unref'd small blocks are definitely lost */
success++;
count_back(xalloc_stat, mem_block_size(q+M_OVERHEAD));
count_back(&xalloc_stat, mem_block_size(q+M_OVERHEAD));
dprintf2(gcollect_outfd, "freeing small block 0x%x (user 0x%x)"
, (p_uint)q, (p_uint)(q+M_OVERHEAD));
#ifdef MALLOC_TRACE
@ -3993,8 +3995,8 @@ mem_consolidate (Bool force)
UNLINK_SMALL_FREE(this+1);
large_free((char *)this);
count_back(small_chunk_stat, chunk_size * SINT);
count_back(small_chunk_wasted, SINT*(M_OVERHEAD+2));
count_back(&small_chunk_stat, chunk_size * SINT);
count_back(&small_chunk_wasted, SINT*(M_OVERHEAD+2));
this = next;
}

View File

@ -133,30 +133,32 @@
typedef unsigned int format_info;
#define INFO_T 0xF
#define INFO_T_ERROR 0x1
#define INFO_T_NULL 0x2
#define INFO_T_LPC 0x3
#define INFO_T_QLPC 0x4
#define INFO_T_STRING 0x5
#define INFO_T_INT 0x6
#define INFO_T_FLOAT 0x7
enum format_info_t {
INFO_T = 0xF,
INFO_T_ERROR = 0x1,
INFO_T_NULL = 0x2,
INFO_T_LPC = 0x3,
INFO_T_QLPC = 0x4,
INFO_T_STRING = 0x5,
INFO_T_INT = 0x6,
INFO_T_FLOAT = 0x7,
#define INFO_A 0x30 /* Right alignment */
#define INFO_A_CENTRE 0x10
#define INFO_A_LEFT 0x20
#define INFO_A_JUSTIFY 0x30
INFO_A = 0x30, /* Right alignment */
INFO_A_CENTRE = 0x10,
INFO_A_LEFT = 0x20,
INFO_A_JUSTIFY = 0x30,
#define INFO_PP 0xC0
#define INFO_PP_SPACE 0x40
#define INFO_PP_PLUS 0x80
INFO_PP = 0xC0,
INFO_PP_SPACE = 0x40,
INFO_PP_PLUS = 0x80,
#define INFO_ARRAY 0x100
#define INFO_COLS 0x200
#define INFO_TABLE 0x400
INFO_ARRAY = 0x100,
INFO_COLS = 0x200,
INFO_TABLE = 0x400,
#define INFO_PS_ZERO 0x800
#define INFO_PS_KEEP 0x1000
INFO_PS_ZERO = 0x800,
INFO_PS_KEEP = 0x1000,
};
/*-------------------------------------------------------------------------*/
@ -166,27 +168,28 @@ typedef unsigned int format_info;
/* The error handling */
enum format_err {
ERR_ID_NUMBER = 0xFFFF, /* Mask for the error number */
ERR_ARGUMENT = 0xFFFF0000, /* Mask for the arg number */
ERR_BUFF_OVERFLOW = 0x1, /* buffer overflowed */
ERR_TO_FEW_ARGS = 0x2, /* more arguments spec'ed than passed */
ERR_INVALID_STAR = 0x3, /* invalid arg to * */
ERR_PREC_EXPECTED = 0x4, /* expected precision not found */
ERR_INVALID_FORMAT_STR = 0x5, /* error in format string */
ERR_INCORRECT_ARG = 0x6, /* invalid arg to %[idcxXs] */
ERR_CST_REQUIRES_FS = 0x7, /* field size not given for c/t */
ERR_UNDEFINED_TYPE = 0x8, /* undefined type found */
ERR_QUOTE_EXPECTED = 0x9, /* expected ' not found */
ERR_UNEXPECTED_EOS = 0xA, /* fs terminated unexpectedly */
ERR_NULL_PS = 0xB, /* pad string is null */
ERR_ARRAY_EXPECTED = 0xC, /* array expected */
ERR_NOMEM = 0xD, /* Out of memory */
ERR_SIZE_OVERFLOW = 0xE, /* Fieldsize/precision numeric overflow */
};
#define ERROR(x) (longjmp(st->error_jmp, (x)))
#define ERR_ID_NUMBER 0xFFFF /* Mask for the error number */
#define ERR_ARGUMENT 0xFFFF0000 /* Mask for the arg number */
#define ERR_BUFF_OVERFLOW 0x1 /* buffer overflowed */
#define ERR_TO_FEW_ARGS 0x2 /* more arguments spec'ed than passed */
#define ERR_INVALID_STAR 0x3 /* invalid arg to * */
#define ERR_PREC_EXPECTED 0x4 /* expected precision not found */
#define ERR_INVALID_FORMAT_STR 0x5 /* error in format string */
#define ERR_INCORRECT_ARG 0x6 /* invalid arg to %[idcxXs] */
#define ERR_CST_REQUIRES_FS 0x7 /* field size not given for c/t */
#define ERR_UNDEFINED_TYPE 0x8 /* undefined type found */
#define ERR_QUOTE_EXPECTED 0x9 /* expected ' not found */
#define ERR_UNEXPECTED_EOS 0xA /* fs terminated unexpectedly */
#define ERR_NULL_PS 0xB /* pad string is null */
#define ERR_ARRAY_EXPECTED 0xC /* array expected */
#define ERR_NOMEM 0xD /* Out of memory */
#define ERR_SIZE_OVERFLOW 0xE /* Fieldsize/precision numeric overflow */
#define ERROR1(e,a) ERROR((e) | (a)<<16)
#define EXTRACT_ERR_ARGUMENT(i) ((i)>>16)
@ -326,60 +329,60 @@ static sprintf_buffer_t *svalue_to_string(fmt_state_t *
, int, Bool, Bool, Bool, Bool);
/*-------------------------------------------------------------------------*/
/* Macros */
#define ADD_CHAR(x) {\
if (st->bpos >= BUFF_SIZE) ERROR(ERR_BUFF_OVERFLOW); \
if (x == '\n' && st->sppos != -1) st->bpos = st->sppos; \
st->sppos = -1; \
st->buff[st->bpos++] = x;\
/* static helper functions */
static inline void ADD_CHAR(fmt_state_t *st, char x) {
if (st->bpos >= BUFF_SIZE) ERROR(ERR_BUFF_OVERFLOW);
if (x == '\n' && st->sppos != -1) st->bpos = st->sppos;
st->sppos = -1;
st->buff[st->bpos++] = x;
}
/* Add character <x> to the buffer.
*/
/*-------------------------------------------------------------------------*/
#define ADD_STRN(s, n) { \
if (st->bpos + n > BUFF_SIZE) ERROR(ERR_BUFF_OVERFLOW); \
if (n >= 1 && (s)[0] == '\n' && st->sppos != -1) st->bpos = st->sppos; \
st->sppos = -1; \
memcpy(st->buff+st->bpos, (s), n);\
st->bpos += n; \
static inline void ADD_STRN(fmt_state_t *st, const char *s, size_t n) {
if (st->bpos + n > BUFF_SIZE) ERROR(ERR_BUFF_OVERFLOW);
if (n >= 1 && s[0] == '\n' && st->sppos != -1) st->bpos = st->sppos;
st->sppos = -1;
memcpy(st->buff+st->bpos, s, n);
st->bpos += n;
}
/* Add the <n> characters from <s> to the buffer.
*/
/*-------------------------------------------------------------------------*/
#define ADD_CHARN(c, n) { \
/* n must not be negative! */ \
if (st->bpos + n > BUFF_SIZE) ERROR(ERR_BUFF_OVERFLOW); \
if (n >= 1 && c == '\n' && st->sppos != -1) st->bpos = st->sppos; \
st->sppos = -1; \
memset(st->buff+st->bpos, c, n); \
st->bpos += n; \
static inline void ADD_CHARN(fmt_state_t *st, char c, size_t n) {
/* n must not be negative! */
if (st->bpos + n > BUFF_SIZE) ERROR(ERR_BUFF_OVERFLOW);
if (n >= 1 && c == '\n' && st->sppos != -1) st->bpos = st->sppos;
st->sppos = -1;
memset(st->buff+st->bpos, c, n);
st->bpos += n;
}
/* Add character <c> <n>-times to the buffer.
*/
/*-------------------------------------------------------------------------*/
#define ADD_PADDING(pad, N) { \
int n = (N); \
\
if (!pad[1]) { \
ADD_CHARN(*pad, n) \
} else { \
int l; \
\
l = strlen(pad); \
for (i=0; --n >= 0; ) { \
if (pad[i] == '\\') \
i++; \
ADD_CHAR(pad[i]); \
if (++i == l) \
i = 0; \
} \
} \
static inline void ADD_PADDING(fmt_state_t *st, const char *pad, size_t N) {
int n = N;
if (!pad[1]) {
ADD_CHARN(st, *pad, n);
} else {
int i, l;
l = strlen(pad);
for (i=0; --n >= 0; ) {
if (pad[i] == '\\')
i++;
ADD_CHAR(st, pad[i]);
if (++i == l)
i = 0;
}
}
}
/* Add the padding string <pad> to the buffer, repeatedly if necessary,
@ -455,7 +458,7 @@ stradd (fmt_state_t *st, sprintf_buffer_t **buffer, char *add)
/*-------------------------------------------------------------------------*/
static void
numadd (fmt_state_t *st, sprintf_buffer_t **buffer, int num)
numadd (fmt_state_t *st, sprintf_buffer_t **buffer, p_int num)
/* Add the <num>ber to the <buffer>.
*/
@ -1082,7 +1085,6 @@ add_justified ( fmt_state_t *st
*/
{
int i;
size_t sppos;
int num_words; /* Number of words in the input */
int num_chars; /* Number of non-space characters in the input */
@ -1149,7 +1151,7 @@ add_justified ( fmt_state_t *st
for (mark = pos ; pos < len && str[pos] != ' '; pos++) NOOP;
/* Add the word */
ADD_STRN(str+mark, pos - mark);
ADD_STRN(st, str+mark, pos - mark);
num_words--;
if (pos >= len || num_words < 1)
@ -1169,7 +1171,7 @@ add_justified ( fmt_state_t *st
else /* Randomly add one space */
padlength = min_spaces + (int)random_number(2);
sppos = st->bpos;
ADD_PADDING(" ", padlength);
ADD_PADDING(st, " ", padlength);
st->sppos = sppos;
num_spaces -= padlength;
@ -1189,7 +1191,6 @@ add_aligned ( fmt_state_t *st
*/
{
int i;
size_t sppos;
Bool is_space_pad;
@ -1206,10 +1207,10 @@ add_aligned ( fmt_state_t *st
case INFO_A_JUSTIFY:
case INFO_A_LEFT:
/* Also called for the last line of a justified block */
ADD_STRN(str, len)
ADD_STRN(st, str, len);
if (is_space_pad)
sppos = st->bpos;
ADD_PADDING(pad, fs - len)
ADD_PADDING(st, pad, fs - len);
if (is_space_pad)
st->sppos = sppos;
break;
@ -1217,16 +1218,16 @@ add_aligned ( fmt_state_t *st
case INFO_A_CENTRE:
if (finfo & INFO_PS_ZERO)
{
ADD_PADDING("0", (fs - len + 1) >> 1)
ADD_PADDING(st, "0", (fs - len + 1) >> 1);
}
else
{
ADD_PADDING(pad, (fs - len + 1) >> 1)
ADD_PADDING(st, pad, (fs - len + 1) >> 1);
}
ADD_STRN(str, len)
ADD_STRN(st, str, len);
if (is_space_pad)
sppos = st->bpos;
ADD_PADDING(pad, (fs - len) >> 1)
ADD_PADDING(st, pad, (fs - len) >> 1);
if (is_space_pad)
st->sppos = sppos;
break;
@ -1236,13 +1237,13 @@ add_aligned ( fmt_state_t *st
*/
if (finfo & INFO_PS_ZERO)
{
ADD_PADDING("0", fs - len)
ADD_PADDING(st, "0", fs - len);
}
else
{
ADD_PADDING(pad, fs - len)
ADD_PADDING(st, pad, fs - len);
}
ADD_STRN(str, len)
ADD_STRN(st, str, len);
}
}
} /* add_aligned() */
@ -1403,7 +1404,7 @@ add_table (fmt_state_t *st, cst **table)
for (; i < TAB->nocols; i++)
{
/* TAB->size is not negative. */
ADD_CHARN(' ', done)
ADD_CHARN(st, ' ', done);
}
}
@ -1454,7 +1455,7 @@ static char buff[BUFF_SIZE]; /* For error messages */
char format_char; /* format type */
unsigned int nelemno; /* next offset into array */
unsigned int fpos; /* position in format_str */
unsigned long fs; /* field size */
p_uint fs; /* field size */
int pres; /* precision */
unsigned int err_num; /* error code */
char *pad; /* fs pad string */
@ -1661,11 +1662,11 @@ static char buff[BUFF_SIZE]; /* For error messages */
*/
if (column_stat == 2)
ADD_CHAR('\n');
ADD_CHAR(st, '\n');
column_stat = 0;
if (!format_str[fpos])
break;
ADD_CHAR('\n');
ADD_CHAR(st, '\n');
st->line_start = st->bpos;
continue;
}
@ -1673,7 +1674,7 @@ static char buff[BUFF_SIZE]; /* For error messages */
column_stat = 0; /* If there was a newline pending, it
* will be implicitely added now.
*/
ADD_CHAR('\n');
ADD_CHAR(st, '\n');
st->line_start = st->bpos;
/* Handle pending columns and tables */
@ -1692,7 +1693,7 @@ static char buff[BUFF_SIZE]; /* For error messages */
while (*((*temp)->d.col) == ' ')
(*temp)->d.col++;
i = (*temp)->start - (st->bpos - st->line_start);
ADD_CHARN(' ', i);
ADD_CHARN(st, ' ', i);
column_stat = add_column(st, temp);
if (!column_stat)
temp = &((*temp)->next);
@ -1701,19 +1702,19 @@ static char buff[BUFF_SIZE]; /* For error messages */
{
i = (*temp)->start - (st->bpos - st->line_start);
if (i > 0)
ADD_CHARN(' ', i);
ADD_CHARN(st, ' ', i);
if (!add_table(st, temp))
temp = &((*temp)->next);
}
} /* while (*temp) */
if (st->csts || format_str[fpos] == '\n')
ADD_CHAR('\n');
ADD_CHAR(st, '\n');
st->line_start = st->bpos;
} /* while (csts) */
if (column_stat == 2 && format_str[fpos] != '\n')
ADD_CHAR('\n');
ADD_CHAR(st, '\n');
if (!format_str[fpos])
break;
@ -1726,16 +1727,16 @@ static char buff[BUFF_SIZE]; /* For error messages */
if (format_str[fpos+1] == '%')
{
ADD_CHAR('%');
ADD_CHAR(st, '%');
fpos++;
continue;
}
if (format_str[fpos+1] == '^')
{
ADD_CHAR('%');
ADD_CHAR(st, '%');
fpos++;
ADD_CHAR('^');
ADD_CHAR(st, '^');
continue;
}
@ -1797,16 +1798,16 @@ static char buff[BUFF_SIZE]; /* For error messages */
{
if (carg->type != T_NUMBER)
ERROR(ERR_INVALID_STAR);
if ((int)(fs = carg->u.number) < 0)
if ((p_int)(fs = carg->u.number) < 0)
{
#ifdef NO64BIT
if (fs == (unsigned int)PINT_MIN)
fs = PINT_MAX;
if (fs == (unsigned int)PINT_MIN)
fs = PINT_MAX;
#else
if (fs == (unsigned int)INT_MIN)
fs = INT_MAX;
if (fs == (unsigned int)INT_MIN)
fs = INT_MAX;
#endif
else
else
fs = -fs;
finfo |= INFO_A_LEFT;
}
@ -1940,7 +1941,7 @@ static char buff[BUFF_SIZE]; /* For error messages */
/* never reached... */
fprintf(stderr, "%s: (s)printf: INFO_T_NULL.... found.\n"
, get_txt(current_object->name));
ADD_CHAR('%');
ADD_CHAR(st, '%');
break;
}
@ -2197,7 +2198,7 @@ add_table_now:
}
else
{
ADD_STRN(get_txt(carg->u.str), slen)
ADD_STRN(st, get_txt(carg->u.str), slen);
}
}
break;
@ -2243,12 +2244,13 @@ add_table_now:
if ((unsigned int)tmpl < fs)
add_aligned(st, temp, tmpl, pad, fs, finfo);
else
ADD_STRN(temp, tmpl)
ADD_STRN(st, temp, tmpl);
break;
}
else
{
char cheat[6]; /* Synthesized format for sprintf() */
/* Synthesized format for sprintf() */
char cheat[6+sizeof(PRI_PINT_PREFIX)-1];
char temp[1024];
/* The buffer must be big enough to hold the biggest float
* in non-exponential representation. 1 KByte is hopefully
@ -2258,15 +2260,14 @@ add_table_now:
double value; /* The value to print */
int numdig; /* (Estimated) number of digits before the '.' */
Bool zeroCharHack = MY_FALSE;
char *p = cheat; /* pointer to the format buffer */
int tmpl;
p_uint i = 1;
*cheat = '%';
*(p++) = '%';
switch (finfo & INFO_PP)
{
case INFO_PP_SPACE: cheat[i++] = ' '; break;
case INFO_PP_PLUS: cheat[i++] = '+'; break;
case INFO_PP_SPACE: *(p++) = ' '; break;
case INFO_PP_PLUS: *(p++) = '+'; break;
}
if ((finfo & INFO_T) == INFO_T_FLOAT)
{
@ -2274,10 +2275,10 @@ add_table_now:
{
ERROR1(ERR_INCORRECT_ARG, format_char);
}
cheat[i++] = '.';
cheat[i++] = '*';
cheat[i++] = format_char;
cheat[i] = '\0';
*(p++) = '.';
*(p++) = '*';
*(p++) = format_char;
*p = '\0';
value = READ_DOUBLE(carg);
@ -2306,18 +2307,27 @@ add_table_now:
ERROR1(ERR_INCORRECT_ARG, format_char);
}
/* System sprintf() can handle ("%c", 0), but LDMud
/* System sprintf() can't handle ("%c", 0), but LDMud
* strings can. So in that case we format with
* character 0x01 and convert to 0 afterwards.
*/
if (format_char == 'c' && carg->u.number == 0)
{
if (format_char == 'c') {
if (carg->u.number == 0)
{
carg->u.number = 1;
zeroCharHack = MY_TRUE;
}
}
cheat[i++] = format_char;
cheat[i] = '\0';
/* insert the correct length modifier for a p_int
* type. (If the prefix is an empty string, this will
* be probably optimized by the compiler anyway. */
else {
p = memcpy(p, PRI_PINT_PREFIX,
strlen(PRI_PINT_PREFIX));
p += strlen(PRI_PINT_PREFIX);
}
*(p++) = format_char;
*p = '\0';
sprintf(temp, cheat, carg->u.number);
tmpl = strlen(temp);
if ((size_t)tmpl >= sizeof(temp))
@ -2349,14 +2359,14 @@ add_table_now:
* with leading zeroes: preserve the sign
* character in the right place.
*/
ADD_STRN(temp, 1);
ADD_STRN(st, temp, 1);
add_aligned(st, temp+1, tmpl-1, pad, fs-1, finfo);
}
else
add_aligned(st, temp, tmpl, pad, fs, finfo);
}
else
ADD_STRN(temp, tmpl)
ADD_STRN(st, temp, tmpl);
break;
}
default: /* type not found */
@ -2376,10 +2386,10 @@ add_table_now:
} /* if format entry */
/* Nothing to format: just copy the character */
ADD_CHAR(format_str[fpos]);
ADD_CHAR(st, format_str[fpos]);
} /* for (fpos=0; 1; fpos++) */
ADD_CHAR('\0'); /* Terminate the formatted string */
ADD_CHAR(st, '\0'); /* Terminate the formatted string */
/* Restore characters */
while (st->saves)

View File

@ -328,9 +328,9 @@ trim_all_spaces (const string_t * txt)
dest = alloca(mstrsize(txt));
if (dest == NULL)
errorf("Stack overflow (%ld bytes)\n", (long)mstrsize(txt));
errorf("Stack overflow (%zu bytes)\n", mstrsize(txt));
src = get_txt(txt);
src = get_txt((string_t *const)txt);
srclen = mstrsize(txt);
src_ix = 0;
dest_ix = 0;
@ -484,20 +484,23 @@ f_convert_charset (svalue_t *sp)
if (errno == EILSEQ)
{
errorf("convert_charset(): Invalid character sequence at index %ld\n", (long)(pIn - get_txt(in_str)));
errorf("convert_charset(): Invalid character sequence at "
"index %td\n",
(ptrdiff_t)(pIn - get_txt(in_str)));
/* NOTREACHED */
return sp;
}
if (errno == EINVAL)
{
errorf("convert_charset(): Incomplete character sequence at index %ld\n", (long)(pIn - get_txt(in_str)));
errorf("convert_charset(): Incomplete character sequence at "
"index %td\n", (ptrdiff_t)(pIn - get_txt(in_str)));
/* NOTREACHED */
return sp;
}
errorf("convert_charset(): Error %d at index %ld\n"
, errno, (long)(pIn - get_txt(in_str))
errorf("convert_charset(): Error %d at index %td\n"
, errno, (ptrdiff_t)(pIn - get_txt(in_str))
);
/* NOTREACHED */
return sp;
@ -544,20 +547,22 @@ f_convert_charset (svalue_t *sp)
if (errno == EILSEQ)
{
errorf("convert_charset(): Invalid character sequence at index %ld\n", (long)(pIn - get_txt(in_str)));
errorf("convert_charset(): Invalid character sequence at "
"index %td\n", (ptrdiff_t)(pIn - get_txt(in_str)));
/* NOTREACHED */
return sp;
}
if (errno == EINVAL)
{
errorf("convert_charset(): Incomplete character sequence at index %ld\n", (long)(pIn - get_txt(in_str)));
errorf("convert_charset(): Incomplete character sequence at "
"index %td\n", (ptrdiff_t)(pIn - get_txt(in_str)));
/* NOTREACHED */
return sp;
}
errorf("convert_charset(): Error %d at index %ld\n"
, errno, (long)(pIn - get_txt(in_str))
errorf("convert_charset(): Error %d at index %td\n"
, errno, (ptrdiff_t)(pIn - get_txt(in_str))
);
/* NOTREACHED */
return sp;
@ -611,7 +616,7 @@ sort_string (const string_t * p_in, size_t len, long ** pos)
size_t step;
size_t i, j;
in = get_txt(p_in);
in = get_txt((string_t *const)p_in);
out = xalloc(len+1);
tmp = xalloc(len+1);
if (!out || !tmp)
@ -620,8 +625,8 @@ sort_string (const string_t * p_in, size_t len, long ** pos)
xfree(out);
if (tmp)
xfree(tmp);
errorf("(sort_string) Out of memory (2 * %lu bytes) for temporaries.\n"
, (unsigned long) len+1);
errorf("(sort_string) Out of memory (2 * %zu bytes) for temporaries.\n"
, len+1);
}
out[len] = '\0';
tmp[len] = '\0';
@ -641,8 +646,8 @@ sort_string (const string_t * p_in, size_t len, long ** pos)
xfree(outpos);
if (tmppos)
xfree(tmppos);
errorf("(sort_string) Out of memory (2 * %lu bytes) for positions.\n"
, (unsigned long) len*sizeof(*outpos)+1);
errorf("(sort_string) Out of memory (2 * %zu bytes) for positions.\n"
, len*sizeof(*outpos)+1);
}
}
else
@ -828,7 +833,7 @@ intersect_strings (const string_t * p_left, const string_t * p_right, Bool bSubt
/* Create the result: copy all flagged characters */
memsafe(result = alloc_mstring(len_out), len_out, "intersection result");
left_txt = get_txt(p_left);
left_txt = get_txt((string_t *const)p_left);
result_txt = get_txt(result);
for (ix_left = 0, ix_right = 0; ix_left < len_left; ix_left++)
if (matches[ix_left])
@ -891,14 +896,6 @@ x_filter_string (svalue_t *sp, int num_arg)
str = arg->u.str;
slen = (mp_int)mstrsize(str);
flags = alloca((size_t)slen+1);
if (!flags)
{
errorf("Stack overflow in filter()");
/* NOTREACHED */
return sp;
}
/* Every element in flags is associated by index number with an
* element in the vector to filter. The filter function is evaluated
* for every string character, and the associated flag is set to 0
@ -915,11 +912,21 @@ x_filter_string (svalue_t *sp, int num_arg)
mapping_t *m;
if (num_arg > 2) {
inter_sp = sp;
errorf("Too many arguments to filter(array)\n");
}
m = arg[1].u.map;
/* Allocate memory for the flag array. Simultaneously an error
* handler is pushed onto the stack (after the arguments) for freeing
* the buffer in case of runtime errors. */
flags = xalloc_with_error_handler((size_t)slen + 1);
if (!flags)
{
errorf("Out of memory (%zu bytes) for temporary buffer in filter().\n",
(size_t)slen + 1);
}
sp = inter_sp;
m = arg[1].u.map;
for (src = get_txt(str), cnt = slen; --cnt >= 0; src++)
{
svalue_t key;
@ -934,9 +941,6 @@ x_filter_string (svalue_t *sp, int num_arg)
res++;
}
free_svalue(arg+1); /* the mapping */
sp = arg;
} else {
/* --- Filter by function call --- */
@ -946,19 +950,33 @@ x_filter_string (svalue_t *sp, int num_arg)
mp_int cnt;
assign_eval_cost();
inter_sp = sp;
/* setup_efun_callback() will adopt and therefore remove the
* arguments from arg+1 on to arg+num_arg from the stack and update
* inter_sp. New top-of-stack will be arg. */
error_index = setup_efun_callback(&cb, arg+1, num_arg-1);
if (error_index >= 0)
{
vefun_bad_arg(error_index+2, arg);
/* NOTREACHED */
return arg;
}
inter_sp = sp = arg+1;
/* push the callback structure onto the stack. */
sp = arg + 1;
put_callback(sp, &cb);
/* Allocate memory for the flag array. Simultaneously an error
* handler is pushed onto the stack (after the arguments) for freeing
* the buffer in case of runtime errors. */
inter_sp = sp;
flags = xalloc_with_error_handler((size_t)slen + 1);
if (!flags)
{
errorf("Out of memory (%"PRIdMPINT" bytes) for temporary buffer "
"in filter().\n", slen + 1);
}
sp = inter_sp;
/* Loop over all elements in p and call the filter.
* w is the current element filtered.
*/
@ -989,32 +1007,38 @@ x_filter_string (svalue_t *sp, int num_arg)
flags[cnt] = 1;
res++;
}
free_callback(&cb);
}
/* flags[] holds the filter results, res is the number of
* elements to keep. Now create the result vector.
*/
rc = alloc_mstring(res);
if (rc)
if (!rc)
{
for (src = get_txt(str), dest = get_txt(rc), flags = &flags[slen]
; res > 0 ; src++)
errorf("Out of memory (%"PRIdMPINT" bytes) for result in filter().\n",
slen+1);
}
for (src = get_txt(str), dest = get_txt(rc), flags = &flags[slen]
; res > 0 ; src++)
{
if (*--flags)
{
if (*--flags)
{
*dest++ = *src;
res--;
}
*dest++ = *src;
res--;
}
}
/* Cleanup. Arguments for the closure have already been removed. On the
* stack are now the string, the mapping or callback structure and the
* error handler. (Not using pop_n_elems() for 2 elements for saving loop
* and function call overhead.) */
free_svalue(sp--); /* errorhandler, buffer and flags are freed by this. */
free_svalue(sp--); /* mapping or callback structure. */
free_mstring(str); /* string, at arg == sp */
sp->u.str = rc; /* put result here */
/* Cleanup (everything but the string has been removed already) */
free_mstring(str);
arg->u.str = rc;
return arg;
return sp;
} /* x_filter_string() */
/*-------------------------------------------------------------------------*/
@ -1054,7 +1078,7 @@ x_map_string (svalue_t *sp, int num_arg)
arg = sp - num_arg + 1;
str = arg->u.str;
len = (mp_int)mstrsize(str);
len = mstrsize(str);
if (arg[1].type == T_MAPPING)
{
@ -1070,7 +1094,9 @@ x_map_string (svalue_t *sp, int num_arg)
res = alloc_mstring(len);
if (!res)
errorf("(map_string) Out of memory: string[%ld] for result\n", len);
errorf("(map_string) Out of memory: string[%"PRIdMPINT
"] for result\n", len);
push_string(inter_sp, res); /* In case of errors */
for (src = get_txt(str), dest = get_txt(res); --len >= 0; src++, dest++)
@ -1116,7 +1142,9 @@ x_map_string (svalue_t *sp, int num_arg)
res = alloc_mstring(len);
if (!res)
errorf("(map_string) Out of memory: string[%ld] for result\n", len);
errorf("(map_string) Out of memory: string[%"PRIdMPINT
"] for result\n", len);
push_string(inter_sp, res); /* In case of errors */
for (src = get_txt(str), dest = get_txt(res); --len >= 0; src++, dest++)

View File

@ -25,7 +25,8 @@ extern void strbuf_free(strbuf_t * buf);
extern void strbuf_add(strbuf_t *buf, const char * text);
extern void strbuf_addn(strbuf_t *buf, const char * text, size_t len);
extern void strbuf_addc(strbuf_t *buf, const char ch);
extern void strbuf_addf(strbuf_t *buf, const char *format, ...);
extern void strbuf_addf(strbuf_t *buf, const char *format, ...)
FORMATDEBUG(printf,2,3);
extern void strbuf_send(strbuf_t *buf);
extern void strbuf_store(strbuf_t *buf, svalue_t *svp);
extern void strbuf_copy (strbuf_t *buf, char *cbuf);

View File

@ -15,7 +15,7 @@ ANONYMOUS "anonymous"
ATAT "@@"
CALL_OTHER "call_other"
CATCH "CATCH"
CL_OBJ_DESTR "Object the closure was bound to has been destructed"
DANGLING_LAMBDA "Dangling function call in lambda closure"
CRPATTERN "\015$"
DANGLING_V_CL "dangling var closure"
DEFAULT_PROMPT "> "
@ -233,6 +233,7 @@ SUCCESS "success"
#ifdef USE_SQLITE
SQLITE_OPEN "sl_open"
SQLITE_PRAGMA "sqlite_pragma"
#endif
#ifdef USE_EXPAT

View File

@ -309,10 +309,10 @@ add_type (struct_type_t * pSType)
#ifdef DEBUG
if (find_by_type(pSType))
fatal("struct type %s (%s %ld) already in table.\n"
fatal("struct type %s (%s %"PRId32") already in table.\n"
, get_txt(struct_t_name(pSType))
, get_txt(struct_t_pname(pSType))
, (long)struct_t_pid(pSType)
, struct_t_pid(pSType)
);
#endif
@ -773,8 +773,8 @@ struct_new_anonymous (int num_members)
pType->member[i].name = new_tabled(buf);
if (!pType->member[i].name)
{
debug_message("(%s:%d) Out of memory (%lu bytes) for member name\n"
, __FILE__, __LINE__, (unsigned long)strlen(buf)
debug_message("(%s:%d) Out of memory (%zu bytes) for member name\n"
, __FILE__, __LINE__, strlen(buf)
);
gotError = MY_TRUE;
break;
@ -839,7 +839,7 @@ struct_free (struct_t *pStruct)
fatal("No wizlist pointer for struct in struct_free().");
if (pStruct->ref != 0)
fatal("Struct with %ld refs passed to struct_free().\n"
fatal("Struct with %"PRIdPINT" refs passed to struct_free().\n"
, pStruct->ref);
#endif
@ -868,7 +868,7 @@ struct_free_type (struct_type_t *pSType)
fatal("NULL pointer passed to struct_free_type().\n");
if (pSType->ref != 0)
fatal("struct typeobject with %ld refs passed to struct_free_type().\n"
fatal("struct typeobject with %"PRIdPINT" refs passed to struct_free_type().\n"
, pSType->ref);
#endif
@ -982,7 +982,8 @@ total_struct_size (strbuf_t *sbuf, Bool verbose)
{
if (!verbose)
{
strbuf_addf(sbuf, "Structs:\t\t\t%8ld %9ld (%ld types: %ld)\n"
strbuf_addf(sbuf, "Structs:\t\t\t%8"PRIdMPINT" %9"PRIdMPINT
" (%"PRIdMPINT" types: %"PRIdMPINT")\n"
, num_struct, size_struct
, num_struct_type, size_struct_type
);
@ -1034,10 +1035,10 @@ struct_t_unique_name (struct_type_t *pSType)
if (pSType->unique_name)
return pSType->unique_name;
sprintf(name, "%s %s #%ld"
snprintf(name, sizeof(name), "%s %s #%"PRId32
, get_txt(struct_t_name(pSType))
, get_txt(struct_t_pname(pSType))
, (long)struct_t_pid(pSType)
, struct_t_pid(pSType)
);
pSType->unique_name = new_mstring(name);
@ -1331,7 +1332,7 @@ x_map_struct (svalue_t *sp, int num_arg)
res = struct_new(st->type);
if (!res)
errorf("(map_struct) Out of memory: struct[%ld] for result\n", cnt);
errorf("(map_struct) Out of memory: struct[%"PRIdMPINT"] for result\n", cnt);
push_struct(inter_sp, res); /* In case of errors */
for (w = st->member, x = res->member; --cnt >= 0; w++, x++)
@ -1369,7 +1370,7 @@ x_map_struct (svalue_t *sp, int num_arg)
res = struct_new(st->type);
if (!res)
errorf("(map_struct) Out of memory: struct[%ld] for result\n", cnt);
errorf("(map_struct) Out of memory: struct[%"PRIdMPINT"] for result\n", cnt);
push_struct(inter_sp, res); /* In case of errors */
/* Loop through arr and res, mapping the values from arr */
@ -1547,7 +1548,7 @@ f_struct_info (svalue_t *sp)
}
default:
free_svalue(&result);
errorf("Bad arg 2 to struct_info(): illegal value %ld\n"
errorf("Bad arg 2 to struct_info(): illegal value %"PRIdPINT"\n"
, sp->u.number);
/* NOTREACHED */
return sp;

View File

@ -612,8 +612,8 @@ store_swap_block (void * buffer, mp_int size)
/* Seek and write the data */
if (fseek(swap_file, offset, 0) == -1)
{
debug_message("%s Couldn't seek the swap file, errno %d, offset %ld.\n"
, time_stamp(), errno, offset);
debug_message("%s Couldn't seek the swap file, errno %d, "
"offset %"PRIdMPINT".\n", time_stamp(), errno, offset);
return -1;
}
@ -664,8 +664,8 @@ store_swap_block2 ( void * buffer1, mp_int size1
/* Seek and write the data */
if (fseek(swap_file, offset, 0) == -1)
{
debug_message("%s Couldn't seek the swap file, errno %d, offset %ld.\n"
, time_stamp(), errno, offset);
debug_message("%s Couldn't seek the swap file, errno %d, "
"offset %"PRIdMPINT".\n", time_stamp(), errno, offset);
return -1;
}
@ -700,8 +700,9 @@ swap_program (object_t *ob)
if (d_flag > 1)
{
debug_message("%s Swap object %s (obj ref %ld, prog ref %ld)\n"
, time_stamp(), get_txt(ob->name), ob->ref, ob->prog->ref);
debug_message("%s Swap object %s (obj ref %"PRIdPINT
", prog ref %"PRIdPINT")\n",
time_stamp(), get_txt(ob->name), ob->ref, ob->prog->ref);
}
prog = ob->prog;
@ -1135,10 +1136,10 @@ check_swapped_values (mp_int num, unsigned char * p)
if (start + swapsize != p) \
{ \
fprintf(stderr \
, "--- Incorrect swapsize on check: expected %lu bytes, " \
"read %lu (%p .. %p)\n" \
, (unsigned long)swapsize \
, (unsigned long)(p - start), start, p \
, "--- Incorrect swapsize on check: expected %zu bytes, " \
"read %zu (%p .. %p)\n" \
, swapsize \
, (size_t)(p - start), start, p \
); \
return NULL; \
}
@ -1284,11 +1285,11 @@ dump_swapped_values (mp_int num, unsigned char * p, int indent)
if (start + swapsize != p) \
{ \
fprintf(stderr \
, "%.*s--- Incorrect swapsize: expected %lu bytes, " \
"read %lu (%p .. %p)\n" \
, "%.*s--- Incorrect swapsize: expected %zu bytes, " \
"read %zu (%p .. %p)\n" \
, indent, " " \
, (unsigned long)swapsize \
, (unsigned long)(p - start), start, p \
, swapsize \
, (size_t)(p - start), start, p \
); \
}
@ -1299,9 +1300,9 @@ dump_swapped_values (mp_int num, unsigned char * p, int indent)
sv.type = *p & ~T_MOD_SWAPPED; /* get the original type */
fprintf(stderr, "%.*s%08lx (%6ld) [%3ld]: type %d"
fprintf(stderr, "%.*s%16p (%6zu) [%3"PRIdMPINT"]: type %d"
, indent, " "
, (unsigned long)p, (unsigned long)(p - block)
, p, (size_t)(p - block)
, max_num - num - 1
, sv.type
);
@ -1338,7 +1339,7 @@ dump_swapped_values (mp_int num, unsigned char * p, int indent)
p += sizeof size;
memcpy(&user, p, sizeof user);
p += sizeof user;
fprintf(stderr, " array: %ld values\n", (long)size);
fprintf(stderr, " array: %zu values\n", size);
p = dump_swapped_values(size, p, indent+2);
if (!p)
return NULL;
@ -1380,8 +1381,8 @@ dump_swapped_values (mp_int num, unsigned char * p, int indent)
p += sizeof num_keys;
memcpy(&user, p, sizeof user);
p += sizeof user;
fprintf(stderr, " mapping: %ld keys, %ld values\n"
, (long)num_keys, (long)num_values);
fprintf(stderr, " mapping: %"PRIdPINT" keys, %"PRIdPINT" values\n"
, num_keys, num_values);
p = dump_swapped_values(num_keys*(1+num_values), p, indent+2);
if (!p)
return NULL;
@ -1473,9 +1474,9 @@ free_swapped_svalues (svalue_t *svp, mp_int num, unsigned char *p)
if (start + swapsize != p) \
{ \
dump_swapped_values(max_num, block, 0); \
fatal("svalue type %d: expected %lu bytes, read %lu (%p .. %p)\n" \
, (int)svp->type, (unsigned long)swapsize \
, (unsigned long)(p - start), start, p \
fatal("svalue type %d: expected %zu bytes, read %zu (%p .. %p)\n" \
, (int)svp->type, swapsize \
, (size_t)(p - start), start, p \
); \
}
@ -1654,8 +1655,9 @@ swap_variables (object_t *ob)
if (fseek(swap_file, last_variable_swap_num + sizeof(p_int), 0) ==
-1)
{
fatal("Couldn't seek the swap file, errno %d, offset %ld.\n",
errno, last_variable_swap_num + sizeof(p_int));
fatal("Couldn't seek the swap file, errno %d, offset %"
PRIdMPINT".\n",
errno, last_variable_swap_num + sizeof(p_int));
}
if (fwrite(
last_variable_block,
@ -1673,12 +1675,14 @@ swap_variables (object_t *ob)
#ifdef CHECK_OBJECT_STAT
if (check_object_stat)
{
fprintf(stderr, "DEBUG: OSTAT: (%ld:%ld) swapout( %p '%s') gc %d vars : %ld -> (%ld:%ld)\n"
, tot_alloc_object, tot_alloc_object_size, ob, ob->name ? get_txt(ob->name) : "<null>"
, num_variables
, (long)(num_variables * sizeof (svalue_t))
, tot_alloc_object, tot_alloc_object_size - (num_variables * sizeof (svalue_t))
);
fprintf(stderr, "DEBUG: OSTAT: (%ld:%ld) swapout( %p '%s') gc %d "
"vars : %ld -> (%ld:%ld)\n",
tot_alloc_object, tot_alloc_object_size, ob,
ob->name ? get_txt(ob->name) : "<null>",
num_variables, (long)(num_variables * sizeof (svalue_t)),
tot_alloc_object,
tot_alloc_object_size - (num_variables * sizeof (svalue_t))
);
}
#endif
tot_alloc_object_size -= num_variables * sizeof (svalue_t);
@ -1697,8 +1701,8 @@ swap_variables (object_t *ob)
if (swapfile_size <= swap_num)
fatal("Attempt to swap in from beyond the end of the swapfile.\n");
if (fseek(swap_file, swap_num, 0) == -1)
fatal("Couldn't seek the swap file, errno %d, offset %ld.\n",
errno, swap_num);
fatal("Couldn't seek the swap file, errno %d, offset %"
PRIdPINT".\n", errno, swap_num);
if (fread(&num_variables, sizeof num_variables, 1, swap_file)
!= 1)
{
@ -1755,12 +1759,14 @@ swap_variables (object_t *ob)
#ifdef CHECK_OBJECT_STAT
if (check_object_stat)
{
fprintf(stderr, "DEBUG: OSTAT: (%ld:%ld) swapout( %p '%s') %d vars : %ld -> (%ld:%ld)\n"
, tot_alloc_object, tot_alloc_object_size, ob, ob->name ? get_txt(ob->name) : "<null>"
, num_variables
, (long)(num_variables * sizeof (svalue_t))
, tot_alloc_object, tot_alloc_object_size - (num_variables * sizeof (svalue_t))
);
fprintf(stderr, "DEBUG: OSTAT: (%ld:%ld) swapout( %p '%s') %d "
"vars : %ld -> (%ld:%ld)\n",
tot_alloc_object, tot_alloc_object_size, ob,
ob->name ? get_txt(ob->name) : "<null>",
num_variables, (long)(num_variables * sizeof (svalue_t)),
tot_alloc_object,
tot_alloc_object_size - (num_variables * sizeof (svalue_t))
);
}
#endif
tot_alloc_object_size -= num_variables * sizeof (svalue_t);
@ -1847,9 +1853,9 @@ read_unswapped_svalues (svalue_t *svp, mp_int num, unsigned char *p)
if (start + swapsize != p) \
{ \
dump_swapped_values(max_num, block, 0); \
fatal("svalue type %d: expected %lu bytes, read %lu (%p .. %p)\n" \
, (int)svp->type, (unsigned long)swapsize \
, (unsigned long)(p - start), start, p \
fatal("svalue type %d: expected %zu bytes, read %zu (%p .. %p)\n" \
, (int)svp->type, swapsize \
, (size_t)(p - start), start, p \
); \
}
@ -2161,12 +2167,12 @@ load_ob_from_swap (object_t *ob)
if (swapfile_size <= swap_num)
fatal("Attempt to swap in from beyond the end of the swapfile.\n");
if (fseek(swap_file, swap_num, 0) == -1)
fatal("Couldn't seek the swap file, errno %d, offset %ld.\n",
errno, swap_num);
fatal("Couldn't seek the swap file, errno %d, offset %"
PRIdPINT".\n", errno, swap_num);
if (d_flag > 1)
{
debug_message("%s Unswap object %s (ref %ld)\n", time_stamp()
, get_txt(ob->name), ob->ref);
debug_message("%s Unswap object %s (ref %"PRIdPINT")\n",
time_stamp(), get_txt(ob->name), ob->ref);
}
/* The size of the program is unkown, so read first part to
@ -2226,8 +2232,8 @@ load_ob_from_swap (object_t *ob)
if (swapfile_size <= swap_num)
fatal("Attempt to swap in from beyond the end of the swapfile.\n");
if (fseek(swap_file, swap_num, 0) == -1)
fatal("Couldn't seek the swap file, errno %d, offset %ld.\n",
errno, swap_num);
fatal("Couldn't seek the swap file, errno %d, offset %"
PRIdPINT".\n", errno, swap_num);
if (d_flag > 1)
{
debug_message("%s Unswap variables of %s\n", time_stamp()
@ -2272,12 +2278,15 @@ load_ob_from_swap (object_t *ob)
#ifdef CHECK_OBJECT_STAT
if (check_object_stat)
{
fprintf(stderr, "DEBUG: OSTAT: (%ld:%ld) swapin( %p '%s') %d vars : %ld -> (%ld:%ld)\n"
, tot_alloc_object, tot_alloc_object_size, ob, ob->name ? get_txt(ob->name) : "<null>"
, ob->prog->num_variables
, (long)(ob->prog->num_variables * sizeof (svalue_t))
, tot_alloc_object, tot_alloc_object_size + (ob->prog->num_variables * sizeof (svalue_t))
);
fprintf(stderr, "DEBUG: OSTAT: (%ld:%ld) swapin( %p '%s') %d "
"vars : %ld -> (%ld:%ld)\n",
tot_alloc_object, tot_alloc_object_size, ob,
ob->name ? get_txt(ob->name) : "<null>",
ob->prog->num_variables,
(long)(ob->prog->num_variables * sizeof (svalue_t)),
tot_alloc_object, tot_alloc_object_size +
(ob->prog->num_variables * sizeof (svalue_t))
);
}
#endif
tot_alloc_object_size += ob->prog->num_variables * sizeof (svalue_t);
@ -2306,10 +2315,11 @@ load_ob_from_swap (object_t *ob)
#ifdef CHECK_OBJECT_STAT
if (check_object_stat)
{
fprintf(stderr, "DEBUG: OSTAT: (%ld:%ld) swapin( %p '%s') %d vars failed\n"
, tot_alloc_object, tot_alloc_object_size, ob, ob->name ? get_txt(ob->name) : "<null>"
, ob->prog->num_variables
);
fprintf(stderr, "DEBUG: OSTAT: (%ld:%ld) swapin( %p '%s') %d "
"vars failed\n",
tot_alloc_object, tot_alloc_object_size, ob,
ob->name ? get_txt(ob->name) : "<null>",
ob->prog->num_variables);
}
#endif
@ -2348,8 +2358,8 @@ load_line_numbers_from_swap (program_t *prog)
if (swapfile_size <= swap_num)
fatal("Attempt to swap in from beyond the end of the swapfile.\n");
if (fseek(swap_file, swap_num, 0) == -1)
fatal("Couldn't seek the swap file, errno %d, offset %ld.\n",
errno, swap_num);
fatal("Couldn't seek the swap file, errno %d, offset %"
PRIdPINT".\n", errno, swap_num);
if (fread((char *)&tmp_numbers, sizeof tmp_numbers, 1, swap_file) != 1) {
fatal("Couldn't read the swap file.\n");
}
@ -2410,8 +2420,8 @@ remove_prog_swap (program_t *prog, Bool load_line_numbers)
linenumbers_t tmp_lines;
if (fseek(swap_file, swap_num + prog->total_size, 0 ) == -1)
fatal("Couldn't seek the swap file, errno %d, offset %ld.\n",
errno, swap_num);
fatal("Couldn't seek the swap file, errno %d, offset %"
PRIdPINT".\n", errno, swap_num);
if (fread(&tmp_lines, sizeof tmp_lines, 1, swap_file) != 1)
{
fatal("Couldn't read the swap file.\n");
@ -2482,12 +2492,12 @@ swap_status (strbuf_t *sbuf)
*/
{
/* maximum seen so far: 10664 var blocks swapped, 5246112 bytes */
strbuf_addf(sbuf, "%6ld prog blocks swapped,%10ld bytes\n"
"%6ld prog blocks unswapped,%8ld bytes\n"
"%6ld var blocks swapped,%11ld bytes\n"
"%6ld free blocks in swap,%10ld bytes\n"
"Swapfile size:%23ld bytes\n"
/* maximum seen so far: 28574 var blocks swapped, 32754860 bytes */
strbuf_addf(sbuf, "%10"PRIdMPINT" prog blocks swapped, %13"PRIdMPINT" bytes\n"
"%10"PRIdMPINT" prog blocks unswapped,%12"PRIdMPINT" bytes\n"
"%10"PRIdMPINT" var blocks swapped,%15"PRIdMPINT" bytes\n"
"%10"PRIdMPINT" free blocks in swap,%14"PRIdMPINT" bytes\n"
"Swapfile size:%31"PRIdMPINT" bytes\n"
, num_swapped - num_unswapped
, total_bytes_swapped - total_bytes_unswapped
, num_unswapped, total_bytes_unswapped
@ -2495,11 +2505,11 @@ swap_status (strbuf_t *sbuf)
, num_swapfree, total_bytes_swapfree
, swapfile_size
);
strbuf_addf(sbuf, "Total reused space:%18ld bytes\n\n"
strbuf_addf(sbuf, "Total reused space:%26"PRIdMPINT" bytes\n\n"
, total_swap_reused);
strbuf_addf(sbuf
, "Swap: searches: %5ld average search length: %3.1f\n"
"Free: searches: %5ld average search length: %3.1f\n"
, "Swap: searches: %10ld average search length: %3.1f\n"
"Free: searches: %10ld average search length: %3.1f\n"
, swap_num_searches
, (double)swap_total_searchlength /
( swap_num_searches ? swap_num_searches : 1 )
@ -2507,9 +2517,9 @@ swap_status (strbuf_t *sbuf)
, (double)swap_free_searchlength /
( swap_free_searches ? swap_free_searches : 1 )
);
strbuf_addf(sbuf, "Overhead: %ld blocks using %ld bytes.\n"
, num_swap_structs, num_swap_structs * sizeof(swap_block_t)
);
strbuf_addf(sbuf, "Overhead: %"PRIdMPINT" blocks using %"
PRIdMPINT" bytes.\n",
num_swap_structs, num_swap_structs * sizeof(swap_block_t) );
strbuf_addf(sbuf, "Mode: %s - Freespace recycling: %s\n"
, swap_compact_mode ? "compact" : "non-compact"
, (recycle_free_space || !swap_compact_mode) ? "on" : "off"

64
src/util/indent/Makefile Normal file
View File

@ -0,0 +1,64 @@
# Makefile.in for indent
# Based on the original Makefile.
#
# Copyright (c) 1987 Regents of the University of California.
# All rights reserved.
#
# Redistribution and use in source and binary forms are permitted
# provided that the above copyright notice and this paragraph are
# duplicated in all such forms and that any documentation,
# advertising materials, and other materials related to such
# distribution and use acknowledge that the software was developed
# by the University of California, Berkeley. The name of the
# University may not be used to endorse or promote products derived
# from this software without specific prior written permission.
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# The placeholders filled in by configure
MAKE=make
SHELL=/bin/sh
INSTALL=/usr/bin/install -c
mkinstalldirs=$(SHELL) ../../mkinstalldirs
CC=gcc -std=gnu99
prefix=/opt/psyced
exec_prefix=${prefix}
SUBDIRS =
SED = sed
BINDIR=/opt/psyced/bin
MUD_LIB=/opt/psyced/world
ERQ_DIR=/opt/psyced/run
# ---------------------------------------------------------
CFLAGS= -g
SRCS= indent.c io.c lexi.c parse.c pr_comment.c args.c globs.c
OBJS= indent.o io.o lexi.o parse.o pr_comment.o args.o globs.o
HEADERS= indent_globs.h version.h
MAN= indent.texinfo ChangeLog Projects
all: indent
indent: ${OBJS} ${LIBC}
${CC} -o $@ ${LDFLAGS} ${OBJS}
indent.tar.Z: ${SRCS} Makefile ${MAN} ${HEADERS}
tar -c -z -f indent.tar.Z ${SRCS} Makefile ${MAN} ${HEADERS}
${OBJS}: indent_globs.h
args.o: version.h
clean:
rm -f ${OBJS} core indent
install: indent
cp $? ${BINDIR}
# $(INSTALL) -c -s $? $(BINDIR)

View File

@ -0,0 +1,64 @@
# Makefile.in for indent
# Based on the original Makefile.
#
# Copyright (c) 1987 Regents of the University of California.
# All rights reserved.
#
# Redistribution and use in source and binary forms are permitted
# provided that the above copyright notice and this paragraph are
# duplicated in all such forms and that any documentation,
# advertising materials, and other materials related to such
# distribution and use acknowledge that the software was developed
# by the University of California, Berkeley. The name of the
# University may not be used to endorse or promote products derived
# from this software without specific prior written permission.
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# The placeholders filled in by configure
MAKE=make
SHELL=@CONFIG_SHELL@
INSTALL=@INSTALL@
mkinstalldirs=$(SHELL) @top_srcdir@/mkinstalldirs
CC=@CC@
prefix=@prefix@
exec_prefix=@exec_prefix@
SUBDIRS =
SED = sed
BINDIR=@bindir@
MUD_LIB=@libdir@
ERQ_DIR=@libexecdir@
# ---------------------------------------------------------
CFLAGS= -g
SRCS= indent.c io.c lexi.c parse.c pr_comment.c args.c globs.c
OBJS= indent.o io.o lexi.o parse.o pr_comment.o args.o globs.o
HEADERS= indent_globs.h version.h
MAN= indent.texinfo ChangeLog Projects
all: indent
indent: ${OBJS} ${LIBC}
${CC} -o $@ ${LDFLAGS} ${OBJS}
indent.tar.Z: ${SRCS} Makefile ${MAN} ${HEADERS}
tar -c -z -f indent.tar.Z ${SRCS} Makefile ${MAN} ${HEADERS}
${OBJS}: indent_globs.h
args.o: version.h
clean:
rm -f ${OBJS} core indent
install: indent
cp $? ${BINDIR}
# $(INSTALL) -c -s $? $(BINDIR)

24
src/util/indent/Projects Normal file
View File

@ -0,0 +1,24 @@
Make it so that the line numbers indent reports are the real line
numbers (currently it is often off by a few).
Error recover should probably be enhanced. At a minimum, "indent
foo.c" should not overwrite foo.c when it gets an error. Fancy error
recover is probably not worth the effort because indent is pretty
fast. Stopping after the first error might be more helpful than the
current error cascades.
Also, there is a bug in that indent flags the following as illegal:
enum bar { a = 1, b = 2 };
Make the -nss option cause
while (foo)
;
This is the real alternative to
while (foo) ;
Look at all the undocumented options, and determine which of them are
bug-free enough that they should be documented.
Look at termcap interface from Berkeley (and other recent enhancements
not in 4.3-tahoe) and see whether it is worth merging those changes
into our indent or our indent into Berkeley's.

416
src/util/indent/args.c Normal file
View File

@ -0,0 +1,416 @@
/*
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980 The Regents of the University of California.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley, the University of Illinois,
* Urbana, and Sun Microsystems, Inc. The name of either University
* or Sun Microsystems may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static char sccsid[] = "@(#)args.c 5.6 (Berkeley) 9/15/88";
#endif /* not lint */
/*
* Argument scanning and profile reading code. Default parameters are set
* here as well.
*/
#include "indent_globs.h"
#include <ctype.h>
#include "version.h"
int else_endif_col;
extern char *in_name;
char *getenv();
/* profile types */
enum profile {PRO_BOOL, /* boolean */
PRO_INT, /* integer */
PRO_FONT, /* troff font */
PRO_IGN, /* ignore it */
PRO_STDIN, /* -st switch */
PRO_KEY, /* -T switch */
PRO_SETTINGS, /* bundled set of settings */
PRO_PRSTRING /* Print string and exit */
};
/* profile specials for booleans */
enum on_or_off {OFF,ON};
/* Explicit flags for each option. */
static int exp_T = 0;
static int exp_bacc = 0;
static int exp_badp = 0;
static int exp_bad = 0;
static int exp_bap = 0;
static int exp_bbb = 0;
static int exp_bc = 0;
static int exp_bli = 0;
static int exp_bl = 0;
static int exp_bs = 0;
static int exp_cdb = 0;
static int exp_cd = 0;
static int exp_ce = 0;
static int exp_ci = 0;
static int exp_cli = 0;
static int exp_cp = 0;
static int exp_c = 0;
static int exp_di = 0;
static int exp_dj = 0;
static int exp_d = 0;
static int exp_eei = 0;
static int exp_ei = 0;
static int exp_fbc = 0;
static int exp_fbx = 0;
static int exp_fb = 0;
static int exp_fc1 = 0;
static int exp_fca = 0;
static int exp_fc = 0;
static int exp_fk = 0;
static int exp_fs = 0;
static int exp_gnu = 0;
static int exp_ip = 0;
static int exp_i = 0;
static int exp_lc = 0;
static int exp_lp = 0;
static int exp_l = 0;
static int exp_pcs = 0;
static int exp_psl = 0;
static int exp_pro = 0;
static int exp_ps = 0;
static int exp_kr = 0;
static int exp_sc = 0;
static int exp_sob = 0;
static int exp_ss = 0;
static int exp_st = 0;
static int exp_troff = 0;
static int exp_v = 0;
static int exp_version = 0;
static int exp_lpc = 0;
/* The following variables are controlled by command line parameters and
their meaning is explained in indent_globs.h. */
int leave_comma;
int decl_com_ind;
int case_indent;
int com_ind;
int decl_indent;
int ljust_decl;
int unindent_displace;
int else_if;
int indent_parameters;
int ind_size;
int blanklines_after_procs;
int lpc;
int noarrowspace;
/*
* N.B.: because of the way the table here is scanned, options whose names are
* substrings of other options must occur later; that is, with -lp vs -l, -lp
* must be first. Also, while (most) booleans occur more than once, the last
* default value is the one actually assigned.
*/
struct pro {
char *p_name; /* name, eg -bl, -cli */
enum profile p_type;
int p_default; /* the default value (if int) */
/* If p_type == PRO_BOOL, ON or OFF to tell how this switch affects
the variable.
Not used for other p_type's. */
enum on_or_off p_special;
/* if p_type == PRO_SETTINGS, a (char *) pointing to a list of the
switches to set, separated by NULs, terminated by 2 NULs.
if p_type == PRO_BOOL, PRO_INT, or PRO_FONT, address of the
variable that gets set by the option.
if p_type == PRO_PRSTRING, a (char *) pointing to the string. */
int *p_obj;
/* Points to a nonzero value (allocated statically for all options)
if the option has been specified explicitly. This is necessary
because for boolean options, the options to set and reset the
variable must share the explicit flag. */
int* p_explicit;
};
struct pro pro[] = {
{"T", PRO_KEY, 0, 0, 0, &exp_T},
{"bacc", PRO_BOOL, false, ON,
&blanklines_around_conditional_compilation, &exp_bacc},
{"badp", PRO_BOOL, false, ON,
&blanklines_after_declarations_at_proctop, &exp_badp},
{"bad", PRO_BOOL, false, ON, &blanklines_after_declarations, &exp_bad},
{"bap", PRO_BOOL, false, ON, &blanklines_after_procs, &exp_bap},
{"bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments, &exp_bbb},
{"bc", PRO_BOOL, true, OFF, &leave_comma, &exp_bc},
{"bli", PRO_INT, 0, 0, &brace_indent, &exp_bli},
{"bl", PRO_BOOL, true, OFF, &btype_2, &exp_bl},
{"br", PRO_BOOL, true, ON, &btype_2, &exp_bl},
{"bs", PRO_BOOL, false, ON, &Bill_Shannon, &exp_bs},
{"cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline, &exp_cdb},
{"cd", PRO_INT, 0, 0, &decl_com_ind, &exp_cd},
{"ce", PRO_BOOL, true, ON, &cuddle_else, &exp_ce},
{"ci", PRO_INT, 0, 0, &continuation_indent, &exp_ci},
{"cli", PRO_INT, 0, 0, &case_indent, &exp_cli},
{"cp", PRO_INT, 33, 0, &else_endif_col, &exp_cp},
{"c", PRO_INT, 33, 0, &com_ind, &exp_c},
{"di", PRO_INT, 16, 0, &decl_indent, &exp_di},
{"dj", PRO_BOOL, false, ON, &ljust_decl, &exp_dj},
{"d", PRO_INT, 0, 0, &unindent_displace, &exp_d},
{"eei", PRO_BOOL, false, ON, &extra_expression_indent, &exp_eei},
{"ei", PRO_BOOL, true, ON, &else_if, &exp_ei},
{"fbc", PRO_FONT, 0, 0, (int *) &blkcomf, &exp_fbc},
{"fbx", PRO_FONT, 0, 0, (int *) &boxcomf, &exp_fbx},
{"fb", PRO_FONT, 0, 0, (int *) &bodyf, &exp_fb},
{"fc1", PRO_BOOL, true, ON, &format_col1_comments, &exp_fc1},
{"fca", PRO_BOOL, true, ON, &format_comments, &exp_fca},
{"fc", PRO_FONT, 0, 0, (int *) &scomf, &exp_fc},
{"fk", PRO_FONT, 0, 0, (int *) &keywordf, &exp_fk},
{"fs", PRO_FONT, 0, 0, (int *) &stringf, &exp_fs},
{"gnu", PRO_SETTINGS, 0, 0,
(int *)"-nbad\0-bap\0-nbbb\0-nbc\0-bl\0-ncdb\0-nce\0-di0\0-ndj\0\
-ei\0-nfc1\0-i2\0-ip5\0-lp\0-pcs\0-nps\0-psl\0-nsc\0-nsob\0-bli2\0-ss\0\
-cp1\0-nfca\0", &exp_gnu},
{"ip", PRO_INT, 4, ON, &indent_parameters, &exp_ip},
{"i", PRO_INT, 4, 0, &ind_size, &exp_i},
{"kr", PRO_SETTINGS, 0, 0,
(int *)"-nbad\0-bap\0-nbbb\0-nbc\0-br\0-c33\0-cd33\0-ncdb\0-ce\0\
-ci4\0-cli0\0-d0\0-di1\0-nfc1\0-i4\0-ip0\0-l75\0-lp\0-npcs\0-npsl\0\
-nsc\0-nsc\0-nsob\0-nfca\0-cp33\0-nss\0", &exp_kr},
{"lpc", PRO_BOOL, false, ON, &lpc, &exp_lpc},
{"lc", PRO_INT, 0, 0, &block_comment_max_col, &exp_lc},
{"lp", PRO_BOOL, true, ON, &lineup_to_parens, &exp_lp},
{"l", PRO_INT, 78, 0, &max_col, &exp_l},
{"nbacc", PRO_BOOL, false, ON,
&blanklines_around_conditional_compilation, &exp_bacc},
{"nbadp", PRO_BOOL, false, OFF,
&blanklines_after_declarations_at_proctop, &exp_badp},
{"nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations, &exp_bad},
{"nbap", PRO_BOOL, false, OFF, &blanklines_after_procs, &exp_bap},
{"nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments, &exp_bbb},
{"nbc", PRO_BOOL, true, ON, &leave_comma, &exp_bc},
{"nbs", PRO_BOOL, false, OFF, &Bill_Shannon, &exp_bs},
{"ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline, &exp_cdb},
{"nce", PRO_BOOL, true, OFF, &cuddle_else, &exp_ce},
{"ndj", PRO_BOOL, false, OFF, &ljust_decl, &exp_dj},
{"neei", PRO_BOOL, false, OFF, &extra_expression_indent, &exp_eei},
{"nei", PRO_BOOL, true, OFF, &else_if, &exp_ei},
{"nfc1", PRO_BOOL, true, OFF, &format_col1_comments, &exp_fc1},
{"nfca", PRO_BOOL, true, OFF, &format_comments, &exp_fca},
{"nlp", PRO_BOOL, true, OFF, &lineup_to_parens, &exp_lp},
{"npcs", PRO_BOOL, false, OFF, &proc_calls_space, &exp_pcs},
{"npro", PRO_IGN, 0, 0, 0, &exp_pro},
{"npsl", PRO_BOOL, true, OFF, &procnames_start_line, &exp_psl},
{"nps", PRO_BOOL, false, OFF, &pointer_as_binop, &exp_ps},
{"nsc", PRO_BOOL, true, OFF, &star_comment_cont, &exp_sc},
{"nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines, &exp_sob},
{"nss", PRO_BOOL, false, OFF, &space_sp_semicolon, &exp_ss},
{"nv", PRO_BOOL, false, OFF, &verbose, &exp_v},
{"pcs", PRO_BOOL, false, ON, &proc_calls_space, &exp_pcs},
{"psl", PRO_BOOL, true, ON, &procnames_start_line, &exp_psl},
{"ps", PRO_BOOL, false, ON, &pointer_as_binop, &exp_ps},
{"sc", PRO_BOOL, true, ON, &star_comment_cont, &exp_sc},
{"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines, &exp_sob},
{"ss", PRO_BOOL, false, ON, &space_sp_semicolon, &exp_ss},
{"st", PRO_STDIN, 0, 0, 0, &exp_st},
{"troff", PRO_BOOL, false, ON, &troff, &exp_troff},
{"version", PRO_PRSTRING, 0, 0, (int *)VERSION_STRING, &exp_version},
{"v", PRO_BOOL, false, ON, &verbose, &exp_v},
/* Signify end of structure. */
{0, 0, 0, 0, 0, 0}
};
/*
* set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments
* given in these files.
*/
set_profile()
{
register FILE *f;
char *fname;
#ifndef MSDOS
static char prof[] = ".indent.pro";
#else
static char prof[] = "indent.pro";
#endif
char *homedir;
homedir = getenv("HOME");
fname = xmalloc(strlen(homedir) + 10 + sizeof prof);
sprintf(fname, "%s/%s", homedir, prof);
if ((f = fopen(prof, "r")) != NULL) {
scan_profile(f);
(void) fclose(f);
}
if ((f = fopen(fname, "r")) != NULL) {
scan_profile(f);
(void) fclose(f);
}
free (fname);
}
scan_profile(f)
register FILE *f;
{
register int i;
register char *p;
char buf[BUFSIZ];
while (1) {
for (p = buf; (i = getc(f)) != EOF && (*p = i) > ' '; ++p);
if (p != buf) {
*p++ = 0;
if (verbose)
printf("profile: %s\n", buf);
set_option(buf, 1);
}
else if (i == EOF)
return;
}
}
/* S1 should be a string. S2 should be a string, perhaps followed by
an argument. Compare the two, returning true if they are equal,
and if they are equal set *START_PARAM to point to the argument
in S2. */
eqin(s1, s2, start_param)
register char *s1;
register char *s2;
char **start_param;
{
while (*s1) {
if (*s1++ != *s2++)
return (false);
}
*start_param = s2;
return (true);
}
/*
* Set the defaults.
*/
set_defaults()
{
register struct pro *p;
for (p = pro; p->p_name; p++)
if (p->p_type == PRO_BOOL || p->p_type == PRO_INT)
*p->p_obj = p->p_default;
}
/* Process an option ARG (e.g. "-l60").
EXPLICIT should be nonzero iff the argument is being explicitly
specified (as opposed to being taken from a PRO_SETTINGS group of
settings). */
set_option (arg, explicit)
char *arg;
int explicit;
{
struct pro *p;
char *param_start;
arg++; /* ignore leading "-" */
for (p = pro; p->p_name; p++)
if (*p->p_name == *arg && eqin(p->p_name, arg, &param_start))
goto found;
fprintf(stderr, "indent: unknown parameter \"%s\"\n", arg - 1);
exit(1);
found:
/* If the parameter has been explicitly specified, we don't */
/* want a group of bundled settings to override the explicit */
/* setting. */
if (explicit || !*(p->p_explicit))
{
if (explicit)
*(p->p_explicit) = 1;
switch (p->p_type) {
case PRO_PRSTRING:
puts ((char *)p->p_obj);
exit (0);
case PRO_SETTINGS:
{
char *t; /* current position */
t = (char *)p->p_obj;
do
{
set_option(t, 0);
/* advance to character following next NUL */
while (*t++) ;
}
while (*t);
}
case PRO_IGN:
break;
case PRO_STDIN:
if (in_name == 0)
{
read_stdin();
/* Let it be known that we have an input file. */
in_name = "Standard Input";
}
if (output == 0)
output = stdout;
break;
case PRO_KEY:
if (*param_start == 0)
goto need_param;
{
register char *str = (char *) xmalloc(strlen(param_start) + 1);
strcpy(str, param_start);
addkey(str, 4);
}
break;
case PRO_BOOL:
if (p->p_special == OFF)
*p->p_obj = false;
else
*p->p_obj = true;
break;
case PRO_INT:
if (*param_start == 0) {
need_param:
fprintf(stderr, "indent: ``%s'' requires a parameter\n",
arg - 1);
exit(1);
}
*p->p_obj = atoi(param_start);
break;
case PRO_FONT:
parsefont((struct fstate *) p->p_obj, param_start);
break;
default:
fprintf(stderr, "indent: set_option: internal error: p_type %d\n",
p->p_type);
exit(1);
}
}
}

51
src/util/indent/globs.c Normal file
View File

@ -0,0 +1,51 @@
/* Copyright (C) 1986, 1989 Free Software Foundation, Inc.
This file is part of GNU indent.
GNU indent is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU indent is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU indent; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "indent_globs.h"
/* Like malloc but get error if no storage available. */
char *
xmalloc (size)
long size;
{
register char *val = (char *) calloc (1, size);
if (!val)
{
fprintf (stderr,"indent: Virtual memory exhausted.\n");
exit (1);
}
return val;
}
/* Like realloc but get error if no storage available. */
char *
xrealloc (ptr, size)
char *ptr;
long size;
{
register char *val = (char *) realloc (ptr, size);
if (!val)
{
fprintf (stderr,"indent: Virtual memory exhausted.\n");
exit (1);
}
return val;
}

View File

@ -0,0 +1,49 @@
#
# Copyright (c) 1987 Regents of the University of California.
# All rights reserved.
#
# Redistribution and use in source and binary forms are permitted
# provided that the above copyright notice and this paragraph are
# duplicated in all such forms and that any documentation,
# advertising materials, and other materials related to such
# distribution and use acknowledge that the software was developed
# by the University of California, Berkeley. The name of the
# University may not be used to endorse or promote products derived
# from this software without specific prior written permission.
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# @(#)Makefile 5.9 (Berkeley) 9/15/88
#
CFLAGS= -g
#LDFLAGS= -g
#LDFLAGS=
#LIBC= /lib/libc.a
#LIBC= /usr/lib/libc.a
SRCS= indent.c io.c lexi.c parse.c pr_comment.c args.c globs.c
OBJS= indent.o io.o lexi.o parse.o pr_comment.o args.o globs.o
HEADERS= indent_globs.h version.h
MAN= indent.texinfo ChangeLog Projects
# -g is here rather than in CFLAGS since many versions of cc do not
# allow -g with -O
CC=gcc
all: indent
indent: ${OBJS} ${LIBC}
${CC} -o $@ ${LDFLAGS} ${OBJS}
cp indent $(BINDIR)/indent
indent.tar.Z: ${SRCS} Makefile ${MAN} ${HEADERS}
tar -c -z -f indent.tar.Z ${SRCS} Makefile ${MAN} ${HEADERS}
${OBJS}: indent_globs.h
args.o: version.h
clean:
rm -f ${OBJS} core indent
install: indent
install -c -s indent $(BINDIR)

1382
src/util/indent/indent.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,406 @@
/*
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980 The Regents of the University of California.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley, the University of Illinois,
* Urbana, and Sun Microsystems, Inc. The name of either University
* or Sun Microsystems may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#)indent_globs.h 5.7 (Berkeley) 9/15/88
*/
#include <stdio.h>
#include <stdlib.h>
/* Do the same thing, but abort with an error if out of memory
(see globs.c). */
char *xmalloc ();
char *xrealloc ();
#ifndef M_UNIX
#include <strings.h>
#else
#include <string.h>
#endif
#define BACKSLASH '\\'
#define label_offset 2 /* number of levels a label is placed to left
* of code */
/* Initial size of internal buffers (they are extended as necessary). */
#define bufsize 1000
#define tabsize 8 /* the size of a tab */
#define tabmask 0177770 /* mask used when figuring length of lines
* with tabs */
enum codes {code_eof = 0, /* end of file */
newline,
lparen, /* '(' or '['. Also '{' in an initialization. */
rparen, /* ')' or ']'. Also '}' in an initialization. */
unary_op, binary_op, postop,
question, casestmt, colon, semicolon, lbrace, rbrace,
ident, /* string or char literal, identifier, number */
comma, comment, swstmt,
preesc, /* '#'. */
form_feed, decl,
sp_paren, /* if, for, or while token */
sp_nparen, ifstmt, whilestmt,
forstmt, stmt, stmtl, elselit, dolit, dohead, ifhead,
elsehead, period };
#define false 0
#define true 1
#ifdef MAIN
#define GLOBAL
#else /* !MAIN */
#define GLOBAL extern
#endif /* MAIN */
/* Name of input file. */
extern char *in_name;
GLOBAL char *in_prog; /* pointer to the null-terminated input program */
/* Point to the position in the input program which we are currently
looking at. */
GLOBAL char *in_prog_pos;
/* Point to the start of the current line. */
GLOBAL char *cur_line;
/* Size of the input program, not including the ' \n\0' we add at the end */
GLOBAL int in_prog_size;
GLOBAL FILE *output; /* the output file */
/* The following macro employs traditional token-pasting. If one desires
to make this thing run without giving gcc the -traditional option
or it becomes inconvenient, it should be rewritten to use a struct
for each buffer (along the lines of the 'struct buf' later in this
file). */
#ifdef __STDC__
#define paste(a, b) a ## b
#else
#define paste(a, b) a/**/b
#endif
#define check_size(name) \
if (paste(e_,name) >= paste(l_,name)) { \
register nsize = paste(l_,name)-paste(s_,name)+400; \
paste(name,buf) = (char *) xrealloc(paste(name,buf), nsize); \
paste(e_,name) = paste(name,buf) + \
(paste(e_,name)-paste(s_,name)) + 1; \
paste(l_,name) = paste(name,buf) + nsize - 5; \
paste(s_,name) = paste(name,buf) + 1; \
}
GLOBAL char *labbuf; /* buffer for label */
GLOBAL char *s_lab; /* start ... */
GLOBAL char *e_lab; /* .. and end of stored label */
GLOBAL char *l_lab; /* limit of label buffer */
GLOBAL char *codebuf; /* buffer for code section */
GLOBAL char *s_code; /* start ... */
GLOBAL char *e_code; /* .. and end of stored code */
GLOBAL char *l_code; /* limit of code section */
GLOBAL char *combuf; /* buffer for comments */
GLOBAL char *s_com; /* start ... */
GLOBAL char *e_com; /* ... and end of stored comments */
GLOBAL char *l_com; /* limit of comment buffer */
GLOBAL char *buf_ptr; /* ptr to next character to be taken from
* in_buffer */
GLOBAL char *buf_end; /* ptr to first after last char in in_buffer */
/* pointer to the token that lexi() has just found */
GLOBAL char *token;
/* points to the first char after the end of token */
GLOBAL char *token_end;
/* Used to keep track of buffers. */
struct buf {
char *ptr; /* points to the start of the buffer */
char *end; /* points to the character beyond the last one (e.g. is equal
to ptr if the buffer is empty). */
int size; /* how many chars are currently allocated. */
};
/* Insure that BUFSTRUC has at least REQ more chars left, if not extend it.
Note: This may change bufstruc.ptr. */
#define need_chars(bufstruc, req) \
if ((bufstruc.end - bufstruc.ptr + (req)) >= bufstruc.size) \
{\
int cur_chars = bufstruc.end - bufstruc.ptr;\
bufstruc.size *= 2;\
bufstruc.ptr = xrealloc(bufstruc.ptr,bufstruc.size);\
bufstruc.end = bufstruc.ptr + cur_chars;\
}
/* Initialize BUFSTRUC. */
#define init_buf(bufstruc) \
bufstruc.end = bufstruc.ptr = xmalloc(bufsize),\
bufstruc.size = bufsize
/* Buffer in which to save a comment which occurs between an if(), while(),
etc., and the statement following it. Note: the fact that we point
into this buffer, and that we might realloc() it (via the
need_chars macro) is a bad thing (since when the buffer is
realloc'd its address might change, making any pointers into it
point to garbage), but since the filling of the buffer (hence the
need_chars) and the using of the buffer (where buf_ptr points into
it) occur at different times, we can get away with it (it would not
be trivial to fix). */
GLOBAL struct buf save_com;
GLOBAL char *bp_save; /* saved value of buf_ptr when taking input
* from save_com */
GLOBAL char *be_save; /* similarly saved value of buf_end */
GLOBAL int pointer_as_binop;
GLOBAL int blanklines_after_declarations;
GLOBAL int blanklines_before_blockcomments;
extern int blanklines_after_procs;
GLOBAL int blanklines_around_conditional_compilation;
GLOBAL int swallow_optional_blanklines;
GLOBAL int n_real_blanklines;
GLOBAL int prefix_blankline_requested;
GLOBAL int postfix_blankline_requested;
GLOBAL int break_comma; /* when true and not in parens, break after a
* comma */
/* number of spaces to indent braces from the suround if, while, etc.
in -bl (bype_2 == 0) code */
GLOBAL int brace_indent;
GLOBAL int btype_2; /* when true, brace should be on same line as
* if, while, etc */
/* If true, a space is inserted between if, while, or for, and a semicolon
for example
while (*p++ == ' ') ;
*/
GLOBAL int space_sp_semicolon;
/* True if a #else or #endif has been encountered. */
extern int else_or_endif;
GLOBAL int case_ind; /* indentation level to be used for a "case
* n:" in spaces */
GLOBAL int code_lines; /* count of lines with code */
GLOBAL int had_eof; /* set to true when input is exhausted */
GLOBAL int line_no; /* the current line number. */
GLOBAL int max_col; /* the maximum allowable line length */
GLOBAL int verbose; /* when true, non-essential error messages are
* printed */
GLOBAL int cuddle_else; /* true if else should cuddle up to '}' */
GLOBAL int star_comment_cont; /* true iff comment continuation lines should
* have stars at the beginning of each line. */
GLOBAL int comment_delimiter_on_blankline;
GLOBAL int troff; /* true iff were generating troff input */
GLOBAL int procnames_start_line;/* if true, the names of procedures
* being defined get placed in column
* 1 (ie. a newline is placed between
* the type of the procedure and its
* name) */
GLOBAL int proc_calls_space; /* If true, procedure calls look like:
* foo(bar) rather than foo (bar) */
GLOBAL int format_col1_comments;/* If comments which start in column 1
* are to be magically reformatted */
/* If any comments are to be reformatted */
GLOBAL int format_comments;
extern int suppress_blanklines;/* set iff following blanklines should be
* suppressed */
GLOBAL int continuation_indent; /* set to the indentation between the edge of
* code and continuation lines in spaces */
GLOBAL int lineup_to_parens; /* if true, continued code within parens will
* be lined up to the open paren */
/* The position that we will line the current line up with when it
comes time to print it (if we are lining up to parentheses). */
extern int paren_target;
GLOBAL int Bill_Shannon; /* true iff a blank should always be inserted
* after sizeof */
GLOBAL int blanklines_after_declarations_at_proctop; /* This is vaguely
* similar to
* blanklines_after_decla
* rations except that
* it only applies to
* the first set of
* declarations in a
* procedure (just after
* the first '{') and it
* causes a blank line
* to be generated even
* if there are no
* declarations */
GLOBAL int block_comment_max_col;
GLOBAL int extra_expression_indent; /* True if continuation lines from the
* expression part of "if(e)",
* "while(e)", "for(e;e;e)" should be
* indented an extra tab stop so that
* they don't conflict with the code
* that follows */
extern int lpc;
/* The following are all controlled by command line switches
(as are some of the things above). */
extern int leave_comma; /* if true, never break declarations after
* commas */
extern int decl_com_ind; /* the column in which comments after
* declarations should be put */
extern int case_indent; /* The distance to indent case labels from the
* switch statement */
extern int com_ind; /* the column in which comments to the right
* of code should start */
extern int decl_indent; /* column to indent declared identifiers to */
extern int ljust_decl; /* true if declarations should be left
* justified */
extern int unindent_displace; /* comments not to the right of code
* will be placed this many
* indentation levels to the left of
* code */
extern int else_if; /* True iff else if pairs should be handled
* specially */
/* Number of spaces to indent parameters. */
extern int indent_parameters;
/* The size of one indentation level in spaces. */
extern int ind_size;
/* -troff font state information */
struct fstate {
char font[4];
char size;
int allcaps:1;
};
char *chfont();
GLOBAL struct fstate
keywordf, /* keyword font */
stringf, /* string font */
boxcomf, /* Box comment font */
blkcomf, /* Block comment font */
scomf, /* Same line comment font */
bodyf; /* major body font */
/* Initial size for the parser's stacks. (p_stack, il, and cstk). */
#define INITIAL_STACK_SIZE 2
struct parser_state {
struct parser_state *next;
enum codes last_token;
struct fstate cfont; /* Current font */
/* This is the parsers stack, and the current allocated size. */
enum codes *p_stack;
int p_stack_size;
/* This stack stores indentation levels */
/* Currently allocated size is stored in p_stack_size. */
int *il;
/* Used to store case stmt indentation levels. */
/* Currently allocated size is stored in p_stack_size. */
int *cstk;
/* Pointer to the top of stack of the p_stack, il and cstk arrays. */
int tos;
int box_com; /* set to true when we are in a "boxed"
* comment. In that case, the first non-blank
* char should be lined up with the / in '/ *' */
int comment_delta,
n_comment_delta;
int cast_mask; /* indicates which close parens close off
* casts */
int sizeof_mask; /* indicates which close parens close off
* sizeof''s */
int block_init; /* true iff inside a block initialization */
int block_init_level; /* The level of brace nesting in an
* initialization */
int last_nl; /* this is true if the last thing scanned was
* a newline */
int in_or_st; /* Will be true iff there has been a
* declarator (e.g. int or char) and no left
* paren since the last semicolon. When true,
* a '{' is starting a structure definition or
* an initialization list */
int bl_line; /* set to 1 by dump_line if the line is blank */
int col_1; /* set to true if the last token started in
* column 1 */
int com_col; /* this is the column in which the current
* coment should start */
int com_lines; /* the number of lines with comments, set by
* dump_line */
int dec_nest; /* current nesting level for structure or init */
int decl_on_line; /* set to true if this line of code has part
* of a declaration on it */
int i_l_follow; /* the level in spaces to which ind_level should be set
* after the current line is printed */
int in_decl; /* set to true when we are in a declaration
* stmt. The processing of braces is then
* slightly different */
int in_stmt; /* set to 1 while in a stmt */
int ind_level; /* the current indentation level in spaces */
int ind_stmt; /* set to 1 if next line should have an extra
* indentation level because we are in the
* middle of a stmt */
int last_u_d; /* set to true after scanning a token which
* forces a following operator to be unary */
int out_coms; /* the number of comments processed, set by
* pr_comment */
int out_lines; /* the number of lines written, set by
* dump_line */
int p_l_follow; /* used to remember how to indent following
* statement */
int paren_level; /* parenthesization level. used to indent
* within stmts */
/* Column positions of paren at each level. If positive, it
contains just the number of characters of code on the line up to
and including the right parenthesis character. If negative, it
contains the opposite of the actual level of indentation in
characters (that is, the indentation of the line has been added
to the number of characters and the sign has been reversed to
indicate that this has been done). */
short *paren_indents; /* column positions of each paren */
int paren_indents_size; /* Currently allocated size. */
int pcase; /* set to 1 if the current line label is a
* case. It is printed differently from a
* regular label */
int search_brace; /* set to true by parse when it is necessary
* to buffer up all info up to the start of a
* stmt after an if, while, etc */
int use_ff; /* set to one if the current line should be
* terminated with a form feed */
int want_blank; /* set to true when the following token should
* be prefixed by a blank. (Said prefixing is
* ignored in some cases.) */
int its_a_keyword;
int sizeof_keyword;
int dumped_decl_indent;
int in_parameter_declaration;
char *procname; /* The name of the current procedure */
char *procname_end; /* One char past the last one in procname */
int just_saw_decl;
};
/* All manipulations of the parser stack occur at the tos
(via the macro ps). The elements of the stack below it are kept in
a linked list via the next field. */
extern struct parser_state *parser_state_tos;
/* The column in which comments to the right of #else and #endif should
start. */
extern int else_endif_col;

717
src/util/indent/io.c Normal file
View File

@ -0,0 +1,717 @@
/*
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980 The Regents of the University of California.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley, the University of Illinois,
* Urbana, and Sun Microsystems, Inc. The name of either University
* or Sun Microsystems may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static char sccsid[] = "@(#)io.c 5.10 (Berkeley) 9/15/88";
#endif /* not lint */
#include "indent_globs.h"
#include <ctype.h>
/* POSIX says that fcntl.h should exist. Linking either sys/fcntl.h
or sys/file.h to fcntl.h should work fine if you don't have fcntl.h */
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int suppress_blanklines = 0;
int comment_open;
int paren_target;
/* true if INDENT OFF is in effect */
static int inhibit_formatting;
dump_line()
{ /* dump_line is the routine that actually
* effects the printing of the new source. It
* prints the label section, followed by the
* code section with the appropriate nesting
* level, followed by any comments */
register int cur_col,
target_col;
static not_first_line;
if (parser_state_tos->procname[0]) {
if (troff) {
if (comment_open) {
comment_open = 0;
fprintf(output, ".*/\n");
}
fprintf(output, ".Pr \"%.*s\"\n", parser_state_tos->procname_end - parser_state_tos->procname,
parser_state_tos->procname);
}
parser_state_tos->ind_level = 0;
parser_state_tos->procname = "\0";
}
if (s_code == e_code && s_lab == e_lab && s_com == e_com) {
/* If we have a formfeed on a blank line, we should just output it,
rather than treat it as a normal blank line. */
if (parser_state_tos->use_ff)
{
putc('\014',output);
parser_state_tos->use_ff = false;
}
else
{
if (suppress_blanklines > 0)
suppress_blanklines--;
else {
parser_state_tos->bl_line = true;
n_real_blanklines++;
}
}
}
else if (!inhibit_formatting) {
suppress_blanklines = 0;
parser_state_tos->bl_line = false;
if (prefix_blankline_requested && not_first_line)
if (swallow_optional_blanklines) {
if (n_real_blanklines == 1)
n_real_blanklines = 0;
}
else {
if (n_real_blanklines == 0)
n_real_blanklines = 1;
}
while (--n_real_blanklines >= 0)
putc('\n', output);
n_real_blanklines = 0;
if (parser_state_tos->ind_level == 0)
parser_state_tos->ind_stmt = 0; /* this is a class A kludge. dont do
* additional statement indentation if we are
* at bracket level 0 */
if (e_lab != s_lab || e_code != s_code)
++code_lines; /* keep count of lines with code */
if (e_lab != s_lab) { /* print lab, if any */
if (comment_open) {
comment_open = 0;
fprintf(output, ".*/\n");
}
while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
e_lab--;
cur_col = pad_output(1, compute_label_target());
fprintf(output, "%.*s", e_lab - s_lab, s_lab);
cur_col = count_spaces(cur_col, s_lab);
}
else
cur_col = 1; /* there is no label section */
parser_state_tos->pcase = false;
if (s_code != e_code) { /* print code section, if any */
register char *p;
if (comment_open) {
comment_open = 0;
fprintf(output, ".*/\n");
}
target_col = compute_code_target();
/* If a line ends in an lparen character, the following
line should not line up with the parenthesis, but
should be indented by the usual amount. */
if (parser_state_tos->last_token == lparen)
{
parser_state_tos->paren_indents[parser_state_tos->p_l_follow-1]
+= ind_size - 1;
}
{
register i;
for (i = 0; i < parser_state_tos->p_l_follow; i++)
if (parser_state_tos->paren_indents[i] >= 0)
parser_state_tos->paren_indents[i] = -(parser_state_tos->paren_indents[i] + target_col);
}
cur_col = pad_output(cur_col, target_col);
for (p = s_code; p < e_code; p++)
if (*p == (char) 0200)
fprintf(output, "%d", target_col * 7);
else
putc(*p, output);
cur_col = count_spaces(cur_col, s_code);
}
if (s_com != e_com)
{
if (troff) {
int all_here = 0;
register char *p;
if (e_com[-1] == '/' && e_com[-2] == '*')
e_com -= 2, all_here++;
while (e_com > s_com && e_com[-1] == ' ')
e_com--;
*e_com = 0;
p = s_com;
while (*p == ' ')
p++;
if (p[0] == '/' && p[1] == '*')
p += 2, all_here++;
else if (p[0] == '*')
p += p[1] == '/' ? 2 : 1;
while (*p == ' ')
p++;
if (*p == 0)
goto inhibit_newline;
if (comment_open < 2 && parser_state_tos->box_com) {
comment_open = 0;
fprintf(output, ".*/\n");
}
if (comment_open == 0) {
if ('a' <= *p && *p <= 'z')
*p = *p + 'A' - 'a';
if (e_com - p < 50 && all_here == 2) {
register char *follow = p;
fprintf(output, "\n.nr C! \\w\1");
while (follow < e_com) {
switch (*follow) {
case '\n':
putc(' ', output);
case 1:
break;
case '\\':
putc('\\', output);
default:
putc(*follow, output);
}
follow++;
}
putc(1, output);
}
fprintf(output, "\n./* %dp %d %dp\n",
parser_state_tos->com_col * 7,
(s_code != e_code || s_lab != e_lab) - parser_state_tos->box_com,
target_col * 7);
}
comment_open = 1 + parser_state_tos->box_com;
while (*p) {
if (*p == BACKSLASH)
putc(BACKSLASH, output);
putc(*p++, output);
}
}
else { /* print comment, if any */
register target = parser_state_tos->com_col;
register char *com_st = s_com;
target += parser_state_tos->comment_delta;
while (*com_st == '\t')
com_st++, target += 8; /* ? */
while (target <= 0)
if (*com_st == ' ')
target++, com_st++;
else if (*com_st == '\t')
target = ((target - 1) & ~7) + 9, com_st++;
else
target = 1;
if (cur_col > target) { /* if comment cant fit on this line,
* put it on next line */
putc('\n', output);
cur_col = 1;
++parser_state_tos->out_lines;
}
while (e_com > com_st && isspace(e_com[-1]))
e_com--;
cur_col = pad_output(cur_col, target);
if (!parser_state_tos->box_com) {
if (star_comment_cont && (com_st[1] != '*' || e_com <= com_st + 1))
if (com_st[1] == ' ' && com_st[0] == ' ' && e_com > com_st + 1)
com_st[1] = '*';
else
fwrite(" * ", com_st[0] == '\t' ? 2 : com_st[0] == '*' ? 1 : 3, 1, output);
}
fwrite(com_st, e_com - com_st, 1, output);
parser_state_tos->comment_delta = parser_state_tos->n_comment_delta;
cur_col = count_spaces(cur_col, com_st);
++parser_state_tos->com_lines; /* count lines with comments */
}
}
if (parser_state_tos->use_ff)
{
putc('\014', output);
parser_state_tos->use_ff = false;
}
else
putc('\n', output);
inhibit_newline:
++parser_state_tos->out_lines;
if (parser_state_tos->just_saw_decl == 1 && blanklines_after_declarations) {
prefix_blankline_requested = 1;
parser_state_tos->just_saw_decl = 0;
}
else
prefix_blankline_requested = postfix_blankline_requested;
postfix_blankline_requested = 0;
}
parser_state_tos->decl_on_line = parser_state_tos->in_decl; /* if we are in the middle of a
* declaration, remember that fact for
* proper comment indentation */
parser_state_tos->ind_stmt = parser_state_tos->in_stmt & ~parser_state_tos->in_decl; /* next line should be
* indented if we have not
* completed this stmt and if
* we are not in the middle of
* a declaration */
parser_state_tos->dumped_decl_indent = 0;
*(e_lab = s_lab) = '\0'; /* reset buffers */
*(e_code = s_code) = '\0';
*(e_com = s_com) = '\0';
parser_state_tos->ind_level = parser_state_tos->i_l_follow;
parser_state_tos->paren_level = parser_state_tos->p_l_follow;
paren_target = -parser_state_tos->paren_indents[parser_state_tos->paren_level - 1];
not_first_line = 1;
return;
}
/* Figure out where we should put the code in codebuf.
Return the column number in spaces. */
int
compute_code_target()
{
register target_col = parser_state_tos->ind_level + 1;
if (parser_state_tos->paren_level)
if (!lineup_to_parens)
target_col += continuation_indent * parser_state_tos->paren_level;
else {
register w;
register t = paren_target;
if ((w = count_spaces(t, s_code) - max_col) > 0
&& count_spaces(target_col, s_code) <= max_col) {
t -= w + 1;
if (t > target_col)
target_col = t;
}
else
target_col = t;
}
else if (parser_state_tos->ind_stmt)
target_col += continuation_indent;
return target_col;
}
int
compute_label_target()
{
return
parser_state_tos->pcase ? case_ind + 1
: *s_lab == '#' ? 1
: parser_state_tos->ind_level - label_offset + 1;
}
/* Allocate space for FILENAME, read in the file, and set in_prog and
in_prog_pos to point to the buffer. If any errors occur, report an
error message and abort. */
void
read_file(filename)
char *filename;
{
/* File descriptor for the input file */
int in_fd;
/* File status for the input file */
struct stat in_stat;
/* buffer used for error messages */
char *errbuf;
errbuf = (char *)xmalloc (strlen (filename) + 80);
sprintf(errbuf,"indent: %s",filename);
in_fd = open(filename,O_RDONLY,0777);
if (in_fd < 0)
{
perror(errbuf);
exit(1);
}
if (fstat(in_fd,&in_stat) < 0)
{
perror(errbuf);
exit(1);
}
in_prog_size = in_stat.st_size;
in_prog = xmalloc(in_prog_size + 3); /* 3 for ' ','\n','\0' */
if (read(in_fd,in_prog,in_prog_size) < 0)
{
perror(errbuf);
exit(1);
}
if (close(in_fd) < 0)
{
perror(errbuf);
exit(1);
}
in_prog[in_prog_size] = ' ';
in_prog[in_prog_size+1] = '\n';
in_prog[in_prog_size+2] = 0;
in_prog_pos = in_prog;
free (errbuf);
}
/* Like read_file but read from stdin. */
void
read_stdin()
{
unsigned int alloc_size = 10000;
char ch;
unsigned int pos;
unsigned i;
in_prog_pos = in_prog = xmalloc(alloc_size);
in_prog_size = 0;
do
{
/* Copy up until 3 bytes before the end of the buffer,
(the 3 is for ' \n\0')... */
for (; in_prog_size < alloc_size - 3; in_prog_size++)
{
ch = getc(stdin);
if (ch == EOF)
break;
in_prog[in_prog_size] = ch;
}
/* ...and if that's not enough allocate more. */
if (ch != EOF) {
alloc_size *= 2;
in_prog = xrealloc(in_prog,alloc_size);
}
}
while (ch != EOF);
in_prog[in_prog_size] = ' ';
in_prog[in_prog_size+1] = '\n';
in_prog[in_prog_size+2] = 0;
in_prog_pos = in_prog;
}
/* Advance buf_ptr so that it points to the next line of input. Skip
over indent errors (comments beginning with *INDENT**), ignoring
them. Process INDENT ON and INDENT OFF. (Note: the name of this
function is a historical artifact from before the time that indent
kept the whole source file in memory). */
fill_buffer()
{
/* Point various places in the buffer. */
char *p;
/* Have we found INDENT ON or INDENT OFF ? */
enum {None,Indent_on,Indent_off} com;
if (bp_save != 0)
{ /* there is a partly filled input buffer left */
buf_ptr = bp_save; /* dont read anything, just switch buffers */
buf_end = be_save;
bp_save = be_save = 0;
if (buf_ptr < buf_end)
return; /* only return if there is really something in
* this buffer */
}
fill_it:
cur_line = in_prog_pos;
buf_ptr = in_prog_pos;
for (p = buf_ptr; *p && *p++ != '\n';)
;
buf_end = p;
if (!*p)
had_eof = true;
p = buf_ptr;
in_prog_pos = buf_end;
while (*p == ' ' || *p == '\t')
p++;
if (*p == '/' && p[1] == '*')
{
p += 2;
if (p[1] == 'I' && strncmp(p,"*INDENT**",9) == 0)
goto fill_it;
while (*p == ' ' || *p == '\t')
p++;
com = None;
if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E'
&& p[4] == 'N' && p[5] == 'T') {
p += 6;
while (*p == ' ' || *p == '\t')
p++;
if (*p == '*')
com = 1;
else if (*p == 'O')
if (*++p == 'N')
p++, com = Indent_on;
else if (*p == 'F' && *++p == 'F')
p++, com = Indent_off;
while (*p == ' ' || *p == '\t')
p++;
if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com) {
if (s_com != e_com || s_lab != e_lab || s_code != e_code)
dump_line();
if (!(inhibit_formatting = com - 1)) {
n_real_blanklines = 0;
postfix_blankline_requested = 0;
prefix_blankline_requested = 0;
suppress_blanklines = 1;
}
}
}
}
if (inhibit_formatting)
{
p = buf_ptr;
do
putc(*p,output);
while (*p++ != '\n');
}
}
/*
* Copyright (C) 1976 by the Board of Trustees of the University of Illinois
*
* All rights reserved
*
*
* NAME: pad_output
*
* FUNCTION: Writes tabs and spaces to move the current column up to the desired
* position.
*
* ALGORITHM: Put tabs and/or blanks into pobuf, then write pobuf.
*
* PARAMETERS: current integer The current column target
* nteger The desired column
*
* RETURNS: Integer value of the new column. (If current >= target, no action is
* taken, and current is returned.
*
* GLOBALS: None
*
* CALLS: write (sys)
*
* CALLED BY: dump_line
*
* HISTORY: initial coding November 1976 D A Willcox of CAC
*
*/
pad_output(current, target) /* writes tabs and blanks (if necessary) to
* get the current output position up to the
* target column */
int current; /* the current column value */
int target; /* position we want it at */
{
register int curr; /* internal column pointer */
register int tcur;
if (troff)
fprintf(output, "\\h'|%dp'", (target - 1) * 7);
else {
if (current >= target)
return (current); /* line is already long enough */
curr = current;
while ((tcur = ((curr - 1) & tabmask) + tabsize + 1) <= target) {
putc('\t', output);
curr = tcur;
}
while (curr++ < target)
putc(' ', output); /* pad with final blanks */
}
return (target);
}
/*
* Copyright (C) 1976 by the Board of Trustees of the University of Illinois
*
* All rights reserved
*
*
* NAME: count_spaces
*
* FUNCTION: Find out where printing of a given string will leave the current
* character position on output.
*
* ALGORITHM: Run thru input string and add appropriate values to current
* position.
*
* RETURNS: Integer value of position after printing "buffer" starting in column
* "current".
*
* HISTORY: initial coding November 1976 D A Willcox of CAC
*
*/
int
count_spaces(current, buffer)
/*
* this routine figures out where the character position will be after
* printing the text in buffer starting at column "current"
*/
int current;
char *buffer;
{
register char *buf; /* used to look thru buffer */
register int cur; /* current character counter */
cur = current;
for (buf = buffer; *buf != '\0'; ++buf) {
switch (*buf) {
case '\n':
case 014: /* form feed */
cur = 1;
break;
case '\t':
cur = ((cur - 1) & tabmask) + tabsize + 1;
break;
case '': /* this is a backspace */
--cur;
break;
default:
++cur;
break;
} /* end of switch */
} /* end of for loop */
return (cur);
}
/* Nonzero if we have found an error (not a warning). */
int found_err;
/* Signal an error. LEVEL is nonzero if it is an error (as opposed to
a warning. MSG is a printf-style format string. Additional
arguments are additional arguments for printf. */
diag(level, msg, a, b)
{
if (level)
found_err = 1;
if (output == stdout) {
fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no);
fprintf(stdout, (char *)msg, a, b);
fprintf(stdout, " */\n");
}
else {
fprintf(stderr, "%s: %d: ", in_name, line_no);
fprintf(stderr, (char *)msg, a, b);
fprintf(stderr, "\n");
}
}
writefdef(f, nm)
register struct fstate *f;
{
fprintf(output, ".ds f%c %s\n.nr s%c %d\n",
nm, f->font, nm, f->size);
}
/* Write characters starting at S to change the font from OF to NF. Return
a pointer to the character after the last character written.
For troff mode only. */
char *
chfont(of, nf, s)
register struct fstate *of,
*nf;
char *s;
{
if (of->font[0] != nf->font[0]
|| of->font[1] != nf->font[1]) {
*s++ = '\\';
*s++ = 'f';
if (nf->font[1]) {
*s++ = '(';
*s++ = nf->font[0];
*s++ = nf->font[1];
}
else
*s++ = nf->font[0];
}
if (nf->size != of->size) {
*s++ = '\\';
*s++ = 's';
if (nf->size < of->size) {
*s++ = '-';
*s++ = '0' + of->size - nf->size;
}
else {
*s++ = '+';
*s++ = '0' + nf->size - of->size;
}
}
return s;
}
parsefont(f, s0)
register struct fstate *f;
char *s0;
{
register char *s = s0;
int sizedelta = 0;
int i;
f->size = 0;
f->allcaps = 1;
for (i = 0; i < 4; i++)
f->font[i] = 0;
while (*s) {
if (isdigit(*s))
f->size = f->size * 10 + *s - '0';
else if (isupper(*s))
if (f->font[0])
f->font[1] = *s;
else
f->font[0] = *s;
else if (*s == 'c')
f->allcaps = 1;
else if (*s == '+')
sizedelta++;
else if (*s == '-')
sizedelta--;
else {
fprintf(stderr, "indent: bad font specification: %s\n", s0);
exit(1);
}
s++;
}
if (f->font[0] == 0)
f->font[0] = 'R';
if (bodyf.size == 0)
bodyf.size = 11;
if (f->size == 0)
f->size = bodyf.size + sizedelta;
else if (sizedelta > 0)
f->size += bodyf.size;
else
f->size = bodyf.size - f->size;
}

584
src/util/indent/lexi.c Normal file
View File

@ -0,0 +1,584 @@
/*
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980 The Regents of the University of California.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley, the University of Illinois,
* Urbana, and Sun Microsystems, Inc. The name of either University
* or Sun Microsystems may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static char sccsid[] = "@(#)lexi.c 5.11 (Berkeley) 9/15/88";
#endif /* not lint */
/*
* Here we have the token scanner for indent. It scans off one token and puts
* it in the global variable "token". It returns a code, indicating the type
* of token scanned.
*/
#include "indent_globs.h"
#include "ctype.h"
#define alphanum 1
#define opchar 3
enum rwcodes {
rw_break,
rw_switch,
rw_case,
rw_struct_like, /* struct, enum, union */
rw_decl,
rw_sp_paren, /* if, while, for */
rw_sp_nparen, /* do, else */
rw_sizeof
};
struct templ {
char *rwd;
enum rwcodes rwcode;
};
struct templ *user_specials = 0;
unsigned int user_specials_max, user_specials_idx;
struct templ specials[] =
{
{"switch", rw_switch},
{"case", rw_case},
{"break", rw_break},
{"struct", rw_struct_like},
{"union", rw_struct_like},
{"enum", rw_struct_like},
{"default", rw_case},
{"int", rw_decl},
{"char", rw_decl},
{"float", rw_decl},
{"double", rw_decl},
/* {"long", rw_decl},
{"short", rw_decl},*/
{"typdef", rw_decl},
{"unsigned", rw_decl},
{"register", rw_decl},
{"static", rw_decl},
{"global", rw_decl},
{"extern", rw_decl},
{"void", rw_decl},
{"va_dcl", rw_decl},
{"goto", rw_break},
{"return", rw_break},
{"if", rw_sp_paren},
{"while", rw_sp_paren},
{"for", rw_sp_paren},
{"else", rw_sp_nparen},
{"do", rw_sp_nparen},
{"sizeof", rw_sizeof},
{0, 0}
};
char chartype[128] =
{ /* this is used to facilitate the decision of
* what type (alphanumeric, operator) each
* character is */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 3, 0, 0, 1, 3, 3, 0,
0, 0, 3, 3, 0, 3, 0, 3,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 0, 0, 3, 3, 3, 3,
0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 3, 1,
0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 3, 0, 3, 0
};
enum codes
lexi()
{
/* used to walk through the token */
char *tok;
int unary_delim; /* this is set to 1 if the current token
*
* forces a following operator to be unary */
static enum codes last_code; /* the last token type returned */
static int l_struct; /* set to 1 if the last token was 'struct' */
int code; /* internal code to be returned */
char qchar; /* the delimiter character for a string */
unary_delim = false;
parser_state_tos->col_1 = parser_state_tos->last_nl; /* tell world that this token started in
* column 1 iff the last thing scanned was nl */
parser_state_tos->last_nl = false;
while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
parser_state_tos->col_1 = false; /* leading blanks imply token is not in column
* 1 */
if (++buf_ptr >= buf_end)
fill_buffer();
}
token = buf_ptr;
/* Scan an alphanumeric token */
if (chartype[*buf_ptr] == alphanum || buf_ptr[0] == '.' && isdigit(buf_ptr[1])) {
/*
* we have a character or number
*/
register char *j; /* used for searching thru list of
*
* reserved words */
register struct templ *p;
if (isdigit(*buf_ptr) || buf_ptr[0] == '.' && isdigit(buf_ptr[1])) {
int seendot = 0,
seenexp = 0;
if (*buf_ptr == '0' &&
(buf_ptr[1] == 'x' || buf_ptr[1] == 'X')) {
buf_ptr += 2;
while (isxdigit(*buf_ptr))
buf_ptr++;
}
else
while (1) {
if (*buf_ptr == '.')
if (seendot)
break;
else
seendot++;
buf_ptr++;
if (!isdigit(*buf_ptr) && *buf_ptr != '.')
if ((*buf_ptr != 'E' && *buf_ptr != 'e') || seenexp)
break;
else {
seenexp++;
seendot++;
buf_ptr++;
if (*buf_ptr == '+' || *buf_ptr == '-')
buf_ptr++;
}
}
if (*buf_ptr == 'L' || *buf_ptr == 'l')
buf_ptr++;
}
else
while (chartype[*buf_ptr] == alphanum) { /* copy it over */
buf_ptr++;
if (buf_ptr >= buf_end)
fill_buffer();
}
token_end = buf_ptr;
while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
if (++buf_ptr >= buf_end)
fill_buffer();
}
parser_state_tos->its_a_keyword = false;
parser_state_tos->sizeof_keyword = false;
if (l_struct) { /* if last token was 'struct', then this token
* should be treated as a declaration */
l_struct = false;
last_code = ident;
parser_state_tos->last_u_d = true;
return (decl);
}
parser_state_tos->last_u_d = false; /* Operator after indentifier is binary */
last_code = ident; /* Remember that this is the code we will
* return */
/*
* This loop will check if the token is a keyword.
*/
for (p = specials; (j = p->rwd) != 0; p++) {
tok = token; /* point at scanned token */
if (*j++ != *tok++ || *j++ != *tok++)
continue; /* This test depends on the fact that
* identifiers are always at least 1 character
* long (ie. the first two bytes of the
* identifier are always meaningful) */
if (tok >= token_end)
break; /* If its a 1 or 2 character identifier */
while (tok < token_end && *tok++ == *j++)
if (*j == 0 && tok == token_end)
goto found_keyword; /* I wish that C had a multi-level
* break... */
}
if (p->rwd) { /* we have a keyword */
found_keyword:
parser_state_tos->its_a_keyword = true;
parser_state_tos->last_u_d = true;
switch (p->rwcode) {
case rw_switch: /* it is a switch */
return (swstmt);
case rw_case: /* a case or default */
return (casestmt);
case rw_struct_like: /* a "struct" */
if (parser_state_tos->p_l_follow)
break; /* inside parens: cast */
l_struct = true;
/*
* Next time around, we will want to know that we have had a
* 'struct'
*/
case rw_decl: /* one of the declaration keywords */
if (parser_state_tos->p_l_follow) {
parser_state_tos->cast_mask |= 1 << parser_state_tos->p_l_follow;
break; /* inside parens: cast */
}
last_code = decl;
return (decl);
case rw_sp_paren: /* if, while, for */
return (sp_paren);
case rw_sp_nparen: /* do, else */
return (sp_nparen);
case rw_sizeof:
parser_state_tos->sizeof_keyword = true;
default: /* all others are treated like any other
* identifier */
return (ident);
} /* end of switch */
} /* end of if (found_it) */
if (*buf_ptr == '(' && parser_state_tos->tos <= 1 && parser_state_tos->ind_level == 0) {
register char *tp = buf_ptr;
while (tp < buf_end)
if (*tp++ == ')' && *tp == ';')
goto not_proc;
parser_state_tos->procname = token;
parser_state_tos->procname_end = token_end;
parser_state_tos->in_parameter_declaration = 1;
not_proc:;
}
/*
* The following hack attempts to guess whether or not the current
* token is in fact a declaration keyword -- one that has been
* typedefd
*/
if (((*buf_ptr == '*' && buf_ptr[1] != '=') || isalpha(*buf_ptr) || *buf_ptr == '_')
&& !parser_state_tos->p_l_follow
&& !parser_state_tos->block_init
&& (parser_state_tos->last_token == rparen || parser_state_tos->last_token == semicolon ||
parser_state_tos->last_token == decl ||
parser_state_tos->last_token == lbrace || parser_state_tos->last_token == rbrace)) {
parser_state_tos->its_a_keyword = true;
parser_state_tos->last_u_d = true;
last_code = decl;
return decl;
}
if (last_code == decl) /* if this is a declared variable, then
* following sign is unary */
parser_state_tos->last_u_d = true; /* will make "int a -1" work */
last_code = ident;
return (ident); /* the ident is not in the list */
} /* end of procesing for alpanum character */
/* l l l Scan a non-alphanumeric token */
/* If it is not a one character token, token_end will get changed
later. */
token_end = buf_ptr + 1;
if (++buf_ptr >= buf_end)
fill_buffer();
switch (*token) {
case '\n':
unary_delim = parser_state_tos->last_u_d;
parser_state_tos->last_nl = true; /* remember that we just had a newline */
code = (had_eof ? 0 : newline);
/*
* if data has been exausted, the newline is a dummy, and we should
* return code to stop
*/
break;
case '\'': /* start of quoted character */
case '"': /* start of string */
qchar = *token;
/* Find out how big the literal is so we can set token_end. */
/* Invariant: before loop test buf_ptr points to the next */
/* character that we have not yet checked. */
while (*buf_ptr != qchar && *buf_ptr != 0 && *buf_ptr != '\n')
{
if (*buf_ptr == '\\')
{
buf_ptr++;
if (buf_ptr >= buf_end)
fill_buffer ();
if (*buf_ptr == '\n')
++line_no;
if (*buf_ptr == 0)
break;
}
buf_ptr++;
if (buf_ptr >= buf_end)
fill_buffer ();
}
if (*buf_ptr == '\n' || *buf_ptr == 0)
{
diag (1,
qchar == '\''
? "Unterminated character constant"
: "Unterminated string constant"
);
}
else
{
/* Advance over end quote char. */
buf_ptr++;
if (buf_ptr >= buf_end)
fill_buffer ();
}
code = ident;
break;
case ('('):
if (lpc && *buf_ptr == '{') {
buf_ptr++;
}
case ('['):
unary_delim = true;
code = lparen;
break;
case (')'):
case (']'):
code = rparen;
break;
case '#':
unary_delim = parser_state_tos->last_u_d;
code = preesc;
break;
case '?':
unary_delim = true;
code = question;
break;
case (':'):
if (lpc && *buf_ptr == ':') {
buf_ptr++;
code = unary_op;
unary_delim = true;
break;
}
code = colon;
unary_delim = true;
break;
case (';'):
unary_delim = true;
code = semicolon;
break;
case ('{'):
unary_delim = true;
/* This check is made in the code for '='. No one who writes
initializers without '=' these days deserves to have indent
work on their code (besides which, uncommenting this would
screw up anything which assumes that parser_state_tos->block_init really
means you are in an initializer. */
/*
* if (parser_state_tos->in_or_st) parser_state_tos->block_init = 1;
*/
/* The following neat hack causes the braces in structure
initializations to be treated as parentheses, thus causing
initializations to line up correctly, e.g.
struct foo bar =
{{a,
b,
c},
{1,
2}};
If lparen is returned, token can be used to distinguish
between '{' and '(' where necessary. */
code = parser_state_tos->block_init ? lparen : lbrace;
break;
case ('}'):
if (lpc && *buf_ptr == ')') {
buf_ptr++;
code = rparen;
break;
}
unary_delim = true;
/* The following neat hack is explained under '{' above. */
code = parser_state_tos->block_init ? rparen : rbrace;
break;
case 014: /* a form feed */
unary_delim = parser_state_tos->last_u_d;
parser_state_tos->last_nl = true; /* remember this so we can set 'parser_state_tos->col_1'
* right */
code = form_feed;
break;
case (','):
unary_delim = true;
code = comma;
break;
case '.':
unary_delim = false;
code = period;
break;
case '-':
case '+': /* check for -, +, --, ++ */
code = (parser_state_tos->last_u_d ? unary_op : binary_op);
unary_delim = true;
if (*buf_ptr == token[0]) {
/* check for doubled character */
buf_ptr++;
/* buffer overflow will be checked at end of loop */
if (last_code == ident || last_code == rparen) {
code = (parser_state_tos->last_u_d ? unary_op : postop);
/* check for following ++ or -- */
unary_delim = false;
}
}
else if (*buf_ptr == '=')
/* check for operator += */
buf_ptr++;
else if (*buf_ptr == '>') {
/* check for operator -> */
buf_ptr++;
if (!pointer_as_binop) {
unary_delim = false;
code = unary_op;
parser_state_tos->want_blank = false;
}
}
break; /* buffer overflow will be checked at end of
* switch */
case '=':
if (parser_state_tos->in_or_st)
parser_state_tos->block_init = 1;
if (*buf_ptr == '=') /* == */
buf_ptr++;
code = binary_op;
unary_delim = true;
break;
/* can drop thru!!! */
case '>':
case '<':
case '!': /* ops like <, <<, <=, !=, etc */
if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') {
if (++buf_ptr >= buf_end)
fill_buffer();
}
code = (parser_state_tos->last_u_d ? unary_op : binary_op);
unary_delim = true;
break;
default:
if (token[0] == '/' && *buf_ptr == '*') {
/* it is start of comment */
if (++buf_ptr >= buf_end)
fill_buffer();
code = comment;
unary_delim = parser_state_tos->last_u_d;
break;
}
while (*(buf_ptr - 1) == *buf_ptr || *buf_ptr == '=') {
/*
* handle ||, &&, etc, and also things as in int *****i
*/
if (++buf_ptr >= buf_end)
fill_buffer();
}
code = (parser_state_tos->last_u_d ? unary_op : binary_op);
unary_delim = true;
} /* end of switch */
if (code != newline) {
l_struct = false;
last_code = code;
}
token_end = buf_ptr;
if (buf_ptr >= buf_end) /* check for input buffer empty */
fill_buffer();
parser_state_tos->last_u_d = unary_delim;
return (code);
}
/*
* Add the given keyword to the keyword table, using val as the keyword type
*/
addkey(key, val)
char *key;
enum rwcodes val;
{
register struct templ *p = specials;
while (p->rwd)
if (p->rwd[0] == key[0] && strcmp(p->rwd, key) == 0)
return;
else
p++;
if (user_specials == 0)
{
user_specials = (struct templ *) xmalloc (5 * sizeof (struct templ));
if (user_specials == 0)
{
fputs ("indent: out of memory\n", stderr);
exit (1);
}
user_specials_max = 5;
user_specials_idx = 0;
}
else if (user_specials_idx == user_specials_max)
{
user_specials_max += 5;
user_specials = (struct templ *) xrealloc ((char *) user_specials,
user_specials_max
* sizeof (struct templ));
}
p = &user_specials[user_specials_idx++];
p->rwd = key;
p->rwcode = val;
p[1].rwd = 0;
p[1].rwcode = 0;
return;
}

359
src/util/indent/parse.c Normal file
View File

@ -0,0 +1,359 @@
/*
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980 The Regents of the University of California.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley, the University of Illinois,
* Urbana, and Sun Microsystems, Inc. The name of either University
* or Sun Microsystems may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static char sccsid[] = "@(#)parse.c 5.8 (Berkeley) 9/15/88";
#endif /* not lint */
#include "indent_globs.h"
struct parser_state *parser_state_tos;
/* like ++parser_state_tos->tos but checks for stack overflow and extends
stack if necessary. */
static int
inc_pstack ()
{
if (++parser_state_tos->tos >= parser_state_tos->p_stack_size)
{
parser_state_tos->p_stack_size *= 2;
parser_state_tos->p_stack = (enum codes *)
xrealloc (parser_state_tos->p_stack,
parser_state_tos->p_stack_size * sizeof (enum codes));
parser_state_tos->il = (int *)
xrealloc (parser_state_tos->il,
parser_state_tos->p_stack_size * sizeof (int));
parser_state_tos->cstk = (int *)
xrealloc (parser_state_tos->cstk,
parser_state_tos->p_stack_size * sizeof (int));
}
return parser_state_tos->tos;
}
void
parse(tk)
enum codes tk; /* the code for the construct scanned */
{
int i;
#ifdef debug
printf("%2d - %s\n", tk, token);
#endif
while (parser_state_tos->p_stack[parser_state_tos->tos] == ifhead && tk != elselit) {
/* true if we have an if without an else */
parser_state_tos->p_stack[parser_state_tos->tos] = stmt; /* apply the if(..) stmt ::= stmt
* reduction */
reduce(); /* see if this allows any reduction */
}
switch (tk) { /* go on and figure out what to do with the
* input */
case decl: /* scanned a declaration word */
parser_state_tos->search_brace = btype_2;
/* indicate that following brace should be on same line */
if (parser_state_tos->p_stack[parser_state_tos->tos] != decl) { /* only put one declaration
* onto stack */
break_comma = true; /* while in declaration, newline should be
* forced after comma */
parser_state_tos->p_stack[inc_pstack()] = decl;
parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->i_l_follow;
if (ljust_decl) {/* only do if we want left justified
* declarations */
parser_state_tos->ind_level = 0;
for (i = parser_state_tos->tos - 1; i > 0; --i)
if (parser_state_tos->p_stack[i] == decl)
/* indentation is number of declaration levels deep
we are times spaces per level */
parser_state_tos->ind_level += ind_size;
parser_state_tos->i_l_follow = parser_state_tos->ind_level;
}
}
break;
case ifstmt: /* scanned if (...) */
if (parser_state_tos->p_stack[parser_state_tos->tos] == elsehead
&& else_if) /* "else if ..." */
parser_state_tos->i_l_follow = parser_state_tos->il[parser_state_tos->tos];
case dolit: /* 'do' */
case forstmt: /* for (...) */
inc_pstack();
parser_state_tos->p_stack[parser_state_tos->tos] = tk;
parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->ind_level = parser_state_tos->i_l_follow;
parser_state_tos->i_l_follow += ind_size; /* subsequent statements should be indented 1 */
parser_state_tos->search_brace = btype_2;
break;
case lbrace: /* scanned { */
break_comma = false; /* don't break comma in an initial list */
if (parser_state_tos->p_stack[parser_state_tos->tos] == stmt || parser_state_tos->p_stack[parser_state_tos->tos] == decl
|| parser_state_tos->p_stack[parser_state_tos->tos] == stmtl)
/* it is a random, isolated stmt group or a declaration */
parser_state_tos->i_l_follow += ind_size;
else {
if (s_code == e_code) {
/*
* only do this if there is nothing on the line
*/
parser_state_tos->ind_level -= ind_size;
/*
* it is a group as part of a while, for, etc.
*/
/* For -bl formatting, indent by brace_indent
additional spaces
e.g.
if (foo == bar)
{
<--> brace_indent spaces (in this example, 4)
*/
if (!btype_2)
{
parser_state_tos->ind_level += brace_indent;
parser_state_tos->i_l_follow += brace_indent;
if (parser_state_tos->p_stack[parser_state_tos->tos] == swstmt)
case_ind += brace_indent;
}
if (parser_state_tos->p_stack[parser_state_tos->tos] == swstmt
&& case_indent
>= ind_size)
parser_state_tos->ind_level -= ind_size;
/*
* for a switch, brace should be two levels out from the code
*/
}
}
inc_pstack();
parser_state_tos->p_stack[parser_state_tos->tos] = lbrace;
parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->ind_level;
inc_pstack();
parser_state_tos->p_stack[parser_state_tos->tos] = stmt;
/* allow null stmt between braces */
parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->i_l_follow;
break;
case whilestmt: /* scanned while (...) */
if (parser_state_tos->p_stack[parser_state_tos->tos] == dohead) {
/* it is matched with do stmt */
parser_state_tos->ind_level = parser_state_tos->i_l_follow = parser_state_tos->il[parser_state_tos->tos];
inc_pstack();
parser_state_tos->p_stack[parser_state_tos->tos] = whilestmt;
parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->ind_level = parser_state_tos->i_l_follow;
}
else { /* it is a while loop */
inc_pstack();
parser_state_tos->p_stack[parser_state_tos->tos] = whilestmt;
parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->i_l_follow;
parser_state_tos->i_l_follow += ind_size;
parser_state_tos->search_brace = btype_2;
}
break;
case elselit: /* scanned an else */
if (parser_state_tos->p_stack[parser_state_tos->tos] != ifhead)
diag(1, "Unmatched 'else'");
else {
parser_state_tos->ind_level = parser_state_tos->il[parser_state_tos->tos]; /* indentation for else should
* be same as for if */
/* everything following should be in 1 level */
parser_state_tos->i_l_follow = parser_state_tos->ind_level + ind_size;
parser_state_tos->p_stack[parser_state_tos->tos] = elsehead;
/* remember if with else */
parser_state_tos->search_brace = btype_2 | else_if;
}
break;
case rbrace: /* scanned a } */
/* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */
if (parser_state_tos->p_stack[parser_state_tos->tos - 1] == lbrace) {
parser_state_tos->ind_level = parser_state_tos->i_l_follow = parser_state_tos->il[--parser_state_tos->tos];
parser_state_tos->p_stack[parser_state_tos->tos] = stmt;
}
else
diag(1, "Stmt nesting error.");
break;
case swstmt: /* had switch (...) */
inc_pstack();
parser_state_tos->p_stack[parser_state_tos->tos] = swstmt;
parser_state_tos->cstk[parser_state_tos->tos] = case_ind;
/* save current case indent level */
parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->i_l_follow;
case_ind = parser_state_tos->i_l_follow + case_indent; /* cases should be one
* level down from
* switch */
/* statements should be two levels in */
parser_state_tos->i_l_follow += case_indent + ind_size;
parser_state_tos->search_brace = btype_2;
break;
case semicolon: /* this indicates a simple stmt */
break_comma = false; /* turn off flag to break after commas in a
* declaration */
inc_pstack();
parser_state_tos->p_stack[parser_state_tos->tos] = stmt;
parser_state_tos->il[parser_state_tos->tos] = parser_state_tos->ind_level;
break;
default: /* this is an error */
diag(1, "Unknown code to parser");
return;
} /* end of switch */
reduce(); /* see if any reduction can be done */
#ifdef debug
for (i = 1; i <= parser_state_tos->tos; ++i)
printf("(%d %d)", parser_state_tos->p_stack[i], parser_state_tos->il[i]);
printf("\n");
#endif
return;
}
/*
* Copyright (C) 1976 by the Board of Trustees of the University of Illinois
*
* All rights reserved
*
*
* NAME: reduce
*
* FUNCTION: Implements the reduce part of the parsing algorithm
*
* ALGORITHM: The following reductions are done. Reductions are repeated until
* no more are possible.
*
* Old TOS New TOS <stmt> <stmt> <stmtl> <stmtl> <stmt> <stmtl> do
* <stmt> "dostmt" if <stmt> "ifstmt" switch <stmt> <stmt> decl
* <stmt> <stmt> "ifelse" <stmt> <stmt> for <stmt> <stmt> while
* <stmt> <stmt> "dostmt" while <stmt>
*
* On each reduction, parser_state_tos->i_l_follow (the indentation for the following line) is
* set to the indentation level associated with the old TOS.
*
* PARAMETERS: None
*
* RETURNS: Nothing
*
* GLOBALS: parser_state_tos->cstk parser_state_tos->i_l_follow = parser_state_tos->il parser_state_tos->p_stack = parser_state_tos->tos =
*
* CALLS: None
*
* CALLED BY: parse 
*
* HISTORY: initial coding November 1976 D A Willcox of CAC
*
*/
/*----------------------------------------------*\
| REDUCTION PHASE |
\*----------------------------------------------*/
reduce()
{
register int i;
for (;;) { /* keep looping until there is nothing left to
* reduce */
switch (parser_state_tos->p_stack[parser_state_tos->tos]) {
case stmt:
switch (parser_state_tos->p_stack[parser_state_tos->tos - 1]) {
case stmt:
case stmtl:
/* stmtl stmt or stmt stmt */
parser_state_tos->p_stack[--parser_state_tos->tos] = stmtl;
break;
case dolit: /* <do> <stmt> */
parser_state_tos->p_stack[--parser_state_tos->tos] = dohead;
parser_state_tos->i_l_follow = parser_state_tos->il[parser_state_tos->tos];
break;
case ifstmt:
/* <if> <stmt> */
parser_state_tos->p_stack[--parser_state_tos->tos] = ifhead;
for (i = parser_state_tos->tos - 1;
(
parser_state_tos->p_stack[i] != stmt
&&
parser_state_tos->p_stack[i] != stmtl
&&
parser_state_tos->p_stack[i] != lbrace
);
--i);
parser_state_tos->i_l_follow = parser_state_tos->il[i];
/*
* for the time being, we will assume that there is no else on
* this if, and set the indentation level accordingly. If an
* else is scanned, it will be fixed up later
*/
break;
case swstmt:
/* <switch> <stmt> */
case_ind = parser_state_tos->cstk[parser_state_tos->tos - 1];
case decl: /* finish of a declaration */
case elsehead:
/* <<if> <stmt> else> <stmt> */
case forstmt:
/* <for> <stmt> */
case whilestmt:
/* <while> <stmt> */
parser_state_tos->p_stack[--parser_state_tos->tos] = stmt;
parser_state_tos->i_l_follow = parser_state_tos->il[parser_state_tos->tos];
break;
default: /* <anything else> <stmt> */
return;
} /* end of section for <stmt> on top of stack */
break;
case whilestmt: /* while (...) on top */
if (parser_state_tos->p_stack[parser_state_tos->tos - 1] == dohead) {
/* it is termination of a do while */
parser_state_tos->p_stack[--parser_state_tos->tos] = stmt;
break;
}
else
return;
default: /* anything else on top */
return;
}
}
}

View File

@ -0,0 +1,415 @@
/*
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980 The Regents of the University of California.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley, the University of Illinois,
* Urbana, and Sun Microsystems, Inc. The name of either University
* or Sun Microsystems may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static char sccsid[] = "@(#)pr_comment.c 5.9 (Berkeley) 9/15/88";
#endif /* not lint */
/*
* NAME:
* pr_comment
*
* FUNCTION:
* This routine takes care of scanning and printing comments.
*
* ALGORITHM:
* 1) Decide where the comment should be aligned, and if lines should
* be broken.
* 2) If lines should not be broken and filled, just copy up to end of
* comment.
* 3) If lines should be filled, then scan thru input_buffer copying
* characters to com_buf. Remember where the last blank, tab, or
* newline was. When line is filled, print up to last blank and
* continue copying.
*
* HISTORY:
* November 1976 D A Willcox of CAC Initial coding
* 12/6/76 D A Willcox of CAC Modification to handle
* UNIX-style comments
*
*/
/*
* this routine processes comments. It makes an attempt to keep comments from
* going over the max line length. If a line is too long, it moves everything
* from the last blank to the next comment line. Blanks and tabs from the
* beginning of the input line are removed
*/
#include "indent_globs.h"
pr_comment()
{
int now_col; /* column we are in now */
int adj_max_col; /* Adjusted max_col for when we decide to
* spill comments over the right margin */
char *last_bl; /* points to the last blank in the output
* buffer */
char *t_ptr; /* used for moving string */
int unix_comment; /* tri-state variable used to decide if it is
* a unix-style comment. 0 means only blanks
* since '/ *', 1 means regular style comment, 2
* means unix style comment */
int break_delim = comment_delimiter_on_blankline;
int l_just_saw_decl = parser_state_tos->just_saw_decl;
#if 0
int parser_state_tos->last_nl = 0; /* true iff the last significant thing
* weve seen is a newline
*/
#endif
int one_liner = 1; /* true iff this comment is a one-liner */
adj_max_col = max_col;
parser_state_tos->just_saw_decl = 0;
last_bl = 0; /* no blanks found so far */
parser_state_tos->box_com = false; /* at first, assume that we are not in
* a boxed comment or some other
* comment that should not be touched */
++parser_state_tos->out_coms; /* keep track of number of comments */
unix_comment = 1; /* set flag to let us figure out if there is a
* unix-style comment ** DISABLED: use 0 to
* reenable this hack! */
/* Figure where to align and how to treat the comment */
if (parser_state_tos->col_1 && !format_col1_comments) { /* if comment starts in column
* 1 it should not be touched */
parser_state_tos->box_com = true;
parser_state_tos->com_col = 1;
}
else {
if (*buf_ptr == '-' || *buf_ptr == '*' || !format_comments) {
parser_state_tos->box_com = true; /* a comment with a '-' or '*' immediately
* after the '/ *' is assumed to be a boxed
* comment */
break_delim = 0;
}
if ( /* parser_state_tos->bl_line && */ (s_lab == e_lab) && (s_code == e_code)) {
/* klg: check only if this line is blank */
/*
* If this (*and previous lines are*) blank, dont put comment way
* out at left
*/
parser_state_tos->com_col = (parser_state_tos->ind_level - unindent_displace) + 1;
adj_max_col = block_comment_max_col;
if (parser_state_tos->com_col <= 1)
parser_state_tos->com_col = 1 + !format_col1_comments;
}
else {
register target_col;
break_delim = 0;
if (s_code != e_code)
target_col = count_spaces(compute_code_target(), s_code);
else {
target_col = 1;
if (s_lab != e_lab)
target_col = count_spaces(compute_label_target(), s_lab);
}
parser_state_tos->com_col = parser_state_tos->decl_on_line || parser_state_tos->ind_level == 0 ? decl_com_ind : com_ind;
/* If we are already past the position for the comment,
put it at the next tab stop. */
if (parser_state_tos->com_col < target_col)
parser_state_tos->com_col = ((target_col + 7) & ~7) + 1;
if (else_or_endif)
{
parser_state_tos->com_col = else_endif_col;
else_or_endif = false;
/* We want the comment to appear one space after the #else
or #endif. */
if (parser_state_tos->com_col < target_col)
parser_state_tos->com_col = target_col + 1;
}
if (parser_state_tos->com_col + 24 > adj_max_col)
adj_max_col = parser_state_tos->com_col + 24;
}
}
if (parser_state_tos->box_com) {
buf_ptr[-2] = 0;
parser_state_tos->n_comment_delta = 1 - count_spaces(1, cur_line);
buf_ptr[-2] = '/';
}
else {
parser_state_tos->n_comment_delta = 0;
while (*buf_ptr == ' ' || *buf_ptr == '\t')
buf_ptr++;
}
parser_state_tos->comment_delta = 0;
*e_com++ = '/'; /* put '/ *' into buffer */
*e_com++ = '*';
if (*buf_ptr != ' ' && !parser_state_tos->box_com)
*e_com++ = ' ';
*e_com = '\0';
if (troff) {
now_col = 1;
adj_max_col = 80;
}
else
now_col = count_spaces(parser_state_tos->com_col, s_com); /* figure what column we
* would be in if we
* printed the comment
* now */
/* Start to copy the comment */
while (1) { /* this loop will go until the comment is
* copied */
if (*buf_ptr > 040 && *buf_ptr != '*')
parser_state_tos->last_nl = 0;
check_size(com);
switch (*buf_ptr) { /* this checks for various spcl cases */
case 014: /* check for a form feed */
if (!parser_state_tos->box_com) { /* in a text comment, break the line here */
parser_state_tos->use_ff = true;
/* fix so dump_line uses a form feed */
dump_line();
last_bl = 0;
*e_com++ = ' ';
*e_com++ = '*';
*e_com++ = ' ';
while (*++buf_ptr == ' ' || *buf_ptr == '\t');
}
else {
if (++buf_ptr >= buf_end)
fill_buffer();
*e_com++ = 014;
}
break;
case '\n':
if (had_eof) { /* check for unexpected eof */
printf("Unterminated comment\n");
*e_com = '\0';
dump_line();
return;
}
one_liner = 0;
if (parser_state_tos->box_com || parser_state_tos->last_nl) { /* if this is a boxed comment,
* we dont ignore the newline */
if (s_com == e_com) {
*e_com++ = ' ';
*e_com++ = ' ';
}
*e_com = '\0';
if (!parser_state_tos->box_com && e_com - s_com > 3) {
if (break_delim == 1 && s_com[0] == '/'
&& s_com[1] == '*' && s_com[2] == ' ') {
char *t = e_com;
break_delim = 2;
e_com = s_com + 2;
*e_com = 0;
if (blanklines_before_blockcomments)
prefix_blankline_requested = 1;
dump_line();
e_com = t;
s_com[0] = s_com[1] = s_com[2] = ' ';
}
dump_line();
check_size(com);
*e_com++ = ' ';
*e_com++ = ' ';
}
dump_line();
now_col = parser_state_tos->com_col;
}
else {
parser_state_tos->last_nl = 1;
if (unix_comment != 1) { /* we not are in unix_style
* comment */
if (unix_comment == 0 && s_code == e_code) {
/*
* if it is a UNIX-style comment, ignore the
* requirement that previous line be blank for
* unindention
*/
parser_state_tos->com_col = ((parser_state_tos->ind_level - unindent_displace)
+ ind_size);
if (parser_state_tos->com_col <= 1)
parser_state_tos->com_col = 2;
}
unix_comment = 2; /* permanently remember that we are in
* this type of comment */
dump_line();
++line_no;
now_col = parser_state_tos->com_col;
*e_com++ = ' ';
/*
* fix so that the star at the start of the line will line
* up
*/
do /* flush leading white space */
if (++buf_ptr >= buf_end)
fill_buffer();
while (*buf_ptr == ' ' || *buf_ptr == '\t');
break;
}
if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t')
last_bl = e_com - 1;
/*
* if there was a space at the end of the last line, remember
* where it was
*/
else { /* otherwise, insert one */
last_bl = e_com;
check_size(com);
*e_com++ = ' ';
++now_col;
}
}
++line_no; /* keep track of input line number */
if (!parser_state_tos->box_com) {
int nstar = 1;
do { /* flush any blanks and/or tabs at start of
* next line */
if (++buf_ptr >= buf_end)
fill_buffer();
if (*buf_ptr == '*' && --nstar >= 0) {
if (++buf_ptr >= buf_end)
fill_buffer();
if (*buf_ptr == '/')
goto end_of_comment;
}
} while (*buf_ptr == ' ' || *buf_ptr == '\t');
}
else if (++buf_ptr >= buf_end)
fill_buffer();
break; /* end of case for newline */
case '*': /* must check for possibility of being at end
* of comment */
if (++buf_ptr >= buf_end) /* get to next char after * */
fill_buffer();
if (unix_comment == 0) /* set flag to show we are not in
* unix-style comment */
unix_comment = 1;
if (*buf_ptr == '/') { /* it is the end!!! */
end_of_comment:
if (++buf_ptr >= buf_end)
fill_buffer();
if (*(e_com - 1) != ' ' && !parser_state_tos->box_com) { /* insure blank before
* end */
*e_com++ = ' ';
++now_col;
}
if (break_delim == 1 && !one_liner && s_com[0] == '/'
&& s_com[1] == '*' && s_com[2] == ' ') {
char *t = e_com;
break_delim = 2;
e_com = s_com + 2;
*e_com = 0;
if (blanklines_before_blockcomments)
prefix_blankline_requested = 1;
dump_line();
e_com = t;
s_com[0] = s_com[1] = s_com[2] = ' ';
}
if (break_delim == 2 && e_com > s_com + 3
/* now_col > adj_max_col - 2 && !parser_state_tos->box_com */ ) {
*e_com = '\0';
dump_line();
now_col = parser_state_tos->com_col;
}
check_size(com);
*e_com++ = '*';
*e_com++ = '/';
*e_com = '\0';
parser_state_tos->just_saw_decl = l_just_saw_decl;
return;
}
else { /* handle isolated '*' */
*e_com++ = '*';
++now_col;
}
break;
default: /* we have a random char */
if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t')
unix_comment = 1; /* we are not in unix-style comment */
*e_com = *buf_ptr++;
if (buf_ptr >= buf_end)
fill_buffer();
if (*e_com == '\t') /* keep track of column */
now_col = ((now_col - 1) & tabmask) + tabsize + 1;
else if (*e_com == '\b') /* this is a backspace */
--now_col;
else
++now_col;
if (*e_com == ' ' || *e_com == '\t')
last_bl = e_com;
/* remember we saw a blank */
++e_com;
if (now_col > adj_max_col && !parser_state_tos->box_com && unix_comment == 1 && e_com[-1] > ' ') {
/*
* the comment is too long, it must be broken up
*/
if (break_delim == 1 && s_com[0] == '/'
&& s_com[1] == '*' && s_com[2] == ' ') {
char *t = e_com;
break_delim = 2;
e_com = s_com + 2;
*e_com = 0;
if (blanklines_before_blockcomments)
prefix_blankline_requested = 1;
dump_line();
e_com = t;
s_com[0] = s_com[1] = s_com[2] = ' ';
}
if (last_bl == 0) { /* we have seen no blanks */
last_bl = e_com; /* fake it */
*e_com++ = ' ';
}
*e_com = '\0'; /* print what we have */
*last_bl = '\0';
while (last_bl > s_com && last_bl[-1] < 040)
*--last_bl = 0;
e_com = last_bl;
dump_line();
*e_com++ = ' '; /* add blanks for continuation */
*e_com++ = ' ';
*e_com++ = ' ';
t_ptr = last_bl + 1;
last_bl = 0;
if (t_ptr >= e_com) {
while (*t_ptr == ' ' || *t_ptr == '\t')
t_ptr++;
while (*t_ptr != '\0') { /* move unprinted part of
* comment down in buffer */
if (*t_ptr == ' ' || *t_ptr == '\t')
last_bl = e_com;
*e_com++ = *t_ptr++;
}
}
*e_com = '\0';
now_col = count_spaces(parser_state_tos->com_col, s_com); /* recompute current
* position */
}
break;
}
}
}

View File

@ -0,0 +1,2 @@
#define VERSION_STRING \
"GNU indent 1.0. Based on Berkeley indent 5.11 (9/15/88)."

11
src/util/indent/wrapper Normal file
View File

@ -0,0 +1,11 @@
#!/bin/sh
MUDLIB=/user/mud/mudlib
case $1 in
/* | *..*)
echo illegal ;;
*)
if test -n "`echo $1 | sed 's/[a-zA-Z0-9._#%/]//g'`"; then
echo illegal; exit 1
fi
/user/mud/bin/indent ${MUDLIB}/$1 -lpc;;
esac

Some files were not shown because too many files have changed in this diff Show More