From 8537fb39bfe42f83ea73f45338a09770506411d0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 20 Nov 1995 17:08:30 +0100
Subject: [PATCH 001/351] added test for get_dir

Rev: src/test/create_testsuite:1.4
---
 src/test/create_testsuite | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 09756283de..6bfa0a1be4 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -1104,6 +1104,8 @@ test_eq(file_stat("conftest"),0)
 // - rm
 // - mkdir
 // - get_dir
+test_true(arrayp(get_dir(".")))
+
 // - cd
 // - getcwd
 test_true(stringp(getcwd()))
-- 
GitLab


From 400a9ab0ddc6c28e541d25fac96dd2fd8f825a18 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 10 Feb 1996 21:54:19 +0100
Subject: [PATCH 002/351] fixed (to work with BMML)

Rev: doc/builtin/aggregate_mapping:1.3
Rev: doc/builtin/arrayp:1.3
Rev: doc/builtin/backtrace:1.2
Rev: doc/builtin/call_function:1.2
Rev: doc/builtin/call_out_info:1.2
Rev: doc/builtin/combine_path:1.2
Rev: doc/builtin/crypt:1.2
Rev: doc/builtin/floatp:1.3
Rev: doc/builtin/functionp:1.3
Rev: doc/builtin/intp:1.3
Rev: doc/builtin/kill:1.2
Rev: doc/builtin/listp:1.3
Rev: doc/builtin/mappingp:1.3
Rev: doc/builtin/object_program:1.3
Rev: doc/builtin/objectp:1.3
Rev: doc/builtin/programp:1.3
Rev: doc/builtin/replace:1.3
Rev: doc/builtin/sscanf:1.3
Rev: doc/builtin/stringp:1.3
Rev: doc/operators/addition:1.2
Rev: doc/simulated/PI:1.3
Rev: doc/simulated/capitalize:1.3
Rev: doc/simulated/file_size:1.3
Rev: doc/simulated/filter_array:1.2
Rev: doc/simulated/get_function:1.2
Rev: doc/simulated/l_sizeof:1.2
Rev: doc/simulated/m_indices:1.2
Rev: doc/simulated/m_sizeof:1.2
Rev: doc/simulated/m_values:1.2
Rev: doc/simulated/map_array:1.2
Rev: doc/simulated/master:1.2
Rev: doc/simulated/member_array:1.2
Rev: doc/simulated/mklist:1.2
Rev: doc/simulated/read_bytes:1.2
Rev: doc/simulated/regexp:1.2
Rev: doc/simulated/search_array:1.2
Rev: doc/simulated/sort_array:1.3
Rev: doc/simulated/spawn:1.2
Rev: doc/simulated/strlen:1.2
Rev: doc/simulated/strstr:1.2
Rev: doc/simulated/sum_arrays:1.2
Rev: doc/simulated/this_function:1.3
Rev: doc/simulated/write_file:1.2
Rev: doc/types/array:1.3
Rev: doc/types/float:1.2
Rev: doc/types/function:1.2
Rev: doc/types/int:1.2
Rev: doc/types/list:1.2
Rev: doc/types/mapping:1.2
Rev: doc/types/object:1.2
Rev: doc/types/program:1.2
Rev: doc/types/string:1.2
---
 doc/builtin/aggregate_mapping |  2 +-
 doc/builtin/arrayp            |  4 +--
 doc/builtin/backtrace         |  6 ++--
 doc/builtin/call_function     |  3 ++
 doc/builtin/call_out_info     | 12 ++++----
 doc/builtin/combine_path      |  5 ++--
 doc/builtin/crypt             |  8 +++--
 doc/builtin/floatp            |  2 +-
 doc/builtin/functionp         |  2 +-
 doc/builtin/intp              |  2 +-
 doc/builtin/kill              | 56 +++++++++++++++++------------------
 doc/builtin/listp             |  2 +-
 doc/builtin/mappingp          |  2 +-
 doc/builtin/object_program    |  2 +-
 doc/builtin/objectp           |  2 +-
 doc/builtin/programp          |  2 +-
 doc/builtin/replace           | 11 ++++---
 doc/builtin/sscanf            | 18 ++++++-----
 doc/builtin/stringp           |  2 +-
 doc/operators/addition        |  4 +--
 doc/simulated/PI              |  3 ++
 doc/simulated/capitalize      |  3 ++
 doc/simulated/file_size       |  3 ++
 doc/simulated/filter_array    |  3 ++
 doc/simulated/get_function    |  3 ++
 doc/simulated/l_sizeof        |  3 ++
 doc/simulated/m_indices       |  3 ++
 doc/simulated/m_sizeof        |  3 ++
 doc/simulated/m_values        |  3 ++
 doc/simulated/map_array       |  3 ++
 doc/simulated/master          |  3 ++
 doc/simulated/member_array    |  3 ++
 doc/simulated/mklist          |  3 ++
 doc/simulated/read_bytes      |  3 ++
 doc/simulated/regexp          |  3 ++
 doc/simulated/search_array    |  3 ++
 doc/simulated/sort_array      |  3 ++
 doc/simulated/spawn           |  4 +--
 doc/simulated/strlen          |  3 ++
 doc/simulated/strstr          |  3 ++
 doc/simulated/sum_arrays      | 17 ++++++-----
 doc/simulated/this_function   |  3 ++
 doc/simulated/write_file      |  3 ++
 doc/types/array               | 45 +++++++++++++++-------------
 doc/types/float               | 29 ++++++++++--------
 doc/types/function            |  3 ++
 doc/types/int                 | 37 ++++++++++++-----------
 doc/types/list                | 41 +++++++++++++------------
 doc/types/mapping             | 49 ++++++++++++++++--------------
 doc/types/object              | 17 ++++++-----
 doc/types/program             |  3 ++
 doc/types/string              | 28 ++++++++++--------
 52 files changed, 295 insertions(+), 188 deletions(-)

diff --git a/doc/builtin/aggregate_mapping b/doc/builtin/aggregate_mapping
index 1526e41be3..498e6616da 100644
--- a/doc/builtin/aggregate_mapping
+++ b/doc/builtin/aggregate_mapping
@@ -4,7 +4,7 @@ NAME
 SYNTAX
 	mapping aggregate_mapping(mixed ... elems);
 	or
-	(< key1:val1, key2:val2, ... >)
+	([ key1:val1, key2:val2, ... ])
 
 DESCRIPTION
 	Groups the arguments together two and two to key-index pairs and
diff --git a/doc/builtin/arrayp b/doc/builtin/arrayp
index c6b844e20d..32c691eb54 100644
--- a/doc/builtin/arrayp
+++ b/doc/builtin/arrayp
@@ -11,5 +11,5 @@ KEYWORDS
 	array
 
 SEE ALSO
-	allocate, intp, programp, floatp, stringp, objectp, regexpp,
-	mappingp, listp, functionp
+	allocate, intp, programp, floatp, stringp, objectp, mappingp,
+	listp, functionp
diff --git a/doc/builtin/backtrace b/doc/builtin/backtrace
index 3d421acc48..ce824d420d 100644
--- a/doc/builtin/backtrace
+++ b/doc/builtin/backtrace
@@ -10,9 +10,9 @@ DESCRIPTION
 	in the stack. Each entry has this format:
 
 	({
-	   file, /* a string with the filename if known, else zero */
-	   function, /* The function-pointer to the called function */
-	   line, /* an integer containing the line if known, else zero */
+	   file,	/* a string with the filename if known, else zero */
+	   function,	/* The function-pointer to the called function */
+	   line,	/* an integer containing the line if known, else zero */
 	})
 
 	The current call frame will be last in the array, and the one above
diff --git a/doc/builtin/call_function b/doc/builtin/call_function
index fb4eafb870..0af1d5b98a 100644
--- a/doc/builtin/call_function
+++ b/doc/builtin/call_function
@@ -12,5 +12,8 @@ DESCRIPTION
 	you will never have to write call_function(), because you will use the
 	second syntax instead.
 
+KEYWORDS
+	function
+
 SEE ALSO
 	backtrace, get_function
diff --git a/doc/builtin/call_out_info b/doc/builtin/call_out_info
index c3399fe8ae..1b20ed3962 100644
--- a/doc/builtin/call_out_info
+++ b/doc/builtin/call_out_info
@@ -10,12 +10,12 @@ DESCRIPTION
 	contains an array that looks like this:
 
 	({
-	   time_left, /* an int */
-	   caller, /* the object that made the call out */
-	   function, /* the function to be called */
-	   arg1, /* the first argument, if any */
-	   arg2, /* the second argument, if any */
-	   ... /* and so on... */
+	   time_left,	/* an int */
+	   caller,	/* the object that made the call out */
+	   function,	/* the function to be called */
+	   arg1,	/* the first argument, if any */
+	   arg2,	/* the second argument, if any */
+	   ...  	/* and so on... */
 	})
 
 SEE ALSO
diff --git a/doc/builtin/combine_path b/doc/builtin/combine_path
index 84cd9cb5b3..49043c3c7a 100644
--- a/doc/builtin/combine_path
+++ b/doc/builtin/combine_path
@@ -17,7 +17,8 @@ EXAMPLES
 	> combine_path("/foo/bar","./sune.c");
 	Result: /foo/bar/sune.c
 
+KEYWORDS
+	file
+
 SEE ALSO
 	getcwd
-
-	
\ No newline at end of file
diff --git a/doc/builtin/crypt b/doc/builtin/crypt
index d4e0e5b68d..8add859493 100644
--- a/doc/builtin/crypt
+++ b/doc/builtin/crypt
@@ -16,8 +16,10 @@ DESCRIPTION
 
 EXAMPLES
 	To crypt a password use:
-		crypted_password = crypt(typed_password);
+	  crypted_password = crypt(typed_password);
 	To see if the same password was used again use:
-		matched = crypt(typed_password, crypted_password);
+	  matched = crypt(typed_password, crypted_password);
 
-		
\ No newline at end of file
+
+KEYWORDS
+	string
diff --git a/doc/builtin/floatp b/doc/builtin/floatp
index 4dfdab9df7..da740e9e4d 100644
--- a/doc/builtin/floatp
+++ b/doc/builtin/floatp
@@ -11,5 +11,5 @@ KEYWORDS
 	float
 
 SEE ALSO
-	intp, programp, arrayp, stringp, objectp, regexpp,
+	intp, programp, arrayp, stringp, objectp,
 	mappingp, listp, functionp
diff --git a/doc/builtin/functionp b/doc/builtin/functionp
index b6996bfe70..abb23b36ef 100644
--- a/doc/builtin/functionp
+++ b/doc/builtin/functionp
@@ -11,5 +11,5 @@ KEYWORDS
 	function
 
 SEE ALSO
-	intp, programp, arrayp, stringp, objectp, regexpp,
+	intp, programp, arrayp, stringp, objectp,
 	mappingp, listp, floatp
diff --git a/doc/builtin/intp b/doc/builtin/intp
index e04eeeb390..cbcd171065 100644
--- a/doc/builtin/intp
+++ b/doc/builtin/intp
@@ -11,5 +11,5 @@ KEYWORDS
 	int
 
 SEE ALSO
-	arrayp, programp, floatp, stringp, objectp, regexpp,
+	arrayp, programp, floatp, stringp, objectp,
 	mappingp, listp, functionp
diff --git a/doc/builtin/kill b/doc/builtin/kill
index ad0dc868a4..25588cfe3c 100644
--- a/doc/builtin/kill
+++ b/doc/builtin/kill
@@ -10,34 +10,34 @@ DESCRIPTION
 
 	Some signals and their supposed purpose:
 
-	SIGHUP	Hangup, sent to process when user logs out
-	SIGINT	Interrupt, normally sent by ctrl-c
-	SIGQUIT	Quit, sent by ctrl-\
-	SIGILL	Illegal instruction
-	SIGTRAP	Trap, mostly used by debuggers
-	SIGABRT	Aborts process, can be caught, used by uLPC whenever something
-		goes seriously wrong.
-	SIGBUS	Bus error
-	SIGFPE	Floating point error (such as division by zero)
-	SIGKILL	Really kill a process, cannot be caught
-	SIGUSR1	Signal reserved for whatever you want to use it for.
-	SIGSEGV	Segmentation fault, caused by accessing memory where you
-		shouldn't. Should never happen to uLPC.
-	SIGUSR2	Signal reserved for whatever you want to use it for.
-	SIGALRM	Signal used for timer interrupts.
-	SIGTERM	Termination signal
-	SIGSTKFLT Stack fault
-	SIGCHLD	Child process died
-	SIGCONT	Continue suspended
-	SIGSTOP	Stop process
-	SIGSTP	Suspend process
-	SIGTTIN	tty input for background process
-	SIGTTOU	tty output for background process
-	SIGXCPU	Out of cpu
-	SIGXFSZ	File size limit exceeded
-	SIGPROF	Profile trap
-	SIGWINCH Window change signal
-	
+	SIGHUP  	Hangup, sent to process when user logs out
+	SIGINT  	Interrupt, normally sent by ctrl-c
+	SIGQUIT 	Quit, sent by ctrl-\
+	SIGILL  	Illegal instruction
+	SIGTRAP 	Trap, mostly used by debuggers
+	SIGABRT 	Aborts process, can be caught, used by uLPC whenever something
+		        goes seriously wrong.
+	SIGBUS  	Bus error
+	SIGFPE  	Floating point error (such as division by zero)
+	SIGKILL 	Really kill a process, cannot be caught
+	SIGUSR1 	Signal reserved for whatever you want to use it for.
+	SIGSEGV 	Segmentation fault, caused by accessing memory where you
+		        shouldn't. Should never happen to uLPC.
+	SIGUSR2 	Signal reserved for whatever you want to use it for.
+	SIGALRM 	Signal used for timer interrupts.
+	SIGTERM 	Termination signal
+	SIGSTKFLT	Stack fault
+	SIGCHLD 	Child process died
+	SIGCONT 	Continue suspended
+	SIGSTOP 	Stop process
+	SIGSTP  	Suspend process
+	SIGTTIN 	tty input for background process
+	SIGTTOU 	tty output for background process
+	SIGXCPU 	Out of cpu
+	SIGXFSZ 	File size limit exceeded
+	SIGPROF 	Profile trap
+	SIGWINCH	Window change signal
+
 	Note that you have to use signame to translate the name of a signal
 	to it's number.
 
diff --git a/doc/builtin/listp b/doc/builtin/listp
index 25fdf57ced..16c92365f4 100644
--- a/doc/builtin/listp
+++ b/doc/builtin/listp
@@ -11,5 +11,5 @@ KEYWORDS
 	list
 
 SEE ALSO
-	intp, programp, arrayp, stringp, objectp, regexpp,
+	intp, programp, arrayp, stringp, objectp,
 	mappingp, floatp, functionp
diff --git a/doc/builtin/mappingp b/doc/builtin/mappingp
index 9eaa3b0e91..6247155ce8 100644
--- a/doc/builtin/mappingp
+++ b/doc/builtin/mappingp
@@ -11,5 +11,5 @@ KEYWORDS
 	mapping
 
 SEE ALSO
-	intp, programp, arrayp, stringp, objectp, regexpp,
+	intp, programp, arrayp, stringp, objectp,
 	listp, floatp, functionp
diff --git a/doc/builtin/object_program b/doc/builtin/object_program
index 028e16e896..88f634f560 100644
--- a/doc/builtin/object_program
+++ b/doc/builtin/object_program
@@ -7,7 +7,7 @@ SYNTAX
 DESCRIPTION
 	This function returns the program from which o was cloned.
 
-KEYWORD
+KEYWORDS
 	object
 
 SEE ALSO
diff --git a/doc/builtin/objectp b/doc/builtin/objectp
index d31cd55bc6..ee74c51b9f 100644
--- a/doc/builtin/objectp
+++ b/doc/builtin/objectp
@@ -11,5 +11,5 @@ KEYWORDS
 	object
 
 SEE ALSO
-	intp, programp, floatp, stringp, arrayp, regexpp,
+	intp, programp, floatp, stringp, arrayp,
 	mappingp, listp, functionp
diff --git a/doc/builtin/programp b/doc/builtin/programp
index 16304dbca7..83757aee93 100644
--- a/doc/builtin/programp
+++ b/doc/builtin/programp
@@ -11,5 +11,5 @@ KEYWORDS
 	program
 
 SEE ALSO
-	intp, listp, arrayp, stringp, objectp, regexpp,
+	intp, listp, arrayp, stringp, objectp,
 	mappingp, floatp, functionp
diff --git a/doc/builtin/replace b/doc/builtin/replace
index ea479ae070..32d2e1ed8a 100644
--- a/doc/builtin/replace
+++ b/doc/builtin/replace
@@ -14,17 +14,20 @@ DESCRIPTION
 	This function can do several kinds replacement operations, the
 	different syntaxes do different things as follow:
 
-	1) string replace(string s, string from, string to);
+	string replace(string s, string from, string to);
+
 	   When given strings as second and third argument, a copy of
 	   s with every occurance of 'from' return 'to'.
 
-	2) string replace(string s, string *from, string *to);
+	string replace(string s, string *from, string *to);
+
 	   When given arrays of strings as second and third argument,
 	   every occurance of from[0] in s is replaced by to[0],
 	   from[1] is replaced by to[1] and so on...
 
-	3) array replace(array a, mixed from, mixed to);
-	4) mapping replace(mapping a, mixed from, mixed to);
+	array replace(array a, mixed from, mixed to);	
+	mapping replace(mapping a, mixed from, mixed to);
+
 	   When the first argument is an array or mapping, the values in
 	   a are searched for values equal to from, which are replaced by
 	   to destructively.
diff --git a/doc/builtin/sscanf b/doc/builtin/sscanf
index af6bd6e990..22526c5210 100644
--- a/doc/builtin/sscanf
+++ b/doc/builtin/sscanf
@@ -9,13 +9,17 @@ DESCRIPTION
 	separated by "%d,%s,%c and %f. Every % corresponds to one of var1,
 	var2...
 
-	%d gives an integer
-	%f gives a float
-	%c matches one char but returns an integer
-	%s gives a string
-	%[set] matches a string containing a given set of characters.
-	 (thos given inside the brackets) %[^set] means any character
-	 ecept those inside brackets. %[0-9H] means any number or 'H'.
+	%d	gives an integer
+	%o	gives an octal integer
+	%x	gives a hexadecimal integer
+	%D	gives an integer that is either octal (leading zero),
+		hexadecimal (leading 0x) or decimal.
+	%f	gives a float
+	%c	matches one char and returns it as an integer
+	%s	gives a string
+	%[set]	matches a string containing a given set of characters.
+		(thos given inside the brackets) %[^set] means any character
+		ecept those inside brackets. %[0-9H] means any number or 'H'.
 
 	If a * is put between the percent and the operator, the operator
 	will not only match it's argument, not assign any variables.
diff --git a/doc/builtin/stringp b/doc/builtin/stringp
index 15fa5d0eee..b153861faf 100644
--- a/doc/builtin/stringp
+++ b/doc/builtin/stringp
@@ -11,5 +11,5 @@ KEYWORDS
 	string
 
 SEE ALSO
-	intp, listp, arrayp, programp, objectp, regexpp,
+	intp, listp, arrayp, programp, objectp,
 	mappingp, floatp, functionp
diff --git a/doc/operators/addition b/doc/operators/addition
index 984838a522..f7ab8da026 100644
--- a/doc/operators/addition
+++ b/doc/operators/addition
@@ -15,8 +15,8 @@ DESCRIPTION
 	the number is converted to a printable string first.
 
 EXAMPLES
-	"a"+10		returns "a10"
-	10+20		returns 30
+	"a"+10  	returns "a10"
+	10+20   	returns 30
 	({1})+({2})	returns ({1,2})
 	(<1>)+(<1>)	returns (<1,1>)
 
diff --git a/doc/simulated/PI b/doc/simulated/PI
index 4723df2dc2..7326afddff 100644
--- a/doc/simulated/PI
+++ b/doc/simulated/PI
@@ -6,3 +6,6 @@ SYNTAX
 
 DESCRIPTION
 	This is not a function, it is a constant added by simulate.lpc.
+
+KEYWORDS
+	float
diff --git a/doc/simulated/capitalize b/doc/simulated/capitalize
index afcd237894..fd6f8bb120 100644
--- a/doc/simulated/capitalize
+++ b/doc/simulated/capitalize
@@ -8,5 +8,8 @@ DESCRIPTION
 	Convert the first character in str to upper case, and return the
 	new string.
 
+KEYWORDS
+	string
+
 SEE ALSO
 	builtin/lower_case, builtin/upper_case
diff --git a/doc/simulated/file_size b/doc/simulated/file_size
index 05a07d0ea2..650918d139 100644
--- a/doc/simulated/file_size
+++ b/doc/simulated/file_size
@@ -9,5 +9,8 @@ DESCRIPTION
 	does not exist, or that it is not readable by you. Size -2
 	indicates that it is a directory.
 
+KEYWORDS
+	file
+
 SEE ALSO
 	write_file, read_bytes
diff --git a/doc/simulated/filter_array b/doc/simulated/filter_array
index bda384c9cd..4ad54ca6e1 100644
--- a/doc/simulated/filter_array
+++ b/doc/simulated/filter_array
@@ -21,5 +21,8 @@ DESCRIPTION
 	Filter array calls all functionpointers in the array arr, and
 	return all that returned true.
 
+KEYWORDS
+	array
+
 SEE ALSO
 	sum_arrays, map_array
diff --git a/doc/simulated/get_function b/doc/simulated/get_function
index 581ec53314..a1da375025 100644
--- a/doc/simulated/get_function
+++ b/doc/simulated/get_function
@@ -6,3 +6,6 @@ SYNTAX
 
 DESCRIPTION
 	Defined as: return o[name];
+
+KEYWORDS
+	function
diff --git a/doc/simulated/l_sizeof b/doc/simulated/l_sizeof
index d8daf84a53..002009287f 100644
--- a/doc/simulated/l_sizeof
+++ b/doc/simulated/l_sizeof
@@ -7,5 +7,8 @@ SYNTAX
 DESCRIPTION
 	This function is equal to builtin/sizeof.
 
+KEYWORDS
+	list
+
 SEE ALSO
 	builtin/sizeof
\ No newline at end of file
diff --git a/doc/simulated/m_indices b/doc/simulated/m_indices
index 657023deb8..01183e045f 100644
--- a/doc/simulated/m_indices
+++ b/doc/simulated/m_indices
@@ -7,5 +7,8 @@ SYNTAX
 DESCRIPTION
 	This function is equal to builtin/indices
 
+KEYWORDS
+	mapping
+
 SEE ALSO
 	builtin/indices
diff --git a/doc/simulated/m_sizeof b/doc/simulated/m_sizeof
index 63db3ea12e..a716131e34 100644
--- a/doc/simulated/m_sizeof
+++ b/doc/simulated/m_sizeof
@@ -7,5 +7,8 @@ SYNTAX
 DESCRIPTION
 	This function is equal to builtin/sizeof.
 
+KEYWORDS
+	mapping
+
 SEE ALSO
 	builtin/sizeof
\ No newline at end of file
diff --git a/doc/simulated/m_values b/doc/simulated/m_values
index 95175ccd02..6624758740 100644
--- a/doc/simulated/m_values
+++ b/doc/simulated/m_values
@@ -7,5 +7,8 @@ SYNTAX
 DESCRIPTION
 	This function is equal to builtin/values
 
+KEYWORDS
+	mapping
+
 SEE ALSO
 	builtin/values
diff --git a/doc/simulated/map_array b/doc/simulated/map_array
index be8fe70b5c..a4c1987289 100644
--- a/doc/simulated/map_array
+++ b/doc/simulated/map_array
@@ -21,5 +21,8 @@ DESCRIPTION
 	Map array calls the functions in the array arr:
 	arr[x]=arr[x]->fun(@ args);
 
+KEYWORDS
+	array
+
 SEE ALSO
 	sum_arrays, filter_array
diff --git a/doc/simulated/master b/doc/simulated/master
index f0594d1aa6..7015cbfaee 100644
--- a/doc/simulated/master
+++ b/doc/simulated/master
@@ -6,3 +6,6 @@ SYNTAX
 
 DESCRIPTION
 	Master is added by the master object to make it easier to access it.
+
+KEYWORDS
+	object
diff --git a/doc/simulated/member_array b/doc/simulated/member_array
index 0abc1df604..c336f183f9 100644
--- a/doc/simulated/member_array
+++ b/doc/simulated/member_array
@@ -7,3 +7,6 @@ SYNTAX
 DESCRIPTION
 	Returns the index of the first occurence of item in array arr.
 	If not found, then -1 is returned.
+
+KEYWORDS
+	array
diff --git a/doc/simulated/mklist b/doc/simulated/mklist
index 2629ce1573..836e52c72e 100644
--- a/doc/simulated/mklist
+++ b/doc/simulated/mklist
@@ -15,5 +15,8 @@ EXAMPLE
 	    3
 	>)
 
+KEYWORDS
+	list
+
 SEE ALSO
 	builtin/aggregate_list
\ No newline at end of file
diff --git a/doc/simulated/read_bytes b/doc/simulated/read_bytes
index 95e5e32ada..7f042ad694 100644
--- a/doc/simulated/read_bytes
+++ b/doc/simulated/read_bytes
@@ -8,6 +8,9 @@ DESCRIPTION
 	Read len number of bytes from file file staring at byte start and
 	return it as a string.
 
+KEYWORDS
+	file
+
 SEE ALSO
 	write_file
 
diff --git a/doc/simulated/regexp b/doc/simulated/regexp
index 05f14528ed..3d3ac3b8eb 100644
--- a/doc/simulated/regexp
+++ b/doc/simulated/regexp
@@ -7,5 +7,8 @@ SYNTAX
 DESCRIPTION
 	Return those strings in arr that matches the regexp in reg.
 
+KEYWORDS
+	string
+
 SEE ALSO
 	regexp/regexp
diff --git a/doc/simulated/search_array b/doc/simulated/search_array
index 98468d9533..8db3a37a92 100644
--- a/doc/simulated/search_array
+++ b/doc/simulated/search_array
@@ -13,5 +13,8 @@ DESCRIPTION
 	first call that returned true instead or returning an array of the
 	returned values. If no call returns true, -1 is returned.
 
+KEYWORDS
+	array
+
 SEE ALSO
 	sum_arrays, filter_array, member_array
diff --git a/doc/simulated/sort_array b/doc/simulated/sort_array
index f50e9753c1..de6a6ea4f5 100644
--- a/doc/simulated/sort_array
+++ b/doc/simulated/sort_array
@@ -11,5 +11,8 @@ DESCRIPTION
 	sent as 3rd, 4th etc. argument to fun. If fun is omitted, < is unsed
 	instead.
 
+KEYWORDS
+	array
+
 SEE ALSO
 	map_array, filter_array
diff --git a/doc/simulated/spawn b/doc/simulated/spawn
index c04ee827b7..231512d32d 100644
--- a/doc/simulated/spawn
+++ b/doc/simulated/spawn
@@ -17,6 +17,6 @@ DESCRIPTION
 	should go.
 
 SEE ALSO
-	popen, files/fork, files/exec, files/files->pipe,
-	files/files->dup2
+	popen, files/fork, files/exec, files/file->pipe,
+	files/file->dup2
 
diff --git a/doc/simulated/strlen b/doc/simulated/strlen
index 905b996047..a9b0ba0704 100644
--- a/doc/simulated/strlen
+++ b/doc/simulated/strlen
@@ -7,5 +7,8 @@ SYNTAX
 DESCRIPTION
 	This function is equal to builtin/sizeof.
 
+KEYWORDS
+	string
+
 SEE ALSO
 	builtin/sizeof
\ No newline at end of file
diff --git a/doc/simulated/strstr b/doc/simulated/strstr
index 08bd1463fa..29d12b5d5d 100644
--- a/doc/simulated/strstr
+++ b/doc/simulated/strstr
@@ -8,5 +8,8 @@ DESCRIPTION
 	Return the position of str2 in str1, if str2 can't be found in str1
 	-1 is returned.
 
+KEYWORDS
+	string
+
 SEE ALSO
 	builtin/sscanf, builtin/explode
diff --git a/doc/simulated/sum_arrays b/doc/simulated/sum_arrays
index 7c9bfb881e..414f09d2f1 100644
--- a/doc/simulated/sum_arrays
+++ b/doc/simulated/sum_arrays
@@ -7,18 +7,21 @@ SYNTAX
 DESCRIPTION
 	Works like this:
 
-        mixed *sum_arrays(function fun,mixed *arr1,...)
-        {
-          int e;
+	mixed *sum_arrays(function fun,mixed *arr1,...)
+	{
+	  int e;
 	  mixed *res=allocate(sizeof(arr1));
-          for(e=0;e<sizeof(arr1);e++)
-          {
+	  for(e=0;e<sizeof(arr1);e++)
+	  {
 	    res[e]=fun(arr1[e],arr2[e],...);
-          }
+	  }
 	  return res;
-        }
+	}
 
 	Simple ehh?
 
+KEYWORDS
+	array
+
 SEE ALSO
 	map_array, filter_array, search_array
diff --git a/doc/simulated/this_function b/doc/simulated/this_function
index ee659e9545..d1bdf36935 100644
--- a/doc/simulated/this_function
+++ b/doc/simulated/this_function
@@ -8,6 +8,9 @@ DESCRIPTION
 	Returns a functionpointer to the current function, useful for
 	making recursive lambda-functions.
 
+KEYWORDS
+	function
+
 SEE ALSO
 	builtin/get_function, builtin/function_name, builtin/function_object,
 	builtin/backtrace
diff --git a/doc/simulated/write_file b/doc/simulated/write_file
index 04e7c1fa84..174e7084ab 100644
--- a/doc/simulated/write_file
+++ b/doc/simulated/write_file
@@ -7,5 +7,8 @@ SYNTAX
 DESCRIPTION
 	Append the string str onto the file file. Returns number of bytes written.
 
+KEYWORDS
+	file
+
 SEE ALSO
 	read_file
diff --git a/doc/types/array b/doc/types/array
index 5576582658..2bbbf51f37 100644
--- a/doc/types/array
+++ b/doc/types/array
@@ -20,27 +20,30 @@ DESCRIPTION
 	Here follows a list of operators that applies to arrays:
 	In this list a and b is used to represent an array expression:
 
-	a + b  : summation ( ({1}) + ({2}) returns ({1,2}) )
-	a - b  : subtraction, returns a copy of a with all values that are
-	         present in b removed, ( ({1, 2, 3}) - ({2}) returns ({1,3}) )
-	a & b  : intersection, return an array with all values that are
-		 present in both a and b
-	a | b  : union, return an array with all values that are present in
-	         a or b, differs from summation in that values that are
-	         present in both a and b are only returned once.
-	a ^ b  : xor, return an array with all values that are present in
-	         a or b but not in both.
-	a * c  : multiplication (c is a string) same thing as implode(a,c)
-	a == b : returns 1 if a is the same array as b, same size and values
-	         is not enough.
-	a != b : returns 0 if a is the same array as b, same size and values
-	         is not enough.
-	! a    : boolean not, returns 0
-	a[c]   : indexing, returns element c in the array (c is an int)
-	a[c]=d : setting, sets element c in the array to d (c is an int)
-	a[c..d]: range (c & d are ints) returns an array containing a pice of
-	         the array a. The piece starts at element c and ends (and
-	         includes) element d.
+	a + b	summation ( ({1}) + ({2}) returns ({1,2}) )
+	a - b	subtraction, returns a copy of a with all values that are
+		present in b removed, ( ({1, 2, 3}) - ({2}) returns ({1,3}) )
+	a & b	intersection, return an array with all values that are
+		present in both a and b
+	a | b	union, return an array with all values that are present in
+		a or b, differs from summation in that values that are
+		present in both a and b are only returned once.
+	a ^ b	xor, return an array with all values that are present in
+		a or b but not in both.
+	a * c	multiplication (c is a string) same thing as implode(a,c)
+	a == b	returns 1 if a is the same array as b, same size and values
+		is not enough.
+	a != b	returns 0 if a is the same array as b, same size and values
+		is not enough.
+	! a	boolean not, returns 0
+	a[c]	indexing, returns element c in the array (c is an int)
+	a[c]=d	setting, sets element c in the array to d (c is an int)
+	a[c..d]	range (c & d are ints) returns an array containing a pice of
+		the array a. The piece starts at element c and ends (and
+		includes) element d.
+
+KEYWORDS
+	type
 
 SEE ALSO
 	mapping, list, builtin/allocate, builtin/sizeof, builtin/values
diff --git a/doc/types/float b/doc/types/float
index 4b27d692e4..ca52ca30af 100644
--- a/doc/types/float
+++ b/doc/types/float
@@ -13,22 +13,25 @@ DESCRIPTION
 	A list of operators that applies to floats follows:
 	In this list a and b is used to represent a float expression:
 
-	a + b  : summation
-	a - b  : subtraction
-	a * b  : multiplication
-	a / b  : integer division
-	a % b  : modulo ( same thing as  a - floor( a / b ) * b )
-	- a    : negation
-	a == b : return 1 if a is equal to b, 0 otherwise
-	a != b : return 0 if a is equal to b, 1 otherwise
-	a < b  : returns 1 if a is lesser than b, 0 otherwise
-	a <= b : returns 1 if a is lesser or equal to b, 0 otherwise
-	a > b  : returns 1 if a is greater than b, 0 otherwise
-	a >= b : returns 1 if a is greater or equal to b, 0 otherwise
+	a + b	summation
+	a - b	subtraction
+	a * b	multiplication
+	a / b	integer division
+	a % b	modulo ( same thing as  a - floor( a / b ) * b )
+	- a	negation
+	a == b	return 1 if a is equal to b, 0 otherwise
+	a != b	return 0 if a is equal to b, 1 otherwise
+	a < b	returns 1 if a is lesser than b, 0 otherwise
+	a <= b	returns 1 if a is lesser or equal to b, 0 otherwise
+	a > b	returns 1 if a is greater than b, 0 otherwise
+	a >= b	returns 1 if a is greater or equal to b, 0 otherwise
 
 NOTA BENE
 	floats and ints cannot be used together, they have to be cast
 	to the same type first.
 
+KEYWORDS
+	type
+
 SEE ALSO
-	float, modules/math
+	math/sin, math/cos, math/tan, math/sqrt
diff --git a/doc/types/function b/doc/types/function
index d0db01411f..ad60ad37a6 100644
--- a/doc/types/function
+++ b/doc/types/function
@@ -13,6 +13,9 @@ DESCRIPTION
 	become 0. If you try to call a functionpointer that has is 0 then 0
 	will be returned.
 
+KEYWORDS
+	type
+
 SEE ALSO
 	object, builtin/call_function, builtin/functionp,
 	builtin/function_object, builtin/function_name
diff --git a/doc/types/int b/doc/types/int
index b4fa880200..e174c18023 100644
--- a/doc/types/int
+++ b/doc/types/int
@@ -14,23 +14,26 @@ DESCRIPTION
 
 	In this list a and b is used to represent an integer expression:
 
-	a + b  : summation
-	a - b  : subtraction
-	a * b  : multiplication
-	a / b  : integer division
-	a % b  : modulo ( same thing as  a - ( a / b ) * b )
-	a | b  : bitwise or
-	a & b  : bitwise and
-	a ^ b  : bitwise xor
-	! a    : boolean not, returns 1 if a is zero 0 otherwise
-	~ a    : bitwise complement
-	- a    : negation
-	a == b : return 1 if a is equal to b, 0 otherwise
-	a != b : return 0 if a is equal to b, 1 otherwise
-	a < b  : returns 1 if a is lesser than b, 0 otherwise
-	a <= b : returns 1 if a is lesser or equal to b, 0 otherwise
-	a > b  : returns 1 if a is greater than b, 0 otherwise
-	a >= b : returns 1 if a is greater or equal to b, 0 otherwise
+	a + b	summation
+	a - b	subtraction
+	a * b	multiplication
+	a / b	integer division
+	a % b	modulo ( same thing as  a - ( a / b ) * b )
+	a | b	bitwise or
+	a & b	bitwise and
+	a ^ b	bitwise xor
+	! a	boolean not, returns 1 if a is zero 0 otherwise
+	~ a	bitwise complement
+	- a	negation
+	a == b	return 1 if a is equal to b, 0 otherwise
+	a != b	return 0 if a is equal to b, 1 otherwise
+	a < b	returns 1 if a is lesser than b, 0 otherwise
+	a <= b	returns 1 if a is lesser or equal to b, 0 otherwise
+	a > b	returns 1 if a is greater than b, 0 otherwise
+	a >= b	returns 1 if a is greater or equal to b, 0 otherwise
+
+KEYWORDS
+	type
 
 SEE ALSO
 	float	
diff --git a/doc/types/list b/doc/types/list
index ceee090925..b361d0915c 100644
--- a/doc/types/list
+++ b/doc/types/list
@@ -11,25 +11,28 @@ DESCRIPTION
 	Here follows a list of operators that applies to lists:
 	In this list a and b is used to represent a list expression:
 
-	a + b  : summation ( (<1>) + (<2>) returns (<1,2>) )
-	a - b  : subtraction, returns a copy of a with all values that are
-                 present in b removed.
-        a & b  : intersection, return a list with all values that are
-                 present in both a & b.
-        a | b  : union, return a list with all values that are present in
-                 a or b, differs from summation in that values that are
-                 present in both a and b are only returned once.
-        a ^ b  : xor, return a list with all indices that are present in
-                 a or b but not in both.
-        a == b : returns 1 if a is the same list as b, same size and values
-                 is not enough.
-        a != b : returns 1 if a is the same list as b, same size and values
-                 is not enough.
-        ! a    : boolean not, returns 0
-	a[c]   : indexing, returns 1 c is present in the list a.
-	a[c]=d : setting, if d is true, c is added to the list if it is not
-		 present already. If d is false, it is removed if it is
-                 present.
+	a + b	summation ( (<1>) + (<2>) returns (<1,2>) )
+	a - b	subtraction, returns a copy of a with all values that are
+		present in b removed.
+	a & b	intersection, return a list with all values that are
+		present in both a & b.
+	a | b	union, return a list with all values that are present in
+		a or b, differs from summation in that values that are
+		present in both a and b are only returned once.
+	a ^ b	xor, return a list with all indices that are present in
+		a or b but not in both.
+	a == b	returns 1 if a is the same list as b, same size and values
+		is not enough.
+	a != b	returns 1 if a is the same list as b, same size and values
+		is not enough.
+	! a	boolean not, returns 0
+	a[c]	indexing, returns 1 c is present in the list a.
+	a[c]=d	setting, if d is true, c is added to the list if it is not
+		present already. If d is false, it is removed if it is
+		present.
+
+KEYWORDS
+	type
 
 SEE ALSO
 	mapping, array, builtin/indices, builtin/sizeof
diff --git a/doc/types/mapping b/doc/types/mapping
index a4db94328f..f009414380 100644
--- a/doc/types/mapping
+++ b/doc/types/mapping
@@ -16,29 +16,32 @@ DESCRIPTION
 	Here follows a list of operators that applies to mappings:
 	In this list a and b is used to represent a mapping expression:
 
-	a + b  : summation ( ([1:1]) + ([2:2,2:2]) returns ([1:1,2:2]) )
-	a - b  : subtraction, returns a copy of a with all pairs whos
-                 index is present in b removed.
-        a & b  : intersection, return a mapping with all indices that are
-		 present in both a and b, if an index is present in both
-                 a & b the data for that index will be taken from b.
-        a | b  : union, return a mapping with all values that are present in
-                 a or b, differs from summation in that values that are
-                 present in both a and b are only returned once, as with
-                 intersection, data will be taken from b when possible.
-        a ^ b  : xor, return a mapping with all indices that are present in
-                 a or b but not in both.
-        a == b : returns 1 if a is the same mapping as b, same size, indices
-                 and values is not enough, 0 otherwise.
-        a != b : returns 0 if a is the same mapping as b, same size, indices
-                 and values is not enough, 1 otherwise.
-        ! a    : boolean not, returns 0
-	a[c]   : indexing, returns the value associated with the value c
-                 in the mapping a. If there is no index c in the mapping
-                 zero will be returned. (With zero type = 1)
-	a[c]=d : setting, this associates d with c in the mapping, the index
-                 c will be added to the mapping automatically if it isn't
-                 already there.
+	a + b	summation ( ([1:1]) + ([2:2,2:2]) returns ([1:1,2:2]) )
+	a - b	subtraction, returns a copy of a with all pairs whos
+		index is present in b removed.
+	a & b	intersection, return a mapping with all indices that are
+		resent in both a and b, if an index is present in both
+		a & b the data for that index will be taken from b.
+	a | b	union, return a mapping with all values that are present in
+		a or b, differs from summation in that values that are
+		present in both a and b are only returned once, as with
+		intersection, data will be taken from b when possible.
+	a ^ b	xor, return a mapping with all indices that are present in
+		a or b but not in both.
+	a == b	returns 1 if a is the same mapping as b, same size, indices
+		and values is not enough, 0 otherwise.
+	a != b	returns 0 if a is the same mapping as b, same size, indices
+		and values is not enough, 1 otherwise.
+	! a	boolean not, returns 0
+	a[c]	indexing, returns the value associated with the value c
+		in the mapping a. If there is no index c in the mapping
+		zero will be returned. (With zero type = 1)
+	a[c]=d	setting, this associates d with c in the mapping, the index
+		c will be added to the mapping automatically if it isn't
+		already there.
+
+KEYWORDS
+	type
 
 SEE ALSO
 	array, list, builtin/sizeof, builtin/indices, builtin/values
diff --git a/doc/types/object b/doc/types/object
index 7c3a1873c8..316e6c185c 100644
--- a/doc/types/object
+++ b/doc/types/object
@@ -10,13 +10,16 @@ DESCRIPTION
 	In this list, o and o2 are used to represent object expressions,
 	and s is a string expression:
 
-	o[s]     : indexing, returns the identifier named s in the object o,
-                   an identifier is a global variable or a function.
-	o[s]=c   : This sets the global variable s int the object o to c,
-		   if s is a function however, an error is produced.
-	o -> foo : same as o["foo"]
-	o == o2  : return 1 if o and o2 are the same object
-	o != o2  : return 0 if o and o2 are the same object
+	o[s]	indexing, returns the identifier named s in the object o,
+		an identifier is a global variable or a function.
+	o[s]=c	This sets the global variable s int the object o to c,
+		if s is a function however, an error is produced.
+	o->foo	same as o["foo"]
+	o == o2	return 1 if o and o2 are the same object
+	o != o2	return 0 if o and o2 are the same object
+
+KEYWORDS
+	type
 
 SEE ALSO
 	program, function, builtin/clone, builtin/destruct
diff --git a/doc/types/program b/doc/types/program
index e48520b314..b428dbcf85 100644
--- a/doc/types/program
+++ b/doc/types/program
@@ -8,6 +8,9 @@ DESCRIPTION
 	arguments to clone() and the only operators that applies to programs
 	are == and !=.
 
+KEYWORDS
+	type
+
 SEE ALSO
 	object, function, builtin/compile_file, builtin/compile_string,
 	builtin/clone
diff --git a/doc/types/string b/doc/types/string
index b69fb8053b..8074d27562 100644
--- a/doc/types/string
+++ b/doc/types/string
@@ -17,18 +17,22 @@ DESCRIPTION
 	A list of operators that applies to strings follow:
 	In this list a and b is used to represent a string expression:
 
-	a + b  : summation ( "a"+"b" returns "ab")
-	a - b  : subtraction ( same as replace(a,b,"") )
-	a / b  : division ( same thing as explode(a,b) )
-	! a    : boolean not, returns 0
-
-	The following operators compare two string alphabetically:	
-	a == b : return 1 if a is equal to b, 0 otherwise
-	a != b : return 0 if a is equal to b, 1 otherwise
-	a < b  : returns 1 if a is lesser than b, 0 otherwise
-	a <= b : returns 1 if a is lesser or equal to b, 0 otherwise
-	a > b  : returns 1 if a is greater than b, 0 otherwise
-	a >= b : returns 1 if a is greater or equal to b, 0 otherwise
+	a + b	summation ( "a"+"b" returns "ab")
+	a - b	subtraction ( same as replace(a,b,"") )
+	a / b	division ( same thing as explode(a,b) )
+	! a	boolean not, returns 0
+
+	The following operators compare two string alphabetically:
+
+	a == b	return 1 if a is equal to b, 0 otherwise
+	a != b	return 0 if a is equal to b, 1 otherwise
+	a < b	returns 1 if a is lesser than b, 0 otherwise
+	a <= b	returns 1 if a is lesser or equal to b, 0 otherwise
+	a > b	returns 1 if a is greater than b, 0 otherwise
+	a >= b	returns 1 if a is greater or equal to b, 0 otherwise
+
+KEYWORDS
+	type
 
 SEE ALSO
 	builtin/indices, builtin/values, builtin/sscanf, builtin/sprintf,
-- 
GitLab


From c46a6932b3c62a68aae69b987c8652cf9340dab2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 10 Feb 1996 22:03:18 +0100
Subject: [PATCH 003/351] New documentation files

Rev: doc/lpc/functions:1.1
Rev: doc/lpc/inherit:1.1
Rev: doc/lpc/lambda:1.1
Rev: doc/lpc/variables:1.1
---
 doc/lpc/functions | 71 +++++++++++++++++++++++++++++++++++++++++++++++
 doc/lpc/inherit   | 52 ++++++++++++++++++++++++++++++++++
 doc/lpc/lambda    | 45 ++++++++++++++++++++++++++++++
 doc/lpc/variables | 35 +++++++++++++++++++++++
 4 files changed, 203 insertions(+)
 create mode 100644 doc/lpc/functions
 create mode 100644 doc/lpc/inherit
 create mode 100644 doc/lpc/lambda
 create mode 100644 doc/lpc/variables

diff --git a/doc/lpc/functions b/doc/lpc/functions
new file mode 100644
index 0000000000..9b1c71d06d
--- /dev/null
+++ b/doc/lpc/functions
@@ -0,0 +1,71 @@
+NAME
+	functions - how to write a function
+
+SYNTAX
+	modifier type function_name (argument_specification)
+	{
+	  /* function body */
+	}
+
+DESCRIPTION
+	This defines a function called 'function_name' returning the type
+	'type'. The argument_specification is a comma separated list of
+	arguments. Each argument is specified with a type, whitespace and
+	the name of the argument. The last argument may have ... before
+	the name to indicate that that argument shall contain an array of
+	the rest of the arguments given by the caller. Note that using
+	... automatically makes an the variable an array, so writing
+
+		int foo(int * ... ints);
+
+	means that 'ints' is an array of arrays of integers. Which might not
+	be what you want.
+
+	The modifiers can be zero or more of: static, no_mask, varargs, inline
+	and private. Varargs means that it is ok to call the function with
+	less arguments that would otherwise be needed. Inline means that
+	the function may be inlined in other code. Inline also makes the
+	function no_mask. Static means that the function can not be called
+	from other objects. Private means that the function can not be accessed
+	from programs that inherits this program.
+
+	Some times you need to use a function before it is defined, then you
+	can write a 'forward declaration' of the function. This is done by
+	copying the function definition up until (but not including) the '{'
+	and putting a semicolon after it. The forward declaration should be
+	put before the use of the function of course.
+
+	Function definitions and forward declarations are toplevel constructs,
+	they can not be written inside functions or expressions.
+
+EXAMPLES
+	/* Forward declare foobar as taking an array of int as argument 
+	 *and returning an int
+	 */
+	static int foobar(int *a);
+
+	/* This function takes a format string and any number of integers
+         * as argument and returns a string
+         */
+	string dofobar(string format ,int ... rest)
+	{
+	  return sprintf(format, foobar(rest));
+	}
+
+	/* Define foobar */
+	static int foobar(int *a)
+	{
+	  int e, ret;
+	  ret=1;
+
+	  for(e=0;e<sizeof(a);e++)
+	    ret*=a[e];
+
+	  return ret;
+	}
+
+KEYWORDS
+	lpc
+
+SEE ALSO
+	lambda, return, modifier
\ No newline at end of file
diff --git a/doc/lpc/inherit b/doc/lpc/inherit
new file mode 100644
index 0000000000..a0136d8651
--- /dev/null
+++ b/doc/lpc/inherit
@@ -0,0 +1,52 @@
+NAME
+	inherit - use definitions from another program
+
+SYNTAX
+	inherit "<program name>";
+	or
+	inherit "<program name>" : local_name;
+
+DESCRIPTION
+	Inherit copies the global identifiers (functions and global variables)
+	from the named program. These functions and variables can then be 
+	used as	if they were defined in this program. All the inherited
+	identifiers that was no declared as no_mask in the inherited program
+	can be also be redefined. The redefinition will not only
+	affect functions following the redefinition, but all functions in
+	this program, including the inherited ones.
+
+	Even if an identifier is redefined you can still access the original
+	though. Prepending the identifier name with :: will return the original
+	identifier, OR an array of all inherited identifiers with that name.
+
+	You can also use the local_name to access a specific identifier, just
+	prepend it like 'local_name::identifier'. This will return the named
+	identifer in the program inherited with the given local_name. If no
+	local_name was given to inherit , the last part of the path in the
+	program name will be used as local_name.
+
+	Inherit calls master()->cast_to_program(<program name>) to get the
+	program to inherit. For this reason there can be no inherits in the
+	master object.
+
+	Inherit is not an expression or statement, it is a toplevel construct
+	and must not be written inside a function body.
+
+EXAMPLES
+	/* This is file hworld.lpc */
+	int hello_world() { write("Hello world.\n"); }
+
+	/* This is the file hello_world.lpc */
+	inherit "hworld.lpc";
+	
+	int main()
+	{
+	  hello_world();
+	  exit(0);
+	}
+
+KEYWORDS
+	lpc
+
+SEE ALSO
+	class
diff --git a/doc/lpc/lambda b/doc/lpc/lambda
new file mode 100644
index 0000000000..9c5f7449e7
--- /dev/null
+++ b/doc/lpc/lambda
@@ -0,0 +1,45 @@
+NAME
+	lambda - write nameless functions
+
+SYNTAX
+	lambda(<argument specifications>) { <code> }
+
+DESCRIPTION
+	Lambda let's you write a function as a value to a function call
+	or anywhere where you can enter an expression. Using lambda is
+	basically the same as defining the function before the current
+	function with a temporary name and then use the name instead.
+
+EXAMPLES
+	/* These two lettersort routines are equal */
+	string *lettersort(string *words)
+	{
+	  return sort_array(lettersort, lambda(string a,string b)
+	    {
+	      return a < b;
+	    });
+	}
+
+	int tmp_cmp_fun(string a, string b)
+	{
+	  return a < b;
+	}
+
+	string *lettersort(string *words)
+	{
+	  return sort_array(lettersort, tmp_cmp_fun);
+	}
+
+NOTA BENE
+	function_name() will return something for lambda functions,
+	what it returns is unspecified though.
+
+BUGS
+	confuses the hell out of C indent programs
+
+KEYWORDS
+	lpc
+
+SEE ALSO
+	class, function
+
diff --git a/doc/lpc/variables b/doc/lpc/variables
new file mode 100644
index 0000000000..2e95b3c256
--- /dev/null
+++ b/doc/lpc/variables
@@ -0,0 +1,35 @@
+NAME
+	variables - how to declare a variable
+
+SYNTAX
+	modifier type variable_name_list;
+
+DESCRIPTION
+	This is how you declare a global variable. Local variables are defined
+	in the same way, but you may not use any modifiers for local variables.
+	The variable_name_list is a comma separated list of the variables
+	to declare as the type 'type'. Note that '*' binds to the variable
+	names, not the type. This means that:
+
+		int * i,j;
+
+	Declares i as an array of int, but j will be declared as int. To
+	declare both i and j as arrays of int you have to write.
+
+		int * i, * j;
+
+	or
+
+		array(int) i,j;
+
+	Modifiers can be zero or more of: static, no_mask and private.
+	Private means that the variable can not be accessed from programs
+	that inherit this program. Static means that it can not be accessed
+	from other objects with the index operator. No_mask means that it
+	can not be redefined in inheriting programs.
+
+KEYWORDS
+	lpc
+
+SEE ALSO
+	functions
-- 
GitLab


From 6e0ac0373c8e7eb25b6fd9576d16ff60afcf88f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 10 Feb 1996 22:04:48 +0100
Subject: [PATCH 004/351] fixed (to work with BMML)

Rev: doc/lpc/class:1.2
Rev: doc/lpc/hilfe:1.2
Rev: doc/lpc/preprocessor:1.2
---
 doc/lpc/class        |  5 +++-
 doc/lpc/hilfe        | 15 +++++-------
 doc/lpc/preprocessor | 57 +++++++++++++++++++++++---------------------
 3 files changed, 40 insertions(+), 37 deletions(-)

diff --git a/doc/lpc/class b/doc/lpc/class
index e2e8144133..56b330b9e9 100644
--- a/doc/lpc/class
+++ b/doc/lpc/class
@@ -1,5 +1,5 @@
 NAME
-	class
+	class - define a inlined program
 
 SYNTAX
 	class { program definition }
@@ -14,5 +14,8 @@ EXAMPLE
 	complex->r=1.0;
 	complex->i=1.0;
 
+KEYWORDS
+	lpc
+
 SEE ALSO
 	inherit, lambda
diff --git a/doc/lpc/hilfe b/doc/lpc/hilfe
index ffb96fbba9..6104838405 100755
--- a/doc/lpc/hilfe
+++ b/doc/lpc/hilfe
@@ -39,17 +39,14 @@ DESCRIPTION
 	Evaluate a statement:
 	<statement> ;
 	Statements include the following examples:
-		for(e=0;e<10;e++) ;
-	
-		e=10;
 
-		write(e);
+	  for(e=0;e<10;e++) ;
 
-		if(foo) return bar; else return gazonk;
+	  e=10;
 
-	Statements beginning with for, while, switch, if, do or return will
-	not automatically return anything, and no result will be printed.
+	  write(e);
 
+	  if(foo) return bar; else return gazonk;
 
-SEE ALSO
-	script_mode
+	Statements beginning with for, while, switch, if, do or return will
+	not automatically return anything, and no result will be printed.
diff --git a/doc/lpc/preprocessor b/doc/lpc/preprocessor
index 4a3bd37c59..b8e0361be8 100644
--- a/doc/lpc/preprocessor
+++ b/doc/lpc/preprocessor
@@ -1,25 +1,28 @@
+NAME
+	preprocessor - textually process code before compiling
+
 DESCRIPTION
 	�LPC has a builtin C-style preprocessor. It works similar to old
 	C preprocessors but has a few extra features. This file describes
 	the different preprocessor directives.
 
 PREPROCESSOR DIRECTIVES
-	#!
-	#define
-	#elif
-	#else
-	#elseif
-	#endif
-	#error
-	#if
-	#ifdef
-	#ifndef
-	#include
-	#line
-	#pragma
-	#undef
-
-----------------------------------------------------------------------------
+	  #!
+	  #define
+	  #elif
+	  #else
+	  #elseif
+	  #endif
+	  #error
+	  #if
+	  #ifdef
+	  #ifndef
+	  #include
+	  #line
+	  #pragma
+	  #undef
+
+============================================================================
 DIRECTIVE
 	#!
 
@@ -30,27 +33,27 @@ DESCRIPTION
 	the script with
 
 	#!/usr/local/bin/ulpc
-----------------------------------------------------------------------------
+============================================================================
 DIRECTIVE
 	#define
 
 DESCRIPTION
 	The simplest way to use define is to write
-	
-		#define <identifier> <replacement string>
+
+	  #define <identifier> <replacement string>
 
 	which will cause all subsequent occurances of 'identifier' to be
 	replaced with the replacement string.
 
 	Define also has the capability to use arguments, thus a line like
 
-		#define <identifier>(arg1, arg2) <replacement string>
+	  #define <identifier>(arg1, arg2) <replacement string>
 
 	would cause identifer to be a macro. All occurances of
 	'identifier(something1,something2d)' would be replaced with
 	the replacement string. And in the replacement string, arg1 and arg2
 	will be replaced with something1 and something2.
-----------------------------------------------------------------------------
+============================================================================
 DIRECTIVE
 	#undef
 
@@ -65,7 +68,7 @@ EXAMPLES
 	#undef foo
 	#define foo(bar) gazonk bar
 	#undef foo
-----------------------------------------------------------------------------
+============================================================================
 DIRECTIVE
 	#if
 	#elif
@@ -111,7 +114,7 @@ EXAMPLES
 	#if !efun(write_file)
 	inherit "simulate.lpc"
 	#endif
-----------------------------------------------------------------------------
+============================================================================
 DIRECTIVE
 	#error
 
@@ -123,7 +126,7 @@ EXAMPLES
 	#if !efun(write_file)
 	#error Move object is missing
 	#endif
-----------------------------------------------------------------------------
+============================================================================
 DIRECTIVE
 	#include
 
@@ -134,7 +137,7 @@ DESCRIPTION
 
 EXAMPLES
 	#include "foo.h"
-----------------------------------------------------------------------------
+============================================================================
 DIRECTIVE
 	#line
 
@@ -149,7 +152,7 @@ DESCRIPTION
 
 EXAMPLES
 	#line 4 "foo.cf" /* The next line was generated from 4 in foo.cf */
-----------------------------------------------------------------------------
+============================================================================
 DIRECTIVE
 	#pragma
 
@@ -157,4 +160,4 @@ DESCRIPTION
 	This is a generic directive for flags to the compiler. Currently, the
 	only flag available is 'all_inline' which is the same as adding the
 	modifier 'inline' to all functions that follows.
-----------------------------------------------------------------------------
+============================================================================
-- 
GitLab


From dab41e8d7c986754d2cdd05a21ddb0c8d45a36df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 10 Feb 1996 22:09:11 +0100
Subject: [PATCH 005/351] updated version, and added exec efun.

Rev: lib/simulate.lpc:1.6
---
 lib/simulate.lpc | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index 4a4d9f9753..8140b0219d 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -19,7 +19,7 @@ static int open(string file, string how)
       return 1;
     }else{
       current_file=current_mode=0;
-      return 1;
+      return 0;
     }
   }
 }
@@ -344,6 +344,7 @@ void create()
   add_efun("PI",3.1415926535897932384626433832795080);
   add_efun("capitalize",capitalize);
   add_efun("code_value",code_value);
+  add_efun("exec","exec");
   add_efun("file_size",file_size);
   add_efun("filter_array",filter_array);
   add_efun("l_sizeof",sizeof);
@@ -364,7 +365,7 @@ void create()
   add_efun("strstr",search);
   add_efun("sum_arrays",sum_arrays);
   add_efun("this_function",this_function);
-  add_efun("version",lambda() { return "uLPC v1.6E-12"; });
+  add_efun("version",lambda() { return "uLPC v1.7E-12"; });
   add_efun("write_file",write_file);
   add_efun("get_function",get_function);
   add_efun("regexp",regexp);
-- 
GitLab


From 921a53da874505f04715370e5497c4e81464cf01 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 10 Feb 1996 22:17:30 +0100
Subject: [PATCH 006/351] shoudln't be in repository

Rev: src/modules/files/configure.in:1.3
Rev: src/modules/files/efuns.c:1.2
Rev: src/modules/files/file.c:1.9
Rev: src/modules/files/file_machine.h.in:1.3
---
 src/modules/files/configure.in      | 50 ++++++++++++++++++++++++++++-
 src/modules/files/efuns.c           | 23 +++++++++----
 src/modules/files/file.c            |  1 +
 src/modules/files/file_machine.h.in |  6 ++++
 4 files changed, 72 insertions(+), 8 deletions(-)

diff --git a/src/modules/files/configure.in b/src/modules/files/configure.in
index 138f65ad1e..0a088d195a 100644
--- a/src/modules/files/configure.in
+++ b/src/modules/files/configure.in
@@ -10,7 +10,7 @@ AC_HAVE_HEADERS(arpa/inet.h sys/socketvar.h netinet/in.h \
 AC_HEADER_DIRENT
 AC_CHECK_LIB(socket, socket)
 
-AC_HAVE_FUNCS(socketpair)
+AC_HAVE_FUNCS(socketpair getwd)
 
 AC_MSG_CHECKING(size of socket buffers)
 AC_CACHE_VAL(lpc_cv_socket_buffer_max,
@@ -58,6 +58,54 @@ lpc_cv_socket_buffer_max=0
 AC_DEFINE_UNQUOTED(SOCKET_BUFFER_MAX,$lpc_cv_socket_buffer_max)
 AC_MSG_RESULT($lpc_cv_socket_buffer_max)
 
+
+AC_MSG_CHECKING(for working getcwd)
+AC_CACHE_VAL(lpc_cv_func_working_getcwd,
+[
+AC_TRY_RUN([
+#include <unistd.h>
+#include <signal.h>
+
+int sig_child(int arg)
+{
+#ifdef HAVE_WAITPID
+  waitpid(-1,0,WNOHANG);
+#else
+#ifdef HAVE_WAIT3
+  wait3(-1,0,WNOHANG);
+#else
+
+  /* Leave'em hanging */
+
+#endif /* HAVE_WAIT3 */
+#endif /* HAVE_WAITPID */
+
+#ifdef SIGNAL_ONESHOT
+  my_signal(SIGCHLD, sig_child);
+#endif
+}
+
+int sig_alarm() { exit(1); }
+
+int main()
+{
+  char *tmp;
+  signal(SIGCHLD,sig_child);
+  signal(SIGALRM,sig_alarm);
+  alarm(4);
+  tmp=getcwd(0,10000);
+  if(tmp && strlen(tmp) <10000) exit(0);
+  exit(1);
+}
+],lpc_cv_func_working_getcwd=yes,lpc_cv_func_working_getcwd=no)])
+
+if test "$lpc_cv_func_working_getcwd" = yes; then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(HAVE_WORKING_GETCWD)
+else
+  AC_MSG_RESULT(no)
+fi
+
 AC_OUTPUT(Makefile,echo FOO >stamp-h )
 
 
diff --git a/src/modules/files/efuns.c b/src/modules/files/efuns.c
index ba75f2805f..b0a07205d0 100644
--- a/src/modules/files/efuns.c
+++ b/src/modules/files/efuns.c
@@ -197,20 +197,29 @@ void f_cd(INT32 args)
 void f_getcwd(INT32 args)
 {
   char *e;
-  pop_n_elems(args);
-
-#ifdef HAVE_GETCWD
-  e=(char *)getcwd(0,1000); 
+#if defined(HAVE_WORKING_GETCWD) || !defined(HAVE_GETWD)
+  char *tmp;
+  INT32 size;
+
+  size=1000;
+  do {
+    tmp=(char *)xalloc(size);
+    e=(char *)getcwd(tmp,1000); 
+    if (e || errno!=ERANGE) break;
+    free((char *)tmp);
+    size*=2;
+  } while (size < 10000);
 #else
 
 #ifndef MAXPATHLEN
 #define MAXPATHLEN 32768
 #endif
-
   e=(char *)getwd((char *)malloc(MAXPATHLEN+1));
-  if(!e)
-    fatal("Couldn't fetch current path.\n");
 #endif
+  if(!e)
+    error("Failed to fetch current path.\n");
+
+  pop_n_elems(args);
   push_string(make_shared_string(e));
   free(e);
 }
diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index 3cb08d6587..a697f5833e 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -95,6 +95,7 @@ static int close_fd(int fd)
 	fatal("Closing a non-active file descriptor.\n");
        
       case EINTR:
+	break;
       }
     }
 
diff --git a/src/modules/files/file_machine.h.in b/src/modules/files/file_machine.h.in
index d091c641f2..8564e516d2 100644
--- a/src/modules/files/file_machine.h.in
+++ b/src/modules/files/file_machine.h.in
@@ -34,5 +34,11 @@
 /* Do we have socketpair() ? */
 #undef HAVE_SOCKETPAIR
 
+/* Define if you have getwd.  */
+#undef HAVE_GETWD
+
+/* Define if you have a working getcwd */
+#undef HAVE_WORKING_GETCWD
+
 #endif
 
-- 
GitLab


From 41375673ce1e73d91d5c6d5fd908922f24019edd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 10 Feb 1996 22:58:00 +0100
Subject: [PATCH 007/351] ignore configure files

Rev: src/modules/files/.cvsignore:1.1
Rev: src/modules/math/.cvsignore:1.1
Rev: src/modules/regexp/.cvsignore:1.1
Rev: src/modules/sprintf/.cvsignore:1.1
---
 src/modules/files/.cvsignore   | 1 +
 src/modules/files/.gitignore   | 1 +
 src/modules/math/.cvsignore    | 1 +
 src/modules/math/.gitignore    | 1 +
 src/modules/regexp/.cvsignore  | 1 +
 src/modules/regexp/.gitignore  | 1 +
 src/modules/sprintf/.cvsignore | 1 +
 src/modules/sprintf/.gitignore | 1 +
 8 files changed, 8 insertions(+)
 create mode 100644 src/modules/files/.cvsignore
 create mode 100644 src/modules/files/.gitignore
 create mode 100644 src/modules/math/.cvsignore
 create mode 100644 src/modules/math/.gitignore
 create mode 100644 src/modules/regexp/.cvsignore
 create mode 100644 src/modules/regexp/.gitignore
 create mode 100644 src/modules/sprintf/.cvsignore
 create mode 100644 src/modules/sprintf/.gitignore

diff --git a/src/modules/files/.cvsignore b/src/modules/files/.cvsignore
new file mode 100644
index 0000000000..e8c05a6b13
--- /dev/null
+++ b/src/modules/files/.cvsignore
@@ -0,0 +1 @@
+configure
diff --git a/src/modules/files/.gitignore b/src/modules/files/.gitignore
new file mode 100644
index 0000000000..55902085e8
--- /dev/null
+++ b/src/modules/files/.gitignore
@@ -0,0 +1 @@
+/configure
diff --git a/src/modules/math/.cvsignore b/src/modules/math/.cvsignore
new file mode 100644
index 0000000000..e8c05a6b13
--- /dev/null
+++ b/src/modules/math/.cvsignore
@@ -0,0 +1 @@
+configure
diff --git a/src/modules/math/.gitignore b/src/modules/math/.gitignore
new file mode 100644
index 0000000000..55902085e8
--- /dev/null
+++ b/src/modules/math/.gitignore
@@ -0,0 +1 @@
+/configure
diff --git a/src/modules/regexp/.cvsignore b/src/modules/regexp/.cvsignore
new file mode 100644
index 0000000000..e8c05a6b13
--- /dev/null
+++ b/src/modules/regexp/.cvsignore
@@ -0,0 +1 @@
+configure
diff --git a/src/modules/regexp/.gitignore b/src/modules/regexp/.gitignore
new file mode 100644
index 0000000000..55902085e8
--- /dev/null
+++ b/src/modules/regexp/.gitignore
@@ -0,0 +1 @@
+/configure
diff --git a/src/modules/sprintf/.cvsignore b/src/modules/sprintf/.cvsignore
new file mode 100644
index 0000000000..e8c05a6b13
--- /dev/null
+++ b/src/modules/sprintf/.cvsignore
@@ -0,0 +1 @@
+configure
diff --git a/src/modules/sprintf/.gitignore b/src/modules/sprintf/.gitignore
new file mode 100644
index 0000000000..55902085e8
--- /dev/null
+++ b/src/modules/sprintf/.gitignore
@@ -0,0 +1 @@
+/configure
-- 
GitLab


From 0e13924b429add47e0a7bb15ad11a3591662a306 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 10 Feb 1996 23:05:23 +0100
Subject: [PATCH 008/351] nice to have

Rev: src/run_autoconfig:1.1
---
 src/run_autoconfig | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100755 src/run_autoconfig

diff --git a/src/run_autoconfig b/src/run_autoconfig
new file mode 100755
index 0000000000..52966349fe
--- /dev/null
+++ b/src/run_autoconfig
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+autoconf
+cd modules
+for a in *
+do
+  case $a in
+    CVS) ;;
+    RCS) ;;
+    *)
+      if [ -d $a ]; then
+        ( cd $a ; autoconf )
+      fi
+   ;;
+  esac
+done
\ No newline at end of file
-- 
GitLab


From 1089c470f0d4df903339714a9297df1f0a43d841 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 10 Feb 1996 23:05:38 +0100
Subject: [PATCH 009/351] added additional tests for sscanf

Rev: src/test/create_testsuite:1.5
---
 src/test/create_testsuite | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 6bfa0a1be4..b79a1b3adc 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -137,6 +137,11 @@ test_any(function bar=clone((program)"/test")->foo; return bar(),17)
 // sscanf
 test_any([[mixed a; return sscanf("11","%d",a)]],1)
 test_any([[mixed a; sscanf("11","%d",a); return a]],11)
+test_any([[mixed a; sscanf("11","%o",a); return a]],011)
+test_any([[mixed a; sscanf("11","%x",a); return a]],0x11)
+test_any([[mixed a; sscanf("11","%D",a); return a]],11)
+test_any([[mixed a; sscanf("0x11","%D",a); return a]],0x11)
+test_any([[mixed a; sscanf("011","%D",a); return a]],011)
 test_any([[mixed a,b; return sscanf("11foo","%dfoo",a)]],1)
 test_any([[mixed a,b; sscanf("11foo","%dfoo",a); return a]],11)
 test_any([[mixed a,b; return sscanf("11foo","%d%s",a,b)]],2)
-- 
GitLab


From f72e8cd337581aa9fca5c68caacf56c7c3764379 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 10 Feb 1996 23:06:25 +0100
Subject: [PATCH 010/351] fixed sscanf to accept %x %o and %D

Rev: src/opcodes.c:1.4
---
 src/opcodes.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/src/opcodes.c b/src/opcodes.c
index 03358c4512..b713d7dd27 100644
--- a/src/opcodes.c
+++ b/src/opcodes.c
@@ -337,6 +337,45 @@ static INT32 low_sscanf(INT32 num_arg)
     {
       char * t;
 
+      if(eye>=input_len) return matches;
+      sval.u.integer=STRTOL(input+eye,&t,10);
+      if(input + eye == t) return matches;
+      eye=t-input;
+      sval.type=T_INT;
+      sval.subtype=NUMBER_NUMBER;
+      break;
+    }
+
+    case 'x':
+    {
+      char * t;
+
+      if(eye>=input_len) return matches;
+      sval.u.integer=STRTOL(input+eye,&t,16);
+      if(input + eye == t) return matches;
+      eye=t-input;
+      sval.type=T_INT;
+      sval.subtype=NUMBER_NUMBER;
+      break;
+    }
+
+    case 'o':
+    {
+      char * t;
+
+      if(eye>=input_len) return matches;
+      sval.u.integer=STRTOL(input+eye,&t,8);
+      if(input + eye == t) return matches;
+      eye=t-input;
+      sval.type=T_INT;
+      sval.subtype=NUMBER_NUMBER;
+      break;
+    }
+
+    case 'D':
+    {
+      char * t;
+
       if(eye>=input_len) return matches;
       sval.u.integer=STRTOL(input+eye,&t,0);
       if(input + eye == t) return matches;
@@ -403,6 +442,24 @@ static INT32 low_sscanf(INT32 num_arg)
 	    set['-']=0;
 	    goto match_set;
 
+	  case 'o':
+	    for(e=0;e<256;e++) set[e]=1;
+	    for(e='0';e<='7';e++) set[e]=0;
+	    goto match_set;
+
+	  case 'x':
+	    for(e=0;e<256;e++) set[e]=1;
+	    for(e='0';e<='9';e++) set[e]=0;
+	    for(e='a';e<='f';e++) set[e]=0;
+	    goto match_set;
+
+	  case 'D':
+	    for(e=0;e<256;e++) set[e]=1;
+	    for(e='0';e<='9';e++) set[e]=0;
+	    set['-']=0;
+	    set['x']=0;
+	    goto match_set;
+
 	  case 'f':
 	    for(e=0;e<256;e++) set[e]=1;
 	    for(e='0';e<='9';e++) set[e]=0;
-- 
GitLab


From 04ee597b8bbc0367c758c2942b310d185a1ba3a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 10 Feb 1996 23:08:26 +0100
Subject: [PATCH 011/351] entry added

Rev: src/BUGS:1.4
---
 src/BUGS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/BUGS b/src/BUGS
index bd425dc941..e58546fdd3 100644
--- a/src/BUGS
+++ b/src/BUGS
@@ -327,3 +327,5 @@ Still to do:
 * 'array' does not match 'string *' ? (in function calls)
 
 * compile errors generate memory leaks
+
+* file->write bugs when given a zero as argument?
-- 
GitLab


From 5d4cd8270b98168c8654a6cbe075f2353493da88 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 10 Feb 1996 23:08:36 +0100
Subject: [PATCH 012/351] fixed typo

Rev: src/machine.h.in:1.6
---
 src/machine.h.in | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/machine.h.in b/src/machine.h.in
index 8b1a41ab46..7340070012 100644
--- a/src/machine.h.in
+++ b/src/machine.h.in
@@ -114,7 +114,7 @@
 #undef USE_IOCTL_FIONBIO
 #undef USE_FCNTL_O_NDELAY
 #undef USE_FCNTL_FNDELAY
-#undef USE_FCNTL_NONBLOCK
+#undef USE_FCNTL_O_NONBLOCK
 
 /* Define if you have index */
 #undef HAVE_STRTOL
-- 
GitLab


From 0b34a6526187637208bdfca4483da307f496e938 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 10 Feb 1996 23:08:44 +0100
Subject: [PATCH 013/351] entries added

Rev: src/ChangeLog:1.13
---
 src/ChangeLog | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index a0a03c90ae..e8023b919d 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,25 @@
+Sat Feb 10 21:43:42 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
+
+	* 
+	* create_testsuite: added tests for sscanfs %d %o and %x
+	* opcodes.c: changed sscanf to use strtol
+	* machine.h.in: changed USE_FCNTL_NONBLOCK to what it should be:
+	  USE_FCNTL_O_NONBLOCK
+	* simulate.lpc: fixed an add_efun for exec
+	* Updated a LOT of docfiles.
+
+Mon Nov 20 16:52:32 1995  Fredrik Hubinette  <hubbe@sparky.signum.se>
+
+	* builtin_efuns.c (replace_many): Fixed an array bound read.
+	* compilation.h: No more macros with empty arguments.
+	* configure.in: changed the mystic 'oneshot signals' message
+	* interpret.c: print_treturn_type -> print_return_value
+	* language.y: inline now implies no_mask
+	* machine.h.in: moved HAVE_GETWD & HAVE_GETCWD to files module
+	* opcodes.c: changed strtod to STRTOD
+	* sprintf.c: fixed some typos, optimized and a bugfix in truncating
+	* create_testsuite: added test for get_dir()
+
 Wed Nov 15 10:56:45 1995  Fredrik Hubinette  <hubbe@sparky.signum.se>
 
         * version 1.6E-12 released
-- 
GitLab


From afa3650b9675bcb8449ed564cf7a440f8ba3e246 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 10 Feb 1996 23:27:18 +0100
Subject: [PATCH 014/351] See changelog

Rev: src/ChangeLog:1.14
Rev: src/array.c:1.3
Rev: src/builtin_efuns.c:1.7
Rev: src/language.y:1.8
Rev: src/las.c:1.3
Rev: src/test/create_testsuite:1.6
---
 src/ChangeLog             | 11 +++++++++++
 src/array.c               |  8 ++++++--
 src/builtin_efuns.c       |  4 +++-
 src/language.y            |  4 ++--
 src/las.c                 |  1 +
 src/test/create_testsuite |  5 +++++
 6 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index e8023b919d..da17511e37 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -8,6 +8,17 @@ Sat Feb 10 21:43:42 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
 	* simulate.lpc: fixed an add_efun for exec
 	* Updated a LOT of docfiles.
 
+Sat Feb 10 02:26:25 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
+
+	* array.c: fixed a coredump when doing & on one compact and
+	  one noncompact array.
+	* language.y: fixed so that continue now always need a semicolon
+          after it.
+        * builtin_efuns.c: replace_many fixed.
+	* array.c: fix_type_field fixed.
+	* las.c: fixed node_is_equal, it can now see the differance between
+          different global variables :P
+
 Mon Nov 20 16:52:32 1995  Fredrik Hubinette  <hubbe@sparky.signum.se>
 
 	* builtin_efuns.c (replace_many): Fixed an array bound read.
diff --git a/src/array.c b/src/array.c
index ff504ba561..76e6f2a1e7 100644
--- a/src/array.c
+++ b/src/array.c
@@ -962,7 +962,7 @@ void array_fix_type_field(struct array *v)
    break;
 
   default:
-    v->type_field=1 << v->array_type;
+    t=1 << v->array_type;
     for(e=0; e<v->size; e++)
     {
       if(! SHORT_ITEM(v)[e].refs)
@@ -973,6 +973,10 @@ void array_fix_type_field(struct array *v)
     }
 
   }
+#ifdef DEBUG
+  if(t & ~(v->type_field))
+    fatal("Type field out of order!\n");
+#endif
   v->type_field = t;
 }
 
@@ -1245,7 +1249,7 @@ struct array *array_zip(struct array *a, struct array *b,INT32 *zipper)
       }else{
 	if(b->array_type == T_MIXED)
 	{
-	  assign_svalue(ITEM(ret)+e, ITEM(a)+*zipper);
+	  assign_svalue_no_free(ITEM(ret)+e, ITEM(b)+~*zipper);
 	}else{
 	  assign_from_short_svalue_no_free(ITEM(ret)+e,
 				   SHORT_ITEM(b)+~*zipper,
diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index 521705eff6..90507b5a82 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -1071,7 +1071,9 @@ struct lpc_string * replace_many(struct lpc_string *str,
 	}
       }
       if(a<from->size &&
-	 !low_quick_binary_strcmp(v[a].ind->str,v[a].ind->len,s,length))
+	 length >= v[a].ind->len &&
+	 !low_quick_binary_strcmp(v[a].ind->str,v[a].ind->len,
+				  s,v[a].ind->len))
       {
 	c=v[a].ind->len;
 	if(!c) c=1;
diff --git a/src/language.y b/src/language.y
index 23dd5d1376..46739d6791 100644
--- a/src/language.y
+++ b/src/language.y
@@ -615,8 +615,8 @@ statement: unused2 ';' { $$=$1; }
          | return ';'
 	 | block {}
          | foreach
-         | break
-         | continue
+         | break ';'
+         | continue ';'
          | error ';' { $$=0; }
   	 | ';' { $$=0; } 
          ;
diff --git a/src/las.c b/src/las.c
index 333ce0f661..8d3d7f8a9b 100644
--- a/src/las.c
+++ b/src/las.c
@@ -327,6 +327,7 @@ int node_is_eq(node *a,node *b)
   switch(a->token)
   {
   case F_LOCAL:
+  case F_IDENTIFIER:
     return a->u.number == b->u.number;
 
   case F_CAST:
diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index b79a1b3adc..3efeae6cb4 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -59,6 +59,11 @@ define(TESTNO,0)
 
 test_compile_error_low(master()->add_precompiled_program(\"/test\",compile_string(\"int foo() { return 17; }\",\"62\")))
 
+test_compile([[while(0)if(0)continue;else;]])
+test_program([[int b=1,c; int a() { c=b+2; return c==3; }]])
+test_true([[ ("foobar"/"o") & ({ "foo" }) ]])
+test_any([[ array a="foo bar"/" "; return sizeof(a & ({"foo"}))]],1)
+
 test_eq("\377"[0],255)
 test_do(add_efun("foo",clone(class {int i;})))
 test_eq(foo->i,0)
-- 
GitLab


From 7d1d49658d02487334bc17781b785066fa89fd37 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 10 Feb 1996 23:35:19 +0100
Subject: [PATCH 015/351] new file

Rev: doc/lpc/control_structures/break:1.1
Rev: doc/lpc/control_structures/catch:1.1
Rev: doc/lpc/control_structures/continue:1.1
Rev: doc/lpc/control_structures/do-while:1.1
Rev: doc/lpc/control_structures/for:1.1
Rev: doc/lpc/control_structures/foreach:1.1
Rev: doc/lpc/control_structures/if-else:1.1
Rev: doc/lpc/control_structures/return:1.1
Rev: doc/lpc/control_structures/switch:1.1
Rev: doc/lpc/control_structures/while:1.1
---
 doc/lpc/control_structures/break    | 15 +++++++++++
 doc/lpc/control_structures/catch    | 18 +++++++++++++
 doc/lpc/control_structures/continue | 15 +++++++++++
 doc/lpc/control_structures/do-while | 24 +++++++++++++++++
 doc/lpc/control_structures/for      | 28 ++++++++++++++++++++
 doc/lpc/control_structures/foreach  | 19 +++++++++++++
 doc/lpc/control_structures/if-else  | 19 +++++++++++++
 doc/lpc/control_structures/return   | 14 ++++++++++
 doc/lpc/control_structures/switch   | 41 +++++++++++++++++++++++++++++
 doc/lpc/control_structures/while    | 16 +++++++++++
 10 files changed, 209 insertions(+)
 create mode 100644 doc/lpc/control_structures/break
 create mode 100644 doc/lpc/control_structures/catch
 create mode 100644 doc/lpc/control_structures/continue
 create mode 100644 doc/lpc/control_structures/do-while
 create mode 100644 doc/lpc/control_structures/for
 create mode 100644 doc/lpc/control_structures/foreach
 create mode 100644 doc/lpc/control_structures/if-else
 create mode 100644 doc/lpc/control_structures/return
 create mode 100644 doc/lpc/control_structures/switch
 create mode 100644 doc/lpc/control_structures/while

diff --git a/doc/lpc/control_structures/break b/doc/lpc/control_structures/break
new file mode 100644
index 0000000000..28d3743f1c
--- /dev/null
+++ b/doc/lpc/control_structures/break
@@ -0,0 +1,15 @@
+NAME
+	break - break a loop or switch
+
+SYNTAX
+	break
+
+DESCRIPTION
+	Break jumps directly out of any loop or switch statement, it is
+	a very vital part of every switch statement.
+
+KEYWORDS
+	control
+
+SEE ALSO
+	do-while, while, for, switch
diff --git a/doc/lpc/control_structures/catch b/doc/lpc/control_structures/catch
new file mode 100644
index 0000000000..66467304ca
--- /dev/null
+++ b/doc/lpc/control_structures/catch
@@ -0,0 +1,18 @@
+NAME
+	catch - catch errors
+
+SYNTAX
+	catch { commands }
+	or
+	catch ( expression )
+
+DESCRIPTION
+	catch traps exceptions such as run time errors or calls to throw() and
+	returns the argument given to throw. For a run time error, this value
+	is ({ "error message", backtrace }) 
+
+KEYWORDS
+	control
+
+SEE ALSO
+	builtin/throw
diff --git a/doc/lpc/control_structures/continue b/doc/lpc/control_structures/continue
new file mode 100644
index 0000000000..6326b87f81
--- /dev/null
+++ b/doc/lpc/control_structures/continue
@@ -0,0 +1,15 @@
+NAME
+	continue - continue a loop
+
+SYNTAX
+	continue
+
+DESCRIPTION
+	Continue work similarly to break only it does't finish the loop,
+	it just aborts the rest of this turn in the loop. 
+
+KEYWORDS
+	control
+
+SEE ALSO
+	do-while, while, for
diff --git a/doc/lpc/control_structures/do-while b/doc/lpc/control_structures/do-while
new file mode 100644
index 0000000000..12a91e91f1
--- /dev/null
+++ b/doc/lpc/control_structures/do-while
@@ -0,0 +1,24 @@
+NAME
+	do-while - execute a statement while an expression is true
+
+SYNTAX
+	do <statement> while ( expression );
+
+DESCRIPTION
+	do - while only differs from the ordinary while-loop in that it does
+	_not_ evaluate the expression until after the statement has been
+	executed once. Thus it always runs the statement once.
+
+EXAMPLE
+	int i=circular_buffer_pos;
+	do
+	{
+	  write(circular_buffer[i]);
+	  i=(i+1) % sizeof(circular_buffer);
+	}while(i != circular_buffer_pos);
+
+KEYWORDS
+	control
+
+SEE ALSO
+	do - while
diff --git a/doc/lpc/control_structures/for b/doc/lpc/control_structures/for
new file mode 100644
index 0000000000..54a2c1883a
--- /dev/null
+++ b/doc/lpc/control_structures/for
@@ -0,0 +1,28 @@
+NAME
+	for - generic loop statement
+
+SYNTAX
+	for ( expression1 ; expression2 ; expression3 ) <statement>
+
+DESCRIPTION
+	the above statement is exactly equal to:
+
+	expression1;
+	while( expression2 )
+	{
+	  <statement>
+	  expression3;
+	}
+
+	Except when using 'continue'. When using continue in <statement>
+	expresstion3 will not be called.
+
+EXAMPLE
+	int e;
+	for(e=0;e<10;e++) write(e+"\n");
+
+KEYWORDS
+	control
+
+SEE ALSO
+	while, break, continue
diff --git a/doc/lpc/control_structures/foreach b/doc/lpc/control_structures/foreach
new file mode 100644
index 0000000000..d934abc05e
--- /dev/null
+++ b/doc/lpc/control_structures/foreach
@@ -0,0 +1,19 @@
+NAME
+	foreach - loop over an array
+
+SYNTAX
+	foreach ( array, variable ) statement
+
+DESCRIPTION
+	For each element in array, set variable to that value and execute
+	'statement'.
+
+EXAMPLE
+	string word;
+	foreach( explode(sentence," "), word) foo(word);
+
+KEYWORDS
+	control
+
+SEE ALSO
+	for, while
diff --git a/doc/lpc/control_structures/if-else b/doc/lpc/control_structures/if-else
new file mode 100644
index 0000000000..d19e638c32
--- /dev/null
+++ b/doc/lpc/control_structures/if-else
@@ -0,0 +1,19 @@
+NAME
+	if-else - run on condition
+
+SYNTAX
+	if( expression ) <statement>
+	or
+	if( expression ) <statement> else <statement>
+
+DESCRIPTION
+	If is the simplest of all control structures, in the first form
+	it runs the statement if the expression is true and in the second
+	form it runs the first statement if the expression is true and the
+	second if it is false.
+
+KEYWORDS
+	control
+
+SEE ALSO
+	switch
diff --git a/doc/lpc/control_structures/return b/doc/lpc/control_structures/return
new file mode 100644
index 0000000000..43ac6e834b
--- /dev/null
+++ b/doc/lpc/control_structures/return
@@ -0,0 +1,14 @@
+NAME
+	return - return from a function
+
+SYNTAX
+	return
+	or
+	return <expression>
+
+DESCRIPTION
+	Return jumps directly out of a function returning the given value to
+	the calling function. If no expression is given, 0 is returned.
+
+KEYWORDS
+	control
diff --git a/doc/lpc/control_structures/switch b/doc/lpc/control_structures/switch
new file mode 100644
index 0000000000..61d3cb60b0
--- /dev/null
+++ b/doc/lpc/control_structures/switch
@@ -0,0 +1,41 @@
+NAME
+	switch - Complicated conditional statement
+
+SYNTAX
+	switch( expression )
+	{
+	  case constant1:
+	    <statement1>
+	
+	  case constant2:
+	    <statement2>
+	    break;
+	
+	  case constant3..constant4:
+	    <statement4>
+	    break;
+	
+	  default:
+	    <statement3>
+	}
+
+DESCRIPTION
+	Switch evaluates the expression give and then executes one or more
+	statement accordingly to the result. If the result is equal to
+	constant1 then statement1 will be executed, please observe that
+	the second case-statement dos _not_ abort the execution in any way
+	instead statement2 will also be executed. After that break will
+	cause execution to continue after the after the last } in the
+	switch statement. If the result is equal to constant2 only
+	statement2 will be executed. If expression <= consant3 and
+	expression >= constant4, statement4 will be executed. In all other
+	cases statement3 is executed because it is 'default'. Please note
+	that the expression and constants can be any type that can be
+	written as a constant. Arrays, mappings and lists have little or
+	no use though.
+
+KEYWORDS
+	control
+
+SEE ALSO
+	if-else, break
diff --git a/doc/lpc/control_structures/while b/doc/lpc/control_structures/while
new file mode 100644
index 0000000000..0d2c2068d0
--- /dev/null
+++ b/doc/lpc/control_structures/while
@@ -0,0 +1,16 @@
+NAME
+	while - execute a statement while an expression is true
+
+SYNTAX
+	while( expression ) <statement>
+
+DESCRIPTION
+	While runns the statement until the expression is false. The
+	expression is evaluated once for every loop. If the expression is
+	false the first time the statement is never executed.
+
+KEYWORDS
+	control
+
+SEE ALSO
+	for, do-while
-- 
GitLab


From 40eb894a5c9730183e39f950596aeaf5c6d6c5ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 11 Feb 1996 01:05:21 +0100
Subject: [PATCH 016/351] now updates configure files

Rev: bin/export.lpc:1.3
---
 bin/export.lpc | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/bin/export.lpc b/bin/export.lpc
index 4e1fab4549..038007c1f2 100755
--- a/bin/export.lpc
+++ b/bin/export.lpc
@@ -23,11 +23,27 @@ string *get_files(string path)
   return ret;
 }
 
+void fix_configure(string dir)
+{
+  int *config,*config_in;
+  config=file_stat(dir+"/configure");
+  config_in=file_stat(dir+"/configure.in");
+
+  if(config_in)
+  {
+    if(!config || config_in[3] > config[3])
+    {
+      perror("Fixing configure in "+dir+".\n");
+      system("cd "+dir+" ; autoconf");
+    }
+  }
+}
+
 int main(int argc, string *argv)
 {
   mixed tmp;
   int e;
-  string files;
+  string *files;
   string s=replace(version()," ","_");
 
   tmp=explode(argv[0],"/");
@@ -44,6 +60,12 @@ int main(int argc, string *argv)
   cd(tmp*"/");
   perror("Sourcedir = "+tmp*"/"+"/ulpc\n");
 
+  fix_configure("ulpc/src");
+
+  foreach(get_dir("ulpc/src/modules") - ({"CVS","RCS"}), tmp)
+    if(file_size("ulpc/src/modules/"+tmp) == -2)
+      fix_configure("modules/"+tmp);
+
   files=sum(({ "ulpc/README" }),
 	    get_files("ulpc/src"),
 	    get_files("ulpc/doc"),
-- 
GitLab


From 914d94cf005e6d651e5fd57da67af52176181806 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 11 Feb 1996 01:06:29 +0100
Subject: [PATCH 017/351] entries added

Rev: src/ChangeLog:1.15
---
 src/ChangeLog | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index da17511e37..f8ca9f7944 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,6 +1,6 @@
-Sat Feb 10 21:43:42 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
+Sun Feb 11 01:04:38 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
 
-	* 
+	* export.lpc: now updates configure files if needed
 	* create_testsuite: added tests for sscanfs %d %o and %x
 	* opcodes.c: changed sscanf to use strtol
 	* machine.h.in: changed USE_FCNTL_NONBLOCK to what it should be:
-- 
GitLab


From 01d69fd2993f13591d70fc729a6a4f72ac960fde Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 11 Feb 1996 01:07:08 +0100
Subject: [PATCH 018/351] configure now generated from export.lpc instead

Rev: src/Makefile.in:1.7
---
 src/Makefile.in | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Makefile.in b/src/Makefile.in
index e0c95c5990..b80a9eaa2f 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -164,7 +164,7 @@ run_hilfe:
 
 # make export archive (requires compiled uLPC)
 # Do not compile in source tree if you want to use this!
-export: $(SRCDIR)/test/testsuite configure
+export: $(SRCDIR)/test/testsuite
 	$(RUNULPC) $(TMP_BINDIR)/export.lpc
 
 # make dependencies (requires compiled uLPC)
-- 
GitLab


From e0e78c8862c3bd86f4a4b168eb3d84af2df41d50 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 11 Feb 1996 01:08:44 +0100
Subject: [PATCH 019/351] nice to have

Rev: .cvsignore:1.1
---
 .cvsignore |  1 +
 .gitignore | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+)
 create mode 100644 .cvsignore
 create mode 100644 .gitignore

diff --git a/.cvsignore b/.cvsignore
new file mode 100644
index 0000000000..599fe44952
--- /dev/null
+++ b/.cvsignore
@@ -0,0 +1 @@
+uLPC_v1.7E-12.tar.gz
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..32b248d243
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,33 @@
+RCS
+SCCS
+CVS
+CVS.adm
+RCSLOG
+cvslog.*
+tags
+TAGS
+.make.state
+.nse_depinfo
+*~
+#*
+.#*
+,*
+_$*
+*$
+*.old
+*.bak
+*.BAK
+*.orig
+*.rej
+.del-*
+*.a
+*.olb
+*.o
+*.obj
+*.so
+*.exe
+*.Z
+*.elc
+*.ln
+core
+/uLPC_v1.7E-12.tar.gz
-- 
GitLab


From eb719a45b0019895533ba803a03fc778e3592f6c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 15 Feb 1996 14:34:55 +0100
Subject: [PATCH 020/351] ignored some more

Rev: .cvsignore:1.2
---
 .cvsignore | 5 +++++
 .gitignore | 5 +++++
 2 files changed, 10 insertions(+)

diff --git a/.cvsignore b/.cvsignore
index 599fe44952..796d6bf45a 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -1 +1,6 @@
+test
+test.lpc
+uLPC_v1.0E-12.tar.gz
+uLPC_v1.0E-13.tar.gz
+uLPC_v1.1E-12.tar.gz
 uLPC_v1.7E-12.tar.gz
diff --git a/.gitignore b/.gitignore
index 32b248d243..a03e4059f2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,4 +30,9 @@ _$*
 *.elc
 *.ln
 core
+/test
+/test.lpc
+/uLPC_v1.0E-12.tar.gz
+/uLPC_v1.0E-13.tar.gz
+/uLPC_v1.1E-12.tar.gz
 /uLPC_v1.7E-12.tar.gz
-- 
GitLab


From fc769526edc62c2895aafdada43d557bca017176 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 17 Feb 1996 15:17:51 +0100
Subject: [PATCH 021/351] In progress of removing compact arrays

Rev: src/array.c:1.4
Rev: src/array.h:1.2
Rev: src/svalue.c:1.4
Rev: src/svalue.h:1.2
---
 src/array.c  | 1270 +++++++++++++-------------------------------------
 src/array.h  |   19 +-
 src/svalue.c |  204 ++------
 src/svalue.h |   27 +-
 4 files changed, 381 insertions(+), 1139 deletions(-)

diff --git a/src/array.c b/src/array.c
index 76e6f2a1e7..41101879f8 100644
--- a/src/array.c
+++ b/src/array.c
@@ -36,7 +36,7 @@ struct array empty_array=
  * NOTE: the new array have zero references
  */
 
-struct array *allocate_array_no_init(INT32 size,INT32 extra_space,TYPE_T type)
+struct array *allocate_array_no_init(INT32 size,INT32 extra_space)
 {
   struct array *v;
 
@@ -46,24 +46,14 @@ struct array *allocate_array_no_init(INT32 size,INT32 extra_space,TYPE_T type)
     return &empty_array;
   }
 
-  if(type == T_FUNCTION || type == T_MIXED)
-  {
-    v=(struct array *)malloc(sizeof(struct array_of_svalues)+
-                             (size+extra_space-1)*sizeof(struct svalue));
-    if(!v)
-      error("Couldn't allocate array, out of memory.\n");
-    v->array_type=T_MIXED;
-    /* for now, we don't know what will go in here */
-    v->type_field=BIT_MIXED;
-  }else{
-    v=(struct array *)malloc(sizeof(struct array_of_short_svalues)+
-                             (size+extra_space-1)*sizeof(union anything));
-    if(!v)
-      error("Couldn't allocate array, out of memory.\n");
-    v->array_type=type;
-    /* This array can only contain zeros and 'type' */
-    v->type_field=BIT_INT | (1 << type);
-  }
+  v=(struct array *)malloc(sizeof(struct array)+
+			   (size+extra_space-1)*sizeof(struct svalue));
+  if(!v)
+    error("Couldn't allocate array, out of memory.\n");
+
+  /* for now, we don't know what will go in here */
+  v->type_field=BIT_MIXED;
+
   v->malloced_size=size+extra_space;
   v->size=size;
   v->flags=0;
@@ -76,21 +66,16 @@ struct array *allocate_array_no_init(INT32 size,INT32 extra_space,TYPE_T type)
   return v;
 }
 
-struct array *allocate_array(INT32 size,TYPE_T type)
+struct array *allocate_array(INT32 size)
 {
   INT32 e;
   struct array *a;
-  a=allocate_array_no_init(size,0,type);
-  if(a->array_type==T_MIXED)
+  a=allocate_array_no_init(size,0);
+  for(e=0;e<a->size;e++)
   {
-    for(e=0;e<a->size;e++)
-    {
-      ITEM(a)[e].type=T_INT;
-      ITEM(a)[e].subtype=NUMBER_NUMBER;
-      ITEM(a)[e].u.integer=0;
-    }
-  }else{
-    MEMSET((char *)SHORT_ITEM(a),0,sizeof(union anything)*a->size);
+    ITEM(a)[e].type=T_INT;
+    ITEM(a)[e].subtype=NUMBER_NUMBER;
+    ITEM(a)[e].u.integer=0;
   }
   return a;
 }
@@ -122,13 +107,7 @@ void really_free_array(struct array *v)
     fatal("Tried to free the empty_array.\n");
 #endif
 
-  if(v->array_type == T_MIXED)
-  {
-    free_svalues(ITEM(v), v->size);
-  }else{
-    free_short_svalues(SHORT_ITEM(v), v->size, v->array_type);
-  }
-
+  free_svalues(ITEM(v), v->size, v->type_field);
   array_free_no_free(v);
 }
 
@@ -142,12 +121,7 @@ void array_index_no_free(struct svalue *s,struct array *v,INT32 index)
     fatal("Illegal index in low level index routine.\n");
 #endif
 
-  if(v->array_type == T_MIXED)
-  {
-    assign_svalue_no_free(s, ITEM(v) + index);
-  }else{
-    assign_from_short_svalue_no_free(s, SHORT_ITEM(v) + index, v->array_type);
-  }
+  assign_svalue_no_free(s, ITEM(v) + index);
 }
 
 /*
@@ -161,13 +135,7 @@ void array_index(struct svalue *s,struct array *v,INT32 index)
 #endif
 
   v->refs++;
-  if(v->array_type == T_MIXED)
-  {
-    assign_svalue(s, ITEM(v) + index);
-  }else{
-    free_svalue(s);
-    assign_from_short_svalue_no_free(s, SHORT_ITEM(v) + index, v->array_type);
-  }
+  assign_svalue(s, ITEM(v) + index);
   free_array(v);
 }
 
@@ -203,12 +171,7 @@ void array_free_index(struct array *v,INT32 index)
     fatal("Illegal index in low level free index routine.\n");
 #endif
 
-  if(v->array_type == T_MIXED)
-  {
-    free_svalue(ITEM(v) + index);
-  }else{
-    free_short_svalue(SHORT_ITEM(v) + index, v->array_type);
-  }
+  free_svalue(ITEM(v) + index);
 }
 
 /*
@@ -223,22 +186,9 @@ void array_set_index(struct array *v,INT32 index, struct svalue *s)
 
   v->refs++;
   check_destructed(s);
-  if(v->array_type == T_MIXED)
-  {
-    v->type_field |= 1 << s->type;
-    assign_svalue( ITEM(v) + index, s);
-  }else if(IS_ZERO(s)){
-    v->type_field |= BIT_INT;
-    SHORT_ITEM(v)[index].refs=0;
-  }else if(v->array_type == s->type){
-    v->type_field |= 1 << s->type;
-    assign_to_short_svalue( SHORT_ITEM(v)+index, v->array_type, s);
-  }else{
-    free_array(v);
-    error("Wrong type in array assignment (%s != %s)\n",
-	  get_name_of_type(v->array_type),
-	  get_name_of_type(s->type));
-  }
+
+  v->type_field |= 1 << s->type;
+  assign_svalue( ITEM(v) + index, s);
   free_array(v);
 }
 
@@ -267,46 +217,28 @@ struct array *array_insert(struct array *v,struct svalue *s,INT32 index)
   /* Can we fit it into the existing block? */
   if(v->refs<=1 && v->malloced_size > v->size)
   {
-    if(v->array_type == T_MIXED)
-    {
-      MEMMOVE((char *)(ITEM(v)+index+1),
-              (char *)(ITEM(v)+index),
-              (v->size-index) * sizeof(struct svalue));
-      ITEM(v)[index].type=T_INT;
+    MEMMOVE((char *)(ITEM(v)+index+1),
+	    (char *)(ITEM(v)+index),
+	    (v->size-index) * sizeof(struct svalue));
+    ITEM(v)[index].type=T_INT;
 #ifdef __CHECKER__
-      ITEM(v)[index].subtype=0;
-      ITEM(v)[index].u.refs=0;
+    ITEM(v)[index].subtype=0;
+    ITEM(v)[index].u.refs=0;
 #endif
-    }else{
-      MEMMOVE((char *)(SHORT_ITEM(v)+index+1),
-              (char *)(SHORT_ITEM(v)+index),
-              (v->size-index) * sizeof(union anything));
-      SHORT_ITEM(v)[index].refs=0;
-    }
     v->size++;
   }else{
     struct array *ret;
 
-    ret=allocate_array_no_init(v->size+1, (v->size >> 3) + 1, v->array_type);
+    ret=allocate_array_no_init(v->size+1, (v->size >> 3) + 1);
     ret->type_field = v->type_field;
 
-    if(v->array_type == T_MIXED)
-    {
-      MEMCPY(ITEM(ret), ITEM(v), sizeof(struct svalue) * index);
-      MEMCPY(ITEM(ret)+index+1, ITEM(v)+index, sizeof(struct svalue) * (v->size-index));
-      ITEM(ret)[index].type=T_INT;
+    MEMCPY(ITEM(ret), ITEM(v), sizeof(struct svalue) * index);
+    MEMCPY(ITEM(ret)+index+1, ITEM(v)+index, sizeof(struct svalue) * (v->size-index));
+    ITEM(ret)[index].type=T_INT;
 #ifdef __CHECKER__
-      ITEM(ret)[index].subtype=0;
-      ITEM(ret)[index].u.refs=0;
+    ITEM(ret)[index].subtype=0;
+    ITEM(ret)[index].u.refs=0;
 #endif
-    }else{
-      MEMCPY(SHORT_ITEM(ret), SHORT_ITEM(v), sizeof(union anything) * index);
-
-      MEMCPY(SHORT_ITEM(ret)+index+1,
-             SHORT_ITEM(v)+index,
-             sizeof(union anything) * (v->size-index));
-      SHORT_ITEM(ret)[index].refs=0;
-    }
     v->size=0;
     free_array(v);
     v=ret;
@@ -328,42 +260,24 @@ static struct array *resize_array(struct array *a, INT32 size)
     /* We should grow the array */
     if(a->malloced_size >= size)
     {
-      if(a->array_type == T_MIXED)
+      for(;a->size < size; a->size++)
       {
-	for(;a->size < size; a->size++)
-	{
-	  ITEM(a)[a->size].type=T_INT;
-	  ITEM(a)[a->size].subtype=NUMBER_NUMBER;
-	  ITEM(a)[a->size].u.integer=0;
-	}
-      }else{
-	MEMSET(SHORT_ITEM(a)+a->size,
-	       0,
-	       sizeof(union anything)*(size-a->size));
-	a->size=size;
+	ITEM(a)[a->size].type=T_INT;
+	ITEM(a)[a->size].subtype=NUMBER_NUMBER;
+	ITEM(a)[a->size].u.integer=0;
       }
       return a;
     }else{
       struct array *ret;
-      ret=allocate_array_no_init(size, (size>>3)+1, a->array_type);
-      if(a->array_type == T_MIXED)
-      {
-	MEMCPY(ITEM(ret),ITEM(a),sizeof(struct svalue)*a->size);
-      }else{
-	MEMCPY(SHORT_ITEM(ret),SHORT_ITEM(a),sizeof(union anything)*a->size);
-      }
+      ret=allocate_array_no_init(size, (size>>3)+1);
+      MEMCPY(ITEM(ret),ITEM(a),sizeof(struct svalue)*a->size);
       a->size=0;
       free_array(a);
       return ret;
     }
   }else{
     /* We should shrink the array */
-    if(a->array_type == T_MIXED)
-    {
-      free_svalues(ITEM(a)+size, a->size - size);
-    }else{
-      free_short_svalues(SHORT_ITEM(a)+size, a->size - size, a->array_type);
-    }
+    free_svalues(ITEM(a)+size, a->size - size, a->type_field);
     a->size = size;
     return a;
   }
@@ -386,27 +300,16 @@ struct array *array_shrink(struct array *v,INT32 size)
 
   if(size*2 < v->malloced_size + 4) /* Should we realloc it? */
   {
-    a=allocate_array_no_init(size,0,v->array_type);
+    a=allocate_array_no_init(size,0);
     a->type_field = v->type_field;
 
-    if(v->array_type == T_MIXED)
-    {
-      free_svalues(ITEM(v) + size, v->size - size);
-      MEMCPY(ITEM(a), ITEM(v), size*sizeof(struct svalue));
-    }else{
-      free_short_svalues(SHORT_ITEM(v) + size, v->size - size, v->array_type);
-      MEMCPY(ITEM(a), ITEM(v), size*sizeof(union anything));
-    }
+    free_svalues(ITEM(v) + size, v->size - size, v->type_field);
+    MEMCPY(ITEM(a), ITEM(v), size*sizeof(struct svalue));
     v->size=0;
     free_array(v);
     return a;
   }else{
-    if(v->array_type == T_MIXED)
-    {
-      free_svalues(ITEM(v) + size, v->size - size);
-    }else{
-      free_short_svalues(SHORT_ITEM(v) + size, v->size - size, v->array_type);
-    }
+    free_svalues(ITEM(v) + size, v->size - size);
     v->size=size;
     return v;
   }
@@ -431,41 +334,24 @@ struct array *array_remove(struct array *v,INT32 index)
   if(v->size!=1 &&
      v->size*2 + 4 < v->malloced_size ) /* Should we realloc it? */
   {
-    a=allocate_array_no_init(v->size-1, 0, v->array_type);
+    a=allocate_array_no_init(v->size-1, 0);
     a->type_field = v->type_field;
 
-    if(v->array_type == T_MIXED)
-    {
-      if(index>0)
-	MEMCPY(ITEM(a), ITEM(v), index*sizeof(struct svalue));
-      if(v->size-index>1)
-	MEMCPY(ITEM(a)+index,
-	       ITEM(v)+index+1,
-	       (v->size-index-1)*sizeof(struct svalue));
-    }else{
-      if(index>0)
-	MEMCPY(SHORT_ITEM(a), SHORT_ITEM(v), index*sizeof(struct svalue));
-      if(v->size-index>1)
-	MEMCPY(SHORT_ITEM(a)+index,
-	       SHORT_ITEM(v)+index+1,
-	       (v->size-index-1)*sizeof(union anything));
-    }
+    if(index>0)
+      MEMCPY(ITEM(a), ITEM(v), index*sizeof(struct svalue));
+    if(v->size-index>1)
+      MEMCPY(ITEM(a)+index,
+	     ITEM(v)+index+1,
+	     (v->size-index-1)*sizeof(struct svalue));
     v->size=0;
     free_array(v);
     return a;
   }else{
     if(v->size-index>1)
     {
-      if(v->array_type == T_MIXED)
-      {
-	MEMMOVE((char *)(ITEM(v)+index),
-		(char *)(ITEM(v)+index+1),
-	        (v->size-index-1)*sizeof(struct svalue));
-      }else{
-	MEMMOVE((char *)(SHORT_ITEM(v)+index),
-		(char *)(SHORT_ITEM(v)+index+1),
-		(v->size-index-1)*sizeof(union anything));
-      }
+      MEMMOVE((char *)(ITEM(v)+index),
+	      (char *)(ITEM(v)+index+1),
+	      (v->size-index-1)*sizeof(struct svalue));
     }
     v->size--;
     return v;
@@ -486,42 +372,17 @@ INT32 array_search(struct array *v, struct svalue *s,INT32 start)
 
   check_destructed(s);
 
-  if(v->type_field & (1 << s->type)) /* Why search for something that is not there? */
+  /* Why search for something that is not there? */
+  if(v->type_field & (1 << s->type))
   {
-    if(v->array_type == T_MIXED)
+    TYPE_FIELD t=0;
+    for(e=start;e<v->size;e++)
     {
-      TYPE_FIELD t=0;
-      for(e=start;e<v->size;e++)
-      {
-	if(is_eq(ITEM(v)+e,s)) return e;
-	t |= 1<<ITEM(v)[e].type;
-      }
-      v->type_field=t;
-      return -1;
-    }else{
-      if(v->array_type == T_FLOAT)
-      {
-	if(s->type == T_FLOAT)
-	  for(e=start;e<v->size;e++)
-	    if(SHORT_ITEM(v)[e].float_number == s->u.float_number)
-	      return e;
-	return -1;
-      }
-      if(v->array_type == s->type)
-      {
-	for(e=start;e<v->size;e++)
-	  if(SHORT_ITEM(v)[e].refs == s->u.refs)
-	    return e;
-	return -1;
-      }
-
-      if(IS_ZERO(s))
-	for(e=start;e<v->size;e++)
-	  if(!SHORT_ITEM(v)[e].refs)
-	    return e;
-
-      return -1;
+      if(is_eq(ITEM(v)+e,s)) return e;
+      t |= 1<<ITEM(v)[e].type;
     }
+    v->type_field=t;
+    return -1;
   }
 
   return -1;
@@ -546,18 +407,10 @@ struct array *slice_array(struct array *v,INT32 start,INT32 end)
     return array_shrink(v,end);
   }
 
-  a=allocate_array_no_init(end-start,0,v->array_type);
+  a=allocate_array_no_init(end-start,0);
   a->type_field = v->type_field;
 
-  if(v->array_type == T_MIXED)
-  {
-    assign_svalues_no_free(ITEM(a), ITEM(v)+start, end-start);
-  }else{
-    assign_short_svalues_no_free(SHORT_ITEM(a),
-				 SHORT_ITEM(v)+start,
-				 v->array_type,
-				 end-start);
-  }
+  assign_svalues_no_free(ITEM(a), ITEM(v)+start, end-start, v->type_field);
 
   return a;
 }
@@ -569,18 +422,10 @@ struct array *copy_array(struct array *v)
 {
   struct array *a;
 
-  a=allocate_array_no_init(v->size, 0, v->array_type);
+  a=allocate_array_no_init(v->size, 0);
   a->type_field = v->type_field;
 
-  if(v->array_type == T_MIXED)
-  {
-    assign_svalues_no_free(ITEM(a), ITEM(v), v->size);
-  }else{
-    assign_short_svalues_no_free(SHORT_ITEM(a),
-				 SHORT_ITEM(v),
-				 v->array_type,
-				 v->size);
-  }
+  assign_svalues_no_free(ITEM(a), ITEM(v), v->size, v->type_field);
 
   return a;
 }
@@ -596,37 +441,20 @@ void check_array_for_destruct(struct array *v)
   types = 0;
   if(v->type_field & (BIT_OBJECT | BIT_FUNCTION))
   {
-    if(v->array_type == T_MIXED)
+    for(e=0; e<v->size; e++)
     {
-      for(e=0; e<v->size; e++)
-      {
-        if((ITEM(v)[e].type == T_OBJECT ||
-	    (ITEM(v)[e].type == T_FUNCTION && ITEM(v)[e].subtype!=-1)) &&
-	   (!ITEM(v)[e].u.object->prog))
-        {
-          free_svalue(ITEM(v)+e);
-	  ITEM(v)[e].type=T_INT;
-	  ITEM(v)[e].subtype=NUMBER_DESTRUCTED;
-	  ITEM(v)[e].u.integer=0;
-
-          types |= BIT_INT;
-        }else{
-          types |= 1<<ITEM(v)[e].type;
-        }
-      }
-    }else{
-      for(e=0; e<v->size; e++)
+      if((ITEM(v)[e].type == T_OBJECT ||
+	  (ITEM(v)[e].type == T_FUNCTION && ITEM(v)[e].subtype!=-1)) &&
+	 (!ITEM(v)[e].u.object->prog))
       {
-	if(!SHORT_ITEM(v)[e].object)
-	{
-	  types |= BIT_INT;
-	}
-	else if(!SHORT_ITEM(v)[e].object->prog)
-	{
-	  free_short_svalue(SHORT_ITEM(v)+e,v->array_type);
-	  SHORT_ITEM(v)[e].refs=0;
-	  types |= BIT_INT;
-	}
+	free_svalue(ITEM(v)+e);
+	ITEM(v)[e].type=T_INT;
+	ITEM(v)[e].subtype=NUMBER_DESTRUCTED;
+	ITEM(v)[e].u.integer=0;
+
+	types |= BIT_INT;
+      }else{
+	types |= 1<<ITEM(v)[e].type;
       }
     }
     v->type_field = types;
@@ -644,29 +472,14 @@ INT32 array_find_destructed_object(struct array *v)
   TYPE_FIELD types;
   if(v->type_field & (BIT_OBJECT | BIT_FUNCTION))
   {
-    if(v->array_type == T_MIXED)
+    types=0;
+    for(e=0; e<v->size; e++)
     {
-      types=0;
-      for(e=0; e<v->size; e++)
-      {
-        if((ITEM(v)[e].type == T_OBJECT ||
-	    (ITEM(v)[e].type == T_FUNCTION && ITEM(v)[e].subtype!=-1)) &&
-	   (!ITEM(v)[e].u.object->prog))
-	  return e;
-	types |= 1<<ITEM(v)[e].type;
-      }
-    }else{
-      types=1<<(v->array_type);
-      for(e=0; e<v->size; e++)
-      {
-	if(SHORT_ITEM(v)[e].object)
-	{
-	  if(!SHORT_ITEM(v)[e].object->prog)
-	    return e;
-	}else{
-	  types |= BIT_INT;
-	}
-      }
+      if((ITEM(v)[e].type == T_OBJECT ||
+	  (ITEM(v)[e].type == T_FUNCTION && ITEM(v)[e].subtype!=-1)) &&
+	 (!ITEM(v)[e].u.object->prog))
+	return e;
+      types |= 1<<ITEM(v)[e].type;
     }
     v->type_field = types;
   }
@@ -691,7 +504,7 @@ static int internal_cmpfun(INT32 *a,INT32 *b)
   return current_cmpfun(current_array_p + *a, current_array_p + *b);
 }
 
-INT32 *get_order(struct array *v, cmpfun fun,cmpfun_getter backfun)
+INT32 *get_order(struct array *v, cmpfun fun)
 {
   INT32 e, *current_order;
 
@@ -701,22 +514,12 @@ INT32 *get_order(struct array *v, cmpfun fun,cmpfun_getter backfun)
   current_order=(INT32 *)xalloc(v->size * sizeof(INT32));
   for(e=0; e<v->size; e++) current_order[e]=e;
 
-  if(v->array_type == T_MIXED)
-  {
-    current_array_p = ITEM(v);
-    current_cmpfun = fun;
-    fsort((char *)current_order,
-	  v->size,
-	  sizeof(INT32),
-	  (fsortfun)internal_cmpfun);
-  }else{
-    current_short_array_p = SHORT_ITEM(v);
-    current_short_cmpfun = backfun(v->array_type);
-    fsort((char *)current_order,
-	  v->size,
-	  sizeof(INT32),
-	  (fsortfun)internal_short_cmpfun);
-  }
+  current_array_p = ITEM(v);
+  current_cmpfun = fun;
+  fsort((char *)current_order,
+	v->size,
+	sizeof(INT32),
+	(fsortfun)internal_cmpfun);
 
   return current_order;
 }
@@ -748,56 +551,6 @@ static int set_svalue_cmpfun(struct svalue *a, struct svalue *b)
   }
 }
 
-static int set_anything_cmpfun_int(union anything *a, union anything *b)
-{
-  return a->integer - b->integer;
-}
-
-static int set_anything_cmpfun_ptr(union anything *a, union anything *b)
-{
-  if(a->refs < b->refs) return -1;
-  if(a->refs > b->refs) return 1;
-  return 0;
-}
-
-static int set_anything_cmpfun_float(union anything *a, union anything *b)
-{
-  if(a->float_number < b->float_number) return -1;
-  if(a->float_number > b->float_number) return 1;
-  return 0;
-}
-
-static short_cmpfun get_set_cmpfun(TYPE_T t)
-{
-  switch(t)
-  {
-  case T_FLOAT: return set_anything_cmpfun_float;
-  case T_INT: return set_anything_cmpfun_int;
-  default: return set_anything_cmpfun_ptr;
-  }
-}
-
-static int switch_anything_cmpfun_string(union anything *a, union anything *b)
-{
-  if(!a->string || !b->string)
-    return set_anything_cmpfun_ptr(a,b);
-  return my_strcmp(a->string, b->string);
-}
-
-
-static short_cmpfun get_switch_cmpfun(TYPE_T t)
-{
-  switch(t)
-  {
-  case T_INT: return set_anything_cmpfun_int;
-  case T_FLOAT: return set_anything_cmpfun_float;
-  case T_STRING: return switch_anything_cmpfun_string;
-  default:
-    error("Illegal type in switch.\n");
-    return 0; /* Make apcc happy */
-  }
-}
-
 static int switch_svalue_cmpfun(struct svalue *a, struct svalue *b)
 {
   if(a->type != b->type) return a->type - b->type;
@@ -824,7 +577,7 @@ static int switch_svalue_cmpfun(struct svalue *a, struct svalue *b)
  */
 INT32 *get_set_order(struct array *a)
 {
-  return get_order(a, set_svalue_cmpfun, get_set_cmpfun);
+  return get_order(a, set_svalue_cmpfun);
 }
 
 /*
@@ -832,76 +585,59 @@ INT32 *get_set_order(struct array *a)
  */
 INT32 *get_switch_order(struct array *a)
 {
-  return get_order(a, switch_svalue_cmpfun, get_switch_cmpfun);
+  return get_order(a, switch_svalue_cmpfun);
 }
 
 
 static INT32 low_lookup(struct array *v,
 			struct svalue *s,
-			cmpfun fun,
-			cmpfun_getter backfun)
+			cmpfun fun)
 {
   INT32 a,b,c;
   int q;
-  if(v->array_type == T_MIXED)
-  {
-    a=0;
-    b=v->size;
-    while(b > a)
-    {
-      c=(a+b)/2;
-      q=fun(ITEM(v)+c,s);
-
-      if(q < 0)
-	a=c+1;
-      else if(q > 0)
-	b=c;
-      else
-	return c;
-    }
-    if(a<v->size && fun(ITEM(v)+a,s)<0) a++;
-    return ~a;
-
-  }else if(s->type == v->array_type ||
-	   (IS_ZERO(s) && v->array_type != T_FLOAT)){
-    short_cmpfun fun;
-    if(IS_ZERO(s))
-      MEMSET((char *)&s->u, 0, sizeof(union anything));
-
-    fun=backfun(v->array_type);
 
-    a=0;
-    b=v->size;
-    while(b > a)
-    {
-      c=(a+b)/2;
-      q=fun(SHORT_ITEM(v)+c,&s->u);
-
-      if(q < 0)
-	a=c+1;
-      else if(q > 0)
-	b=c;
-      else
-	return c;
-    }
-    if(a<v->size && fun(SHORT_ITEM(v)+a,&s->u)<0) a++;
-    return ~a;
-
-  }else{
-    /* face it, it's not there */
-    if((long)s->type < (long)v->array_type) return -1;
-    return ~v->size;
+  a=0;
+  b=v->size;
+  while(b > a)
+  {
+    c=(a+b)/2;
+    q=fun(ITEM(v)+c,s);
+    
+    if(q < 0)
+      a=c+1;
+    else if(q > 0)
+      b=c;
+    else
+      return c;
   }
+  if(a<v->size && fun(ITEM(v)+a,s)<0) a++;
+  return ~a;
 }
 
 INT32 set_lookup(struct array *a, struct svalue *s)
 {
-  return low_lookup(a,s,set_svalue_cmpfun,get_set_cmpfun);
+  /* face it, it's not there */
+  if( (((2 << s->type) -1) & s->type_field) == 0)
+    return -1;
+
+  /* face it, it's not there */
+  if( ((BIT_MIXED << s->type) & BIT_MIXED & s->type_field) == 0)
+    return ~v->size;
+
+  return low_lookup(a,s,set_svalue_cmpfun);
 }
 
 INT32 switch_lookup(struct array *a, struct svalue *s)
 {
-  return low_lookup(a,s,switch_svalue_cmpfun,get_switch_cmpfun);
+  /* face it, it's not there */
+  if( (((2 << s->type) -1) & s->type_field) == 0)
+    return -1;
+
+  /* face it, it's not there */
+  if( ((BIT_MIXED << s->type) & BIT_MIXED & s->type_field) == 0)
+    return ~v->size;
+
+  return low_lookup(a,s,switch_svalue_cmpfun);
 }
 
 
@@ -910,11 +646,7 @@ INT32 switch_lookup(struct array *a, struct svalue *s)
  */
 struct array *order_array(struct array *v, INT32 *order)
 {
-  if(v->array_type == T_MIXED)
-    reorder((char *)ITEM(v),v->size,sizeof(struct svalue),order);
-  else
-    reorder((char *)SHORT_ITEM(v),v->size,sizeof(union anything),order);
-
+  reorder((char *)ITEM(v),v->size,sizeof(struct svalue),order);
   return v;
 }
 
@@ -926,19 +658,11 @@ struct array *reorder_and_copy_array(struct array *v, INT32 *order)
 {
   INT32 e;
   struct array *ret;
-  ret=allocate_array_no_init(v->size, 0, v->array_type);
+  ret=allocate_array_no_init(v->size, 0);
   ret->type_field = v->type_field;
 
-  if(v->array_type == T_MIXED)
-  {
-    for(e=0;e<v->size;e++)
-      assign_svalue_no_free(ITEM(ret)+e, ITEM(v)+order[e]);
-  }else{
-    for(e=0;e<v->size;e++)
-      assign_short_svalue_no_free(SHORT_ITEM(ret)+e,
-				  SHORT_ITEM(v)+order[e],
-				  v->array_type);
-  }
+  for(e=0;e<v->size;e++)
+    assign_svalue_no_free(ITEM(ret)+e, ITEM(v)+order[e]);
 
   return ret;
 }
@@ -950,29 +674,9 @@ void array_fix_type_field(struct array *v)
   TYPE_FIELD t;
 
   t=0;
-  switch(v->array_type)
-  {
-  case T_MIXED:
-    for(e=0; e<v->size; e++) t |= 1 << ITEM(v)[e].type;
-    break;
-
-  case T_INT:
-  case T_FLOAT:
-    t=1 << v->array_type; 
-   break;
 
-  default:
-    t=1 << v->array_type;
-    for(e=0; e<v->size; e++)
-    {
-      if(! SHORT_ITEM(v)[e].refs)
-      {
-	t |= 1 << T_INT;
-	break;
-      }
-    }
+  for(e=0; e<v->size; e++) t |= 1 << ITEM(v)[e].type;
 
-  }
 #ifdef DEBUG
   if(t & ~(v->type_field))
     fatal("Type field out of order!\n");
@@ -980,60 +684,7 @@ void array_fix_type_field(struct array *v)
   v->type_field = t;
 }
 
-/*
- * Replace a large array with a small one if possible
- */
-struct array *compact_array(struct array *v)
-{
-  INT32 e;
-  int type;
-  struct array *ret;
-  if(v->array_type != T_MIXED) return v;
-
-  if(!v->size) return v; /* won't become smaller */
-
-  array_fix_type_field(v);
-
-  type=-1;
-  switch(v->type_field)
-  {
-  case BIT_INT | BIT_STRING:  type=T_STRING; goto check_possible;
-  case BIT_INT | BIT_ARRAY:   type=T_ARRAY; goto check_possible;
-  case BIT_INT | BIT_MAPPING: type=T_MAPPING; goto check_possible;
-  case BIT_INT | BIT_LIST:    type=T_LIST; goto check_possible;
-  case BIT_INT | BIT_OBJECT:  type=T_OBJECT; goto check_possible;
-  case BIT_INT | BIT_PROGRAM: type=T_PROGRAM;
-
-  check_possible:
-    for(e=0; e<v->size; e++)
-      if(ITEM(v)[e].type == T_INT)
-	if(ITEM(v)[e].u.integer != 0)
-	  return v;
-
-    goto do_compact;
-
-  case BIT_INT:     type=T_INT; goto do_compact;
-  case BIT_FLOAT:   type=T_FLOAT; goto do_compact;
-  case BIT_STRING:  type=T_STRING; goto do_compact;
-  case BIT_ARRAY:   type=T_ARRAY; goto do_compact;
-  case BIT_MAPPING: type=T_MAPPING; goto do_compact;
-  case BIT_LIST:    type=T_LIST; goto do_compact;
-  case BIT_OBJECT:  type=T_OBJECT; goto do_compact;
-  case BIT_PROGRAM: type=T_PROGRAM; goto do_compact;
-
-  do_compact:
-    ret=allocate_array_no_init(v->size, 0, type);
-    for(e=0; e<v->size; e++)
-      assign_to_short_svalue_no_free(SHORT_ITEM(ret)+e,
-				     type,
-				     ITEM(v)+e);
-    free_array(v);
-    return ret;
-
-  default:
-    return v;
-  }
-}
+struct array *compact_array(struct array *v) { return v; }
 
 /*
  * Get a pointer to the 'union anything' specified IF it is of the specified
@@ -1043,13 +694,7 @@ union anything *low_array_get_item_ptr(struct array *a,
 				       INT32 ind,
 				       TYPE_T t)
 {
-  if(a->array_type == T_MIXED)
-  {
-    if(ITEM(a)[ind].type == t)
-      return & (ITEM(a)[ind].u);
-  }else if(a->array_type == t){
-    return SHORT_ITEM(a)+ind;
-  }
+  if(ITEM(a)[ind].type == t) return & (ITEM(a)[ind].u);
   return 0;
 }
 
@@ -1104,85 +749,21 @@ INT32 * merge(struct array *a,struct array *b,INT32 opcode)
 
   ptr=ret=(INT32 *)xalloc(sizeof(INT32)*(a->size + b->size + 1));
   ptr++;
-  if(a->array_type == T_MIXED && b->array_type == T_MIXED)
-  {
-    while(ap < a->size && bp < b->size)
-    {
-      i=set_svalue_cmpfun(ITEM(a)+ap,ITEM(b)+bp);
-      if(i < 0)
-	i=opcode >> 8;
-      else if(i > 0)
-	i=opcode;
-      else
-	i=opcode >> 4;
-
-      if(i & OP_A) *(ptr++)=ap;
-      if(i & OP_B) *(ptr++)=~bp;
-      if(i & OP_SKIP_A) ap++;
-      if(i & OP_SKIP_B) bp++;
-    }
-  }else if(a->array_type == b->array_type)
-  {
-    short_cmpfun short_alist_cmp;
-    short_alist_cmp=get_set_cmpfun(a->array_type);
-    while(ap < a->size && bp < b->size)
-    {
-      i=short_alist_cmp(SHORT_ITEM(a)+ap,SHORT_ITEM(b)+bp);
-      if(i < 0)
-	i=opcode >> 8;
-      else if(i > 0)
-	i=opcode;
-      else
-	i=opcode >> 4;
-
-      if(i & OP_A) *(ptr++)=ap;
-      if(i & OP_B) *(ptr++)=~bp;
-      if(i & OP_SKIP_A) ap++;
-      if(i & OP_SKIP_B) bp++;
-    }
-  }else{
-    struct svalue sa,sb;
-    while(ap < a->size && bp < b->size)
-    {
-      if(a->array_type == T_MIXED)
-      {
-	sa=ITEM(a)[ap];
-      }else{
-	sa.u = SHORT_ITEM(a)[ap];
-	if(!sa.u.refs )
-	{
-	  if( (sa.type=a->array_type) != T_FLOAT)  sa.type=T_INT;
-	}else{
-	  sa.type=a->array_type;
-	}
-      }
-
-      if(b->array_type == T_MIXED)
-      {
-	sb=ITEM(b)[bp];
-      }else{
-	sb.u=SHORT_ITEM(b)[bp];
-	if(!sb.u.refs)
-	{
-	  if( (sb.type=b->array_type) != T_FLOAT)  sb.type=T_INT;
-	}else{
-	  sb.type=b->array_type;
-	}
-      }
 
-      i=set_svalue_cmpfun(&sa, &sb);
-      if(i < 0)
-	i=opcode >> 8;
-      else if(i > 0)
-	i=opcode;
-      else
-	i=opcode >> 4;
-
-      if(i & OP_A) *(ptr++)=ap;
-      if(i & OP_B) *(ptr++)=~bp;
-      if(i & OP_SKIP_A) ap++;
-      if(i & OP_SKIP_B) bp++;
-    }
+  while(ap < a->size && bp < b->size)
+  {
+    i=set_svalue_cmpfun(ITEM(a)+ap,ITEM(b)+bp);
+    if(i < 0)
+      i=opcode >> 8;
+    else if(i > 0)
+      i=opcode;
+    else
+      i=opcode >> 4;
+    
+    if(i & OP_A) *(ptr++)=ap;
+    if(i & OP_B) *(ptr++)=~bp;
+    if(i & OP_SKIP_A) ap++;
+    if(i & OP_SKIP_B) bp++;
   }
 
   if((opcode >> 8) & OP_A) while(ap<a->size) *(ptr++)=ap++;
@@ -1204,60 +785,14 @@ struct array *array_zip(struct array *a, struct array *b,INT32 *zipper)
   size=zipper[0];
   zipper++;
 
-  if(a->array_type == T_MIXED && b->array_type == T_MIXED)
-  {
-    ret=allocate_array_no_init(size,0, T_MIXED);
-    for(e=0; e<size; e++)
-    {
-      if(*zipper >= 0)
-	assign_svalue_no_free(ITEM(ret)+e, ITEM(a)+*zipper);
-      else
-	assign_svalue_no_free(ITEM(ret)+e, ITEM(b)+~*zipper);
-      zipper++;
-    }
-  }else if(a->array_type == b->array_type)
+  ret=allocate_array_no_init(size,0, T_MIXED);
+  for(e=0; e<size; e++)
   {
-    ret=allocate_array_no_init(size, 0, a->array_type);
-    for(e=0; e<size; e++)
-    {
-      if(*zipper >= 0)
-      {
-	assign_short_svalue_no_free(SHORT_ITEM(ret)+e,
-			    SHORT_ITEM(a)+*zipper,
-			    a->array_type);
-      }else{
-	assign_short_svalue_no_free(SHORT_ITEM(ret)+e,
-			    SHORT_ITEM(b)+~*zipper,
-			    b->array_type);
-      }
-      zipper++;
-    }
-  }else{
-    ret=allocate_array_no_init(size, 0, T_MIXED);
-    for(e=0; e<size; e++)
-    {
-      if(*zipper >= 0)
-      {
-	if(a->array_type == T_MIXED)
-	{
-	  assign_svalue_no_free(ITEM(ret)+e, ITEM(a)+*zipper);
-	}else{
-	  assign_from_short_svalue_no_free(ITEM(ret)+e,
-				   SHORT_ITEM(a)+*zipper,
-				   a->array_type);
-	}
-      }else{
-	if(b->array_type == T_MIXED)
-	{
-	  assign_svalue_no_free(ITEM(ret)+e, ITEM(b)+~*zipper);
-	}else{
-	  assign_from_short_svalue_no_free(ITEM(ret)+e,
-				   SHORT_ITEM(b)+~*zipper,
-				   b->array_type);
-	}
-      }
-      zipper++;
-    }
+    if(*zipper >= 0)
+      assign_svalue_no_free(ITEM(ret)+e, ITEM(a)+*zipper);
+    else
+      assign_svalue_no_free(ITEM(ret)+e, ITEM(b)+~*zipper);
+    zipper++;
   }
   ret->type_field = a->type_field | b->type_field;
   return ret;
@@ -1267,20 +802,8 @@ struct array *add_arrays(struct svalue *argp, INT32 args)
 {
   INT32 e, size;
   struct array *v;
-  TYPE_T array_type;
-
-  array_type=args ? argp[0].u.array->array_type : T_MIXED;
-  for(size=e=0; e<args; e++)
-  {
-    check_array_for_destruct(argp[e].u.array);
-    size+=argp[e].u.array->size;
-    if(array_type != argp[e].u.array->array_type)
-      array_type=T_MIXED;
-  }
 
-  if(args &&
-     argp[0].u.array->refs==1 &&
-     argp[0].u.array->array_type == array_type)
+  if(args && argp[0].u.array->refs==1)
   {
     e=argp[0].u.array->size;
     v=resize_array(argp[0].u.array, size);
@@ -1288,38 +811,19 @@ struct array *add_arrays(struct svalue *argp, INT32 args)
     size=e;
     e=1;
   }else{
-    v=allocate_array_no_init(size, 0, array_type);
+    v=allocate_array_no_init(size, 0);
     v->type_field=0;
     e=size=0;
   }
-  if(array_type == T_MIXED)
+
+  for(; e<args; e++)
   {
-    for(; e<args; e++)
-    {
-      v->type_field|=argp[e].u.array->type_field;
-      if(argp[e].u.array->array_type == T_MIXED)
-      {
-	assign_svalues_no_free(ITEM(v)+size,
-			     ITEM(argp[e].u.array),
-			     argp[e].u.array->size);
-      }else{
-	assign_from_short_svalues_no_free(ITEM(v)+size,
-					  SHORT_ITEM(argp[e].u.array),
-					  argp[e].u.array->array_type,
-					  argp[e].u.array->size);
-      }
-      size+=argp[e].u.array->size;
-    }
-  }else{
-    for(;e<args;e++)
-    {
-      v->type_field |= argp[e].u.array->type_field;
-      assign_short_svalues_no_free(SHORT_ITEM(v)+size,
-				   SHORT_ITEM(argp[e].u.array),
-				   argp[e].u.array->array_type,
-				   argp[e].u.array->size);
-      size+=argp[e].u.array->size;
-    }
+    v->type_field|=argp[e].u.array->type_field;
+    assign_svalues_no_free(ITEM(v)+size,
+			   ITEM(argp[e].u.array),
+			   argp[e].u.array->size,
+			   argp[e].u.array->type_field);
+    size+=argp[e].u.array->size;
   }
 
   return v;
@@ -1332,6 +836,13 @@ int array_equal_p(struct array *a, struct array *b, struct processing *p)
 
   if(a == b) return 1;
   if(a->size != b->size) return 0;
+  if(!a->size) return 1;
+
+  /* This could be done much better if I KNEW that
+   * the type fields didn't contain types that
+   * really aren't in the array
+   */
+  if(!(a->type_field & b->type_field)) return 0;
 
   curr.pointer_a = a;
   curr.pointer_b = b;
@@ -1341,46 +852,10 @@ int array_equal_p(struct array *a, struct array *b, struct processing *p)
     if(p->pointer_a == (void *)a && p->pointer_b == (void *)b)
       return 1;
 
-  if(a->array_type == T_MIXED && b->array_type==T_MIXED)
-  {
-    for(e=0; e<a->size; e++)
-      if(!low_is_equal(ITEM(a)+e, ITEM(b)+e, &curr))
-	return 0;
-  }else{
-    for(e=0; e<a->size; e++)
-    {
-      struct svalue sa,sb;
+  for(e=0; e<a->size; e++)
+    if(!low_is_equal(ITEM(a)+e, ITEM(b)+e, &curr))
+      return 0;
 
-      if(a->array_type == T_MIXED)
-      {
-	sa=ITEM(a)[e];
-      }else{
-	sa.u=SHORT_ITEM(a)[e];
-	if(!sa.u.refs)
-	{
-	  if( (sa.type=a->array_type) != T_FLOAT)  sa.type=T_INT;
-	}else{
-	  sa.type=a->array_type;
-	}
-      }
-
-      if(b->array_type == T_MIXED)
-      {
-	sb=ITEM(b)[e];
-      }else{
-	sb.u=SHORT_ITEM(b)[e];
-	if(!sb.u.refs)
-	{
-	  if( (sb.type=b->array_type) != T_FLOAT)  sb.type=T_INT;
-	}else{
-	  sb.type=b->array_type;
-	}
-      }
-      
-      if(!low_is_equal(&sa, &sb, &curr))
-	return 0;
-    }
-  }
   return 1;
 }
 
@@ -1517,47 +992,16 @@ node *make_node_from_array(struct array *a)
   array_fix_type_field(a);
   if(a->type_field == (1 << T_INT))
   {
-    if(a->array_type == T_MIXED)
-    {
-      for(e=0; e<a->size; e++)
-	if(ITEM(a)[e].u.integer != 0)
-	  break;
-      if(e == a->size)
-      {
-	return mkefuncallnode("allocate",
-			      mknode(F_ARG_LIST,
-				     mkintnode(a->size),
-				     mkstrnode(make_shared_string("mixed"))
-				     ));
-      }
-    }else{
-      e=a->size;
-      switch(a->array_type)
-      {
-      case T_INT:
-	str="int";
-	for(e=0; e<a->size; e++)
-	  if(SHORT_ITEM(a)[e].integer != 0)
-	    break;
+    for(e=0; e<a->size; e++)
+      if(ITEM(a)[e].u.integer != 0)
 	break;
-      case T_FLOAT:    str="float"; break;
-      case T_STRING:   str="string"; break;
-      case T_ARRAY:    str="array"; break;
-      case T_LIST:     str="list"; break;
-      case T_MAPPING:  str="mapping"; break;
-      case T_OBJECT:   str="object"; break;
-      case T_FUNCTION: str="function"; break;
-      case T_PROGRAM:  str="program"; break;
-      default:         str="mixed";
-      }
-      if(e==a->size)
-      {
-	return mkefuncallnode("allocate",
-			      mknode(F_ARG_LIST,
-				     mkintnode(a->size),
-				     mkstrnode(make_shared_string(str))
-				     ));
-      }
+    if(e == a->size)
+    {
+      return mkefuncallnode("allocate",
+			    mknode(F_ARG_LIST,
+				   mkintnode(a->size),
+				   mkstrnode(make_shared_string("mixed"))
+				   ));
     }
   }
   if(check_that_array_is_constant(a))
@@ -1568,24 +1012,8 @@ node *make_node_from_array(struct array *a)
     return mkconstantsvaluenode(&s);
   }else{
     node *ret=0;
-    if(a->array_type == T_MIXED)
-    {
-      for(e=0; e<a->size; e++)
-	ret=mknode(F_ARG_LIST,ret,mksvaluenode(ITEM(a)+e));
-    }else{
-      s.type=a->array_type;
-      s.subtype=0;
-      for(e=0; e<a->size; e++)
-      {
-	s.u=SHORT_ITEM(a)[e];
-	if(s.u.refs)
-	{
-	  ret=mknode(F_ARG_LIST,ret,mksvaluenode(&s));
-	}else{
-	  ret=mknode(F_ARG_LIST,ret,mkintnode(0));
-	}
-      }
-    }
+    for(e=0; e<a->size; e++)
+      ret=mknode(F_ARG_LIST,ret,mksvaluenode(ITEM(a)+e));
     return mkefuncallnode("aggregate",ret);
   }
 }
@@ -1595,20 +1023,15 @@ void push_array_items(struct array *a)
   if(sp + a->size >= &evaluator_stack[EVALUATOR_STACK_SIZE])
     error("Array does not fit on stack.\n");
   check_array_for_destruct(a);
-  if(a->array_type == T_MIXED)
+  if(a->refs == 1)
   {
-    if(a->refs == 1)
-    {
-      MEMCPY(sp,ITEM(a),sizeof(struct svalue)*a->size);
-      sp += a->size;
-      a->size=0;
-      free_array(a);
-      return;
-    }else{
-      assign_svalues_no_free(sp, ITEM(a), a->size);
-    }
+    MEMCPY(sp,ITEM(a),sizeof(struct svalue)*a->size);
+    sp += a->size;
+    a->size=0;
+    free_array(a);
+    return;
   }else{
-    assign_from_short_svalues_no_free(sp, SHORT_ITEM(a), a->array_type, a->size);
+    assign_svalues_no_free(sp, ITEM(a), a->size);
   }
   sp += a->size;
   free_array(a);
@@ -1618,31 +1041,12 @@ void describe_array_low(struct array *a, struct processing *p, int indent)
 {
   INT32 e,d;
   indent += 2;
-  if(a->array_type == T_MIXED)
+
+  for(e=0; e<a->size; e++)
   {
-    for(e=0; e<a->size; e++)
-    {
-      if(e) my_strcat(",\n");
-      for(d=0; d<indent; d++) my_putchar(' ');
-      describe_svalue(ITEM(a)+e,indent,p);
-    }
-  }else{
-    struct svalue s;
-    for(e=0; e<a->size; e++)
-    {
-      if(e) my_strcat(",\n");
-      for(d=0; d<indent; d++) my_putchar(' ');
-      if(SHORT_ITEM(a)[e].refs)
-      {
-	s.type=a->array_type;
-	s.u=SHORT_ITEM(a)[e];
-      }else{
-	s.type=T_INT;
-	s.subtype=NUMBER_NUMBER;
-	s.u.integer=0;
-      }
-      describe_svalue(&s, indent, p);
-    }
+    if(e) my_strcat(",\n");
+    for(d=0; d<indent; d++) my_putchar(' ');
+    describe_svalue(ITEM(a)+e,indent,p);
   }
 }
 
@@ -1661,22 +1065,7 @@ void describe_index(struct array *a,
 		    struct processing *p,
 		    int indent)
 {
-  if(a->array_type == T_MIXED)
-  {
-    describe_svalue(ITEM(a)+e, indent, p);
-  }else{
-    struct svalue s;
-    if(SHORT_ITEM(a)[e].refs)
-    {
-      s.type=a->array_type;
-      s.u=SHORT_ITEM(a)[e];
-    }else{
-      s.type=T_INT;
-      s.subtype=NUMBER_NUMBER;
-      s.u.integer=0;
-    }
-    describe_svalue(&s, indent, p);
-  }
+  describe_svalue(ITEM(a)+e, indent, p);
 }
 
 
@@ -1684,7 +1073,7 @@ void describe_array(struct array *a,struct processing *p,int indent)
 {
   struct processing doing;
   INT32 e;
-  char buf[40];
+  char buf[60];
   if(! a->size)
   {
     my_strcat("({ })");
@@ -1711,34 +1100,14 @@ void describe_array(struct array *a,struct processing *p,int indent)
   my_strcat("})");
 }
 
-struct array *aggregate_array(INT32 args, TYPE_T type)
+struct array *aggregate_array(INT32 args)
 {
   struct array *a;
 
-  a=allocate_array_no_init(args,0,type);
-  if(type == T_MIXED)
-  {
-    MEMCPY((char *)ITEM(a),(char *)(sp-args),args*sizeof(struct svalue));
-    a->type_field=BIT_MIXED;
-    sp-=args;
-  }else{
-    struct svalue *save_sp;
-    save_sp=sp;
-    while(--args >= 0)
-    {
-      sp--;
-      if(sp->type == type)
-      {
-	SHORT_ITEM(a)[args].refs = sp->u.refs;
-      }else if(IS_ZERO(sp)){
-	SHORT_ITEM(a)[args].refs = 0;
-      }else{
-	sp=save_sp;
-	array_free_no_free(a);
-	error("Bad type when constructing array.\n");
-      }
-    }
-  }
+  a=allocate_array_no_init(args,0);
+  MEMCPY((char *)ITEM(a),(char *)(sp-args),args*sizeof(struct svalue));
+  a->type_field=BIT_MIXED;
+  sp-=args;
   return a;
 }
 
@@ -1789,65 +1158,32 @@ struct lpc_string *implode(struct array *a,struct lpc_string *del)
   struct lpc_string *ret,*tmp;
 
   len=0;
-  if(a->array_type==T_STRING)
-  {
-    for(e=0;e<a->size;e++)
-      if(SHORT_ITEM(a)[e].string)
-	len+=SHORT_ITEM(a)[e].string->len + del->len;
-    if(len) len-=del->len;
-
-    ret=begin_shared_string(len);
-    r=ret->str;
-    inited=0;
-    for(e=0;e<a->size;e++)
-    {
-      if(SHORT_ITEM(a)[e].string)
-      {
-	if(inited)
-	{
-	  MEMCPY(r,del->str,del->len);
-	  r+=del->len;
-	}
-	inited=1;
-	tmp=SHORT_ITEM(a)[e].string;
-	MEMCPY(r,tmp->str,tmp->len);
-	r+=tmp->len;
-	len++;
-      }
-    }
-    return end_shared_string(ret);
-  }
 
-  if(a->array_type==T_MIXED)
+  for(e=0;e<a->size;e++)
+    if(ITEM(a)[e].type==T_STRING)
+      len+=ITEM(a)[e].u.string->len + del->len;
+  if(len) len-=del->len;
+  
+  ret=begin_shared_string(len);
+  r=ret->str;
+  inited=0;
+  for(e=0;e<a->size;e++)
   {
-    for(e=0;e<a->size;e++)
-      if(ITEM(a)[e].type==T_STRING)
-	len+=ITEM(a)[e].u.string->len + del->len;
-    if(len) len-=del->len;
-
-    ret=begin_shared_string(len);
-    r=ret->str;
-    inited=0;
-    for(e=0;e<a->size;e++)
+    if(ITEM(a)[e].type==T_STRING)
     {
-      if(ITEM(a)[e].type==T_STRING)
+      if(inited)
       {
-	if(inited)
-	{
-	  MEMCPY(r,del->str,del->len);
-	  r+=del->len;
-	}
-	inited=1;
-	tmp=ITEM(a)[e].u.string;
-	MEMCPY(r,tmp->str,tmp->len);
-	r+=tmp->len;
-	len++;
+	MEMCPY(r,del->str,del->len);
+	r+=del->len;
       }
+      inited=1;
+      tmp=ITEM(a)[e].u.string;
+      MEMCPY(r,tmp->str,tmp->len);
+      r+=tmp->len;
+      len++;
     }
-    return end_shared_string(ret);
   }
-
-  return make_shared_string("");
+  return end_shared_string(ret);
 }
 
 struct array *copy_array_recursively(struct array *a,struct processing *p)
@@ -1867,17 +1203,10 @@ struct array *copy_array_recursively(struct array *a,struct processing *p)
     }
   }
 
-  ret=allocate_array_no_init(a->size,0,a->array_type);
+  ret=allocate_array_no_init(a->size,0);
   doing.pointer_b=(void *)ret;
-  if(a->array_type == T_MIXED)
-  {
-    copy_svalues_recursively_no_free(ITEM(ret),ITEM(a),a->size,&doing);
-  }else{
-    copy_short_svalues_recursively_no_free(SHORT_ITEM(ret),
-					   SHORT_ITEM(a),
-					   a->array_type,
-					   a->size,&doing);
-  }
+
+  copy_svalues_recursively_no_free(ITEM(ret),ITEM(a),a->size,&doing);
   return ret;
 }
 
@@ -1887,22 +1216,11 @@ void apply_array(struct array *a, INT32 args)
   INT32 e;
   struct array *ret;
   argp=sp-args;
-  if(a->array_type == T_MIXED)
+  for(e=0;e<a->size;e++)
   {
-    for(e=0;e<a->size;e++)
-    {
-      assign_svalues_no_free(sp,argp,args);
-      sp+=args;
-      apply_svalue(ITEM(a)+e,args);
-    }
-  }else{
-    for(e=0;e<a->size;e++)
-    {
-      array_index_no_free(sp++,a,e);
-      assign_svalues_no_free(sp,argp,args);
-      sp+=args;
-      f_call_function(args+1);
-    }
+    assign_svalues_no_free(sp,argp,args);
+    sp+=args;
+    apply_svalue(ITEM(a)+e,args);
   }
   ret=aggregate_array(a->size,T_MIXED);
   pop_n_elems(args);
@@ -1913,17 +1231,11 @@ struct array *reverse_array(struct array *a)
 {
   INT32 e;
   struct array *ret;
-  ret=allocate_array_no_init(a->size,0,a->array_type);
-  if(a->array_type == T_MIXED)
-  {
-    for(e=0;e<a->size;e++)
-      assign_svalue_no_free(ITEM(ret)+e,ITEM(a)+a->size+~e);
-  }else{
-    for(e=0;e<a->size;e++)
-      assign_short_svalue_no_free(SHORT_ITEM(ret)+e,
-				  SHORT_ITEM(a)+a->size+~e,
-				  a->array_type);
-  }
+
+  /* FIXME: Check refs so we might optimize */
+  ret=allocate_array_no_init(a->size,0);
+  for(e=0;e<a->size;e++)
+    assign_svalue_no_free(ITEM(ret)+e,ITEM(a)+a->size+~e);
   return ret;
 }
 
@@ -1936,6 +1248,85 @@ void array_replace(struct array *a,
   while((i=array_search(a,from,i+1)) >= 0) array_set_index(a,i,to);
 }
 
+#ifdef GC
+
+void array_gc_clear_mark()
+{
+  struct array *a;
+  a=&empty_array;
+  do
+  {
+    a->flags &=~ ARRAY_FLAG_MARK;
+    check_array(a, pass);
+
+    a=a->next;
+
+#ifdef DEBUG
+    if(!a) fatal("Null pointer in array list.\n");
+#endif
+  } while (a != & empty_array);
+}
+
+void array_gc_mark(array *a)
+{
+  INT e;
+  if(a->flags & ARRAY_FLAG_MARK) return;
+  a->flags |= ARRAY_FLAG_MARK;
+
+  if(!(a->type_field & ~(BIT_STRING|BIT_INT|BIT_FLOAT)))
+    return 0;
+
+  for(e=0;e<a->size;e++) svalue_gc_sweep(ITEM(a) + e);
+}
+
+void array_gc_sweep()
+{
+  struct array *a, *next;
+
+  a=&empty_array;
+  do
+  {
+    a->refs++;
+
+    if(!(a->flags & ARRAY_FLAG_MARK))
+    {
+      free_svalues(ITEM(a), a->size, a->type_field);
+      a->size=0; /* Don't free them again */
+    }
+    
+    next=a->next;
+    free_array(a);
+
+    a=next;
+#ifdef DEBUG
+    if(!a) fatal("Null pointer in array list.\n");
+#endif
+  } while (a != & empty_array);
+}
+
+
+#ifdef DEBUG
+void array_gc_sweep2()
+{
+  struct array *a;
+
+  a=&empty_array;
+  do
+  {
+    if(!(a->flags & ARRAY_FLAG_MARK))
+      fatal("Array ref count incorrect!\n");
+
+    a=a->next
+    
+#ifdef DEBUG
+    if(!a) fatal("Null pointer in array list.\n");
+#endif
+  } while (a != & empty_array);
+}
+#endif /* DEBUG */
+#endif /* GC */
+
+
 #ifdef DEBUG
 void check_array(struct array *a, int pass)
 {
@@ -1961,27 +1352,12 @@ void check_array(struct array *a, int pass)
   if(a->refs <=0 )
     fatal("Array has zero refs.\n");
 
-  if(a->array_type == T_MIXED)
-  {
-    for(e=0;e<a->size;e++)
-    {
-      if(! ( (1 << ITEM(a)[e].type) & (a->type_field) ))
-	fatal("Type field lies.\n");
-
-      check_svalue(ITEM(a)+e);
-    }
-  }
-  else if(a->array_type <= MAX_TYPE)
+  for(e=0;e<a->size;e++)
   {
-    if(a->type_field & ~(BIT_INT | (1<<a->array_type)))
-      fatal("Type field in short array lies!\n");
-
-    for(e=0;e<a->size;e++)
-      check_short_svalue(SHORT_ITEM(a)+e,a->array_type);
-  }
-  else
-  {
-    fatal("Array type out of range.\n");
+    if(! ( (1 << ITEM(a)[e].type) & (a->type_field) ))
+      fatal("Type field lies.\n");
+    
+    check_svalue(ITEM(a)+e);
   }
 }
 
@@ -2004,5 +1380,5 @@ void check_all_arrays(int pass)
     checked((void *)&empty_array,1);
   }
 }
-#endif
+#endif /* DEBUG */
 
diff --git a/src/array.h b/src/array.h
index 9cd029f2f5..4d4687072c 100644
--- a/src/array.h
+++ b/src/array.h
@@ -20,27 +20,12 @@ struct array
 			 * Bits can be set that don't exist in the array
 			 * though.
 			 */
-  TYPE_T array_type;	/* This is T_MIXED for a mixed array, or the type for
-			 * an array that can only contain one type.
-			 */
-  INT8 flags;		/* flags, like gc_cycle */
-};
-
-struct array_of_svalues
-{
-  struct array array;
+  INT16 flags;		/* flags, like gc_cycle */
   struct svalue item[1];
 };
 
-struct array_of_short_svalues
-{
-  struct array array;
-  union anything item[1];
-};
-
-#define ITEM(X) (((struct array_of_svalues *)(X))->item)
-#define SHORT_ITEM(X) (((struct array_of_short_svalues *)(X))->item)
 
+#define ITEM(X) ((X)->item)
 
 /* These are arguments for the function 'merge' which merges two sorted
  * set stored in arrays in the way you specify
diff --git a/src/svalue.c b/src/svalue.c
index d742cb186d..a9dd15e646 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -139,47 +139,40 @@ void free_svalue(struct svalue *s)
  * We put this routine here so the compiler can optimize the call
  * inside the loop if it wants to
  */
-void free_svalues(struct svalue *s,INT32 num)
+void free_svalues(struct svalue *s,INT32 num, INT32 type_hint)
 {
-  while(--num >= 0) free_svalue(s++);
-}
-
-void free_short_svalues(union anything *s,INT32 num,TYPE_T type)
-{
-  union anything tmp;
-#ifdef DEBUG
-  int e;
-  for(e=0;e<num;e++)
-    check_refs2(s+e,type);
-#endif
-
-#define PRE \
-  for(;--num >= 0;s++) { \
-    if(s->refs && --*(s->refs) <= 0) { \
-      tmp=*s; \
-      s->refs=0
-
-#define POST }}break
-
-
-
-  switch(type)
+  switch(type_hint)
   {
-    case T_ARRAY: PRE; really_free_array(tmp.array); POST;
-    case T_MAPPING: PRE; really_free_mapping(tmp.mapping); POST;
-    case T_LIST: PRE; really_free_list(tmp.list); POST;
-    case T_OBJECT: PRE; really_free_object(tmp.object); POST;
-    case T_PROGRAM: PRE; really_free_program(tmp.program); POST;
-    case T_STRING: PRE; really_free_string(tmp.string); POST;
-
-    case T_INT:
-    case T_FLOAT:
-      break;
+  case 0:
+  case BIT_INT:
+  case BIT_FLOAT:
+  case BIT_FLOAT | BIT_INT:
+    return;
+
+#define DOTYPE(X,Y,Z) case X:while(--num>=0)if(s->u.refs--==0) Y(s->u.Z); return
+    DOTYPE(BIT_STRING, really_free_string, string);
+    DOTYPE(BIT_ARRAY, really_free_array, array);
+    DOTYPE(BIT_MAPPING, really_free_mapping, mapping);
+    DOTYPE(BIT_LIST, really_free_list, list);
+    DOTYPE(BIT_OBJECT, really_free_object, object);
+    DOTYPE(BIT_PROGRAM, really_free_program, program);
+
+  case BIT_FUNCTION:
+    while(--num>=0)
+    {
+      if(s->u.refs--==0)
+      {
+	if(s->subtype == -1)
+	  really_free_callable(s->u.efun);
+	else
+	  really_free_object(s->u.object);
+      }
+    }
+    return
 
-#ifdef DEBUG
-    default:
-      fatal("Bad type in free_short_svalues.\n");
-#endif
+#undef DOTYPE
+  default:
+    while(--num >= 0) free_svalue(s++);
   }
 }
 
@@ -196,12 +189,30 @@ void assign_svalue_no_free(struct svalue *to,
 
 void assign_svalues_no_free(struct svalue *to,
 			    struct svalue *from,
-			    INT32 num)
+			    INT32 num,
+			    INT32 type_hint)
 {
+  if((type_hint & ~(BIT_INT | BIT_FLOAT))==0)
+  {
+    MEMCPY((char *)to, (char *)from, sizeof(svalue) * num);
+    return;
+  }
+
+  if((type_hint & (BIT_INT | BIT_FLOAT)==0))
+  {
+    while(--num > 0)
+    {
+      struct svalue tmp;
+      tmp=*(from++);
+      *(to++)=tmp;
+      tmp.u.refs++;
+    }
+    return;
+  }
+
   while(--num >= 0) assign_svalue_no_free(to++,from++);
 }
 
-
 void assign_svalue(struct svalue *to, struct svalue *from)
 {
   free_svalue(to);
@@ -259,14 +270,6 @@ void assign_to_short_svalue_no_free(union anything *u,
   }
 }
 
-void assign_to_short_svalues_no_free(union anything *u,
-				     TYPE_T type,
-				     struct svalue *s,
-				     INT32 num)
-{
-  while(--num >= 0) assign_to_short_svalue_no_free(u++,type,s++);
-}
-
 
 void assign_from_short_svalue_no_free(struct svalue *s,
 					     union anything *u,
@@ -292,44 +295,6 @@ void assign_from_short_svalue_no_free(struct svalue *s,
   }
 }
 
-void assign_from_short_svalues_no_free(struct svalue *s,
-				       union anything *u,
-				       TYPE_T type,
-				       INT32 num)
-{
-  check_type(type);
-    
-  if(type <= MAX_REF_TYPE)
-  {
-    while(--num >= 0)
-    {
-      check_refs2(u,type);
-
-      s->u=*u;
-      if(u->refs)
-      {
-	s->type=type;
-	u->refs[0]++;
-      }else{
-	s->type=T_INT;
-	s->subtype=NUMBER_NUMBER;
-      }
-      s++;
-      u++;
-    }
-  }
-  else
-  {
-    while(--num >= 0)
-    {
-      s->type=type;
-      s->u=*u;
-      s++;
-      u++;
-    }
-  }
-}
-
 void assign_short_svalue_no_free(union anything *to,
 				 union anything *from,
 				 TYPE_T type)
@@ -360,28 +325,6 @@ void assign_short_svalue(union anything *to,
   }
 }
 
-void assign_short_svalues_no_free(union anything *to,
-				 union anything *from,
-				 TYPE_T type,
-				 INT32 num)
-{
-  union anything tmp;
-  check_type(type);
-
-  if(type <= MAX_REF_TYPE)
-  {
-    while(--num >= 0)
-    {
-      check_refs2(from,type);
-
-      *(to++) = tmp = *(from++);
-      if(tmp.refs) tmp.refs[0]++;
-    }
-  }else{
-    MEMCPY((char *)to, (char *)from, num*sizeof(union anything *));
-  }
-}
-
 int is_eq(struct svalue *a, struct svalue *b)
 {
   check_type(a->type);
@@ -686,51 +629,6 @@ void copy_svalues_recursively_no_free(struct svalue *to,
   }
 }
 
-
-void copy_short_svalues_recursively_no_free(union anything *to,
-					    union anything *from,
-					    TYPE_T type,
-					    INT32 num,
-					    struct processing *p)
-{
-  check_type(type);
-  check_refs2(from,type);
-
-  switch(type)
-  {
-  default:
-    assign_short_svalues_no_free(to,from,type,num);
-    break;
-
-  case T_ARRAY:
-    while(--num >= 0)
-    {
-      to->array=from->array?copy_array_recursively(from->array,p):0;
-      from++;
-      to++;
-    }
-    break;
-
-  case T_MAPPING:
-    while(--num >= 0)
-    {
-      to->mapping=from->mapping?copy_mapping_recursively(from->mapping,p):0;
-      from++;
-      to++;
-    }
-    break;
-
-  case T_LIST:
-    while(--num >= 0)
-    {
-      to->list=from->list?copy_list_recursively(from->list,p):0;
-      from++;
-      to++;
-    }
-    break;
-  }
-}
-
 #ifdef DEBUG
 void check_short_svalue(union anything *u,TYPE_T type)
 {
diff --git a/src/svalue.h b/src/svalue.h
index 1834145f0b..290d10307d 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -124,42 +124,30 @@ do{ \
 /* Prototypes begin here */
 void free_short_svalue(union anything *s,TYPE_T type);
 void free_svalue(struct svalue *s);
-void free_svalues(struct svalue *s,INT32 num);
-void free_short_svalues(union anything *s,INT32 num,TYPE_T type);
+void free_svalues(struct svalue *s,INT32 num, INT32 type_hint);
 void assign_svalue_no_free(struct svalue *to,
 			   struct svalue *from);
 void assign_svalues_no_free(struct svalue *to,
 			    struct svalue *from,
-			    INT32 num);
+			    INT32 num,
+			    INT32 type_hint);
 void assign_svalue(struct svalue *to, struct svalue *from);
 void assign_svalues(struct svalue *to, struct svalue *from, INT32 num);
 void assign_to_short_svalue(union anything *u,
 			    TYPE_T type,
 			    struct svalue *s);
 void assign_to_short_svalue_no_free(union anything *u,
-					   TYPE_T type,
-					   struct svalue *s);
-void assign_to_short_svalues_no_free(union anything *u,
-				     TYPE_T type,
-				     struct svalue *s,
-				     INT32 num);
+				    TYPE_T type,
+				    struct svalue *s);
 void assign_from_short_svalue_no_free(struct svalue *s,
 					     union anything *u,
 					     TYPE_T type);
-void assign_from_short_svalues_no_free(struct svalue *s,
-				       union anything *u,
-				       TYPE_T type,
-				       INT32 num);
 void assign_short_svalue_no_free(union anything *to,
 				 union anything *from,
 				 TYPE_T type);
 void assign_short_svalue(union anything *to,
 			 union anything *from,
 			 TYPE_T type);
-void assign_short_svalues_no_free(union anything *to,
-				 union anything *from,
-				 TYPE_T type,
-				 INT32 num);
 int is_eq(struct svalue *a, struct svalue *b);
 int low_is_equal(struct svalue *a,
 		 struct svalue *b,
@@ -177,11 +165,6 @@ void copy_svalues_recursively_no_free(struct svalue *to,
 				      struct svalue *from,
 				      INT32 num,
 				      struct processing *p);
-void copy_short_svalues_recursively_no_free(union anything *to,
-					    union anything *from,
-					    TYPE_T type,
-					    INT32 num,
-					    struct processing *p);
 void check_short_svalue(union anything *u,TYPE_T type);
 void check_svalue(struct svalue *s);
 /* Prototypes end here */
-- 
GitLab


From 99946cb8c71a6ce769d928dc2a0f396151f11365 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 17 Feb 1996 16:55:54 +0100
Subject: [PATCH 022/351] Completed removing compact arrays

Rev: src/array.c:1.5
Rev: src/array.h:1.3
Rev: src/builtin_efuns.c:1.8
Rev: src/call_out.c:1.2
Rev: src/interpret.c:1.6
Rev: src/list.c:1.2
Rev: src/lpc_types.c:1.2
Rev: src/main.c:1.2
Rev: src/mapping.c:1.2
Rev: src/modules/files/efuns.c:1.3
Rev: src/modules/regexp/glue.c:1.2
Rev: src/object.c:1.4
Rev: src/svalue.c:1.5
Rev: src/svalue.h:1.3
---
 src/array.c               |  57 +++++++++----------
 src/array.h               |  15 +++--
 src/builtin_efuns.c       | 113 +++++++++++++++-----------------------
 src/call_out.c            |   9 +--
 src/interpret.c           |   2 +-
 src/list.c                |   2 +-
 src/lpc_types.c           |  29 +---------
 src/main.c                |  15 +++--
 src/mapping.c             |   8 +--
 src/modules/files/efuns.c |  24 ++++----
 src/modules/regexp/glue.c |   2 +-
 src/object.c              |   7 ++-
 src/svalue.c              |  13 +++--
 src/svalue.h              |   5 +-
 14 files changed, 133 insertions(+), 168 deletions(-)

diff --git a/src/array.c b/src/array.c
index 41101879f8..46e51f1d2b 100644
--- a/src/array.c
+++ b/src/array.c
@@ -40,7 +40,7 @@ struct array *allocate_array_no_init(INT32 size,INT32 extra_space)
 {
   struct array *v;
 
-  if(size == 0 && type == T_MIXED)
+  if(size == 0)
   {
     empty_array.refs++;
     return &empty_array;
@@ -309,7 +309,7 @@ struct array *array_shrink(struct array *v,INT32 size)
     free_array(v);
     return a;
   }else{
-    free_svalues(ITEM(v) + size, v->size - size);
+    free_svalues(ITEM(v) + size, v->size - size, v->type_field);
     v->size=size;
     return v;
   }
@@ -486,16 +486,6 @@ INT32 array_find_destructed_object(struct array *v)
   return -1;
 }
 
-
-static short_cmpfun current_short_cmpfun;
-static union anything *current_short_array_p;
-
-static int internal_short_cmpfun(INT32 *a,INT32 *b)
-{
-  return current_short_cmpfun(current_short_array_p + *a,
-			      current_short_array_p + *b);
-}
-
 static struct svalue *current_array_p;
 static cmpfun current_cmpfun;
 
@@ -617,12 +607,12 @@ static INT32 low_lookup(struct array *v,
 INT32 set_lookup(struct array *a, struct svalue *s)
 {
   /* face it, it's not there */
-  if( (((2 << s->type) -1) & s->type_field) == 0)
+  if( (((2 << s->type) -1) & a->type_field) == 0)
     return -1;
 
   /* face it, it's not there */
-  if( ((BIT_MIXED << s->type) & BIT_MIXED & s->type_field) == 0)
-    return ~v->size;
+  if( ((BIT_MIXED << s->type) & BIT_MIXED & a->type_field) == 0)
+    return ~a->size;
 
   return low_lookup(a,s,set_svalue_cmpfun);
 }
@@ -630,12 +620,12 @@ INT32 set_lookup(struct array *a, struct svalue *s)
 INT32 switch_lookup(struct array *a, struct svalue *s)
 {
   /* face it, it's not there */
-  if( (((2 << s->type) -1) & s->type_field) == 0)
+  if( (((2 << s->type) -1) & a->type_field) == 0)
     return -1;
 
   /* face it, it's not there */
-  if( ((BIT_MIXED << s->type) & BIT_MIXED & s->type_field) == 0)
-    return ~v->size;
+  if( ((BIT_MIXED << s->type) & BIT_MIXED & a->type_field) == 0)
+    return ~a->size;
 
   return low_lookup(a,s,switch_svalue_cmpfun);
 }
@@ -785,7 +775,7 @@ struct array *array_zip(struct array *a, struct array *b,INT32 *zipper)
   size=zipper[0];
   zipper++;
 
-  ret=allocate_array_no_init(size,0, T_MIXED);
+  ret=allocate_array_no_init(size,0);
   for(e=0; e<size; e++)
   {
     if(*zipper >= 0)
@@ -803,6 +793,9 @@ struct array *add_arrays(struct svalue *argp, INT32 args)
   INT32 e, size;
   struct array *v;
 
+  for(size=e=0;e<args;e++)
+    size+=argp[e].u.array->size;
+
   if(args && argp[0].u.array->refs==1)
   {
     e=argp[0].u.array->size;
@@ -971,7 +964,7 @@ struct array *and_arrays(struct array *a, struct array *b)
   {
     return merge_array_without_order(a, b, OP_AND);
   }else{
-    return allocate_array_no_init(0,0,T_MIXED);
+    return allocate_array_no_init(0,0);
   }
 }
 
@@ -986,7 +979,6 @@ int check_that_array_is_constant(struct array *a)
 node *make_node_from_array(struct array *a)
 {
   struct svalue s;
-  char *str;
   INT32 e;
 
   array_fix_type_field(a);
@@ -1031,7 +1023,7 @@ void push_array_items(struct array *a)
     free_array(a);
     return;
   }else{
-    assign_svalues_no_free(sp, ITEM(a), a->size);
+    assign_svalues_no_free(sp, ITEM(a), a->size, a->type_field);
   }
   sp += a->size;
   free_array(a);
@@ -1120,10 +1112,13 @@ struct array *explode(struct lpc_string *str,
 
   if(!del->len)
   {
-    ret=allocate_array_no_init(str->len,0,T_STRING);
+    ret=allocate_array_no_init(str->len,0);
     ret->type_field |= 1<<T_STRING;
     for(e=0;e<str->len;e++)
-      SHORT_ITEM(ret)[e].string=make_shared_binary_string(str->str+e,1);
+    {
+      ITEM(ret)[e].type=T_STRING;
+      ITEM(ret)[e].u.string=make_shared_binary_string(str->str+e,1);
+    }
   }else{
 
     s=str->str;
@@ -1136,17 +1131,19 @@ struct array *explode(struct lpc_string *str,
       e++;
     }
 
-    ret=allocate_array_no_init(e+1,0,T_STRING);
+    ret=allocate_array_no_init(e+1,0);
     ret->type_field |= 1<<T_STRING;
 
     s=str->str;
     for(d=0;d<e;d++)
     {
       tmp=MEMMEM((char *)(del->str), del->len, (char *)s, end-s);
-      SHORT_ITEM(ret)[d].string=make_shared_binary_string(s,tmp-s);
+      ITEM(ret)[d].type=T_STRING;
+      ITEM(ret)[d].u.string=make_shared_binary_string(s,tmp-s);
       s=tmp+del->len;
     }
-    SHORT_ITEM(ret)[d].string=make_shared_binary_string(s,end-s);
+    ITEM(ret)[d].type=T_STRING;
+    ITEM(ret)[d].u.string=make_shared_binary_string(s,end-s);
   }
   return ret;
 }
@@ -1218,11 +1215,11 @@ void apply_array(struct array *a, INT32 args)
   argp=sp-args;
   for(e=0;e<a->size;e++)
   {
-    assign_svalues_no_free(sp,argp,args);
+    assign_svalues_no_free(sp,argp,args,BIT_MIXED);
     sp+=args;
     apply_svalue(ITEM(a)+e,args);
   }
-  ret=aggregate_array(a->size,T_MIXED);
+  ret=aggregate_array(a->size);
   pop_n_elems(args);
   push_array(ret);
 }
@@ -1267,7 +1264,7 @@ void array_gc_clear_mark()
   } while (a != & empty_array);
 }
 
-void array_gc_mark(array *a)
+void array_gc_mark(struct array *a)
 {
   INT e;
   if(a->flags & ARRAY_FLAG_MARK) return;
diff --git a/src/array.h b/src/array.h
index 4d4687072c..34f74e4baa 100644
--- a/src/array.h
+++ b/src/array.h
@@ -54,8 +54,8 @@ typedef short_cmpfun (*cmpfun_getter)(TYPE_T);
 
 
 /* Prototypes begin here */
-struct array *allocate_array_no_init(INT32 size,INT32 extra_space,TYPE_T type);
-struct array *allocate_array(INT32 size,TYPE_T type);
+struct array *allocate_array_no_init(INT32 size,INT32 extra_space);
+struct array *allocate_array(INT32 size);
 void really_free_array(struct array *v);
 void array_index_no_free(struct svalue *s,struct array *v,INT32 index);
 void array_index(struct svalue *s,struct array *v,INT32 index);
@@ -72,7 +72,7 @@ struct array *slice_array(struct array *v,INT32 start,INT32 end);
 struct array *copy_array(struct array *v);
 void check_array_for_destruct(struct array *v);
 INT32 array_find_destructed_object(struct array *v);
-INT32 *get_order(struct array *v, cmpfun fun,cmpfun_getter backfun);
+INT32 *get_order(struct array *v, cmpfun fun);
 INT32 *get_set_order(struct array *a);
 INT32 *get_switch_order(struct array *a);
 INT32 set_lookup(struct array *a, struct svalue *s);
@@ -107,7 +107,7 @@ void describe_index(struct array *a,
 		    struct processing *p,
 		    int indent);
 void describe_array(struct array *a,struct processing *p,int indent);
-struct array *aggregate_array(INT32 args, TYPE_T type);
+struct array *aggregate_array(INT32 args);
 struct array *explode(struct lpc_string *str,
 		       struct lpc_string *del);
 struct lpc_string *implode(struct array *a,struct lpc_string *del);
@@ -117,7 +117,12 @@ struct array *reverse_array(struct array *a);
 void array_replace(struct array *a,
 		   struct svalue *from,
 		   struct svalue *to);
-void check_all_arrays();
+void array_gc_clear_mark();
+void array_gc_mark(struct array *a);
+void array_gc_sweep();
+void array_gc_sweep2();
+void check_array(struct array *a, int pass);
+void check_all_arrays(int pass);
 /* Prototypes end here */
 
 
diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index 90507b5a82..28120bf6e9 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -47,7 +47,7 @@ void f_aggregate(INT32 args)
   if(args < 0) fatal("Negative args to f_aggregate()\n");
 #endif
 
-  a=aggregate_array(args,T_MIXED);
+  a=aggregate_array(args);
   push_array(a); /* beware, macro */
 }
 
@@ -290,7 +290,7 @@ void f_backtrace(INT32 args)
   for(f=fp;f;f=f->parent_frame) frames++;
 
   sp->type=T_ARRAY;
-  sp->u.array=a=allocate_array_no_init(frames,0,T_ARRAY);
+  sp->u.array=a=allocate_array_no_init(frames,0);
   sp++;
 
   for(f=fp;f;f=f->parent_frame)
@@ -301,7 +301,8 @@ void f_backtrace(INT32 args)
 
     if(f->current_object && f->current_object->prog)
     {
-      SHORT_ITEM(a)[frames].array=i=allocate_array_no_init(3,0,T_MIXED);
+      ITEM(a)[frames].u.array=i=allocate_array_no_init(3,0);
+      ITEM(a)[frames].type=T_ARRAY;
       ITEM(i)[2].type=T_FUNCTION;
       ITEM(i)[2].subtype=f->fun;
       ITEM(i)[2].u.object=f->current_object;
@@ -328,7 +329,8 @@ void f_backtrace(INT32 args)
 	ITEM(i)[0].type=T_INT;
       }
     }else{
-      SHORT_ITEM(a)[frames].refs=0;
+      ITEM(a)[frames].type=T_INT;
+      ITEM(a)[frames].u.integer=0;
     }
   }
 }
@@ -562,7 +564,6 @@ void f_all_efuns(INT32 args)
 
 void f_allocate(INT32 args)
 {
-  TYPE_T t;
   INT32 size;
 
   if(args < 1)
@@ -571,25 +572,12 @@ void f_allocate(INT32 args)
   if(sp[-args].type!=T_INT)
     error("Bad argument 1 to allocate.\n");
 
-  if(args > 1)
-  {
-    struct lpc_string *s;
-    if(sp[1-args].type != T_STRING)
-      error("Bad argument 2 to allocate.\n");
-
-    s=sp[1-args].u.string;
-    s=parse_type(s->str);
-    t=compile_type_to_runtime_type(s);
-    free_string(s);
-  }else{
-    t=T_MIXED;
-  }
 
   size=sp[-args].u.integer;
   if(size < 0)
     error("Allocate on negative number.\n");
   pop_n_elems(args);
-  push_array( allocate_array(size, t) );
+  push_array( allocate_array(size) );
 }
 
 void f_sizeof(INT32 args)
@@ -632,14 +620,21 @@ void f_sizeof(INT32 args)
 
 void f_rusage(INT32 args)
 {
-  INT32 *rus;
+  INT32 *rus,e;
   struct array *v;
   pop_n_elems(args);
   rus=low_rusage();
   if(!rus)
     error("System rusage information not available.\n");
-  v=allocate_array_no_init(29,0,T_INT);
-  MEMCPY((char *)SHORT_ITEM(v),(char *)rus,sizeof(INT32)*29);
+  v=allocate_array_no_init(29,0);
+
+  for(e=0;e<29;e++)
+  {
+    ITEM(v)[e].type=T_INT;
+    ITEM(v)[e].subtype=NUMBER_NUMBER;
+    ITEM(v)[e].u.integer=rus[e];
+  }
+
   sp->u.array=v;
   sp->type=T_ARRAY;
   sp++;
@@ -798,9 +793,13 @@ void f_indices(INT32 args)
     size=sp[-args].u.array->size;
 
   qjump:
-    a=allocate_array_no_init(size,0,T_INT);
+    a=allocate_array_no_init(size,0);
     while(--size>=0)
-      SHORT_ITEM(a)[size].integer=size;
+    {
+      ITEM(a)[size].type=T_INT;
+      ITEM(a)[size].subtype=NUMBER_NUMBER;
+      ITEM(a)[size].u.integer=size;
+    }
     break;
 
   case T_MAPPING:
@@ -834,9 +833,13 @@ void f_values(INT32 args)
   {
   case T_STRING:
     size=sp[-args].u.string->len;
-    a=allocate_array_no_init(size,0,T_INT);
+    a=allocate_array_no_init(size,0);
     while(--size>=0)
-      SHORT_ITEM(a)[size].integer=EXTRACT_UCHAR(sp[-args].u.string->str+size);
+    {
+      ITEM(a)[size].type=T_INT;
+      ITEM(a)[size].subtype=NUMBER_NUMBER;
+      ITEM(a)[size].u.integer=EXTRACT_UCHAR(sp[-args].u.string->str+size);
+    }
     break;
 
   case T_ARRAY:
@@ -849,9 +852,13 @@ void f_values(INT32 args)
 
   case T_LIST:
     size=sp[-args].u.list->ind->size;
-    a=allocate_array_no_init(size,0,T_INT);
-    while(size>0)
-      SHORT_ITEM(a)[--size].integer=1;
+    a=allocate_array_no_init(size,0);
+    while(--size>=0)
+    {
+      ITEM(a)[size].type=T_INT;
+      ITEM(a)[size].subtype=NUMBER_NUMBER;
+      ITEM(a)[size].u.integer=1;
+    }
     break;
 
   case T_OBJECT:
@@ -990,50 +997,18 @@ struct lpc_string * replace_many(struct lpc_string *str,
 
   v=(struct tupel *)xalloc(sizeof(struct tupel)*from->size);
 
-  if(from->array_type == T_MIXED)
-  {
-    for(e=0;e<from->size;e++)
-    {
-      if(ITEM(from)[e].type != T_STRING)
-	error("Replace: from array not string *\n");
-      v[e].ind=ITEM(from)[e].u.string;
-    }
-  }
-  else if(from->array_type == T_STRING)
-  {
-    for(e=0;e<from->size;e++)
-    {
-      if(!SHORT_ITEM(from)[e].string)
-	error("Replace: from array not string *\n");
-      v[e].ind=SHORT_ITEM(from)[e].string;
-    }
-  }
-  else
+  for(e=0;e<from->size;e++)
   {
-    error("Replace: from array is not string *\n");
+    if(ITEM(from)[e].type != T_STRING)
+      error("Replace: from array not string *\n");
+    v[e].ind=ITEM(from)[e].u.string;
   }
 
-  if(to->array_type == T_MIXED)
-  {
-    for(e=0;e<to->size;e++)
-    {
-      if(ITEM(to)[e].type != T_STRING)
-	error("Replace: to array not string *\n");
-      v[e].val=ITEM(to)[e].u.string;
-    }
-  }
-  else if(to->array_type == T_STRING)
-  {
-    for(e=0;e<to->size;e++)
-    {
-      if(!SHORT_ITEM(to)[e].string)
-	error("Replace: to array not string *\n");
-      v[e].val=SHORT_ITEM(to)[e].string;
-    }
-  }
-  else
+  for(e=0;e<to->size;e++)
   {
-    error("Replace: to array is not string *\n");
+    if(ITEM(to)[e].type != T_STRING)
+      error("Replace: to array not string *\n");
+    v[e].val=ITEM(to)[e].u.string;
   }
 
   fsort((char *)v,from->size,sizeof(struct tupel),(fsortfun)replace_sortfun);
diff --git a/src/call_out.c b/src/call_out.c
index da5c6fd47f..cfda6cc071 100644
--- a/src/call_out.c
+++ b/src/call_out.c
@@ -246,11 +246,11 @@ struct array *get_all_call_outs()
   struct array *ret;
 
   verify_call_outs();
-  ret=allocate_array_no_init(num_pending_calls,0,T_ARRAY);
+  ret=allocate_array_no_init(num_pending_calls,0);
   for(e=0;e<num_pending_calls;e++)
   {
     struct array *v;
-    v=allocate_array_no_init(pending_calls[e]->args->size+2, 0, T_MIXED);
+    v=allocate_array_no_init(pending_calls[e]->args->size+2, 0);
     ITEM(v)[0].type=T_INT;
     ITEM(v)[0].subtype=NUMBER_NUMBER;
     ITEM(v)[0].u.integer=pending_calls[e]->time-current_time;
@@ -265,9 +265,10 @@ struct array *get_all_call_outs()
       ITEM(v)[1].u.integer=0;
     }
 
-    assign_svalues_no_free(ITEM(v)+2,ITEM(pending_calls[e]->args),pending_calls[e]->args->size);
+    assign_svalues_no_free(ITEM(v)+2,ITEM(pending_calls[e]->args),pending_calls[e]->args->size,BIT_MIXED);
 
-    SHORT_ITEM(ret)[e].array=v;
+    ITEM(ret)[e].type=T_ARRAY;
+    ITEM(ret)[e].u.array=v;
   }
   return ret;
 }
diff --git a/src/interpret.c b/src/interpret.c
index d1a9cb69be..ce61e6db18 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -196,7 +196,7 @@ void pop_n_elems(INT32 x)
 
   if(x < 0) fatal("Popping negative number of args....\n");
 #endif
-  free_svalues(sp-x,x);
+  free_svalues(sp-x,x,BIT_MIXED);
   sp-=x;
 }
 
diff --git a/src/list.c b/src/list.c
index 439b89c0c1..c2a968482e 100644
--- a/src/list.c
+++ b/src/list.c
@@ -136,7 +136,7 @@ struct list *add_lists(struct svalue *argp,INT32 args)
   switch(args)
   {
   case 0:
-    ret=allocate_list(allocate_array_no_init(0,0,T_MIXED));
+    ret=allocate_list(allocate_array_no_init(0,0));
     break;
 
   case 1:
diff --git a/src/lpc_types.c b/src/lpc_types.c
index 3a2aa02d6f..4cf28ef120 100644
--- a/src/lpc_types.c
+++ b/src/lpc_types.c
@@ -744,34 +744,7 @@ struct lpc_string *check_call(struct lpc_string *args,
 
 void check_array_type(struct array *a)
 {
-  int t;
-  t=my_log2(a->array_type);
-  if( ( 1 << t ) == a->array_type )
-  {
-    switch(t)
-    {
-    case T_ARRAY:
-      push_type(T_MIXED);
-      push_type(T_ARRAY);
-      break;
-
-    case T_LIST:
-      push_type(T_MIXED);
-      push_type(T_LIST);
-      break;
-
-    case T_MAPPING:
-      push_type(T_MIXED);
-      push_type(T_MIXED);
-      push_type(T_MAPPING);
-      break;
-
-    default:
-      push_type(t);
-    }
-  }else{
-    push_type(T_MIXED);
-  }
+  push_type(T_MIXED);
 }
 
 struct lpc_string *get_type_of_svalue(struct svalue *s)
diff --git a/src/main.c b/src/main.c
index 3afa0c7152..a5c0b77ef3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -158,15 +158,22 @@ void main(int argc, char **argv, char **env)
   call_and_free_callback_list(& post_master_callbacks);
   init_modules_programs();
 
-  a=allocate_array_no_init(argc-e,0,T_STRING);
+  a=allocate_array_no_init(argc-e,0);
   for(num=0;e<argc;e++)
-    SHORT_ITEM(a)[num++].string=make_shared_string(argv[e]);
+  {
+    ITEM(a)[num].u.string=make_shared_string(argv[e]);
+    ITEM(a)[num].type=T_STRING;
+    num++;
+  }
   push_array(a);
 
   for(num=0;env[num];num++);
-  a=allocate_array_no_init(num,0,T_STRING);
+  a=allocate_array_no_init(num,0);
   for(num=0;env[num];num++)
-    SHORT_ITEM(a)[num].string=make_shared_string(env[num]);
+  {
+    ITEM(a)[num].u.string=make_shared_string(env[num]);
+    ITEM(a)[num].type=T_STRING;
+  }
   push_array(a);
 
   if(SETJMP(back))
diff --git a/src/mapping.c b/src/mapping.c
index f41b731ae1..de252f7fbf 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -219,8 +219,8 @@ struct mapping *add_mappings(struct svalue *argp,INT32 args)
   switch(args)
   {
   case 0:
-    ret=allocate_mapping(allocate_array_no_init(0,0,T_MIXED),
-			 allocate_array_no_init(0,0,T_MIXED));
+    ret=allocate_mapping(allocate_array_no_init(0,0),
+			 allocate_array_no_init(0,0));
     break;
 
   case 1:
@@ -334,8 +334,8 @@ void f_aggregate_mapping(INT32 args)
   if(args & 1)
     error("Uneven number of arguments to aggregage_mapping.\n");
 
-  ind=allocate_array_no_init(args/2,0,T_MIXED);
-  val=allocate_array_no_init(args/2,0,T_MIXED);
+  ind=allocate_array_no_init(args/2,0);
+  val=allocate_array_no_init(args/2,0);
 
   s=sp-args;
   for(e=0;e<args/2;e++)
diff --git a/src/modules/files/efuns.c b/src/modules/files/efuns.c
index b0a07205d0..b2172ad6c4 100644
--- a/src/modules/files/efuns.c
+++ b/src/modules/files/efuns.c
@@ -41,20 +41,20 @@
 struct array *encode_stat(struct stat *s)
 {
   struct array *a;
-  a=allocate_array_no_init(7,0,T_INT);
-  SHORT_ITEM(a)[0].integer=s->st_mode;
+  a=allocate_array(7);
+  ITEM(a)[0].u.integer=s->st_mode;
   switch(S_IFMT & s->st_mode)
   {
-  case S_IFREG: SHORT_ITEM(a)[1].integer=s->st_size; break;
-  case S_IFDIR: SHORT_ITEM(a)[1].integer=-2; break;
-  case S_IFLNK: SHORT_ITEM(a)[1].integer=-3; break;
-  default: SHORT_ITEM(a)[1].integer=-4; break;
+  case S_IFREG: ITEM(a)[1].u.integer=s->st_size; break;
+  case S_IFDIR: ITEM(a)[1].u.integer=-2; break;
+  case S_IFLNK: ITEM(a)[1].u.integer=-3; break;
+  default: ITEM(a)[1].u.integer=-4; break;
   }
-  SHORT_ITEM(a)[2].integer=s->st_atime;
-  SHORT_ITEM(a)[3].integer=s->st_mtime;
-  SHORT_ITEM(a)[4].integer=s->st_ctime;
-  SHORT_ITEM(a)[5].integer=s->st_uid;
-  SHORT_ITEM(a)[6].integer=s->st_gid;
+  ITEM(a)[2].u.integer=s->st_atime;
+  ITEM(a)[3].u.integer=s->st_mtime;
+  ITEM(a)[4].u.integer=s->st_ctime;
+  ITEM(a)[5].u.integer=s->st_uid;
+  ITEM(a)[6].u.integer=s->st_gid;
   return a;
 }
 
@@ -170,7 +170,7 @@ void f_get_dir(INT32 args)
       push_string(make_shared_binary_string(d->d_name,NAMLEN(d)));
     }
     closedir(dir);
-    a=aggregate_array(sp-save_sp, T_STRING);
+    a=aggregate_array(sp-save_sp);
   }
 
   pop_n_elems(args);
diff --git a/src/modules/regexp/glue.c b/src/modules/regexp/glue.c
index f378f797ba..4a728f2102 100644
--- a/src/modules/regexp/glue.c
+++ b/src/modules/regexp/glue.c
@@ -84,7 +84,7 @@ static void regexp_split(INT32 args)
       }
     }
     if(j<i-1) pop_n_elems(i-j-1);
-    push_array(aggregate_array(j,T_STRING));
+    push_array(aggregate_array(j));
     free_string(s);
   }else{
     pop_n_elems(args);
diff --git a/src/object.c b/src/object.c
index 44883029ea..d0a2784a3a 100644
--- a/src/object.c
+++ b/src/object.c
@@ -655,11 +655,12 @@ struct array *object_indices(struct object *o)
   if(!p)
     error("indices() on destructed object.\n");
 
-  a=allocate_array_no_init(p->num_identifier_indexes,0, T_STRING);
+  a=allocate_array_no_init(p->num_identifier_indexes,0);
   for(e=0;e<(int)p->num_identifier_indexes;e++)
   {
-    copy_shared_string(SHORT_ITEM(a)[e].string,
+    copy_shared_string(ITEM(a)[e].u.string,
 		       ID_FROM_INT(p,p->identifier_index[e])->name);
+    ITEM(a)[e].type=T_STRING;
   }
   return a;
 }
@@ -674,7 +675,7 @@ struct array *object_values(struct object *o)
   if(!p)
     error("values() on destructed object.\n");
 
-  a=allocate_array_no_init(p->num_identifier_indexes,0, T_MIXED);
+  a=allocate_array_no_init(p->num_identifier_indexes,0);
   for(e=0;e<(int)p->num_identifier_indexes;e++)
   {
     low_object_index(ITEM(a)+e, o, p->identifier_index[e]);
diff --git a/src/svalue.c b/src/svalue.c
index a9dd15e646..04af973f0b 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -168,7 +168,7 @@ void free_svalues(struct svalue *s,INT32 num, INT32 type_hint)
 	  really_free_object(s->u.object);
       }
     }
-    return
+    return;
 
 #undef DOTYPE
   default:
@@ -194,7 +194,7 @@ void assign_svalues_no_free(struct svalue *to,
 {
   if((type_hint & ~(BIT_INT | BIT_FLOAT))==0)
   {
-    MEMCPY((char *)to, (char *)from, sizeof(svalue) * num);
+    MEMCPY((char *)to, (char *)from, sizeof(struct svalue) * num);
     return;
   }
 
@@ -219,10 +219,13 @@ void assign_svalue(struct svalue *to, struct svalue *from)
   assign_svalue_no_free(to,from);
 }
 
-void assign_svalues(struct svalue *to, struct svalue *from, INT32 num)
+void assign_svalues(struct svalue *to,
+		    struct svalue *from,
+		    INT32 num,
+		    TYPE_FIELD types)
 {
-  free_svalues(to,num);
-  assign_svalues_no_free(to,from,num);
+  free_svalues(to,num,BIT_MIXED);
+  assign_svalues_no_free(to,from,num,types);
 }
 
 void assign_to_short_svalue(union anything *u,
diff --git a/src/svalue.h b/src/svalue.h
index 290d10307d..0978075478 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -132,7 +132,10 @@ void assign_svalues_no_free(struct svalue *to,
 			    INT32 num,
 			    INT32 type_hint);
 void assign_svalue(struct svalue *to, struct svalue *from);
-void assign_svalues(struct svalue *to, struct svalue *from, INT32 num);
+void assign_svalues(struct svalue *to,
+		    struct svalue *from,
+		    INT32 num,
+		    TYPE_FIELD types);
 void assign_to_short_svalue(union anything *u,
 			    TYPE_T type,
 			    struct svalue *s);
-- 
GitLab


From a206c1af86a72471b4b7ff10d19106ee6295938f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 17 Feb 1996 17:23:42 +0100
Subject: [PATCH 023/351] Bumped version

Rev: lib/simulate.lpc:1.7
---
 lib/simulate.lpc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index 8140b0219d..f2d317a52e 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -365,7 +365,7 @@ void create()
   add_efun("strstr",search);
   add_efun("sum_arrays",sum_arrays);
   add_efun("this_function",this_function);
-  add_efun("version",lambda() { return "uLPC v1.7E-12"; });
+  add_efun("version",lambda() { return "uLPC v1.0E-11"; });
   add_efun("write_file",write_file);
   add_efun("get_function",get_function);
   add_efun("regexp",regexp);
-- 
GitLab


From f135c4d359699f9f4818e5a9f168c5fa03bab086 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 17 Feb 1996 23:28:42 +0100
Subject: [PATCH 024/351] entry added

Rev: src/ChangeLog:1.16
---
 src/ChangeLog | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index f8ca9f7944..482ff040be 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+Sat Feb 17 23:05:24 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
+
+	* sprintf: added support for %2c
+
 Sun Feb 11 01:04:38 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
 
 	* export.lpc: now updates configure files if needed
-- 
GitLab


From 27c8e12e0812f158e93252adefa57595f47a552f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 17 Feb 1996 23:30:04 +0100
Subject: [PATCH 025/351] test for %2c added

Rev: src/test/create_testsuite:1.7
---
 src/test/create_testsuite | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 3efeae6cb4..18261c1d23 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -1132,6 +1132,8 @@ test_eq(sprintf("%o",255),"377")
 test_eq(sprintf("%x",255),"ff")
 test_eq(sprintf("%X",255),"FF")
 test_eq(sprintf("%c",255),"\377")
+test_eq(sprintf("%2c",65535),"\377\377")
+test_eq(sprintf("%3c",0xffffff),"\377\377\377")
 test_true(stringp(sprintf("%f",255.0)))
 test_true(stringp(sprintf("%g",255.0)))
 test_true(stringp(sprintf("%e",255.0)))
-- 
GitLab


From a638a418b34dcf124ae8f5b1ecc7378cee424883 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 17 Feb 1996 23:37:41 +0100
Subject: [PATCH 026/351] %2c implemented

Rev: doc/sprintf/sprintf:1.1.1.3
Rev: src/modules/sprintf/sprintf.c:1.4
---
 doc/sprintf/sprintf           | 82 ++++++++++++++++++-----------------
 src/modules/sprintf/sprintf.c | 18 ++++++--
 2 files changed, 56 insertions(+), 44 deletions(-)

diff --git a/doc/sprintf/sprintf b/doc/sprintf/sprintf
index bc52740140..87312b54b3 100644
--- a/doc/sprintf/sprintf
+++ b/doc/sprintf/sprintf
@@ -7,50 +7,52 @@ SYNTAX
 DESCRIPTION
 	The format string is a string containing a description of how to
 	output the data in the rest of the arguments. This string should
-	generally speaking have one %<modifyers><operator> (examples:
+	generally speaking have one %<modifiers><operator> (examples:
 	%s, %0d, %-=20s) for each of the rest arguments.
 
-	Modifyers:
-	  0  Zero pad numbers (implies right justification)
-	  !  Toggle truncation
-	 ' ' (space) pad positive integers with a space
-	  +  pad positive integers with a plus sign
-	  -  left adjusted within field size (default is right)
-	  |  centered within field size
-	  =  column mode if strings are greater than field size
-	  /  Rough linebreak (break at exactly fieldsize instead of
-	     between words)
-	  #  table mode, print a list of '\n' separated word
-	     (top-to-bottom order)
-	  $  Inverse table mode (left-to-right order)
-	  n  (where n is a number or *) a number specifies field size
-	 .n  set precision
-	 :n  set field size & precision
-	 ;n  Set column width
-	  *  if n is a * then next argument is used
-	 'X' Set a pad string. ' cannot be a part of the pad_string (yet)
-	  <  Use same arg again
-	  ^  repeat this on every line produced
-	  @  do this format for each entry in argument array
-	  > Put the string at the bottom end of column instead of top
-	  _ Set width to the length of data
+	Modifiers:
+
+	0	Zero pad numbers (implies right justification)
+	!	Toggle truncation
+	' ' (space)	pad positive integers with a space
+	+	pad positive integers with a plus sign
+	-	left adjusted within field size (default is right)
+	|	centered within field size
+	=	column mode if strings are greater than field size
+	/	Rough linebreak (break at exactly fieldsize instead of
+		between words)
+	#	table mode, print a list of '\n' separated word
+		(top-to-bottom order)
+	$	Inverse table mode (left-to-right order)
+	n	(where n is a number or *) a number specifies field size
+	.n	set precision
+	:n	set field size & precision
+	;n	Set column width
+	*	if n is a * then next argument is used
+	'X'	Set a pad string. ' cannot be a part of the pad_string (yet)
+	<	Use same arg again
+	^	repeat this on every line produced
+	@	do this format for each entry in argument array
+	>	Put the string at the bottom end of column instead of top
+	_	Set width to the length of data
 
 	Operators:
-	  %% percent
-	  %d signed decimal int
-	  %u unsigned decimal int (doesn't really exist in lpc)
-	  %o unsigned octal int
-	  %x lowercase unsigned hexadecimal int
-	  %X uppercase unsigned hexadecimal int
-	  %c char
-	  %f float
-	  %g heruistically chosen representation of float
-	  %e exponential notation float
-	  %s string
-	  %O any type (debug style)
-	  %n nop
-	  %t type of argument
-	  %<modifyers>{format%}  do a format for every index in an array.
+
+	%%	percent
+	%d	signed decimal int
+	%u	unsigned decimal int (doesn't really exist in lpc)
+	%o	unsigned octal int
+	%x	lowercase unsigned hexadecimal int
+	%X	uppercase unsigned hexadecimal int
+	%c	char (or short with %2c, %3c gives 3 bytes etc.)
+	%f	float
+	%g	heruistically chosen representation of float
+	%e	exponential notation float
+	%s	string
+	%O	any type (debug style)
+	%n	nop
+	%t	type of argument
+	%<modifiers>{format%}	do a format for every index in an array.
 
 EXAMPLES
 	uLPC v1.0E-95 Running Hilfe v1.2 (Hubbe's Incremental LPC FrontEnd)
diff --git a/src/modules/sprintf/sprintf.c b/src/modules/sprintf/sprintf.c
index e80951c890..9b0ef5bf84 100644
--- a/src/modules/sprintf/sprintf.c
+++ b/src/modules/sprintf/sprintf.c
@@ -626,11 +626,21 @@ static string low_lpc_sprintf(char *format,
       }
 
       case 'c':
-	DO_OP();
-	fsp->b=(char *)alloca(1);
-	GET_INT(fsp->b[0]);
-	fsp->len=1;
+      {
+        INT32 l,tmp;
+        DO_OP();
+        l=1;
+        if(fsp->width > 0) l=fsp->width;
+	fsp->b=(char *)alloca(l);
+	GET_INT(tmp);
+        while(--l>=0)
+        {
+          fsp->b[l]=tmp & 0xff;
+          tmp>>=8;
+        }
+	fsp->len=l;
 	break;
+      }
 
       case 'o':
       case 'd':
-- 
GitLab


From dcf8e5207e7ef39685f6584a8df157ccff564c81 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 17 Feb 1996 23:42:20 +0100
Subject: [PATCH 027/351] no more compact arrays

Rev: doc/builtin/allocate:1.4
---
 doc/builtin/allocate | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/doc/builtin/allocate b/doc/builtin/allocate
index 4e6c716d0f..90ed148de5 100644
--- a/doc/builtin/allocate
+++ b/doc/builtin/allocate
@@ -2,21 +2,13 @@ NAME
 	allocate - allocate an array
 
 SYNTAX
-	mixed *allocate(int size, [ string type ]);
+	mixed *allocate(int size);
 
 DESCRIPTION
-	Allocate an array of size elements. Optionally, write what type you
-	want to store in the array in the second argument as a string.
-	Note that the type given in this string should be simple, instead
-	of writing "int ***" just write "array".
+	Allocate an array of size elements and initialize them to zero.
 
 EXAMPLES
 	mixed *a=allocate(17);
-	int *b=allocate(17, "int");
-	int **c=allocate(17, "array");
-	mapping *c=allocate(17, "mapping");
-	array (list (int)) c=allocate(17, "list");
-	array (string) c=allocate(17, "string");
 
 NOTA BENE
 	Arrays are dynamically allocated there is no need to declare them
-- 
GitLab


From c0de56c5ed6dafac2d4527488fa8fc9a3d16c30e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 18 Feb 1996 01:55:08 +0100
Subject: [PATCH 028/351] fixed file->write() now loops on EINTR

Rev: src/modules/files/file.c:1.10
---
 src/modules/files/file.c | 38 ++++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index a697f5833e..d025a859cd 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -305,29 +305,39 @@ static void file_write_callback(int fd, void *data)
 
 static void file_write(INT32 args)
 {
-  INT32 i;
+  INT32 written;
+  char *out;
+
   if(args<1 || sp[-args].type != T_STRING)
     error("Bad argument 1 to file->write().\n");
 
   if(FD < 0)
     error("File not open for write.\n");
-
-  i=write(FD, sp[-args].u.string->str, sp[-args].u.string->len);
-
-  if(i<0)
+  
+  written=0;
+  while(written < sp[-args].u.string->len)
   {
-    switch(errno)
+    i=write(FD, sp[-args].u.string->str, sp[-args].u.string->len);
+
+    if(i<0)
     {
-    default:
-      THIS->errno=errno;
-      pop_n_elems(args);
-      push_int(-1);
-      return;
+      switch(errno)
+      {
+      default:
+	THIS->errno=errno;
+	pop_n_elems(args);
+	push_int(-1);
+	return;
 
-    case EINTR:
-    case EWOULDBLOCK:
-      i=0;
+      case EINTR:
+	continue;
+
+      case EWOULDBLOCK:
+	i=0;
+	break;
+      }
     }
+    written+=i;
   }
 
   if(!IS_ZERO(& THIS->write_callback))
-- 
GitLab


From 366a4391c60e10b2ab2b56f66bb7998c083f6cd0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 18 Feb 1996 02:29:11 +0100
Subject: [PATCH 029/351] removed manual verification from 'make verify'

Rev: src/Makefile.in:1.8
---
 src/Makefile.in | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/Makefile.in b/src/Makefile.in
index b80a9eaa2f..aae59ad77d 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -145,11 +145,11 @@ TAGS:
 verify_manual:
 	$(RUNULPC) $(SRCDIR)/test/verifymanual.lpc $(TMP_DOCDIR)
 
-verify: $(SRCDIR)/test/testsuite verify_manual
+verify:
 	$(RUNULPC) $(SRCDIR)/test/test_lpc.lpc $(SRCDIR)/test/testsuite
 
 # verify / debug verbose
-verbose_verify: $(SRCDIR)/test/testsuite verify_manual
+verbose_verify:
 	$(RUNULPC) $(SRCDIR)/test/test_lpc.lpc $(SRCDIR)/test/testsuite --verbose
 
 # verify & debug VERBOSE
@@ -196,7 +196,6 @@ configure: configure.in
 
 config.status: configure
 	./config.status --recheck
-	
 
 Makefile: Makefile.in config.status
 	./config.status
-- 
GitLab


From 38145af1b66ecdd4f455451792979fee1a8e5758 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 18 Feb 1996 02:29:26 +0100
Subject: [PATCH 030/351] fixed bug with zero sized buffers

Rev: src/dynamic_buffer.c:1.2
---
 src/dynamic_buffer.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/dynamic_buffer.c b/src/dynamic_buffer.c
index 4e5871699a..d4f71cdf91 100644
--- a/src/dynamic_buffer.c
+++ b/src/dynamic_buffer.c
@@ -16,6 +16,8 @@ char *low_make_buf_space(INT32 space,dynamic_buffer *buf)
   char *ret;
   if(buf->s.len+space>=buf->bufsize)
   {
+    if(!buf->bufsize) buf->bufsize=1;
+
     do{
       buf->bufsize*=2;
     }while(buf->s.len+space>=buf->bufsize);
-- 
GitLab


From c5efd674fe3437e288028f284f88333e4ba284a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 18 Feb 1996 02:30:06 +0100
Subject: [PATCH 031/351] write now does what it should, ie. EINTR retries

Rev: src/modules/files/file.c:1.11
---
 src/modules/files/file.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index d025a859cd..d5bef66d8e 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -305,8 +305,7 @@ static void file_write_callback(int fd, void *data)
 
 static void file_write(INT32 args)
 {
-  INT32 written;
-  char *out;
+  INT32 written,i;
 
   if(args<1 || sp[-args].type != T_STRING)
     error("Bad argument 1 to file->write().\n");
@@ -317,7 +316,7 @@ static void file_write(INT32 args)
   written=0;
   while(written < sp[-args].u.string->len)
   {
-    i=write(FD, sp[-args].u.string->str, sp[-args].u.string->len);
+    i=write(FD, sp[-args].u.string->str + written, sp[-args].u.string->len - written);
 
     if(i<0)
     {
@@ -345,7 +344,7 @@ static void file_write(INT32 args)
   THIS->errno=0;
 
   pop_n_elems(args);
-  push_int(i);
+  push_int(written);
 }
 
 static void do_close(int fd, int flags)
-- 
GitLab


From 86910a9b69d2b7b49307bcbee6a1cb6cdfd61af0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 18 Feb 1996 02:30:15 +0100
Subject: [PATCH 032/351] %4c now works

Rev: src/modules/sprintf/sprintf.c:1.5
---
 src/modules/sprintf/sprintf.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/modules/sprintf/sprintf.c b/src/modules/sprintf/sprintf.c
index 9b0ef5bf84..56dda0711d 100644
--- a/src/modules/sprintf/sprintf.c
+++ b/src/modules/sprintf/sprintf.c
@@ -632,13 +632,13 @@ static string low_lpc_sprintf(char *format,
         l=1;
         if(fsp->width > 0) l=fsp->width;
 	fsp->b=(char *)alloca(l);
+	fsp->len=l;
 	GET_INT(tmp);
         while(--l>=0)
         {
           fsp->b[l]=tmp & 0xff;
           tmp>>=8;
         }
-	fsp->len=l;
 	break;
       }
 
-- 
GitLab


From ad16f4bfccc41e63676d09a5c749c6e517b082be Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 18 Feb 1996 05:53:09 +0100
Subject: [PATCH 033/351] E-12 patch for close_fd included

Rev: src/modules/files/file.c:1.12
---
 src/modules/files/file.c | 36 ++++++++++++++++++++++++------------
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index d5bef66d8e..4deb061b1c 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -85,18 +85,30 @@ static int close_fd(int fd)
   {
     while(1)
     {
-      if(close(fd) >= 0) break;
-      switch(errno)
+      if(close(fd) < 0)
       {
-      default:
-	fatal("Unknown error in close().\n");
-	
-      case EBADF:
-	fatal("Closing a non-active file descriptor.\n");
-       
-      case EINTR:
-	break;
+	switch(errno)
+	{
+	default:
+	  /* What happened? */
+	  files[fd].errno=errno;
+
+	  /* Try waiting it out in blocking mode */
+	  set_nonblocking(fd,0);
+	  if(close(fd) >= 0 || errno==EBADF)
+	    break; /* It was actually closed, good! */
+
+	  /* Failed, give up, crash, burn, die */
+	  error("Failed to close file.\n");
+
+	case EBADF:
+	  fatal("Closing a non-active file descriptor.\n");
+	  
+	case EINTR:
+	  continue;
+	}
       }
+      break;
     }
 
     set_read_callback(fd,0,0);
@@ -360,7 +372,6 @@ static void do_close(int fd, int flags)
     return;
 
   case FILE_READ:
-    files[fd].open_mode &=~ FILE_READ;
     if(files[fd].open_mode & FILE_WRITE)
     {
       set_read_callback(fd,0,0);
@@ -368,10 +379,10 @@ static void do_close(int fd, int flags)
     }else{
       close_fd(fd);
     }
+    files[fd].open_mode &=~ FILE_READ;
     break;
 
   case FILE_WRITE:
-    files[fd].open_mode &=~ FILE_WRITE;
     if(files[fd].open_mode & FILE_READ)
     {
       set_write_callback(fd,0,0);
@@ -379,6 +390,7 @@ static void do_close(int fd, int flags)
     }else{
       close_fd(fd);
     }
+    files[fd].open_mode &=~ FILE_WRITE;
     break;
 
   case FILE_READ | FILE_WRITE:
-- 
GitLab


From a89e8854916bb03633fd47a58e51bceb539ce540 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 18 Feb 1996 05:57:49 +0100
Subject: [PATCH 034/351] keywords added

Rev: doc/files/cd:1.1.1.2
Rev: doc/files/file:1.1.1.3
Rev: doc/files/file_stat:1.1.1.3
Rev: doc/files/get_dir:1.1.1.2
Rev: doc/files/getcwd:1.1.1.2
Rev: doc/files/mkdir:1.1.1.2
Rev: doc/files/mv:1.1.1.2
Rev: doc/files/port:1.1.1.2
Rev: doc/files/rm:1.1.1.2
Rev: doc/math/acos:1.1.1.2
Rev: doc/math/asin:1.1.1.2
Rev: doc/math/atan:1.1.1.2
Rev: doc/math/ceil:1.1.1.2
Rev: doc/math/cos:1.1.1.2
Rev: doc/math/exp:1.1.1.2
Rev: doc/math/floor:1.1.1.2
Rev: doc/math/log:1.1.1.2
Rev: doc/math/pow:1.1.1.3
Rev: doc/math/sin:1.1.1.2
Rev: doc/math/sqrt:1.1.1.2
Rev: doc/math/tan:1.1.1.2
Rev: doc/regexp/regexp:1.1.1.2
Rev: doc/sprintf/sprintf:1.1.1.4
---
 doc/files/cd        |  3 +++
 doc/files/file      | 24 ++++++++++++------------
 doc/files/file_stat | 26 ++++++++++++++------------
 doc/files/get_dir   |  3 +++
 doc/files/getcwd    |  3 +++
 doc/files/mkdir     |  3 +++
 doc/files/mv        |  3 +++
 doc/files/port      |  2 +-
 doc/files/rm        |  4 +++-
 doc/math/acos       |  3 +++
 doc/math/asin       |  3 +++
 doc/math/atan       |  3 +++
 doc/math/ceil       |  3 +++
 doc/math/cos        |  3 +++
 doc/math/exp        |  3 +++
 doc/math/floor      |  3 +++
 doc/math/log        |  3 +++
 doc/math/pow        |  3 +++
 doc/math/sin        |  3 +++
 doc/math/sqrt       |  3 +++
 doc/math/tan        |  3 +++
 doc/regexp/regexp   | 26 +++++++++++++-------------
 doc/sprintf/sprintf |  3 +++
 23 files changed, 97 insertions(+), 39 deletions(-)

diff --git a/doc/files/cd b/doc/files/cd
index e7a7e7eea6..e1b63bbf40 100644
--- a/doc/files/cd
+++ b/doc/files/cd
@@ -8,5 +8,8 @@ DESCRIPTION
 	Change the current directory for the whole LPC process, return
 	1 for success, 0 otherwise.
 
+KEYWORDS
+	file
+
 SEE ALSO
 	files/getcwd
\ No newline at end of file
diff --git a/doc/files/file b/doc/files/file
index 251a6202c9..53fc4eb76d 100644
--- a/doc/files/file
+++ b/doc/files/file
@@ -38,12 +38,12 @@ DESCRIPTION
 	Open a file for read write or append. The variable how should
 	contain one or more of the following letters:
 
-		'r'	: open file for reading
-		'w'	: open file for writing
-		'a'	: open file for append (use with 'w')
-		't'	: truncate file at close (use with 'w')
-		'c'	: create file if it doesn't exist (use with 'w')
-		'x'	: fail if file already exist (use with 'c')
+	'r'	open file for reading
+	'w'	open file for writing
+	'a'	open file for append (use with 'w')
+	't'	truncate file at close (use with 'w')
+	'c'	create file if it doesn't exist (use with 'w')
+	'x'	fail if file already exist (use with 'c')
 
 	How should _always_ contain at least one of 'r' or 'w'.
 
@@ -171,17 +171,17 @@ DESCRIPTION
 	transfer speed when it does.
 
 SEE ALSO
-	files/socket, port/accept
-
+	file->open_socket, port->accept
 
 ============================================================================
 NAME
 	set_nonblocking - make stream nonblocking
 
 SYNTAX
-	void file->set_nonblocking(function read_callback,
-			           function write_callback,
-			           function close_callback);
+	void file->set_nonblocking(
+	       function read_callback,
+	       function write_callback,
+	       function close_callback);
 
 DESCRIPTION
 	This function sets a stream to nonblocking mode. When data arrives on
@@ -305,7 +305,7 @@ DESCRIPTION
 	the argument a reference to the same file, it creates a new file
 	with the same properties and places it in the argument.
 
-EXAMPLE	
+EXAMPLE
 	/* Redirect stdin to come from the file 'foo' */
 	object o;
 	o=clone((program)"/precompiled/file");
diff --git a/doc/files/file_stat b/doc/files/file_stat
index c911ac1354..8cccd143ad 100644
--- a/doc/files/file_stat
+++ b/doc/files/file_stat
@@ -10,24 +10,26 @@ SYNTAX
 
 DESCRIPTION
 	file_stat returns an array of integers describing some properties
-	about the file.	Currently file_stat return 5 entries:
+	about the file. Currently file_stat return 7 entries:
 	({
-	   mode, /* file mode, protection bits etc. etc. */
-	   size, /* file size for regular files,
-	          * -2 for dirs,
-	          * -3 for links,
-	          * -4 for otherwise
-	          */
-	   atime, /* last access time */
-	   mtime, /* last modify time */
-	   ctime, /* last status time change */
-	   uid,   /* The user who owns this file */
-	   gid   /* The group this file belongs to */
+	   mode,	/* file mode, protection bits etc. etc. */
+	   size,	/* file size for regular files,
+	   	           -2 for dirs,
+	   	           -3 for links,
+	   	           -4 for otherwise */
+	   atime,	/* last access time */
+	   mtime,	/* last modify time */
+	   ctime,	/* last status time change */
+	   uid,  	/* The user who owns this file */
+	   gid   	/* The group this file belongs to */
 	})
 	If you give 1 as a second argument, stat does not follow links.
 	You can never get -3 as size if you don't give a second argument.
 
 	If there is no such file or directory, zero is returned.
 
+KEYWORDS
+	file
+
 SEE ALSO
 	files/get_dir
diff --git a/doc/files/get_dir b/doc/files/get_dir
index c344114abd..aa7aa6df87 100644
--- a/doc/files/get_dir
+++ b/doc/files/get_dir
@@ -8,5 +8,8 @@ DESCRIPTION
 	Return an array of all filenames in the directory dir, or zero if
 	no such directory exists.
 
+KEYWORDS
+	file
+
 SEE ALSO
 	files/mkdir, files/cd
diff --git a/doc/files/getcwd b/doc/files/getcwd
index d3c010ec8e..7d6ec4b385 100644
--- a/doc/files/getcwd
+++ b/doc/files/getcwd
@@ -7,5 +7,8 @@ SYNTAX
 DESCRIPTION
 	getcwd returns the current working directory.
 
+KEYWORDS
+	file
+
 SEE ALSO
 	files/cd
diff --git a/doc/files/mkdir b/doc/files/mkdir
index 780d8ed253..49c9ae7596 100644
--- a/doc/files/mkdir
+++ b/doc/files/mkdir
@@ -7,5 +7,8 @@ SYNTAX
 DESCRIPTION
 	Create a directory, return zero if it fails and nonzero if it fails.
 
+KEYWORDS
+	file
+
 SEE ALSO
 	files/rm, files/cd
diff --git a/doc/files/mv b/doc/files/mv
index c76ea4cb86..679710b241 100644
--- a/doc/files/mv
+++ b/doc/files/mv
@@ -9,5 +9,8 @@ DESCRIPTION
 	file already exists, it will be overwritten. Returns 1 on sucess,
 	0 otherwise.
 
+KEYWORDS
+	file
+
 SEE ALSO
 	files/rm
diff --git a/doc/files/port b/doc/files/port
index fa3c67fab7..92ebfd2b68 100644
--- a/doc/files/port
+++ b/doc/files/port
@@ -133,6 +133,6 @@ DESCRIPTION
 	/precompiled/file. The new file is by default set to blocking.
 
 SEE ALSO
-	file
+	/precompiled/file
 
 ============================================================================
diff --git a/doc/files/rm b/doc/files/rm
index fdfbef9ff5..a7a86fef89 100644
--- a/doc/files/rm
+++ b/doc/files/rm
@@ -7,6 +7,8 @@ SYNTAX
 DESCRIPTION
 	Remove a file or directory, return 0 if it fails. Nonzero otherwise.
 
+KEYWORDS
+	file
+
 SEE ALSO
 	files/mkdir
-	
\ No newline at end of file
diff --git a/doc/math/acos b/doc/math/acos
index 0c2f758e37..bd3ca9225b 100644
--- a/doc/math/acos
+++ b/doc/math/acos
@@ -7,5 +7,8 @@ SYNTAX
 DESCRIPTION
 	Return the arcus cosinus value for f.
 
+KEYWORDS
+	float
+
 SEE ALSO
 	math/cos, math/asin
diff --git a/doc/math/asin b/doc/math/asin
index c71c06156a..af772d5b39 100644
--- a/doc/math/asin
+++ b/doc/math/asin
@@ -7,5 +7,8 @@ SYNTAX
 DESCRIPTION
 	Return the arcus sinus value for f.
 
+KEYWORDS
+	float
+
 SEE ALSO
 	math/sin, math/acos
diff --git a/doc/math/atan b/doc/math/atan
index 64092f422d..d6ebcb7002 100644
--- a/doc/math/atan
+++ b/doc/math/atan
@@ -7,5 +7,8 @@ SYNTAX
 DESCRIPTION
 	Return the arcus tangent value for f.
 
+KEYWORDS
+	float
+
 SEE ALSO
 	math/tan, math/asin, math/acos
diff --git a/doc/math/ceil b/doc/math/ceil
index c560d878d0..5017676469 100644
--- a/doc/math/ceil
+++ b/doc/math/ceil
@@ -8,5 +8,8 @@ DESCRIPTION
 	Return the closest integral value higher or equal to x.
 	Note that ceil() does _not_ return an int, merely an integral value.
 
+KEYWORDS
+	float
+
 SEE ALSO
 	math/floor
diff --git a/doc/math/cos b/doc/math/cos
index e8d9536639..921c46ded2 100644
--- a/doc/math/cos
+++ b/doc/math/cos
@@ -7,5 +7,8 @@ SYNTAX
 DESCRIPTION
 	Return the cosinus value for f.
 
+KEYWORDS
+	float
+
 SEE ALSO
 	math/acos, math/sin
diff --git a/doc/math/exp b/doc/math/exp
index 45698f298f..13963c29de 100644
--- a/doc/math/exp
+++ b/doc/math/exp
@@ -8,5 +8,8 @@ DESCRIPTION
 	Return the natural exponent of f.
 	log( exp( x ) ) == x as long as exp(x) doesn't overflow an int.
 
+KEYWORDS
+	float
+
 SEE ALSO
 	math/pow, math/log
diff --git a/doc/math/floor b/doc/math/floor
index 3dc6cd8826..b257489c99 100644
--- a/doc/math/floor
+++ b/doc/math/floor
@@ -8,5 +8,8 @@ DESCRIPTION
 	Return the closest integral value lower or equal to x.
 	Note that floor() does _not_ return an int, merely an integral value.
 
+KEYWORDS
+	float
+
 SEE ALSO
 	math/ceil
diff --git a/doc/math/log b/doc/math/log
index 80dee7c7f9..e58c48f673 100644
--- a/doc/math/log
+++ b/doc/math/log
@@ -8,5 +8,8 @@ DESCRIPTION
 	Return the natural logarithm of f.
 	exp( log(x) ) == x for x > 0.
 
+KEYWORDS
+	float
+
 SEE ALSO
 	math/pow, math/exp
diff --git a/doc/math/pow b/doc/math/pow
index ad87a22ad4..8bc39e252f 100644
--- a/doc/math/pow
+++ b/doc/math/pow
@@ -7,5 +7,8 @@ SYNTAX
 DESCRIPTION
 	Return n raised to the power of x.
 
+KEYWORDS
+	float
+
 SEE ALSO
 	math/exp, math/log
diff --git a/doc/math/sin b/doc/math/sin
index 8944254e81..e3d6ae96bf 100644
--- a/doc/math/sin
+++ b/doc/math/sin
@@ -7,5 +7,8 @@ SYNTAX
 DESCRIPTION
 	Return the sinus value for f.
 
+KEYWORDS
+	float
+
 SEE ALSO
 	math/asin, math/cos
diff --git a/doc/math/sqrt b/doc/math/sqrt
index 6bfa0d6784..c84faca6dc 100644
--- a/doc/math/sqrt
+++ b/doc/math/sqrt
@@ -10,5 +10,8 @@ DESCRIPTION
 	Return the square root of f, or in the second case, the square root
 	truncated to the closest lower integer.
 
+KEYWORDS
+	float, int
+
 SEE ALSO
 	math/pow, math/log, math/exp, math/floor
diff --git a/doc/math/tan b/doc/math/tan
index f78b014e4f..0672360e6f 100644
--- a/doc/math/tan
+++ b/doc/math/tan
@@ -7,5 +7,8 @@ SYNTAX
 DESCRIPTION
 	Return the tangent value for f.
 
+KEYWORDS
+	float
+
 SEE ALSO
 	math/atan, math/sin, math/cos
diff --git a/doc/regexp/regexp b/doc/regexp/regexp
index a9c0faf941..f2c5b06389 100644
--- a/doc/regexp/regexp
+++ b/doc/regexp/regexp
@@ -6,18 +6,18 @@ DESCRIPTION
 	regexp package written in C. It contains a few simple functions to
 	handle regexps. A short description of regexp follows:
 
-	.      Matches any character
-	[abc]  Matches a, b or c
-	[a-z]  Matches any character a to z inclusive
-	[^ac]  Matches any character except a and c
-	(x)    Matches x (x might be any regexp)
-	x*     Matches zero or more occurances of 'x' (x may be anything)
-	x|y    Matches x or y. (x or y may be any regexp)
-	xy     Matches xy (x and y may be any regexp)
-	^      Matches beginning of string (but no characters)
-	$      Matches end of string (but no characters)
-	<x>    Used with split() to put the string matching x into the
-	       result array.
+	.	Matches any character
+	[abc]	Matches a, b or c
+	[a-z]	Matches any character a to z inclusive
+	[^ac]	Matches any character except a and c
+	(x)	Matches x (x might be any regexp)
+	x*	Matches zero or more occurances of 'x' (x may be anything)
+	x|y	Matches x or y. (x or y may be any regexp)
+	xy	Matches xy (x and y may be any regexp)
+	^	Matches beginning of string (but no characters)
+	$	Matches end of string (but no characters)
+	<x>	Used with split() to put the string matching x into the
+		result array.
 
 	Note that \ can be used to quote these characters in which case
 	they match themselves, nothing else. Also note that when quoting
@@ -27,7 +27,7 @@ DESCRIPTION
 	For more information about regexps, refer to your unix manuals such
 	as sed or ed.
 
-	Descriptions of all functions in /precompiled/file follows:
+	Descriptions of all functions in /precompiled/regexp follows:
 
 ============================================================================
 NAME
diff --git a/doc/sprintf/sprintf b/doc/sprintf/sprintf
index 87312b54b3..65b26021dc 100644
--- a/doc/sprintf/sprintf
+++ b/doc/sprintf/sprintf
@@ -174,5 +174,8 @@ EXAMPLES
 	> quit
 	Exiting.
 
+KEYWORDS
+	string
+
 SEE ALSO
 	sscanf
-- 
GitLab


From 7bd0ea80b968b857bef5b82911c27b0b6c986dbf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 19 Feb 1996 05:37:36 +0100
Subject: [PATCH 035/351] Implemented operator functions

Rev: lib/simulate.lpc:1.8
Rev: src/add_efun.c:1.2
Rev: src/add_efun.h:1.2
Rev: src/builtin_efuns.c:1.9
Rev: src/docode.c:1.3
Rev: src/docode.h:1.2
Rev: src/interpret.c:1.7
Rev: src/language.y:1.9
Rev: src/las.c:1.4
Rev: src/las.h:1.4
Rev: src/lex.c:1.6
Rev: src/modules/files/efuns.c:1.4
Rev: src/operators.c:1.2
Rev: src/operators.h:1.2
---
 lib/simulate.lpc          |   5 +-
 src/add_efun.c            |  23 ++-
 src/add_efun.h            |  17 +-
 src/builtin_efuns.c       |   4 +-
 src/docode.c              |  48 +++--
 src/docode.h              |  12 +-
 src/interpret.c           |  18 +-
 src/language.y            |  36 ++--
 src/las.c                 |  16 +-
 src/las.h                 |   1 +
 src/lex.c                 |  97 ++++++++--
 src/modules/files/efuns.c |   2 +-
 src/operators.c           | 391 +++++++++++++++++++++++++++++++++++---
 src/operators.h           |  56 +++---
 14 files changed, 603 insertions(+), 123 deletions(-)

diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index f2d317a52e..80b96aac1b 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -288,7 +288,7 @@ varargs mixed *sort_array(array foo,function cmp,mixed ... args)
 
   if(sizeof(foo)<2) return copy_value(foo);
 
-  if(!cmp) cmp=lambda(mixed a,mixed b) { return a > b; };
+  if(!cmp) cmp=`>;
 
   a=sort_array(foo[0..sizeof(foo)/2-1],cmp,@args);
   b=sort_array(foo[sizeof(foo)/2..sizeof(foo)],cmp,@args);
@@ -342,6 +342,7 @@ list mklist(mixed *a)
 void create()
 {
   add_efun("PI",3.1415926535897932384626433832795080);
+  add_efun("sum",`+);
   add_efun("capitalize",capitalize);
   add_efun("code_value",code_value);
   add_efun("exec","exec");
@@ -365,7 +366,7 @@ void create()
   add_efun("strstr",search);
   add_efun("sum_arrays",sum_arrays);
   add_efun("this_function",this_function);
-  add_efun("version",lambda() { return "uLPC v1.0E-11"; });
+  add_efun("version",lambda() { return "uLPC v1.0E-10"; });
   add_efun("write_file",write_file);
   add_efun("get_function",get_function);
   add_efun("regexp",regexp);
diff --git a/src/add_efun.c b/src/add_efun.c
index 86ce35af75..7c35fa8cf2 100644
--- a/src/add_efun.c
+++ b/src/add_efun.c
@@ -53,7 +53,12 @@ void low_add_efun(struct lpc_string *name, struct svalue *fun)
 }
 
 
-struct callable *make_callable(c_fun fun,char *name, char *type, INT16 flags)
+struct callable *make_callable(c_fun fun,
+			       char *name,
+			       char *type,
+			       INT16 flags,
+			       optimize_fun optimize,
+			       docode_fun docode)
 {
   struct callable *f;
   f=ALLOC_STRUCT(callable);
@@ -62,6 +67,8 @@ struct callable *make_callable(c_fun fun,char *name, char *type, INT16 flags)
   f->name=make_shared_string(name);
   f->type=parse_type(type);
   f->flags=flags;
+  f->docode=docode;
+  f->optimize=optimize;
   return f;
 }
 
@@ -72,7 +79,12 @@ void really_free_callable(struct callable *fun)
   free((char *)fun);
 }
 
-void add_efun(char *name, c_fun fun, char *type, INT16 flags)
+void add_efun2(char *name,
+	       c_fun fun,
+	       char *type,
+	       INT16 flags,
+	       optimize_fun optimize,
+	       docode_fun docode)
 {
   struct svalue s;
   struct lpc_string *n;
@@ -80,12 +92,17 @@ void add_efun(char *name, c_fun fun, char *type, INT16 flags)
   n=make_shared_string(name);
   s.type=T_FUNCTION;
   s.subtype=-1;
-  s.u.efun=make_callable(fun, name, type, flags);
+  s.u.efun=make_callable(fun, name, type, flags, optimize, docode);
   low_add_efun(n, &s);
   free_svalue(&s);
   free_string(n);
 }
 
+void add_efun(char *name, c_fun fun, char *type, INT16 flags)
+{
+  add_efun2(name,fun,type,flags,0,0);
+}
+
 static void push_efun_entry(struct hash_entry *h)
 {
   struct efun *f;
diff --git a/src/add_efun.h b/src/add_efun.h
index f27b34a2c2..2400328411 100644
--- a/src/add_efun.h
+++ b/src/add_efun.h
@@ -17,6 +17,8 @@ struct efun
 };
 
 typedef void (*c_fun)(INT32);
+typedef int (*docode_fun)(node *n);
+typedef void (*optimize_fun)(node *n);
 
 struct callable
 {
@@ -25,13 +27,26 @@ struct callable
   struct lpc_string *type;
   struct lpc_string *name;
   INT16 flags;
+  optimize_fun optimize;
+  docode_fun docode;
 };
 
 /* Prototypes begin here */
 struct efun *lookup_efun(struct lpc_string *name);
 void low_add_efun(struct lpc_string *name, struct svalue *fun);
-struct callable *make_callable(c_fun fun,char *name, char *type, INT16 flags);
+struct callable *make_callable(c_fun fun,
+			       char *name,
+			       char *type,
+			       INT16 flags,
+			       optimize_fun optimize,
+			       docode_fun docode);
 void really_free_callable(struct callable *fun);
+void add_efun2(char *name,
+	       c_fun fun,
+	       char *type,
+	       INT16 flags,
+	       optimize_fun optimize,
+	       docode_fun docode);
 void add_efun(char *name, c_fun fun, char *type, INT16 flags);
 void push_all_efuns_on_stack();
 void cleanup_added_efuns();
diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index 28120bf6e9..aa094a6853 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -1234,6 +1234,8 @@ TYPEP(f_floatp, "floatp", T_FLOAT)
 
 void init_builtin_efuns()
 {
+  init_operators();
+
   add_efun("add_efun",f_add_efun,"function(string,void|mixed:void)",OPT_SIDE_EFFECT);
   add_efun("aggregate",f_aggregate,"function(mixed ...:mixed *)",OPT_TRY_OPTIMIZE);
   add_efun("aggregate_list",f_aggregate_list,"function(mixed ...:list)",OPT_TRY_OPTIMIZE);
@@ -1286,7 +1288,7 @@ void init_builtin_efuns()
   add_efun("sizeof", f_sizeof, "function(string|list|array|mapping:int)",0);
   add_efun("sleep", f_sleep, "function(int:void)",OPT_SIDE_EFFECT);
   add_efun("stringp", f_stringp, "function(mixed:int)",0);
-  add_efun("sum",f_sum,"function(int ...:int)|function(float ...:float)|function(string,string|int|float ...:string)|function(string,string|int|float ...:string)|function(int|float,string,string|int|float:string)|function(array ...:array)|function(mapping ...:mapping)|function(list...:list)",0);
+
   add_efun("this_object", f_this_object, "function(:object)",OPT_EXTERNAL_DEPEND);
   add_efun("throw",f_throw,"function(mixed:void)",0);
   add_efun("time",f_time,"function(void|int:int)",OPT_EXTERNAL_DEPEND);
diff --git a/src/docode.c b/src/docode.c
index 4421a16df0..3eab7112dd 100644
--- a/src/docode.c
+++ b/src/docode.c
@@ -389,7 +389,7 @@ static int do_docode2(node *n,int flags);
 
 #define DO_CODE_BLOCK(N) do_pop(do_docode(N,DO_NOT_COPY | DO_POP))
 
-static int do_docode(node *n,INT16 flags)
+int do_docode(node *n,INT16 flags)
 {
   int i;
   int save_current_line=current_line;
@@ -535,6 +535,9 @@ static int do_docode2(node *n,int flags)
 
     if(tmp2 < tmp1) tmp1=tmp2;
 
+    if(tmp1 == -1)
+      fatal("Unknown number of args in ? :\n");
+
     tmp2=do_jump_when_zero(CAR(n),-1);
 
     tmp3=do_docode(CADR(n), flags);
@@ -873,26 +876,46 @@ static int do_docode2(node *n,int flags)
     return 1;
 
   case F_APPLY:
-    ins_f_byte(F_MARK);
     if(CAR(n)->token == F_CONSTANT)
     {
-      do_docode(CDR(n),0);
-      if(CAR(n)->u.sval.type == T_FUNCTION && 
-	 CAR(n)->u.sval.subtype != -1 &&
-	 CAR(n)->u.sval.u.object == &fake_object)
+      if(CAR(n)->u.sval.type == T_FUNCTION)
       {
-	ins_f_byte_with_numerical_arg(F_CALL_LFUN, CAR(n)->u.sval.subtype);
-      }else{
-	tmp1=store_constant(& CAR(n)->u.sval,
-			    !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND));
-	ins_f_byte(F_MAX_OPCODE + tmp1);
-	if(n->type == void_type_string) return 0;
+	if(CAR(n)->u.sval.subtype == -1) /* driver fun? */
+	{
+	  if(!CAR(n)->u.sval.u.efun->docode || 
+	     !CAR(n)->u.sval.u.efun->docode(n))
+	  {
+	    ins_f_byte(F_MARK);
+	    do_docode(CDR(n),0);
+	    tmp1=store_constant(& CAR(n)->u.sval,
+				!(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND));
+	    ins_f_byte(F_MAX_OPCODE + tmp1);
+	  }
+	  if(n->type == void_type_string) return 0;
+	  return 1;
+	}else{
+	  if(CAR(n)->u.sval.u.object == &fake_object)
+	  {
+	    ins_f_byte(F_MARK);
+	    do_docode(CDR(n),0);
+	    ins_f_byte_with_numerical_arg(F_CALL_LFUN, CAR(n)->u.sval.subtype);
+	    return 1;
+	  }
+       	}
       }
+
+      ins_f_byte(F_MARK);
+      do_docode(CDR(n),0);
+      tmp1=store_constant(& CAR(n)->u.sval,
+			  !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND));
+      ins_f_byte(F_MAX_OPCODE + tmp1);
+      
       return 1;
     }
     else if(CAR(n)->token == F_IDENTIFIER &&
 	    ID_FROM_INT(& fake_program, CAR(n)->u.number)->flags & IDENTIFIER_FUNCTION)
     {
+      ins_f_byte(F_MARK);
       do_docode(CDR(n),0);
       ins_f_byte_with_numerical_arg(F_CALL_LFUN, CAR(n)->u.number);
       return 1;
@@ -902,6 +925,7 @@ static int do_docode2(node *n,int flags)
       struct lpc_string *tmp;
       struct efun *fun;
 
+      ins_f_byte(F_MARK);
       tmp=make_shared_string("call_function");
       if(!tmp) yyerror("No call_function efun.");
       fun=lookup_efun(tmp);
diff --git a/src/docode.h b/src/docode.h
index 78bf2f8230..8f87b05b8d 100644
--- a/src/docode.h
+++ b/src/docode.h
@@ -6,6 +6,10 @@
 #ifndef DOCODE_H
 #define DOCODE_H
 
+#define DO_LVALUE 1
+#define DO_NOT_COPY 2
+#define DO_POP 4
+
 extern int store_linenumbers;
 extern int comp_stackp;
 extern INT32 comp_stack[COMPILER_STACK_SIZE];
@@ -14,12 +18,14 @@ extern INT32 comp_stack[COMPILER_STACK_SIZE];
 void ins_byte(unsigned char b,int area);
 void ins_signed_byte(char b,int area);
 void ins_short(INT16 l,int area);
-void ins_long(long l,int area);
+void ins_long(INT32 l,int area);
 void ins_f_byte(unsigned int b);
 void push_address();
-void push_explicit(int address);
-int pop_address();
+void push_explicit(INT32 address);
+INT32 pop_address();
 struct jump;
+struct jump_list;
+int do_docode(node *n,INT16 flags);
 int docode(node *n);
 void do_code_block(node *n);
 /* Prototypes end here */
diff --git a/src/interpret.c b/src/interpret.c
index ce61e6db18..117e643c83 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -797,14 +797,14 @@ static void eval_instruction(unsigned char *pc)
       COMPARISMENT(F_LT, is_lt(sp-2,sp-1));
       COMPARISMENT(F_LE,!is_gt(sp-2,sp-1));
 
-      CASE(F_ADD);      f_sum(2);     break;
-      CASE(F_SUBTRACT); f_subtract(); break;
-      CASE(F_AND);      f_and();      break;
-      CASE(F_OR);       f_or();       break;
-      CASE(F_XOR);      f_xor();      break;
-      CASE(F_MULTIPLY); f_multiply(); break;
-      CASE(F_DIVIDE);   f_divide();   break;
-      CASE(F_MOD);      f_mod();      break;
+      CASE(F_ADD);      f_add(2);     break;
+      CASE(F_SUBTRACT); o_subtract(); break;
+      CASE(F_AND);      o_and();      break;
+      CASE(F_OR);       o_or();       break;
+      CASE(F_XOR);      o_xor();      break;
+      CASE(F_MULTIPLY); o_multiply(); break;
+      CASE(F_DIVIDE);   o_divide();   break;
+      CASE(F_MOD);      o_mod();      break;
 
       CASE(F_PUSH_ARRAY);
       if(sp[-1].type!=T_ARRAY) error("Bad argument to @\n");
@@ -819,7 +819,7 @@ static void eval_instruction(unsigned char *pc)
 
       CASE(F_CAST); f_cast(); break;
 
-      CASE(F_RANGE); f_range(); break;
+      CASE(F_RANGE); o_range(); break;
       CASE(F_COPY_VALUE);
       copy_svalues_recursively_no_free(sp,sp-1,1,0);
       sp++;
diff --git a/src/language.y b/src/language.y
index 46739d6791..fc5266f752 100644
--- a/src/language.y
+++ b/src/language.y
@@ -879,22 +879,22 @@ assoc_pair:  expr0 ':' expr1
 expr1: expr2
      | expr1 F_LOR expr1  { $$=mknode(F_LOR,$1,$3); }
      | expr1 F_LAND expr1 { $$=mknode(F_LAND,$1,$3); }
-     | expr1 '|' expr1    { $$=mknode(F_OR,$1,$3); }
-     | expr1 '^' expr1    { $$=mknode(F_XOR,$1,$3); }
-     | expr1 '&' expr1    { $$=mknode(F_AND,$1,$3); }
-     | expr1 F_EQ expr1   { $$=mknode(F_EQ,$1,$3); }
-     | expr1 F_NE expr1   { $$=mknode(F_NE,$1,$3); }
-     | expr1 '>' expr1    { $$=mknode(F_GT,$1,$3); }
-     | expr1 F_GE expr1   { $$=mknode(F_GE,$1,$3); }
-     | expr1 '<' expr1    { $$=mknode(F_LT,$1,$3); }
-     | expr1 F_LE expr1   { $$=mknode(F_LE,$1,$3); }
-     | expr1 F_LSH expr1  { $$=mknode(F_LSH,$1,$3); }
-     | expr1 F_RSH expr1  { $$=mknode(F_RSH,$1,$3); }
-     | expr1 '+' expr1    { $$=mknode(F_ADD,$1,$3); }
-     | expr1 '-' expr1    { $$=mknode(F_SUBTRACT,$1,$3); }
-     | expr1 '*' expr1    { $$=mknode(F_MULTIPLY,$1,$3); }
-     | expr1 '%' expr1    { $$=mknode(F_MOD,$1,$3); }
-     | expr1 '/' expr1    { $$=mknode(F_DIVIDE,$1,$3); }
+     | expr1 '|' expr1    { $$=mkopernode("`|",$1,$3); }
+     | expr1 '^' expr1    { $$=mkopernode("`^",$1,$3); }
+     | expr1 '&' expr1    { $$=mkopernode("`&",$1,$3); }
+     | expr1 F_EQ expr1   { $$=mkopernode("`==",$1,$3); }
+     | expr1 F_NE expr1   { $$=mkopernode("`!=",$1,$3); }
+     | expr1 '>' expr1    { $$=mkopernode("`>",$1,$3); }
+     | expr1 F_GE expr1   { $$=mkopernode("`>=",$1,$3); }
+     | expr1 '<' expr1    { $$=mkopernode("`<",$1,$3); }
+     | expr1 F_LE expr1   { $$=mkopernode("`<=",$1,$3); }
+     | expr1 F_LSH expr1  { $$=mkopernode("`<<",$1,$3); }
+     | expr1 F_RSH expr1  { $$=mkopernode("`>>",$1,$3); }
+     | expr1 '+' expr1    { $$=mkopernode("`+",$1,$3); }
+     | expr1 '-' expr1    { $$=mkopernode("`-",$1,$3); }
+     | expr1 '*' expr1    { $$=mkopernode("`*",$1,$3); }
+     | expr1 '%' expr1    { $$=mkopernode("`%",$1,$3); }
+     | expr1 '/' expr1    { $$=mkopernode("`/",$1,$3); }
      ;
 
 expr2: expr3
@@ -906,8 +906,8 @@ expr2: expr3
      | F_INC expr4       { $$=mknode(F_INC,$2,0); }
      | F_DEC expr4       { $$=mknode(F_DEC,$2,0); }
      | F_NOT expr2        { $$=mknode(F_NOT,$2,0); }
-     | '~' expr2          { $$=mknode(F_COMPL,$2,0); }
-     | '-' expr2          { $$=mknode(F_NEGATE,$2,0); }
+     | '~' expr2          { $$=mkopernode("`~",$2,0); }
+     | '-' expr2          { $$=mkopernode("`-",$2,0); }
      ;
 
 expr3: expr4
diff --git a/src/las.c b/src/las.c
index 8d3d7f8a9b..9f3165bdcf 100644
--- a/src/las.c
+++ b/src/las.c
@@ -67,12 +67,17 @@ int cdr_is_node(node *n)
 
 INT32 count_args(node *n)
 {
+  int a,b;
   if(!n) return 0;
   switch(n->token)
   {
   case F_VAL_LVAL:
   case F_ARG_LIST:
-    return count_args(CAR(n)) + count_args(CDR(n));
+    a=count_args(CAR(n));
+    if(a==-1) return -1;
+    b=count_args(CDR(n));
+    if(b==-1) return -1;
+    return a+b;
 
   case F_CAST:
     if(n->type == void_type_string)
@@ -98,6 +103,7 @@ INT32 count_args(node *n)
     int tmp1,tmp2;
     tmp1=count_args(CDAR(n));
     tmp2=count_args(CDAR(n));
+    if(tmp1==-1 || tmp2==-2) return -1;
     if(tmp1 < tmp2) return tmp1;
     return tmp2;
   }
@@ -267,6 +273,14 @@ node *mkefuncallnode(char *function, node *args)
   return mkapplynode(mksvaluenode(&fun->function), args);
 }
 
+node *mkopernode(char *oper_id, node *arg1, node *arg2)
+{
+  if(arg1 && arg2)
+    arg1=mknode(F_ARG_LIST,arg1,arg2);
+
+  return mkefuncallnode(oper_id, arg1);
+}
+
 node *mklocalnode(int var)
 {
   node *res = mkemptynode();
diff --git a/src/las.h b/src/las.h
index 2b73993e15..3d99b7328a 100644
--- a/src/las.h
+++ b/src/las.h
@@ -85,6 +85,7 @@ node *mkintnode(int nr);
 node *mkfloatnode(FLOAT_TYPE foo);
 node *mkapplynode(node *func,node *args);
 node *mkefuncallnode(char *function, node *args);
+node *mkopernode(char *oper_id, node *arg1, node *arg2);
 node *mklocalnode(int var);
 node *mkidentifiernode(int i);
 node *mkcastnode(struct lpc_string *type,node *n);
diff --git a/src/lex.c b/src/lex.c
index 16f024b578..173b4655d5 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -808,12 +808,12 @@ static void do_define()
       if(e==argc)
       {
 	push_string(s2);
-	if(sp[-2].type==T_STRING) f_add();
+	if(sp[-2].type==T_STRING) f_add(2);
       }
       if(c=='\n' || c==MY_EOF)
       {
 	push_string(make_shared_string(" "));
-	if(sp[-2].type==T_STRING) f_add();
+	if(sp[-2].type==T_STRING) f_add(2);
 	break;
       }
       t=!!isidchar(c);
@@ -1507,6 +1507,61 @@ static int do_lex2(int literal, YYSTYPE *yylval)
     case '{':
     case ';':
     case '}': return c;
+
+    case '`':
+    {
+      char *tmp;
+      switch(GETC())
+      {
+      case '+': tmp="`+"; break;
+      case '-': tmp="`-"; break;
+      case '/': tmp="`/"; break;
+      case '%': tmp="`%"; break;
+      case '*': tmp="`*"; break;
+      case '&': tmp="`&"; break;
+      case '|': tmp="`|"; break;
+      case '^': tmp="`^"; break;
+      case '~': tmp="`~"; break;
+      case '(':
+	if(GOBBLE(')')) { tmp="`()"; break; }
+
+      default:
+	yyerror("Illegal ` identifier.");
+	tmp="";
+	break;
+
+      case '<':
+	if(GOBBLE('<')) { tmp="`<<"; break; }
+	if(GOBBLE('=')) { tmp="`<="; break; }
+	tmp="`<";
+	break;
+
+      case '>':
+	if(GOBBLE('>')) { tmp="`>>"; break; }
+	if(GOBBLE('=')) { tmp="`>="; break; }
+	tmp="`>";
+	break;
+
+      case '!':
+	if(GOBBLE('=')) { tmp="`!="; break; }
+	tmp="`!";
+	break;
+
+      case '=':
+	if(GOBBLE('=')) { tmp="`=="; break; }
+	tmp="`=";
+	break;
+      }
+
+      if(literal)
+      {
+	yylval->str=buf;
+      }else{
+	yylval->string=make_shared_string(tmp);
+      }
+      return F_IDENTIFIER;
+    }
+
   
     default:
       if(isidchar(c))
@@ -1679,9 +1734,9 @@ static void calcB()
 {
   switch(lookahead)
   {
-    case '-': low_lex(); calcB(); f_negate(); break;
-    case F_NOT: low_lex(); calcB(); f_not(); break;
-    case '~': low_lex(); calcB(); f_compl(); break;
+    case '-': low_lex(); calcB(); o_negate(); break;
+    case F_NOT: low_lex(); calcB(); o_not(); break;
+    case '~': low_lex(); calcB(); o_compl(); break;
     default: calcC();
   }
 }
@@ -1693,9 +1748,9 @@ static void calcA()
   {
     switch(lookahead)
     {
-      case '/': low_lex(); calcB(); f_divide(); continue;
-      case '*': low_lex(); calcB(); f_multiply(); continue;
-      case '%': low_lex(); calcB(); f_mod(); continue;
+      case '/': low_lex(); calcB(); o_divide(); continue;
+      case '*': low_lex(); calcB(); o_multiply(); continue;
+      case '%': low_lex(); calcB(); o_mod(); continue;
     }
     break;
   }
@@ -1709,8 +1764,8 @@ static void calc9()
   {
     switch(lookahead)
     {
-      case '+': low_lex(); calcA(); f_add(); continue;
-      case '-': low_lex(); calcA(); f_subtract(); continue;
+      case '+': low_lex(); calcA(); f_add(2); continue;
+      case '-': low_lex(); calcA(); o_subtract(); continue;
     }
     break;
   }
@@ -1724,8 +1779,8 @@ static void calc8()
   {
     switch(lookahead)
     {
-      case F_LSH: low_lex(); calc9(); f_lsh(); continue;
-      case F_RSH: low_lex(); calc9(); f_rsh(); continue;
+      case F_LSH: low_lex(); calc9(); o_lsh(); continue;
+      case F_RSH: low_lex(); calc9(); o_rsh(); continue;
     }
     break;
   }
@@ -1739,10 +1794,10 @@ static void calc7b()
   {
     switch(lookahead)
     {
-      case '<': low_lex(); calc8(); f_lt(); continue;
-      case '>': low_lex(); calc8(); f_gt(); continue;
-      case F_GE: low_lex(); calc8(); f_ge(); continue;
-      case F_LE: low_lex(); calc8(); f_le(); continue;
+      case '<': low_lex(); calc8(); f_lt(2); continue;
+      case '>': low_lex(); calc8(); f_gt(2); continue;
+      case F_GE: low_lex(); calc8(); f_ge(2); continue;
+      case F_LE: low_lex(); calc8(); f_le(2); continue;
     }
     break;
   }
@@ -1756,8 +1811,8 @@ static void calc7()
   {
     switch(lookahead)
     {
-      case F_EQ: low_lex(); calc7b(); f_eq(); continue;
-      case F_NE: low_lex(); calc7b(); f_ne(); continue;
+      case F_EQ: low_lex(); calc7b(); f_eq(2); continue;
+      case F_NE: low_lex(); calc7b(); f_ne(2); continue;
     }
     break;
   }
@@ -1771,7 +1826,7 @@ static void calc6()
   {
     low_lex();
     calc7();
-    f_and();
+    o_and();
   }
 }
 
@@ -1783,7 +1838,7 @@ static void calc5()
   {
     low_lex();
     calc6();
-    f_xor();
+    o_xor();
   }
 }
 
@@ -1795,7 +1850,7 @@ static void calc4()
   {
     low_lex();
     calc5();
-    f_or();
+    o_or();
   }
 }
 
diff --git a/src/modules/files/efuns.c b/src/modules/files/efuns.c
index b2172ad6c4..28cf14afc2 100644
--- a/src/modules/files/efuns.c
+++ b/src/modules/files/efuns.c
@@ -301,7 +301,7 @@ void f_exece(INT32 args)
       push_string(a->string);
       a->string->refs++;
 
-      f_sum(3);
+      f_add(3);
 
       env[e]=sp[-1].u.string->str;
     }
diff --git a/src/operators.c b/src/operators.c
index 9b18904820..ae7a11c3da 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -16,25 +16,33 @@
 #include "language.h"
 #include "memory.h"
 #include "error.h"
-
-#define COMPARISON(ID,EXPR) \
-void ID() \
-{ \
-  int i=EXPR; \
+#include "docode.h"
+#include "add_efun.h"
+
+#define COMPARISON(ID,NAME,EXPR) \
+void ID(INT32 args) \
+{\
+  int i; \
+  if(args > 2) \
+    pop_n_elems(args-2); \
+  else if(args < 2) \
+    error("Too few arguments to %s\n",NAME); \
+  i=EXPR; \
   pop_n_elems(2); \
   sp->type=T_INT; \
   sp->u.integer=i; \
   sp++; \
-} 
+}
+
+COMPARISON(f_eq,"`==", is_eq(sp-2,sp-1))
+COMPARISON(f_ne,"`!=",!is_eq(sp-2,sp-1))
+COMPARISON(f_lt,"`<" , is_lt(sp-2,sp-1))
+COMPARISON(f_le,"`<=",!is_gt(sp-2,sp-1))
+COMPARISON(f_gt,"`>" , is_gt(sp-2,sp-1))
+COMPARISON(f_ge,"`>=",!is_lt(sp-2,sp-1))
 
-COMPARISON(f_eq, is_eq(sp-2,sp-1))
-COMPARISON(f_ne,!is_eq(sp-2,sp-1))
-COMPARISON(f_lt, is_lt(sp-2,sp-1))
-COMPARISON(f_le,!is_gt(sp-2,sp-1))
-COMPARISON(f_gt, is_gt(sp-2,sp-1))
-COMPARISON(f_ge,!is_lt(sp-2,sp-1))
 
-void f_sum(INT32 args)
+void f_add(INT32 args)
 {
   INT32 e,size;
   TYPE_FIELD types;
@@ -192,9 +200,51 @@ void f_sum(INT32 args)
   }
 }
 
-void f_add() { f_sum(2); }
+static int generate_sum(node *n)
+{
+  switch(count_args(CDR(n)))
+  {
+  case 1:
+    do_docode(CDR(n),0);
+    return 1;
+
+  case 2:
+    do_docode(CDR(n),DO_NOT_COPY);
+    ins_f_byte(F_ADD);
+    return 1;
+
+  default:
+    return 0;
+  }
+}
+
+static int generate_comparison(node *n)
+{
+  if(count_args(CDR(n))==2)
+  {
+    do_docode(CDR(n),DO_NOT_COPY);
+
+    if(CAR(n)->u.sval.u.efun->function == f_eq)
+      ins_f_byte(F_EQ);
+    else if(CAR(n)->u.sval.u.efun->function == f_ne)
+      ins_f_byte(F_NE);
+    else if(CAR(n)->u.sval.u.efun->function == f_lt)
+      ins_f_byte(F_LT);
+    else if(CAR(n)->u.sval.u.efun->function == f_le)
+      ins_f_byte(F_LE);
+    else if(CAR(n)->u.sval.u.efun->function == f_gt)
+      ins_f_byte(F_GT);
+    else if(CAR(n)->u.sval.u.efun->function == f_ge)
+      ins_f_byte(F_GE);
+    else
+      fatal("Couldn't generate comparison!\n");
+    return 1;
+  }
+  return 0;
+}
+
 
-void f_subtract()
+void o_subtract()
 {
   if (sp[-2].type != sp[-1].type )
     error("Subtract on different types.\n");
@@ -259,7 +309,35 @@ void f_subtract()
   }
 }
 
-void f_and()
+void f_minus(INT32 args)
+{
+  switch(args)
+  {
+  case 0: error("Too few arguments to `-\n");
+  case 1: o_negate(); break;
+  case 2: o_subtract(); break;
+  default: error("Too many arguments to `-\n");
+  }
+}
+
+static int generate_minus(node *n)
+{
+  switch(count_args(CDR(n)))
+  {
+  case 1:
+    do_docode(CDR(n),DO_NOT_COPY);
+    ins_f_byte(F_NEGATE);
+    return 1;
+
+  case 2:
+    do_docode(CDR(n),DO_NOT_COPY);
+    ins_f_byte(F_SUBTRACT);
+    return 1;
+  }
+  return 0;
+}
+
+void o_and()
 {
   if(sp[-1].type != sp[-2].type)
     error("Bitwise and on different types.\n");
@@ -302,7 +380,36 @@ void f_and()
   }
 }
 
-void f_or()
+void f_and(INT32 args)
+{
+  switch(args)
+  {
+  case 0: error("Too few arguments to `&\n");
+  case 1: return;
+  case 2: o_and(); return;
+  default: while(--args > 0) o_and();
+  }
+}
+
+static int generate_and(node *n)
+{
+  switch(count_args(CDR(n)))
+  {
+  case 1:
+    do_docode(CDR(n),0);
+    return 1;
+
+  case 2:
+    do_docode(CDR(n),0);
+    ins_f_byte(F_AND);
+    return 1;
+
+  default:
+    return 0;
+  }
+}
+
+void o_or()
 {
   if(sp[-1].type != sp[-2].type)
     error("Bitwise or on different types.\n");
@@ -346,7 +453,37 @@ void f_or()
   }
 }
 
-void f_xor()
+void f_or(INT32 args)
+{
+  switch(args)
+  {
+  case 0: error("Too few arguments to `|\n");
+  case 1: return;
+  case 2: o_or(); return;
+  default: while(--args > 0) o_or();
+  }
+}
+
+static int generate_or(node *n)
+{
+  switch(count_args(CDR(n)))
+  {
+  case 1:
+    do_docode(CDR(n),0);
+    return 1;
+
+  case 2:
+    do_docode(CDR(n),0);
+    ins_f_byte(F_OR);
+    return 1;
+
+  default:
+    return 0;
+  }
+}
+
+
+void o_xor()
 {
   if(sp[-1].type != sp[-2].type)
     error("Bitwise xor on different types.\n");
@@ -389,7 +526,36 @@ void f_xor()
   }
 }
 
-void f_lsh()
+void f_xor(INT32 args)
+{
+  switch(args)
+  {
+  case 0: error("Too few arguments to `^\n");
+  case 1: return;
+  case 2: o_xor(); return;
+  default: while(--args > 0) o_xor();
+  }
+}
+
+static int generate_xor(node *n)
+{
+  switch(count_args(CDR(n)))
+  {
+  case 1:
+    do_docode(CDR(n),0);
+    return 1;
+
+  case 2:
+    do_docode(CDR(n),0);
+    ins_f_byte(F_XOR);
+    return 1;
+
+  default:
+    return 0;
+  }
+}
+
+void o_lsh()
 {
   if(sp[-2].type != T_INT) error("Bad argument 1 to <<\n");
   if(sp[-1].type != T_INT) error("Bad argument 2 to <<\n");
@@ -397,7 +563,25 @@ void f_lsh()
   sp[-1].u.integer <<= sp[0].u.integer;
 }
 
-void f_rsh()
+void f_lsh(INT32 args)
+{
+  if(args != 2)
+    error("Bad number of args to `<<\n");
+  o_lsh();
+}
+
+static int generate_lsh(node *n)
+{
+  if(count_args(CDR(n))==2)
+  {
+    do_docode(CDR(n),DO_NOT_COPY);
+    ins_f_byte(F_LSH);
+    return 1;
+  }
+  return 0;
+}
+
+void o_rsh()
 {
   if(sp[-2].type != T_INT) error("Bad argument 1 to >>\n"); 
   if(sp[-1].type != T_INT) error("Bad argument 2 to >>\n");
@@ -405,7 +589,25 @@ void f_rsh()
   sp[-1].u.integer >>= sp[0].u.integer;
 }
 
-void f_multiply()
+void f_rsh(INT32 args)
+{
+  if(args != 2)
+    error("Bad number of args to `>>\n");
+  o_rsh();
+}
+
+static int generate_rsh(node *n)
+{
+  if(count_args(CDR(n))==2)
+  {
+    do_docode(CDR(n),DO_NOT_COPY);
+    ins_f_byte(F_RSH);
+    return 1;
+  }
+  return 0;
+}
+
+void o_multiply()
 {
   switch(sp[-2].type)
   {
@@ -441,7 +643,36 @@ void f_multiply()
   }
 }
 
-void f_divide()
+void f_multiply(INT32 args)
+{
+  switch(args)
+  {
+  case 0: error("Too few arguments to `*\n");
+  case 1: return;
+  case 2: o_multiply(); return;
+  case 3: while(--args > 0) o_multiply(); 
+  }
+}
+
+static int generate_multiply(node *n)
+{
+  switch(count_args(CDR(n)))
+  {
+  case 1:
+    do_docode(CDR(n),0);
+    return 1;
+
+  case 2:
+    do_docode(CDR(n),0);
+    ins_f_byte(F_MULTIPLY);
+    return 1;
+
+  default:
+    return 0;
+  }
+}
+
+void o_divide()
 {
   if(sp[-2].type!=sp[-1].type)
     error("Division on different types.\n");
@@ -479,7 +710,25 @@ void f_divide()
   }
 }
 
-void f_mod()
+void f_divide(INT32 args)
+{
+  if(args != 2)
+    error("Bad number of args to `/\n");
+  o_divide();
+}
+
+static int generate_divide(node *n)
+{
+  if(count_args(CDR(n))==2)
+  {
+    do_docode(CDR(n),DO_NOT_COPY);
+    ins_f_byte(F_DIVIDE);
+    return 1;
+  }
+  return 0;
+}
+
+void o_mod()
 {
   if(sp[-2].type != sp[-1].type)
     error("Modulo on different types.\n");
@@ -508,7 +757,25 @@ void f_mod()
   }
 }
 
-void f_not()
+void f_mod(INT32 args)
+{
+  if(args != 2)
+    error("Bad number of args to `%%\n");
+  o_mod();
+}
+
+static int generate_mod(node *n)
+{
+  if(count_args(CDR(n))==2)
+  {
+    do_docode(CDR(n),DO_NOT_COPY);
+    ins_f_byte(F_MOD);
+    return 1;
+  }
+  return 0;
+}
+
+void o_not()
 {
   if(sp[-1].type==T_INT)
   {
@@ -521,13 +788,47 @@ void f_not()
   }
 }
 
-void f_compl()
+void f_not(INT32 args)
+{
+  if(args != 1) error("Bad number of args to `!\n");
+  o_not();
+}
+
+static int generate_not(node *n)
+{
+  if(count_args(CDR(n))==1)
+  {
+    do_docode(CDR(n),DO_NOT_COPY);
+    ins_f_byte(F_NOT);
+    return 1;
+  }
+  return 0;
+}
+
+void o_compl()
 {
   if (sp[-1].type != T_INT) error("Bad argument to ~\n");
   sp[-1].u.integer = ~ sp[-1].u.integer;
 }
 
-void f_negate()
+void f_compl(INT32 args)
+{
+  if(args != 1) error("Bad number of args to `~\n");
+  o_compl();
+}
+
+static int generate_compl(node *n)
+{
+  if(count_args(CDR(n))==1)
+  {
+    do_docode(CDR(n),DO_NOT_COPY);
+    ins_f_byte(F_COMPL);
+    return 1;
+  }
+  return 0;
+}
+
+void o_negate()
 {
   switch(sp[-1].type)
   {
@@ -544,8 +845,7 @@ void f_negate()
   }
 }
 
-
-void f_range()
+void o_range()
 {
   INT32 from,to;
   if(sp[-2].type != T_INT)
@@ -599,3 +899,38 @@ void f_range()
     error("[ .. ] can only be done on strings and arrays.\n");
   }
 }
+
+void init_operators()
+{
+  
+
+  add_efun2("`==",f_eq,"function(mixed,mixed:int)",0,0,generate_comparison);
+  add_efun2("`!=",f_ne,"function(mixed,mixed:int)",0,0,generate_comparison);
+  add_efun2("`<", f_lt,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison);
+  add_efun2("`<=",f_le,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison);
+  add_efun2("`>", f_gt,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison);
+  add_efun2("`>=",f_ge,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison);
+
+  add_efun2("`+",f_add,"function(int ...:int)|function(float ...:float)|function(string,string|int|float ...:string)|function(string,string|int|float ...:string)|function(int|float,string,string|int|float:string)|function(array ...:array)|function(mapping ...:mapping)|function(list...:list)",0,0,generate_sum);
+
+  add_efun2("`-",f_minus,"function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(list,list:list)|function(float,float:float)|function(int,int:int)|function(string,string:string)",0,0,generate_minus);
+
+  add_efun2("`&",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,0,generate_and);
+
+  add_efun2("`|",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,0,generate_or);
+
+  add_efun2("`^",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,0,generate_xor);
+
+  add_efun2("`<<",f_lsh,"function(int,int:int)",0,0,generate_lsh);
+  add_efun2("`>>",f_rsh,"function(int,int:int)",0,0,generate_rsh);
+
+  add_efun2("`*",f_multiply,"function(int...:int)|function(float...:float)|function(string*,string:string)",0,0,generate_multiply);
+
+  add_efun2("`/",f_divide,"function(int,int:int)|function(float,float:float)|function(string,string:string*)",0,0,generate_divide);
+
+  add_efun2("`%",f_mod,"function(int,int:int)|function(float,float:float)",0,0,generate_mod);
+
+  add_efun2("`!",f_not,"function(mixed:int)",0,0,generate_not);
+  add_efun2("`~",f_compl,"function(int:int)",0,0,generate_compl);
+  
+}
diff --git a/src/operators.h b/src/operators.h
index a93a17f2b0..5870c4e35c 100644
--- a/src/operators.h
+++ b/src/operators.h
@@ -6,31 +6,41 @@
 #ifndef OPERATORS_H
 #define OPERATORS_H
 
-#define COMPARISON(ID,X) void ID(void);
+#define COMPARISON(ID,NAME,X) void ID(INT32 num_arg);
 
 /* Prototypes begin here */
-COMPARISON(f_eq, is_eq(sp-2,sp-1))
-COMPARISON(f_ne,!is_eq(sp-2,sp-1))
-COMPARISON(f_lt, is_lt(sp-2,sp-1))
-COMPARISON(f_le,!is_gt(sp-2,sp-1))
-COMPARISON(f_gt, is_gt(sp-2,sp-1))
-COMPARISON(f_ge,!is_lt(sp-2,sp-1))
-void f_sum(INT32 args);
-void f_add();
-void f_subtract();
-void f_and();
-void f_or();
-void f_xor();
-void f_lsh();
-void f_rsh();
-void f_multiply();
-void f_divide();
-void f_mod();
-void f_not();
-void f_compl();
-void f_negate();
-void f_is_equal(int args,struct svalue *argp);
-void f_range();
+COMPARISON(f_eq,"`==", is_eq(sp-2,sp-1))
+COMPARISON(f_ne,"`!=",!is_eq(sp-2,sp-1))
+COMPARISON(f_lt,"`<" , is_lt(sp-2,sp-1))
+COMPARISON(f_le,"`<=",!is_gt(sp-2,sp-1))
+COMPARISON(f_gt,"`>" , is_gt(sp-2,sp-1))
+COMPARISON(f_ge,"`>=",!is_lt(sp-2,sp-1))
+void f_add(INT32 args);
+void o_subtract();
+void f_minus(INT32 args);
+void o_and();
+void f_and(INT32 args);
+void o_or();
+void f_or(INT32 args);
+void o_xor();
+void f_xor(INT32 args);
+void o_lsh();
+void f_lsh(INT32 args);
+void o_rsh();
+void f_rsh(INT32 args);
+void o_multiply();
+void f_multiply(INT32 args);
+void o_divide();
+void f_divide(INT32 args);
+void o_mod();
+void f_mod(INT32 args);
+void o_not();
+void f_not(INT32 args);
+void o_compl();
+void f_compl(INT32 args);
+void o_negate();
+void o_range();
+void init_operators();
 /* Prototypes end here */
 
 #undef COMPARISON
-- 
GitLab


From a22fdc517078e292efb2f22b83d7fc2b9601104e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 19 Feb 1996 20:50:05 +0100
Subject: [PATCH 036/351] more gc stuff implemented

Rev: src/array.c:1.6
Rev: src/object.c:1.5
Rev: src/object.h:1.3
---
 src/array.c  |   3 +-
 src/object.c | 126 ++++++++++++++++++++++++++++++---------------------
 src/object.h |   6 ++-
 3 files changed, 82 insertions(+), 53 deletions(-)

diff --git a/src/array.c b/src/array.c
index 46e51f1d2b..e2e2a86592 100644
--- a/src/array.c
+++ b/src/array.c
@@ -1266,7 +1266,7 @@ void array_gc_clear_mark()
 
 void array_gc_mark(struct array *a)
 {
-  INT e;
+  INT32 e;
   if(a->flags & ARRAY_FLAG_MARK) return;
   a->flags |= ARRAY_FLAG_MARK;
 
@@ -1306,6 +1306,7 @@ void array_gc_sweep()
 void array_gc_sweep2()
 {
   struct array *a;
+  if(!d_flag) return;
 
   a=&empty_array;
   do
diff --git a/src/object.c b/src/object.c
index d0a2784a3a..7f24245964 100644
--- a/src/object.c
+++ b/src/object.c
@@ -269,18 +269,14 @@ void object_index_no_free(struct svalue *to,
     else if(i->run_time_type == T_MIXED)
     {
       struct svalue *s;
-      s=(struct svalue *)(o->storage+
-			  INHERIT_FROM_INT(p, f)->storage_offset +
-			  i->func.offset);
+      s=(struct svalue *)LOW_GET_GLOBAL(o,f,i);
       check_destructed(s);
       assign_svalue_no_free(to,s);
     }
     else
     {
       union anything *u;
-      u=(union anything *)(o->storage+
-			   INHERIT_FROM_INT(p, f)->storage_offset +
-			   i->func.offset);
+      u=(union anything *)LOW_GET_GLOBAL(o,f,i);
       check_short_destructed(u,i->run_time_type);
       assign_from_short_svalue_no_free(to,u,i->run_time_type);
     }
@@ -304,18 +300,14 @@ static void low_object_index(struct svalue *to,struct object *o, INT32 f)
   else if(i->run_time_type == T_MIXED)
   {
     struct svalue *s;
-    s=(struct svalue *)(o->storage+
-			INHERIT_FROM_INT(p, f)->storage_offset +
-			i->func.offset);
+    s=(struct svalue *)LOW_GET_GLOBAL(o,f,i);
     check_destructed(s);
     assign_svalue_no_free(to, s);
   }
   else
   {
     union anything *u;
-    u=(union anything *)(o->storage+
-			 INHERIT_FROM_INT(p, f)->storage_offset +
-			 i->func.offset);
+    u=(union anything *)LOW_GET_GLOBAL(o,f,i);
     check_short_destructed(u,i->run_time_type);
     assign_from_short_svalue_no_free(to, u, i->run_time_type);
   }
@@ -373,18 +365,12 @@ void object_low_set_index(struct object *o,
   }
   else if(i->run_time_type == T_MIXED)
   {
-    assign_svalue((struct svalue *) 
-		  (o->storage+
-		   INHERIT_FROM_INT(p, f)->storage_offset+
-		   i->func.offset),
-		  from);
+    assign_svalue((struct svalue *)LOW_GET_GLOBAL(o,f,i),from);
   }
   else
   {
     assign_to_short_svalue((union anything *) 
-			   (o->storage+
-			    INHERIT_FROM_INT(p, f)->storage_offset+
-			    i->func.offset),
+			   LOW_GET_GLOBAL(o,f,i),
 			   i->run_time_type,
 			   from);
   }
@@ -438,16 +424,12 @@ union anything *object_low_get_item_ptr(struct object *o,
   else if(i->run_time_type == T_MIXED)
   {
     struct svalue *s;
-    s=(struct svalue *)(o->storage+
-			INHERIT_FROM_INT(p, f)->storage_offset +
-			i->func.offset);
+    s=(struct svalue *)LOW_GET_GLOBAL(o,f,i);
     if(s->type == type) return & s->u;
   }
   else if(i->run_time_type == type)
   {
-    return (union anything *) (o->storage+
-			       INHERIT_FROM_INT(p, f)->storage_offset +
-			       i->func.offset);
+    return (union anything *) LOW_GET_GLOBAL(o,f,i);
   }
   return 0;
 }
@@ -534,15 +516,9 @@ void verify_all_objects(int pass)
 
 	if(i->run_time_type == T_MIXED)
 	{
-	  check_svalue((struct svalue *)
-		       (o->storage+
-			INHERIT_FROM_INT(o->prog, e)->storage_offset+
-			i->func.offset));
+	  check_svalue((struct svalue *)LOW_GET_GLOBAL(o,e,i));
 	}else{
-	  check_short_svalue((union anything *)
-			     (o->storage+
-			      INHERIT_FROM_INT(o->prog, e)->storage_offset+
-			      i->func.offset),
+	  check_short_svalue((union anything *)LOW_GET_GLOBAL(o,e,i),
 			     i->run_time_type);
 	}
       }
@@ -601,25 +577,13 @@ int object_equal_p(struct object *a, struct object *b, struct processing *p)
 
       if(i->run_time_type == T_MIXED)
       {
-	if(!low_is_equal((struct svalue *)
-			(a->storage+
-			 INHERIT_FROM_INT(a->prog, e)->storage_offset+
-			 i->func.offset),
-			(struct svalue *)
-			(b->storage+
-			 INHERIT_FROM_INT(a->prog, e)->storage_offset+
-			 i->func.offset),
-			&curr))
+	if(!low_is_equal((struct svalue *)LOW_GET_GLOBAL(a,e,i),
+			 (struct svalue *)LOW_GET_GLOBAL(b,e,i),
+			 &curr))
 	  return 0;
       }else{
-	if(!low_short_is_equal((union anything *)
-			       (a->storage+
-				INHERIT_FROM_INT(a->prog, e)->storage_offset+
-				i->func.offset),
-			       (union anything *)
-			       (b->storage+
-				INHERIT_FROM_INT(a->prog, e)->storage_offset+
-				i->func.offset),
+	if(!low_short_is_equal((union anything *)LOW_GET_GLOBAL(a,e,i),
+			       (union anything *)LOW_GET_GLOBAL(b,e,i),
 			       i->run_time_type,
 			       &curr))
 	  return 0;
@@ -682,3 +646,63 @@ struct array *object_values(struct object *o)
   }
   return a;
 }
+
+#ifdef GC
+void object_gc_clear_mark()
+{
+  struct object *o;
+  for(o=first_object;o;o=o->next)
+    o->flags &=~ OBJECT_FLAG_MARK;
+}
+
+void object_gc_mark(struct object *o)
+{
+  INT32 e;
+  if(o->flags & OBJECT_FLAG_MARK) return;
+  a->flags |= OBJECT_FLAG_MARK;
+
+  if(!o->prog) return;
+
+  for(e=0;e<(int)o->prog->num_identifier_indexes;e++)
+  {
+    struct identifier *i;
+    
+    i=ID_FROM_INT(o->prog, e);
+
+    if(i->run_time_type & IDENTIFIER_FUNCTION) continue;
+
+    if(i->run_time_type == T_MIXED)
+    {
+      svalue_gc_sweep((struct svalue *)LOW_GET_GLOBAL(o,e,i));
+    }else{
+      short_svalue_gc_sweep((struct svalue *)LOW_GET_GLOBAL(o,e,i),
+			    i->run_time_type);
+    }
+  }
+}
+
+void object_gc_sweep()
+{
+  struct object *o, *next;
+  for(o=first_object;o;o=next)
+  {
+    o->refs++;
+    if(!(o->flags & OBJECT_FLAG_MARK)) destruct(o);
+    next=o->next;
+    free_object(o);
+  }
+}
+
+#ifdef DEBUG
+void object_gc_sweep2()
+{
+  struct object *o;
+  if(!d_flag) return;
+
+
+  for(o=first_object;o;o=o->next)
+    if(!(o->flags & OBJECT_FLAG_MARK)) 
+      fatal("Object ref count incorrect.\n");
+}
+#endif /* DEBUG */
+#endif /* GC */
diff --git a/src/object.h b/src/object.h
index 478e13b3ee..8d67f15dd0 100644
--- a/src/object.h
+++ b/src/object.h
@@ -14,6 +14,7 @@
 struct object
 {
   INT32 refs;                    /* Reference count, must be first. */
+  INT16 flags;
   struct program *prog;
   struct object *next;
   struct object *prev;
@@ -24,7 +25,10 @@ extern struct object fake_object;
 extern struct object *first_object;
 
 #define free_object(O) do{ struct object *o_=(O); if(!--o_->refs) really_free_object(o_); }while(0)
-#define GLOBAL_FROM_INT(I) (fp->current_object->storage+INHERIT_FROM_INT(fp->current_object->prog,(I))->storage_offset+ID_FROM_INT(fp->current_object->prog,(I))->func.offset)
+
+#define LOW_GET_GLOBAL(O,I,ID) ((O)->storage+INHERIT_FROM_INT((O)->prog, (I))->storage_offset+(ID)->func.offset)
+#define GET_GLOBAL(O,I) LOW_GET_GLOBAL(O,I,ID_FROM_INT((O)->prog,I))
+#define GLOBAL_FROM_INT(I) GET_GLOBAL(fp->current_object, I)
 
 /* Prototypes begin here */
 void setup_fake_object();
-- 
GitLab


From 624d0919ccb7ed82a11cf9b7f7d11db9440cd0ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 24 Feb 1996 03:42:05 +0100
Subject: [PATCH 037/351] Garbage collect finished

Rev: lib/simulate.lpc:1.9
Rev: src/ChangeLog:1.17
Rev: src/Makefile.in:1.9
Rev: src/array.c:1.7
Rev: src/array.h:1.4
Rev: src/backend.c:1.3
Rev: src/backend.h:1.3
Rev: src/builtin_efuns.c:1.10
Rev: src/call_out.c:1.3
Rev: src/config.h:1.3
Rev: src/debug.c:1.2(DEAD)
Rev: src/debug.h:1.2(DEAD)
Rev: src/global.h:1.2
Rev: src/mapping.c:1.3
Rev: src/mapping.h:1.2
Rev: src/modules/efuns.c:1.2(DEAD)
Rev: src/modules/files/Makefile.in:1.2
Rev: src/modules/regexp/Makefile.in:1.2
Rev: src/modules/sprintf/Makefile.in:1.2
Rev: src/object.c:1.6
Rev: src/object.h:1.4
Rev: src/program.c:1.7
Rev: src/program.h:1.3
Rev: src/stralloc.c:1.2
Rev: src/stralloc.h:1.2
Rev: src/svalue.c:1.6
Rev: src/svalue.h:1.4
Rev: src/test/create_testsuite:1.8
---
 lib/simulate.lpc                |  32 +-
 src/ChangeLog                   |   5 +
 src/Makefile.in                 | 627 ++++++++++++++++++++------------
 src/array.c                     | 169 ++++-----
 src/array.h                     |  11 +-
 src/backend.c                   |  48 +--
 src/backend.h                   |   2 +-
 src/builtin_efuns.c             |  11 +
 src/call_out.c                  |   6 -
 src/config.h                    |   5 +
 src/debug.c                     | 125 -------
 src/debug.h                     |  19 -
 src/global.h                    |   4 -
 src/mapping.c                   |  18 +-
 src/mapping.h                   |   2 +
 src/modules/efuns.c             |  47 ---
 src/modules/files/Makefile.in   |  23 +-
 src/modules/regexp/Makefile.in  |   8 +-
 src/modules/sprintf/Makefile.in |   4 +-
 src/object.c                    |  71 ++--
 src/object.h                    |   7 +-
 src/program.c                   |  85 +++--
 src/program.h                   |   8 +-
 src/stralloc.c                  |  12 +-
 src/stralloc.h                  |   2 +-
 src/svalue.c                    |  58 ++-
 src/svalue.h                    |   3 +
 src/test/create_testsuite       |   2 +
 28 files changed, 708 insertions(+), 706 deletions(-)
 delete mode 100644 src/debug.c
 delete mode 100644 src/debug.h
 delete mode 100644 src/modules/efuns.c

diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index 80b96aac1b..985735cf8d 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -5,27 +5,9 @@ inherit "/precompiled/regexp";
 
 string current_file, current_mode;
 
-static int open(string file, string how)
-{
-  if(file == current_file && how == current_mode)
-  {
-    seek(0);
-    return 1;
-  }else{
-    if(file::open(file,how))
-    {
-      current_file=file;
-      current_mode=how;
-      return 1;
-    }else{
-      current_file=current_mode=0;
-      return 0;
-    }
-  }
-}
-
 string read_bytes(string filename,void|int start,void|int len)
 {
+  string ret;
   if(!open(filename,"r"))
     error("Couldn't open file "+filename+".\n");
   
@@ -37,16 +19,20 @@ string read_bytes(string filename,void|int start,void|int len)
   case 3:
     seek(start);
   }
-  return read(len);
+  ret=read(len);
+  close();
+  return ret;
 }
 
 int write_file(string filename,string what)
 {
-  if(!open(filename,"wc"))
+  int ret;
+  if(!open(filename,"awc"))
     error("Couldn't open file "+filename+".\n");
   
-  seek(-1);
-  return write(what);
+  ret=write(what);
+  close();
+  return ret;
 }
 
 mixed *map_array(mixed *arr, mixed fun, mixed ... args)
diff --git a/src/ChangeLog b/src/ChangeLog
index 482ff040be..6e349ca19e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+Sat Feb 24 04:12:52 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
+
+	* program.c, array.c, object.c, gc.c: 
+	  Added routines to remove cyclic structures.
+
 Sat Feb 17 23:05:24 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
 
 	* sprintf: added support for %2c
diff --git a/src/Makefile.in b/src/Makefile.in
index aae59ad77d..fbfd057af6 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -72,7 +72,7 @@ OBJ=language.o add_efun.o array.o builtin_efuns.o backend.o \
     fsort.o hashtable.o interpret.o lex.o las.o list.o \
     lpc_types.o main.o mapping.o memory.o module.o object.o \
     opcodes.o operators.o port.o program.o rusage.o stralloc.o \
-    stuff.o svalue.o debug.o callback.o lpc_signal.o @EXTRA_OBJS@
+    stuff.o svalue.o gc.o callback.o lpc_signal.o @EXTRA_OBJS@
 
 #
 MODULES=@subdirs@
@@ -145,11 +145,11 @@ TAGS:
 verify_manual:
 	$(RUNULPC) $(SRCDIR)/test/verifymanual.lpc $(TMP_DOCDIR)
 
-verify:
+verify: $(SRCDIR)/test/testsuite
 	$(RUNULPC) $(SRCDIR)/test/test_lpc.lpc $(SRCDIR)/test/testsuite
 
 # verify / debug verbose
-verbose_verify:
+verbose_verify: $(SRCDIR)/test/testsuite
 	$(RUNULPC) $(SRCDIR)/test/test_lpc.lpc $(SRCDIR)/test/testsuite --verbose
 
 # verify & debug VERBOSE
@@ -214,250 +214,423 @@ $(SRCDIR)/test/testsuite: $(SRCDIR)/test/create_testsuite
 
 #Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
 language.o: language.c global.h machine.h \
-  config.h debug.h \
-  port.h interpret.h \
-  program.h array.h \
-  las.h svalue.h \
-  dynamic_buffer.h object.h \
-  stralloc.h lex.h \
-  lpc_types.h add_efun.h \
-  hashtable.h macros.h \
-  error.h docode.h
-add_efun.o: add_efun.c add_efun.h \
-  svalue.h types.h machine.h \
-  hashtable.h las.h \
-  config.h dynamic_buffer.h \
-  program.h macros.h \
-  memory.h lpc_types.h \
-  stralloc.h interpret.h
+  config.h \
+  port.h \
+  interpret.h \
+  program.h \
+  array.h las.h \
+  svalue.h \
+  dynamic_buffer.h \
+  object.h \
+  stralloc.h \
+  lex.h \
+  lpc_types.h \
+  add_efun.h \
+  hashtable.h \
+  macros.h \
+  error.h \
+  docode.h
+add_efun.o: add_efun.c \
+  add_efun.h \
+  svalue.h \
+  types.h machine.h \
+  hashtable.h \
+  las.h \
+  config.h \
+  dynamic_buffer.h \
+  program.h \
+  macros.h \
+  memory.h \
+  lpc_types.h \
+  stralloc.h \
+  interpret.h
 alloca.o: alloca.c
-array.o: array.c global.h \
-  machine.h config.h debug.h \
-  port.h svalue.h \
+array.o: array.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  svalue.h \
   array.h las.h \
-  dynamic_buffer.h program.h \
-  object.h stralloc.h \
-  interpret.h language.h error.h \
-  lpc_types.h fsort.h \
-  builtin_efuns.h
-backend.o: backend.c global.h \
-  machine.h config.h debug.h \
-  port.h interpret.h \
-  program.h object.h \
-  svalue.h error.h \
-  call_out.h backend.h \
-  fd_control.h main.h \
-  callback.h array.h \
-  las.h dynamic_buffer.h
+  dynamic_buffer.h \
+  program.h \
+  object.h \
+  stralloc.h \
+  interpret.h language.h \
+  error.h \
+  lpc_types.h \
+  fsort.h \
+  builtin_efuns.h \
+  gc.h
 builtin_efuns.o: builtin_efuns.c \
-  global.h machine.h config.h \
-  debug.h port.h \
-  interpret.h program.h \
-  svalue.h macros.h \
-  object.h array.h \
-  las.h dynamic_buffer.h \
-  error.h add_efun.h \
-  hashtable.h mapping.h \
-  stralloc.h lex.h \
-  list.h lpc_types.h \
-  rusage.h operators.h \
-  fsort.h call_out.h \
-  callback.h
-call_out.o: call_out.c global.h \
-  machine.h config.h debug.h \
-  port.h array.h \
-  las.h svalue.h \
-  dynamic_buffer.h program.h \
-  call_out.h object.h \
-  interpret.h error.h \
-  builtin_efuns.h main.h
-callback.o: callback.c macros.h \
-  memory.h types.h machine.h \
-  callback.h array.h \
-  las.h config.h \
-  svalue.h dynamic_buffer.h \
+  global.h machine.h \
+  config.h \
+  port.h \
+  interpret.h \
+  program.h \
+  svalue.h \
+  macros.h \
+  object.h \
+  array.h las.h \
+  dynamic_buffer.h \
+  error.h \
+  add_efun.h \
+  hashtable.h \
+  mapping.h \
+  stralloc.h \
+  lex.h list.h \
+  lpc_types.h \
+  rusage.h \
+  operators.h \
+  fsort.h \
+  call_out.h \
+  callback.h \
+  gc.h
+call_out.o: call_out.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  array.h las.h \
+  svalue.h \
+  dynamic_buffer.h \
+  program.h \
+  call_out.h \
+  object.h \
+  interpret.h \
+  error.h \
+  builtin_efuns.h \
+  main.h
+callback.o: callback.c \
+  macros.h \
+  memory.h \
+  types.h machine.h \
+  callback.h \
+  array.h las.h \
+  config.h \
+  svalue.h \
+  dynamic_buffer.h \
   program.h
-debug.o: debug.c global.h \
-  machine.h config.h debug.h \
-  port.h
-docode.o: docode.c global.h \
-  machine.h config.h debug.h \
+docode.o: docode.c \
+  global.h machine.h \
+  config.h \
   port.h las.h \
-  svalue.h dynamic_buffer.h \
+  svalue.h \
+  dynamic_buffer.h \
   program.h language.h \
-  lpc_types.h stralloc.h \
-  interpret.h add_efun.h \
-  hashtable.h array.h \
-  macros.h error.h \
+  lpc_types.h \
+  stralloc.h \
+  interpret.h \
+  add_efun.h \
+  hashtable.h \
+  array.h \
+  macros.h \
+  error.h \
   main.h lex.h \
   builtin_efuns.h
 dynamic_buffer.o: dynamic_buffer.c \
-  global.h machine.h config.h \
-  debug.h port.h \
-  dynamic_buffer.h stralloc.h \
-  error.h svalue.h
-error.o: error.c global.h \
-  machine.h config.h debug.h \
-  port.h macros.h \
-  error.h svalue.h \
-  interpret.h program.h \
-  stralloc.h builtin_efuns.h \
+  global.h machine.h \
+  config.h \
+  port.h \
+  dynamic_buffer.h \
+  stralloc.h \
+  error.h \
+  svalue.h
+error.o: error.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  macros.h \
+  error.h \
+  svalue.h \
+  interpret.h \
+  program.h \
+  stralloc.h \
+  builtin_efuns.h \
   array.h las.h \
-  dynamic_buffer.h object.h
+  dynamic_buffer.h \
+  object.h
 fd_control.o: fd_control.c \
-  fd_control.h global.h \
-  machine.h config.h debug.h \
+  fd_control.h \
+  global.h machine.h \
+  config.h \
   port.h
-fsort.o: fsort.c global.h \
-  machine.h config.h debug.h \
-  port.h fsort.h
-hashtable.o: hashtable.c global.h \
-  machine.h config.h debug.h \
-  port.h hashtable.h \
-  stralloc.h stuff.h \
-  error.h svalue.h
-interpret.o: interpret.c global.h \
-  machine.h config.h debug.h \
-  port.h interpret.h \
-  program.h object.h \
-  svalue.h array.h \
-  las.h dynamic_buffer.h \
-  mapping.h error.h language.h \
-  stralloc.h add_efun.h \
-  hashtable.h macros.h \
-  list.h backend.h \
-  operators.h opcodes.h \
+fsort.o: fsort.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  fsort.h
+gc.o: gc.c \
+  global.h machine.h \
+  config.h \
+  port.h gc.h \
+  main.h
+hashtable.o: hashtable.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  hashtable.h \
+  stralloc.h \
+  stuff.h \
+  error.h \
+  svalue.h
+interpret.o: interpret.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  interpret.h \
+  program.h \
+  object.h \
+  svalue.h \
+  array.h las.h \
+  dynamic_buffer.h \
+  mapping.h \
+  error.h language.h \
+  stralloc.h \
+  add_efun.h \
+  hashtable.h \
+  macros.h \
+  list.h \
+  backend.h \
+  operators.h \
+  opcodes.h \
   main.h lex.h \
-  builtin_efuns.h lpc_signal.h
-las.o: las.c global.h machine.h \
-  config.h debug.h \
-  port.h language.h interpret.h \
-  program.h las.h \
-  svalue.h dynamic_buffer.h \
-  array.h object.h \
-  stralloc.h lex.h \
-  lpc_types.h add_efun.h \
-  hashtable.h mapping.h \
-  list.h error.h \
-  docode.h main.h
-lex.o: lex.c global.h machine.h \
-  config.h debug.h \
-  port.h language.h array.h \
-  las.h svalue.h \
-  dynamic_buffer.h program.h \
-  lex.h stralloc.h \
-  add_efun.h hashtable.h \
-  stuff.h interpret.h \
-  error.h object.h \
-  operators.h opcodes.h \
-  builtin_efuns.h macros.h
-list.o: list.c global.h \
-  machine.h config.h debug.h \
-  port.h array.h \
-  las.h svalue.h \
-  dynamic_buffer.h program.h \
-  list.h macros.h \
-  error.h interpret.h \
+  builtin_efuns.h \
+  lpc_signal.h
+las.o: las.c \
+  global.h machine.h \
+  config.h \
+  port.h language.h \
+  interpret.h \
+  program.h \
+  las.h \
+  svalue.h \
+  dynamic_buffer.h \
+  array.h \
+  object.h \
+  stralloc.h \
+  lex.h \
+  lpc_types.h \
+  add_efun.h \
+  hashtable.h \
+  mapping.h \
+  list.h \
+  error.h \
+  docode.h \
+  main.h
+lex.o: lex.c \
+  global.h machine.h \
+  config.h \
+  port.h language.h \
+  array.h las.h \
+  svalue.h \
+  dynamic_buffer.h \
+  program.h \
+  lex.h \
+  stralloc.h \
+  add_efun.h \
+  hashtable.h \
+  stuff.h \
+  interpret.h \
+  error.h \
+  object.h \
+  operators.h \
+  opcodes.h \
+  builtin_efuns.h \
+  macros.h
+list.o: list.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  array.h las.h \
+  svalue.h \
+  dynamic_buffer.h \
+  program.h \
+  list.h \
+  macros.h \
+  error.h \
+  interpret.h \
   builtin_efuns.h
 lpc_signal.o: lpc_signal.c \
-  global.h machine.h config.h \
-  debug.h port.h \
-  svalue.h interpret.h \
-  program.h stralloc.h \
-  add_efun.h hashtable.h \
-  las.h dynamic_buffer.h \
-  macros.h backend.h
-lpc_types.o: lpc_types.c global.h \
-  machine.h config.h debug.h \
-  port.h svalue.h \
-  lpc_types.h stralloc.h \
-  stuff.h array.h \
-  las.h dynamic_buffer.h \
-  program.h add_efun.h \
-  hashtable.h object.h \
-  list.h mapping.h \
-  macros.h error.h
-main.o: main.c global.h \
-  machine.h config.h debug.h \
-  port.h backend.h \
-  module.h object.h \
-  svalue.h lex.h \
-  lpc_types.h builtin_efuns.h \
+  global.h machine.h \
+  config.h \
+  port.h \
+  svalue.h \
+  interpret.h \
+  program.h \
+  stralloc.h \
+  add_efun.h \
+  hashtable.h \
+  las.h \
+  dynamic_buffer.h \
+  macros.h \
+  backend.h
+lpc_types.o: lpc_types.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  svalue.h \
+  lpc_types.h \
+  stralloc.h \
+  stuff.h \
+  array.h las.h \
+  dynamic_buffer.h \
+  program.h \
+  add_efun.h \
+  hashtable.h \
+  object.h \
+  list.h \
+  mapping.h \
+  macros.h \
+  error.h
+main.o: main.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  backend.h \
+  module.h \
+  object.h \
+  svalue.h \
+  lex.h \
+  lpc_types.h \
+  builtin_efuns.h \
   array.h las.h \
-  dynamic_buffer.h program.h \
-  stralloc.h interpret.h \
-  error.h macros.h \
-  callback.h lpc_signal.h
-mapping.o: mapping.c global.h \
-  machine.h config.h debug.h \
-  port.h mapping.h \
-  las.h svalue.h \
-  dynamic_buffer.h program.h \
-  array.h macros.h language.h \
-  error.h interpret.h
-memory.o: memory.c global.h \
-  machine.h config.h debug.h \
-  port.h error.h \
+  dynamic_buffer.h \
+  program.h \
+  stralloc.h \
+  interpret.h \
+  error.h \
+  macros.h \
+  callback.h \
+  lpc_signal.h
+mapping.o: mapping.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  mapping.h \
+  las.h \
+  svalue.h \
+  dynamic_buffer.h \
+  program.h \
+  array.h \
+  macros.h language.h \
+  error.h \
+  interpret.h
+memory.o: memory.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  error.h \
   svalue.h
-module.o: module.c module.h \
-  types.h machine.h macros.h \
-  memory.h error.h \
+module.o: module.c \
+  module.h \
+  types.h machine.h \
+  macros.h \
+  memory.h \
+  error.h \
   svalue.h modlist.h
-object.o: object.c global.h \
-  machine.h config.h debug.h \
-  port.h object.h \
-  svalue.h dynamic_buffer.h \
-  interpret.h program.h \
-  stralloc.h macros.h \
-  error.h main.h
-opcodes.o: opcodes.c global.h \
-  machine.h config.h debug.h \
-  port.h interpret.h \
-  program.h svalue.h \
+object.o: object.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  object.h \
+  svalue.h \
+  dynamic_buffer.h \
+  interpret.h \
+  program.h \
+  stralloc.h \
+  macros.h \
+  error.h \
+  main.h \
+  array.h las.h \
+  gc.h
+opcodes.o: opcodes.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  interpret.h \
+  program.h \
+  svalue.h \
   array.h las.h \
-  dynamic_buffer.h stralloc.h \
-  mapping.h list.h \
-  opcodes.h object.h \
-  error.h lpc_types.h
-operators.o: operators.c global.h \
-  machine.h config.h debug.h \
-  port.h interpret.h \
-  program.h svalue.h \
+  dynamic_buffer.h \
+  stralloc.h \
+  mapping.h \
+  list.h \
+  opcodes.h \
+  object.h \
+  error.h \
+  lpc_types.h
+operators.o: operators.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  interpret.h \
+  program.h \
+  svalue.h \
   list.h las.h \
-  dynamic_buffer.h mapping.h \
-  array.h stralloc.h \
-  opcodes.h operators.h \
-  language.h error.h
-port.o: port.c global.h \
-  machine.h config.h debug.h \
-  port.h macros.h
-program.o: program.c global.h \
-  machine.h config.h debug.h \
-  port.h program.h \
-  object.h svalue.h \
-  dynamic_buffer.h lpc_types.h \
-  stralloc.h las.h language.h \
-  lex.h macros.h \
-  fsort.h error.h \
-  docode.h interpret.h \
-  hashtable.h compilation.h
-rusage.o: rusage.c global.h \
-  machine.h config.h debug.h \
-  port.h rusage.h
-stralloc.o: stralloc.c global.h \
-  machine.h config.h debug.h \
-  port.h stralloc.h \
-  macros.h dynamic_buffer.h \
-  error.h svalue.h
-stuff.o: stuff.c stuff.h \
+  dynamic_buffer.h \
+  mapping.h \
+  array.h \
+  stralloc.h \
+  opcodes.h \
+  operators.h language.h \
+  error.h \
+  docode.h \
+  add_efun.h \
+  hashtable.h
+port.o: port.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  macros.h
+program.o: program.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  program.h \
+  object.h \
+  svalue.h \
+  dynamic_buffer.h \
+  lpc_types.h \
+  stralloc.h \
+  las.h language.h \
+  lex.h \
+  macros.h \
+  fsort.h \
+  error.h \
+  docode.h \
+  interpret.h \
+  hashtable.h \
+  main.h gc.h \
+  compilation.h
+rusage.o: rusage.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  rusage.h
+stralloc.o: stralloc.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  stralloc.h \
+  macros.h \
+  dynamic_buffer.h \
+  error.h \
+  svalue.h
+stuff.o: stuff.c \
+  stuff.h \
   types.h machine.h
-svalue.o: svalue.c global.h \
-  machine.h config.h debug.h \
-  port.h svalue.h \
-  stralloc.h array.h \
-  las.h dynamic_buffer.h \
-  program.h mapping.h \
-  list.h object.h \
-  add_efun.h hashtable.h \
+svalue.o: svalue.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  svalue.h \
+  stralloc.h \
+  array.h las.h \
+  dynamic_buffer.h \
+  program.h \
+  mapping.h \
+  list.h \
+  object.h \
+  add_efun.h \
+  hashtable.h \
   error.h
 ualarm.o: ualarm.c
diff --git a/src/array.c b/src/array.c
index e2e2a86592..2697bdeb8b 100644
--- a/src/array.c
+++ b/src/array.c
@@ -16,6 +16,7 @@
 #include "fsort.h"
 #include "builtin_efuns.h"
 #include "memory.h"
+#include "gc.h"
 
 struct array empty_array=
 {
@@ -46,10 +47,13 @@ struct array *allocate_array_no_init(INT32 size,INT32 extra_space)
     return &empty_array;
   }
 
+  GC_ALLOC();
+
   v=(struct array *)malloc(sizeof(struct array)+
 			   (size+extra_space-1)*sizeof(struct svalue));
   if(!v)
     error("Couldn't allocate array, out of memory.\n");
+  
 
   /* for now, we don't know what will go in here */
   v->type_field=BIT_MIXED;
@@ -94,6 +98,8 @@ static void array_free_no_free(struct array *v)
   v->next->prev=prev;
 
   free((char *)v);
+
+  GC_FREE();
 }
 
 /*
@@ -1245,138 +1251,111 @@ void array_replace(struct array *a,
   while((i=array_search(a,from,i+1)) >= 0) array_set_index(a,i,to);
 }
 
-#ifdef GC
-
-void array_gc_clear_mark()
-{
-  struct array *a;
-  a=&empty_array;
-  do
-  {
-    a->flags &=~ ARRAY_FLAG_MARK;
-    check_array(a, pass);
-
-    a=a->next;
-
 #ifdef DEBUG
-    if(!a) fatal("Null pointer in array list.\n");
-#endif
-  } while (a != & empty_array);
-}
-
-void array_gc_mark(struct array *a)
+void check_array(struct array *a)
 {
   INT32 e;
-  if(a->flags & ARRAY_FLAG_MARK) return;
-  a->flags |= ARRAY_FLAG_MARK;
 
-  if(!(a->type_field & ~(BIT_STRING|BIT_INT|BIT_FLOAT)))
-    return 0;
+  if(a->next->prev != a)
+    fatal("Array check: a->next->prev != a\n");
 
-  for(e=0;e<a->size;e++) svalue_gc_sweep(ITEM(a) + e);
-}
+  if(a->size > a->malloced_size)
+    fatal("Array is larger than malloced block!\n");
 
-void array_gc_sweep()
-{
-  struct array *a, *next;
+  if(a->refs <=0 )
+    fatal("Array has zero refs.\n");
 
-  a=&empty_array;
-  do
+  for(e=0;e<a->size;e++)
   {
-    a->refs++;
-
-    if(!(a->flags & ARRAY_FLAG_MARK))
-    {
-      free_svalues(ITEM(a), a->size, a->type_field);
-      a->size=0; /* Don't free them again */
-    }
+    if(! ( (1 << ITEM(a)[e].type) & (a->type_field) ))
+      fatal("Type field lies.\n");
     
-    next=a->next;
-    free_array(a);
-
-    a=next;
-#ifdef DEBUG
-    if(!a) fatal("Null pointer in array list.\n");
-#endif
-  } while (a != & empty_array);
+    check_svalue(ITEM(a)+e);
+  }
 }
 
-
-#ifdef DEBUG
-void array_gc_sweep2()
+void check_all_arrays()
 {
   struct array *a;
-  if(!d_flag) return;
 
   a=&empty_array;
   do
   {
-    if(!(a->flags & ARRAY_FLAG_MARK))
-      fatal("Array ref count incorrect!\n");
+    check_array(a);
 
-    a=a->next
-    
-#ifdef DEBUG
-    if(!a) fatal("Null pointer in array list.\n");
-#endif
+    a=a->next;
+    if(!a)
+      fatal("Null pointer in array list.\n");
   } while (a != & empty_array);
 }
 #endif /* DEBUG */
-#endif /* GC */
 
+#ifdef GC2
 
-#ifdef DEBUG
-void check_array(struct array *a, int pass)
+void gc_check_array(struct array *a)
 {
-  INT32 e;
-  if(pass)
-  {
-    e=checked((void *)a,0);
-    if(e!=a->refs)
-    {
-      simple_describe_array(a);
-      fatal("Above array has wrong number of references. (%ld != %ld)\n",
-	    (long)e,(long)a->refs);
-    }
-    return;
-  }
-
-  if(a->next->prev != a)
-    fatal("Array check: a->next->prev != a\n");
+  if(a == gc_ptr) gc_refs++;
+  if(a->flags & GC_MARK) return;
+  a->flags |= GC_MARK;
+  if(!(a->type_field & BIT_COMPLEX)) return;
+  gc_check_svalues(ITEM(a), a->size);
+}
 
-  if(a->size > a->malloced_size)
-    fatal("Array is larger than malloced block!\n");
 
-  if(a->refs <=0 )
-    fatal("Array has zero refs.\n");
+void gc_check_all_arrays()
+{
+  struct array *a,*n;
 
-  for(e=0;e<a->size;e++)
+  a=&empty_array;
+  do
   {
-    if(! ( (1 << ITEM(a)[e].type) & (a->type_field) ))
-      fatal("Type field lies.\n");
-    
-    check_svalue(ITEM(a)+e);
-  }
+    if(!(a->flags & GC_MARK) && a->type_field & BIT_COMPLEX)
+    {
+      gc_ptr=a;
+      gc_refs=0;
+      
+      gc_check_array(a);
+      
+      a->refs++;
+      
+      if(gc_refs == a->refs)
+      {
+	/* This structure contains as many references to itself as
+	 * it has referenes, which means that it is circular and
+	 * should be destroyed, so please go away.
+	 */
+	
+	free_svalues(ITEM(a), a->size, a->type_field);
+	
+	a->size=0;
+	
+      }
+      
+      if(!(n=a->next))
+	fatal("Null pointer in array list.\n");
+      
+      free_array(a);
+      a=n;
+    }else{
+      a=a->next;
+    }
+  } while (a != & empty_array);
 }
 
-void check_all_arrays(int pass)
+void gc_clear_array_marks()
 {
   struct array *a;
 
   a=&empty_array;
   do
   {
-    check_array(a, pass);
-
+    a->flags &=~ GC_MARK;
     a=a->next;
-    if(!a)
-      fatal("Null pointer in array list.\n");
-  } while (a != & empty_array);
 
-  if(!pass)
-  {
-    checked((void *)&empty_array,1);
-  }
+  } while (a != & empty_array);
 }
-#endif /* DEBUG */
+
+
+
+#endif /* GC2 */
 
diff --git a/src/array.h b/src/array.h
index 34f74e4baa..758fc6cbad 100644
--- a/src/array.h
+++ b/src/array.h
@@ -117,12 +117,11 @@ struct array *reverse_array(struct array *a);
 void array_replace(struct array *a,
 		   struct svalue *from,
 		   struct svalue *to);
-void array_gc_clear_mark();
-void array_gc_mark(struct array *a);
-void array_gc_sweep();
-void array_gc_sweep2();
-void check_array(struct array *a, int pass);
-void check_all_arrays(int pass);
+void check_array(struct array *a);
+void check_all_arrays();
+void gc_check_array(struct array *a);
+void gc_check_all_arrays();
+void gc_clear_array_marks();
 /* Prototypes end here */
 
 
diff --git a/src/backend.c b/src/backend.c
index f3a47a4d03..f8cb88b7af 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -157,40 +157,22 @@ void *query_write_callback_data(int fd)
 }
 
 #ifdef DEBUG
-void do_debug(int check_refs)
+void do_debug()
 {
-  extern void check_all_arrays(int);
-  extern void check_all_mappings(int);
-  extern void check_all_programs(int);
-  extern void check_all_objects(int);
-  extern void verify_shared_strings_tables(int);
-  extern void slow_check_stack(int);
-
-#if 0
-  if(d_flag>1)
-    init_checked();
-#endif
-
-  slow_check_stack(0);
-  check_all_arrays(0);
-  check_all_mappings(0);
-  check_all_programs(0);
-  verify_all_objects(0);
-  verify_shared_strings_tables(0);
+  extern void check_all_arrays();
+  extern void check_all_mappings();
+  extern void check_all_programs();
+  extern void check_all_objects();
+  extern void verify_shared_strings_tables();
+  extern void slow_check_stack();
+
+  slow_check_stack();
+  check_all_arrays();
+  check_all_mappings();
+  check_all_programs();
+  verify_all_objects();
+  verify_shared_strings_tables();
   verify_all_call_outs();
-
-#if 0
-  if(d_flag>1)
-  {
-    check_all_arrays(1);
-    check_all_mappings(1);
-    check_all_programs(1);
-    verify_all_objects(1);
-    verify_shared_strings_tables(1);
-    exit_checked();
-  }
-#endif
-
 }
 #endif
 
@@ -263,7 +245,7 @@ void backend()
     alloca(0);			/* Do garbage collect */
 #ifdef DEBUG
     if(d_flag > 1)
-      do_debug(1);
+      do_debug();
 #endif
   }
 
diff --git a/src/backend.h b/src/backend.h
index b69daeb74c..a80179d81d 100644
--- a/src/backend.h
+++ b/src/backend.h
@@ -26,7 +26,7 @@ callback query_read_callback(int fd);
 callback query_write_callback(int fd);
 void *query_read_callback_data(int fd);
 void *query_write_callback_data(int fd);
-void do_debug(int check_refs);
+void do_debug();
 void backend();
 int write_to_stderr(char *a, INT32 len);
 /* Prototypes end here */
diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index aa094a6853..e5428f0b44 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -22,6 +22,7 @@
 #include "fsort.h"
 #include "call_out.h"
 #include "callback.h"
+#include "gc.h"
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
@@ -1210,6 +1211,15 @@ void f_sleep(INT32 args)
   }
 }
 
+void f_gc(INT32 args)
+{
+  INT32 tmp;
+  pop_n_elems(args);
+  tmp=num_objects;
+  do_gc();
+  push_int(tmp - num_objects);
+}
+
 #ifdef TYPEP
 #undef TYPEP
 #endif
@@ -1296,6 +1306,7 @@ void init_builtin_efuns()
   add_efun("upper_case",f_upper_case,"function(string:string)",0);
   add_efun("values",f_values,"function(string|list:int*)|function(array|mapping|object:mixed*)",0);
   add_efun("zero_type",f_zero_type,"function(int:int)",0);
+  add_efun("gc",f_gc,"function(:int)",OPT_SIDE_EFFECT);
 }
 
 
diff --git a/src/call_out.c b/src/call_out.c
index cfda6cc071..f596c0ce30 100644
--- a/src/call_out.c
+++ b/src/call_out.c
@@ -308,12 +308,6 @@ time_t get_next_call_out()
 #ifdef DEBUG
 void verify_all_call_outs()
 {
-  int e;
   verify_call_outs();
-  for(e=0;e<num_pending_calls;e++)
-  {
-    checked((void *)pending_calls[e]->caller,1);
-    checked((void *)pending_calls[e]->args,1);
-  }
 }
 #endif
diff --git a/src/config.h b/src/config.h
index fcb99f4b9a..d905a755de 100644
--- a/src/config.h
+++ b/src/config.h
@@ -32,6 +32,11 @@
  * Define the size of the cache that is used for method lookup.
  */
 #define FIND_FUNCTION_HASHSIZE 4711
+
+/*
+ * Undefine this to disable garabge collection
+ */
+#define GC2
    
 
 /*
diff --git a/src/debug.c b/src/debug.c
deleted file mode 100644
index c11c55f082..0000000000
--- a/src/debug.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*\
-||| This file a part of uLPC, and is copyright by Fredrik Hubinette
-||| uLPC is distributed as GPL (General Public License)
-||| See the files COPYING and DISCLAIMER for more information.
-\*/
-#include "global.h"
-#include "types.h"
-#include "memory.h"
-
-#define MARKER_CHUNK_SIZE 4096
-#define REHASH_LIMIT 16
-#define REHASH_FORMULA(X) ((X)*4-1)
-
-struct marker
-{
-  struct marker *next;
-  void *marked;
-  INT32 refs;
-};
-
-struct marker_chunk
-{
-  struct marker_chunk *next;
-  struct marker markers[MARKER_CHUNK_SIZE];
-};
-
-static struct marker_chunk *chunk=0;
-static int markers_left_in_chunk=0;
-
-static struct marker *new_marker()
-{
-  if(!markers_left_in_chunk)
-  {
-    struct marker_chunk *m;
-    m=(struct marker_chunk *)xalloc(sizeof(struct marker_chunk));
-    m->next=chunk;
-    chunk=m;
-    markers_left_in_chunk=MARKER_CHUNK_SIZE;
-  }
-  markers_left_in_chunk--;
-
-  return chunk->markers + markers_left_in_chunk;
-}
-
-static struct marker **hash=0;
-static int hashsize=0;
-static int hashed=0;
-
-INT32 checked(void *a,INT32 delta)
-{
-  int hashval;
-  struct marker *m;
-
-  if(!hash) return 0;
-
-  hashval=((long)a)%hashsize;
-
-  for(m=hash[hashval];m;m=m->next)
-  {
-    if(m->marked == a)
-    {
-      m->refs+=delta;
-      return m->refs;
-    }
-  }
-  if(!delta) return 0;
-
-  m=new_marker();
-  m->marked=a;
-  m->next=hash[hashval];
-  m->refs=delta;
-  hash[hashval]=m;
-
-  hashed++;
-  if(hashed / REHASH_LIMIT > hashsize)
-  {
-    struct marker **new_hash,*next;
-    int new_hashsize;
-    int e;
-
-    new_hashsize=REHASH_FORMULA(hashsize);
-    new_hash=(struct marker **)xalloc(sizeof(struct marker **)*new_hashsize);
-    memset((char *)new_hash,0,sizeof(struct marker **)*new_hashsize);
-
-    for(e=0;e<hashsize;e++)
-    {
-      for(m=hash[e];m;m=next)
-      {
-	next=m->next;
-	m->next=new_hash[((long)m->marked)%new_hashsize];
-	new_hash[((long)m->marked)%new_hashsize]=m;
-      }
-    }
-
-    free((char *)hash);
-    hash=new_hash;
-    hashsize=new_hashsize;
-  }
-
-  return m->refs;
-}
-
-void init_checked()
-{
-  /* init hash*/
-  hashsize=4711;
-  hashed=0;
-  hash=(struct marker **)xalloc(sizeof(struct marker **)*hashsize);
-  memset((char *)hash,0,sizeof(struct marker **)*hashsize);
-  markers_left_in_chunk=0;
-}
-
-void exit_checked()
-{
-  struct marker_chunk *m;
-
-  if(!hash) return;
-  free((char *)hash);
-  while(m=chunk)
-  {
-    chunk=m->next;
-    free((char *)m);
-  }
-  hash=0;
-}
diff --git a/src/debug.h b/src/debug.h
deleted file mode 100644
index 7e482708e7..0000000000
--- a/src/debug.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*\
-||| This file a part of uLPC, and is copyright by Fredrik Hubinette
-||| uLPC is distributed as GPL (General Public License)
-||| See the files COPYING and DISCLAIMER for more information.
-\*/
-#ifndef DEBUG_H
-#define DEBUG_H
-
-#include "types.h"
-
-/* Prototypes begin here */
-struct marker;
-struct marker_chunk;
-INT32 checked(void *a,INT32 delta);
-void init_checked();
-void exit_checked();
-/* Prototypes end here */
-
-#endif
diff --git a/src/global.h b/src/global.h
index 7eca62d6c8..e8be108dbf 100644
--- a/src/global.h
+++ b/src/global.h
@@ -66,10 +66,6 @@ char *alloca ();
 #include <memory.h>
 #endif
 
-#ifdef DEBUG
-#include "debug.h"
-#endif
-
 #if defined(__GNUC__) && !defined(DEBUG) && !defined(lint)
 #define INLINE inline
 #else
diff --git a/src/mapping.c b/src/mapping.c
index de252f7fbf..b23d2bdff5 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -411,15 +411,8 @@ void mapping_search_no_free(struct svalue *to,
 
 #ifdef DEBUG
 
-void check_mapping(struct mapping *m,int pass)
+void check_mapping(struct mapping *m)
 {
-  if(pass)
-  {
-    if(checked((void *)m,0) != m->refs)
-      fatal("Mapping has wrong number of refs.\n");
-    return;
-  }
-
   if(m->refs <=0)
     fatal("Mapping has zero refs.\n");
 
@@ -434,17 +427,12 @@ void check_mapping(struct mapping *m,int pass)
     if(first_mapping != m)
       fatal("Mapping ->prev == 0 but first_mapping != mapping.\n");
   }
-  checked((void *)m->ind,1);
-  checked((void *)m->val,1);
 }
 
-void check_all_mappings(int pass)
+void check_all_mappings()
 {
   struct mapping *m;
   for(m=first_mapping;m;m=m->next)
-    check_mapping(m,pass);
-
-  if(!pass)
-    checked((void *)first_mapping,1);
+    check_mapping(m);
 }
 #endif
diff --git a/src/mapping.h b/src/mapping.h
index 9a9132cb14..8eb88ae873 100644
--- a/src/mapping.h
+++ b/src/mapping.h
@@ -53,5 +53,7 @@ void mapping_search_no_free(struct svalue *to,
 			    struct mapping *m,
 			    struct svalue *look_for,
 			    struct svalue *start);
+void check_mapping(struct mapping *m);
+void check_all_mappings();
 /* Prototypes end here */
 #endif
diff --git a/src/modules/efuns.c b/src/modules/efuns.c
deleted file mode 100644
index 16fb213bb3..0000000000
--- a/src/modules/efuns.c
+++ /dev/null
@@ -1,47 +0,0 @@
-
-/* function *get_function_list(object); */
-void f_get_function_list(int num_arg,struct svalue *argp)
-{
-  int e;
-  int funs;
-  struct program *p;
-  struct vector *v;
-  struct object *o;
-  o=argp[0].u.ob;
-
-  p=o->prog;
-  for(funs=e=0;e<p->num_funindex;e++)
-    if(!(p->function_ptrs[e].type & TYPE_MOD_STATIC))
-      funs++;
-
-  v=allocate_array_no_init(funs,0);
-  funs=0;
-
-  for(e=0;e<p->num_funindex;e++)
-  {
-    if(!(p->function_ptrs[e].type & TYPE_MOD_STATIC))
-    {
-      v->item[funs].type=T_FUNCTION;
-      v->item[funs].u.ob=o;
-      v->item[funs].subtype=e;
-      add_ref(o,"get_function_list");
-      funs++;
-    }
-  }
-  v->types=BIT_FUNCTION;
-  free_svalue(argp);
-  argp->type=T_ARRAY;
-  argp->u.vec=v;
-}
-
-/* int function_args(function); */
-void f_function_args(int num_arg,struct svalue *argp)
-{
-  int i;
-  i=FUNC(argp[0].u.ob->prog,argp[0].subtype)->num_arg;
-  free_svalue(argp);
-  argp->type=T_INT;
-  argp->subtype=0;
-  argp->u.number=i;
-}
-
diff --git a/src/modules/files/Makefile.in b/src/modules/files/Makefile.in
index cee0d45584..9df921c43f 100644
--- a/src/modules/files/Makefile.in
+++ b/src/modules/files/Makefile.in
@@ -21,9 +21,9 @@ depend:
 #Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
 datagram.o: datagram.c
 efuns.o: efuns.c \
-  global.h machine.h \
+  global.h \
+  machine.h \
   config.h \
-  debug.h \
   port.h \
   interpret.h \
   program.h \
@@ -34,11 +34,12 @@ efuns.o: efuns.c \
   dynamic_buffer.h \
   mapping.h \
   macros.h \
-  fd_control.h file_machine.h
+  fd_control.h \
+  file_machine.h
 file.o: file.c \
-  global.h machine.h \
+  global.h \
+  machine.h \
   config.h \
-  debug.h \
   port.h \
   interpret.h \
   program.h \
@@ -50,14 +51,14 @@ file.o: file.c \
   object.h \
   macros.h \
   backend.h \
-  fd_control.h file_machine.h \
-  file.h \
+  fd_control.h \
+  file_machine.h file.h \
   error.h \
   lpc_signal.h
 socket.o: socket.c \
-  global.h machine.h \
+  global.h \
+  machine.h \
   config.h \
-  debug.h \
   port.h \
   interpret.h \
   program.h \
@@ -69,5 +70,5 @@ socket.o: socket.c \
   object.h \
   macros.h \
   backend.h \
-  fd_control.h file_machine.h \
-  file.h
+  fd_control.h \
+  file_machine.h file.h
diff --git a/src/modules/regexp/Makefile.in b/src/modules/regexp/Makefile.in
index d2bc317acd..f3a73a2b6c 100644
--- a/src/modules/regexp/Makefile.in
+++ b/src/modules/regexp/Makefile.in
@@ -19,9 +19,9 @@ depend:
 
 #Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
 glue.o: glue.c \
-  global.h machine.h \
+  global.h \
+  machine.h \
   config.h \
-  debug.h \
   port.h \
   interpret.h \
   program.h \
@@ -33,9 +33,9 @@ glue.o: glue.c \
   object.h \
   macros.h
 regexp.o: regexp.c \
-  global.h machine.h \
+  global.h \
+  machine.h \
   config.h \
-  debug.h \
   port.h \
   regexp.h \
   error.h \
diff --git a/src/modules/sprintf/Makefile.in b/src/modules/sprintf/Makefile.in
index 5ace6c5549..56de303c76 100644
--- a/src/modules/sprintf/Makefile.in
+++ b/src/modules/sprintf/Makefile.in
@@ -19,9 +19,9 @@ depend:
 
 #Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
 sprintf.o: sprintf.c \
-  global.h machine.h \
+  global.h \
+  machine.h \
   config.h \
-  debug.h \
   port.h \
   error.h \
   svalue.h \
diff --git a/src/object.c b/src/object.c
index 7f24245964..9d6e0ff087 100644
--- a/src/object.c
+++ b/src/object.c
@@ -15,6 +15,7 @@
 #include "error.h"
 #include "main.h"
 #include "array.h"
+#include "gc.h"
 
 struct object *master_object = 0;
 struct object *first_object;
@@ -34,6 +35,8 @@ struct object *clone(struct program *p, int args)
   struct object *o;
   struct frame frame;
 
+  GC_ALLOC();
+
   o=(struct object *)xalloc(sizeof(struct object)-1+p->storage_needed);
 
   o->prog=p;
@@ -231,6 +234,8 @@ void really_free_object(struct object *o)
   if(o->next) o->next->prev=o->prev;
   
   free((char *)o);
+
+  GC_FREE();
 }
 
 void object_index_no_free(struct svalue *to,
@@ -463,22 +468,13 @@ union anything *object_get_item_ptr(struct object *o,
 }
 
 #ifdef DEBUG
-void verify_all_objects(int pass)
+void verify_all_objects()
 {
   struct object *o;
   struct frame frame;
 
   for(o=first_object;o;o=o->next)
   {
-    if(pass)
-    {
-      if(checked((void *)o, 0) != o->refs)
-      {
-	fatal("Object has wrong number of refs.\n");
-      }
-      continue;
-    }
-
     if(o->next && o->next->prev !=o)
       fatal("Object check: o->next->prev != o\n");
 
@@ -537,9 +533,6 @@ void verify_all_objects(int pass)
 	frame.context=o->prog->inherits[e];
 	frame.context.prog->refs++;
 	frame.current_storage=o->storage+frame.context.storage_offset;
-
-	if(frame.context.prog->checkrefs)
-	  frame.context.prog->checkrefs(frame.current_storage,o,pass);
       }
 
       free_object(frame.current_object);
@@ -647,19 +640,14 @@ struct array *object_values(struct object *o)
   return a;
 }
 
-#ifdef GC
-void object_gc_clear_mark()
-{
-  struct object *o;
-  for(o=first_object;o;o=o->next)
-    o->flags &=~ OBJECT_FLAG_MARK;
-}
+#ifdef GC2
 
-void object_gc_mark(struct object *o)
+void gc_check_object(struct object *o)
 {
   INT32 e;
-  if(o->flags & OBJECT_FLAG_MARK) return;
-  a->flags |= OBJECT_FLAG_MARK;
+  if(o == gc_ptr) gc_refs++;
+  if(o->flags & GC_MARK) return;
+  o->flags |= GC_MARK;
 
   if(!o->prog) return;
 
@@ -673,36 +661,41 @@ void object_gc_mark(struct object *o)
 
     if(i->run_time_type == T_MIXED)
     {
-      svalue_gc_sweep((struct svalue *)LOW_GET_GLOBAL(o,e,i));
+      gc_check_svalues((struct svalue *)LOW_GET_GLOBAL(o,e,i),1);
     }else{
-      short_svalue_gc_sweep((struct svalue *)LOW_GET_GLOBAL(o,e,i),
+      gc_check_short_svalue((struct svalue *)LOW_GET_GLOBAL(o,e,i),
 			    i->run_time_type);
     }
   }
 }
 
-void object_gc_sweep()
+void gc_check_all_objects()
 {
   struct object *o, *next;
   for(o=first_object;o;o=next)
   {
-    o->refs++;
-    if(!(o->flags & OBJECT_FLAG_MARK)) destruct(o);
-    next=o->next;
-    free_object(o);
+    if(!(o->flags & GC_MARK))
+    {
+      gc_ptr=o;
+      gc_refs=0;
+      
+      o->refs++;
+      
+      if(gc_refs == o->refs) destruct(o);
+      
+      next=o->next;
+      free_object(o);
+    }else{
+      next=o->next;
+    }
   }
 }
 
-#ifdef DEBUG
-void object_gc_sweep2()
+void gc_clear_object_marks()
 {
   struct object *o;
-  if(!d_flag) return;
 
-
-  for(o=first_object;o;o=o->next)
-    if(!(o->flags & OBJECT_FLAG_MARK)) 
-      fatal("Object ref count incorrect.\n");
+  for(o=first_object;o;o=o->next) o->flags &=~ GC_MARK;
 }
-#endif /* DEBUG */
-#endif /* GC */
+
+#endif /* GC2 */
diff --git a/src/object.h b/src/object.h
index 8d67f15dd0..32608e56ed 100644
--- a/src/object.h
+++ b/src/object.h
@@ -14,7 +14,9 @@
 struct object
 {
   INT32 refs;                    /* Reference count, must be first. */
+#ifdef GC2
   INT16 flags;
+#endif
   struct program *prog;
   struct object *next;
   struct object *prev;
@@ -55,11 +57,14 @@ union anything *object_low_get_item_ptr(struct object *o,
 union anything *object_get_item_ptr(struct object *o,
 				    struct svalue *index,
 				    TYPE_T type);
-void verify_all_objects(int pass);
+void verify_all_objects();
 int object_equal_p(struct object *a, struct object *b, struct processing *p);
 void cleanup_objects();
 struct array *object_indices(struct object *o);
 struct array *object_values(struct object *o);
+void gc_check_object(struct object *o);
+void gc_check_all_objects();
+void gc_clear_object_marks();
 /* Prototypes end here */
 
 #endif /* OBJECT_H */
diff --git a/src/program.c b/src/program.c
index 274f1e34a3..85de0f4f96 100644
--- a/src/program.c
+++ b/src/program.c
@@ -19,6 +19,7 @@
 #include "interpret.h"
 #include "hashtable.h"
 #include "main.h"
+#include "gc.h"
 #include <stdio.h>
 #include <fcntl.h>
 
@@ -156,6 +157,8 @@ void really_free_program(struct program *p)
     p->next->prev=p->prev;
 
   free((char *)p);
+
+  GC_FREE();
 }
 
 #ifdef DEBUG
@@ -214,19 +217,11 @@ void toss_current_program()
 }
 
 #ifdef DEBUG
-void check_program(struct program *p, int pass)
+void check_program(struct program *p)
 {
   INT32 size,e;
   unsigned INT32 checksum;
 
-  if(pass)
-  {
-    if(checked((void *)p,0) != p->refs)
-      fatal("Program has wrong number of references.\n");
-
-    return;
-  }
-
   if(p->refs <=0)
     fatal("Program has zero refs.\n");
 
@@ -333,10 +328,7 @@ void check_program(struct program *p, int pass)
   {
     if(p->inherits[e].storage_offset < 0)
       fatal("Inherit->storage_offset is wrong.\n");
-
-    checked((void *)p->inherits[e].prog,1);
   }
-  checked((void *)p,-1); /* One too many were added above */
 }
 #endif
 
@@ -466,7 +458,7 @@ struct program *end_program()
     first_program=prog;
 
 #ifdef DEBUG
-    check_program(prog,0);
+    check_program(prog);
     if(l_flag)
       dump_program_desc(prog);
 #endif
@@ -1190,12 +1182,15 @@ struct program *compile_file(struct lpc_string *file_name)
 {
   int fd;
   struct program *p;
-  
+
   fd=open(file_name->str,O_RDONLY);
   if(fd < 0)
     error("Couldn't open file '%s'.\n",file_name->str);
 
 
+  GC_ALLOC();
+  
+
 #define FILE_STATE
 #define PUSH
 #include "compilation.h"
@@ -1226,6 +1221,8 @@ struct program *compile_string(struct lpc_string *prog,
 #include "compilation.h"
 #undef PUSH
 
+  GC_ALLOC();
+
   start_new_string(prog->str,prog->len,name);
   start_new_program();
   compile();
@@ -1281,23 +1278,11 @@ void add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags)
 }
 
 #ifdef DEBUG
-void check_all_programs(int pass)
+void check_all_programs()
 {
   struct program *p;
   for(p=first_program;p;p=p->next)
-    check_program(p,pass);
-
-#ifdef FIND_FUNCTION_HASHSIZE
-  if(!pass)
-  {
-    int e;
-    for(e=0;e<FIND_FUNCTION_HASHSIZE;e++)
-    {
-      if(cache[e].name)
-	checked((void *)cache[e].name,1);
-    }
-  }
-#endif
+    check_program(p);
 }
 #endif
 
@@ -1315,3 +1300,47 @@ void cleanup_program()
   }
 #endif
 }
+
+#ifdef GC2
+
+void gc_check_program(struct program *p)
+{
+  if(p==gc_ptr) gc_refs++;
+  if(p->flags & GC_MARK) return;
+  p->flags |= GC_MARK;
+  gc_check_svalues(p->constants, p->num_constants);
+}
+
+void gc_check_all_programs()
+{
+  struct program *p, *next;
+  for(p=first_program;p;p=next)
+  {
+    if(!(p->flags & GC_MARK))
+    {
+      gc_ptr=p;
+      gc_refs=0;
+
+      gc_check_program(p);
+      
+      p->refs++;
+      
+      if(gc_refs == p->refs)
+	free_svalues(p->constants, p->num_constants, -1);
+      
+      next=p->next;
+      free_program(p);
+    }else{
+      next=p->next;
+    }
+  }
+}
+
+void gc_clear_program_marks()
+{
+  struct program *p;
+
+  for(p=first_program;p;p=p->next) p->flags &=~ GC_MARK;
+}
+
+#endif /* GC2 */
diff --git a/src/program.h b/src/program.h
index 0204f52548..fe1c265aab 100644
--- a/src/program.h
+++ b/src/program.h
@@ -111,7 +111,6 @@ struct program
   void (*init)(char *,struct object *);
   void (*exit)(char *,struct object *);
 #ifdef DEBUG
-  void (*checkrefs)(char *,struct object *,int pass);
   unsigned INT32 checksum;
 #endif
 
@@ -145,7 +144,7 @@ void start_new_program();
 void really_free_program(struct program *p);
 void dump_program_desc(struct program *p);
 void toss_current_program();
-void check_program(struct program *p, int pass);
+void check_program(struct program *p);
 struct program *end_program();
 SIZE_T add_storage(SIZE_T size);
 void set_init_callback(void (*init)(char *,struct object *));
@@ -181,8 +180,11 @@ struct program *compile_string(struct lpc_string *prog,
 			       struct lpc_string *name);
 struct program *end_c_program(char *name);
 void add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags);
-void check_all_programs(int pass);
+void check_all_programs();
 void cleanup_program();
+void gc_check_program(struct program *p);
+void gc_check_all_programs();
+void gc_clear_program_marks();
 /* Prototypes end here */
 
 
diff --git a/src/stralloc.c b/src/stralloc.c
index c915693f90..8c3d1317c5 100644
--- a/src/stralloc.c
+++ b/src/stralloc.c
@@ -30,11 +30,9 @@ void check_string(struct lpc_string *s)
 
   if(s->str[s->len])
     fatal("Shared string is not zero terminated properly.\n");
-
-  checked((void *)s,1);
 }
 
-void verify_shared_strings_tables(int pass)
+void verify_shared_strings_tables()
 {
   unsigned int e, h;
   struct lpc_string *s;
@@ -44,14 +42,6 @@ void verify_shared_strings_tables(int pass)
     h=0;
     for(s=base_table[e];s;s=s->next)
     {
-      if(pass)
-      {
-	if(checked((void *)s,0)!=s->refs)
-	{
-	  fatal("Shared string has wrong number of refs '%s'.\n",s->str);
-	}
-	continue;
-      }
       h++;
       if(s->len < 0)
 	fatal("Shared string shorter than zero bytes.\n");
diff --git a/src/stralloc.h b/src/stralloc.h
index a2b6261935..7da0aa5e98 100644
--- a/src/stralloc.h
+++ b/src/stralloc.h
@@ -33,7 +33,7 @@ struct lpc_string *debug_findstring(const struct lpc_string *foo);
 
 /* Prototypes begin here */
 void check_string(struct lpc_string *s);
-void verify_shared_strings_tables(int pass);
+void verify_shared_strings_tables();
 struct lpc_string *findstring(const char *foo);
 struct lpc_string *debug_findstring(const struct lpc_string *foo);
 struct lpc_string *begin_shared_string(int len);
diff --git a/src/svalue.c b/src/svalue.c
index 04af973f0b..612ab00302 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -639,11 +639,6 @@ void check_short_svalue(union anything *u,TYPE_T type)
   check_refs2(u,type);
   if(!u->refs) return;
 
-  if(type <= MAX_REF_TYPE)
-  {
-    checked((void *) u->refs,1);
-  }
-
   switch(type)
   {
   case T_STRING:
@@ -660,3 +655,56 @@ void check_svalue(struct svalue *s)
 }
 
 #endif
+
+#ifdef GC2
+void gc_check_svalues(struct svalue *s, int num)
+{
+  INT32 e;
+  for(e=0;e<num;e++,s++)
+  {
+    switch(s->type)
+    {
+    case T_ARRAY: gc_check_array(s->u.array); break;
+    case T_LIST:
+      gc_check_array(s->u.list->ind);
+      break;
+    case T_MAPPING:
+      gc_check_array(s->u.mapping->ind);
+      gc_check_array(s->u.mapping->val);
+      break;
+    case T_OBJECT:
+      if(s->u.object->prog)
+      {
+	gc_check_object(s->u.object);
+      }else{
+	free_svalue(s);
+      }
+      break;
+    case T_PROGRAM: gc_check_program(s->u.program); break;
+    }
+  }
+}
+
+void gc_check_short_svalue(union anything *u, TYPE_T type)
+{
+  if(!u->refs) return;
+  switch(type)
+  {
+  case T_ARRAY: gc_check_array(u->array); break;
+  case T_LIST: gc_check_array(u->list->ind); break;
+  case T_MAPPING:
+    gc_check_array(u->mapping->ind);
+    gc_check_array(u->mapping->val);
+    break;
+  case T_OBJECT:
+    if(u->object->prog)
+    {
+      gc_check_object(u->object);
+    }else{
+      free_short_svalue(u,T_OBJECT);
+    }
+    break;
+  case T_PROGRAM: gc_check_program(u->program); break;
+  }
+}
+#endif /* GC2 */
diff --git a/src/svalue.h b/src/svalue.h
index 0978075478..9e536ff2f1 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -75,6 +75,9 @@ struct svalue
 
 #define BIT_NOTHING 0
 #define BIT_MIXED 0xffff
+#define BIT_BASIC (BIT_INT|BIT_FLOAT|BIT_STRING)
+#define BIT_COMPLEX (BIT_ARRAY|BIT_LIST|BIT_OBJECT|BIT_PROGRAM|BIT_MAPPING)
+
 /* Max type with ref count */
 #define MAX_REF_TYPE T_STRING
 /* Max type handled by svalue primitives */
diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 18261c1d23..5dbe7f6a33 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -63,6 +63,8 @@ test_compile([[while(0)if(0)continue;else;]])
 test_program([[int b=1,c; int a() { c=b+2; return c==3; }]])
 test_true([[ ("foobar"/"o") & ({ "foo" }) ]])
 test_any([[ array a="foo bar"/" "; return sizeof(a & ({"foo"}))]],1)
+test_true(intp(gc()));
+test_any([[ gc(); array a=({0}); a[0]=a; a=0; return gc() > 0; ]],1);
 
 test_eq("\377"[0],255)
 test_do(add_efun("foo",clone(class {int i;})))
-- 
GitLab


From 49a535333f2bad8b0beca9ba0e328793ce94ae8c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 24 Feb 1996 04:01:39 +0100
Subject: [PATCH 038/351] E-12 changes merged

Rev: src/ChangeLog:1.18
---
 src/ChangeLog | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 6e349ca19e..de000c9bf8 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -3,6 +3,11 @@ Sat Feb 24 04:12:52 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
 	* program.c, array.c, object.c, gc.c: 
 	  Added routines to remove cyclic structures.
 
+Fri Feb 23 02:39:11 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
+
+        * version 1.7E-12 released
+	* file->close() fixed to handle unknown errors
+
 Sat Feb 17 23:05:24 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
 
 	* sprintf: added support for %2c
-- 
GitLab


From c21dd735ea938cc8d4920639a91082a133de6330 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 24 Feb 1996 04:14:20 +0100
Subject: [PATCH 039/351] implode removed

Rev: src/builtin_efuns.c:1.11
---
 src/builtin_efuns.c | 43 -------------------------------------------
 1 file changed, 43 deletions(-)

diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index e5428f0b44..18b85913a0 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -458,47 +458,6 @@ void f_combine_path(INT32 args)
   free(path);
 }
 
-void f_implode(INT32 args)
-{
-  struct lpc_string *ret;
-
-  if(args < 1)
-    error("Too few arguments to implode.\n");
-
-  if(sp[-args].type != T_ARRAY)
-    error("Bad argument 1 to implode.\n");
-
-  if(args<2)
-  {
-    push_string(make_shared_string(""));
-  }else{
-    pop_n_elems(args-2);
-    if(sp[-1].type != T_STRING)
-      error("Bad argument 2 to implode.\n");
-  }
-
-  ret=implode(sp[-2].u.array, sp[-1].u.string);
-  pop_n_elems(2);
-  push_string(ret);
-}
-
-void f_explode(INT32 args)
-{
-  struct array *ret;
-  if(args < 2)
-    error("Too few arguments to explode.\n");
-
-  if(sp[-args].type != T_STRING)
-    error("Bad argument 1 to explode.\n");
-
-  if(sp[1-args].type != T_STRING)
-    error("Bad argument 2 to explode.\n");
-
-  ret=explode(sp[-args].u.string, sp[1-args].u.string);
-  pop_n_elems(args);
-  push_array(ret);
-}
-
 void f_function_object(INT32 args)
 {
   if(args < 1)
@@ -1267,14 +1226,12 @@ void init_builtin_efuns()
   add_efun("destruct",f_destruct,"function(object|void:void)",OPT_SIDE_EFFECT);
   add_efun("equal",f_equal,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE);
   add_efun("exit",f_exit,"function(int:void)",OPT_SIDE_EFFECT);
-  add_efun("explode",f_explode,"function(string,string:array(string))",OPT_TRY_OPTIMIZE);
   add_efun("find_call_out",f_find_call_out,"function(function:int)",OPT_EXTERNAL_DEPEND);
   add_efun("floatp",  f_floatp,  "function(mixed:int)",OPT_TRY_OPTIMIZE);
   add_efun("function_name",f_function_name,"function(function:string)",OPT_TRY_OPTIMIZE);
   add_efun("function_object",f_function_object,"function(function:object)",OPT_TRY_OPTIMIZE);
   add_efun("functionp",  f_functionp,  "function(mixed:int)",OPT_TRY_OPTIMIZE);
   add_efun("hash",f_hash,"function(string,int|void:int)",OPT_TRY_OPTIMIZE);
-  add_efun("implode",f_implode,"function(array,string|void:string)",OPT_TRY_OPTIMIZE);
   add_efun("indices",f_indices,"function(string|array:int*)|function(mapping|list:mixed*)|function(object:string*)",0);
   add_efun("intp",   f_intp,    "function(mixed:int)",OPT_TRY_OPTIMIZE);
   add_efun("listp",   f_listp,   "function(mixed:int)",OPT_TRY_OPTIMIZE);
-- 
GitLab


From 69218f9c9007af5c297f448edcf5269bcaac87c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 24 Feb 1996 04:22:31 +0100
Subject: [PATCH 040/351] implode/explode removed

Rev: doc/builtin/explode:1.3(DEAD)
Rev: doc/builtin/implode:1.3(DEAD)
Rev: lib/simulate.lpc:1.10
---
 doc/builtin/explode | 29 -----------------------------
 doc/builtin/implode | 28 ----------------------------
 lib/simulate.lpc    | 12 +++++++-----
 3 files changed, 7 insertions(+), 62 deletions(-)
 delete mode 100644 doc/builtin/explode
 delete mode 100644 doc/builtin/implode

diff --git a/doc/builtin/explode b/doc/builtin/explode
deleted file mode 100644
index 5c211fd74b..0000000000
--- a/doc/builtin/explode
+++ /dev/null
@@ -1,29 +0,0 @@
-NAME
-	explode - explode a string on a delimeter
-
-SYNTAX
-	string *explode(string victim, string delimeter);
-	or
-	victim / delimiter
-
-DESCRIPTION
-	Explode divides the string called victim at every occurance of
-	the string delimeter and returns the resulting parts in an array.
-	If delimeter is an empty string, victim will be divided into strings
-	of length 1.
-
-EXAMPLES
-	> explode("foobar","o");
-	Result: ({ "f", "", "bar" })
-	> explode("10101001010100010101","10");
-	Result: ({ "", "", "", "0", "", "", "00", "", "1" })
-	> explode("/foo/bar/gazonk","/");
-	Result: ({ "", "foo", "bar", "gazonk" })
-	> explode("foobar","");
-	Result: ({ "f", "o", "o", "b", "a", "r" })
-
-KEYWORDS
-	string
-
-SEE ALSO
-	implode
diff --git a/doc/builtin/implode b/doc/builtin/implode
deleted file mode 100644
index 9c603bae54..0000000000
--- a/doc/builtin/implode
+++ /dev/null
@@ -1,28 +0,0 @@
-NAME
-	implode - implode an array of strings
-
-SYNTAX
-	string implode(string *a, string delimeter);
-	or
-	a * delimeter
-
-DESCRIPTION
-	This function is the inverse of explode. It contatenates all the
-	strings in a with a delimeter in between each. If no delimeter is
-	given, an empty string will be used.
-
-EXAMPLES
-	> implode( ({ "foo","bar","gazonk"}), "-" );
-	Result: foo-bar-gazonk
-	> implode( ({ "f","o","o" }) );
-	Result: foo
-	> ({ "a","b","c" })*" and ";
-	Result: a and b and c
-	> 
-
-KEYWORDS
-	string
-
-SEE ALSO
-	explode
-	
\ No newline at end of file
diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index 985735cf8d..82a26a8e0e 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -328,12 +328,14 @@ list mklist(mixed *a)
 void create()
 {
   add_efun("PI",3.1415926535897932384626433832795080);
-  add_efun("sum",`+);
   add_efun("capitalize",capitalize);
   add_efun("code_value",code_value);
   add_efun("exec","exec");
+  add_efun("explode",`/);
   add_efun("file_size",file_size);
   add_efun("filter_array",filter_array);
+  add_efun("get_function",get_function);
+  add_efun("implode",`*);
   add_efun("l_sizeof",sizeof);
   add_efun("m_indices",indices);
   add_efun("m_sizeof",sizeof);
@@ -342,19 +344,19 @@ void create()
   add_efun("member_array",member_array);
   add_efun("mklist",mklist);
   add_efun("popen",popen);
-  add_efun("spawn",spawn);
-  add_efun("system",system);
   add_efun("previous_object",previous_object);
   add_efun("read_bytes",read_bytes);
+  add_efun("regexp",regexp);
   add_efun("search_array",search_array);
   add_efun("sort_array",sort_array);
+  add_efun("spawn",spawn);
   add_efun("strlen",sizeof);
   add_efun("strstr",search);
+  add_efun("sum",`+);
   add_efun("sum_arrays",sum_arrays);
+  add_efun("system",system);
   add_efun("this_function",this_function);
   add_efun("version",lambda() { return "uLPC v1.0E-10"; });
   add_efun("write_file",write_file);
-  add_efun("get_function",get_function);
-  add_efun("regexp",regexp);
 }
 
-- 
GitLab


From 465041f1d4e8efb6f498e441fea55590d180af24 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 24 Feb 1996 04:23:09 +0100
Subject: [PATCH 041/351] explode/implode now simulated

Rev: doc/simulated/explode:1.1
Rev: doc/simulated/implode:1.1
---
 doc/simulated/explode | 29 +++++++++++++++++++++++++++++
 doc/simulated/implode | 28 ++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+)
 create mode 100644 doc/simulated/explode
 create mode 100644 doc/simulated/implode

diff --git a/doc/simulated/explode b/doc/simulated/explode
new file mode 100644
index 0000000000..5c211fd74b
--- /dev/null
+++ b/doc/simulated/explode
@@ -0,0 +1,29 @@
+NAME
+	explode - explode a string on a delimeter
+
+SYNTAX
+	string *explode(string victim, string delimeter);
+	or
+	victim / delimiter
+
+DESCRIPTION
+	Explode divides the string called victim at every occurance of
+	the string delimeter and returns the resulting parts in an array.
+	If delimeter is an empty string, victim will be divided into strings
+	of length 1.
+
+EXAMPLES
+	> explode("foobar","o");
+	Result: ({ "f", "", "bar" })
+	> explode("10101001010100010101","10");
+	Result: ({ "", "", "", "0", "", "", "00", "", "1" })
+	> explode("/foo/bar/gazonk","/");
+	Result: ({ "", "foo", "bar", "gazonk" })
+	> explode("foobar","");
+	Result: ({ "f", "o", "o", "b", "a", "r" })
+
+KEYWORDS
+	string
+
+SEE ALSO
+	implode
diff --git a/doc/simulated/implode b/doc/simulated/implode
new file mode 100644
index 0000000000..9c603bae54
--- /dev/null
+++ b/doc/simulated/implode
@@ -0,0 +1,28 @@
+NAME
+	implode - implode an array of strings
+
+SYNTAX
+	string implode(string *a, string delimeter);
+	or
+	a * delimeter
+
+DESCRIPTION
+	This function is the inverse of explode. It contatenates all the
+	strings in a with a delimeter in between each. If no delimeter is
+	given, an empty string will be used.
+
+EXAMPLES
+	> implode( ({ "foo","bar","gazonk"}), "-" );
+	Result: foo-bar-gazonk
+	> implode( ({ "f","o","o" }) );
+	Result: foo
+	> ({ "a","b","c" })*" and ";
+	Result: a and b and c
+	> 
+
+KEYWORDS
+	string
+
+SEE ALSO
+	explode
+	
\ No newline at end of file
-- 
GitLab


From 693018b6e926aa9ad49d5e3470b0c75f1188e501 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 25 Feb 1996 01:25:47 +0100
Subject: [PATCH 042/351] `+ optimization done

Rev: doc/builtin/gc:1.1
Rev: doc/simulated/implode:1.2
Rev: lib/master.lpc:1.4
Rev: src/add_efun.h:1.3
Rev: src/backend.c:1.4
Rev: src/backend.h:1.4
Rev: src/builtin_efuns.c:1.12
Rev: src/call_out.h:1.3
Rev: src/configure:1.2
Rev: src/configure.in:1.7
Rev: src/debug.c:1.3(DEAD)
Rev: src/debug.h:1.3(DEAD)
Rev: src/docode.c:1.4
Rev: src/gc.c:1.1
Rev: src/gc.h:1.1
Rev: src/language.y:1.10
Rev: src/las.c:1.5
Rev: src/las.h:1.5
Rev: src/lex.c:1.7
Rev: src/lpc_signal.c:1.8
Rev: src/machine.h.in:1.7
Rev: src/main.c:1.3
Rev: src/modules/files/configure.in:1.4
Rev: src/operators.c:1.3
Rev: src/rusage.c:1.4
Rev: src/test/create_testsuite:1.9
---
 doc/builtin/gc                 |   17 +
 doc/simulated/implode          |    5 +-
 lib/master.lpc                 |   10 +-
 src/add_efun.h                 |    2 +-
 src/backend.c                  |    6 +-
 src/backend.h                  |   18 +-
 src/builtin_efuns.c            |   15 +-
 src/call_out.h                 |   19 +-
 src/configure                  | 1549 +++++++++++++++++++-------------
 src/configure.in               |   50 +-
 src/docode.c                   |   39 +-
 src/gc.c                       |   89 ++
 src/gc.h                       |   30 +
 src/language.y                 |    2 +-
 src/las.c                      |   17 +-
 src/las.h                      |    2 +
 src/lex.c                      |   14 +-
 src/lpc_signal.c               |    9 +-
 src/machine.h.in               |    3 +
 src/main.c                     |   15 +-
 src/modules/files/configure.in |    6 +-
 src/operators.c                |   68 +-
 src/rusage.c                   |   18 +-
 src/test/create_testsuite      |    2 +-
 24 files changed, 1250 insertions(+), 755 deletions(-)
 create mode 100644 doc/builtin/gc
 create mode 100644 src/gc.c
 create mode 100644 src/gc.h

diff --git a/doc/builtin/gc b/doc/builtin/gc
new file mode 100644
index 0000000000..c3d21db790
--- /dev/null
+++ b/doc/builtin/gc
@@ -0,0 +1,17 @@
+NAME
+	gc - do garbage collection
+
+SYNTAX
+	int gc();
+
+DESCRIPTION
+	This function checks all the memory for cyclic structures such
+	as arrays containing themselves and frees them if approperiate.
+	It also frees up destructed objects. It then returns how many
+	arrays/objects/programs/etc. it managed	to free by doing this.
+	
+	Normally there is no need to call this function since uLPC will
+	call it by itself every now and then. (uLPC will try to predict
+	when 20% of all arrays/object/programs in memory is 'garbage'
+	and call this routine then.)
+
diff --git a/doc/simulated/implode b/doc/simulated/implode
index 9c603bae54..21cb7fc3c7 100644
--- a/doc/simulated/implode
+++ b/doc/simulated/implode
@@ -8,14 +8,11 @@ SYNTAX
 
 DESCRIPTION
 	This function is the inverse of explode. It contatenates all the
-	strings in a with a delimeter in between each. If no delimeter is
-	given, an empty string will be used.
+	strings in a with a delimeter in between each.
 
 EXAMPLES
 	> implode( ({ "foo","bar","gazonk"}), "-" );
 	Result: foo-bar-gazonk
-	> implode( ({ "f","o","o" }) );
-	Result: foo
 	> ({ "a","b","c" })*" and ";
 	Result: a and b and c
 	> 
diff --git a/lib/master.lpc b/lib/master.lpc
index 975afdbd8c..bf6d7b91e9 100644
--- a/lib/master.lpc
+++ b/lib/master.lpc
@@ -78,9 +78,9 @@ program handle_inherit(string pname, string current_file)
   string *tmp;
   p=cast_to_program(pname);
   if(p) return p;
-  tmp=explode(current_file,"/");
+  tmp=current_file/"/";
   tmp[-1]=pname;
-  return cast_to_program(implode(tmp,"/"));
+  return cast_to_program(tmp*"/");
 }
 
 mapping (string:object) objects=(["/master.lpc":this_object()]);
@@ -197,14 +197,14 @@ string handle_include(string f, string current_file)
   string *tmp, path;
 /*  perror("Handle include: "+f+"\n"); */
 
-  tmp=explode(current_file, "/");
+  tmp=current_file/"/";
   tmp[-1]=f;
-  path=combine_path(getcwd(),implode(tmp,"/"));
+  path=combine_path(getcwd(),tmp*"/");
   if(file_stat(path)) return path;
   
   if(path=getenv("LPC_INCLUDE_PATH"))
   {
-    foreach(explode(path,":"), path)
+    foreach(path/":", path)
     {
       path=combine_path(path,f);
       if(file_stat(path)) return path;
diff --git a/src/add_efun.h b/src/add_efun.h
index 2400328411..90191795f9 100644
--- a/src/add_efun.h
+++ b/src/add_efun.h
@@ -18,7 +18,7 @@ struct efun
 
 typedef void (*c_fun)(INT32);
 typedef int (*docode_fun)(node *n);
-typedef void (*optimize_fun)(node *n);
+typedef node *(*optimize_fun)(node *n);
 
 struct callable
 {
diff --git a/src/backend.c b/src/backend.c
index f8cb88b7af..0b07f66099 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -4,11 +4,9 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
+#include "backend.h"
 #include <errno.h>
 #include <sys/types.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
 #include <sys/param.h>
 #include <string.h>
 #include "interpret.h"
@@ -16,10 +14,8 @@
 #include "types.h"
 #include "error.h"
 #include "call_out.h"
-#include "backend.h"
 #include "fd_control.h"
 #include "main.h"
-#include "debug.h"
 #include "callback.h"
 
 #ifdef HAVE_SYS_SELECT_H
diff --git a/src/backend.h b/src/backend.h
index a80179d81d..0b556c8359 100644
--- a/src/backend.h
+++ b/src/backend.h
@@ -8,11 +8,23 @@
 
 #include "global.h"
 
-#ifdef HAVE_TIME_H
-#include <time.h>
-#undef HAVE_TIME_H
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  if HAVE_TIME_H
+#   include <time.h>
+#  endif
+# endif
 #endif
 
+#undef HAVE_SYS_TIME_H
+#undef HAVE_TIME_H
+#undef TIME_WITH_SYS_TIME
+
 extern time_t current_time;
 typedef void (*callback)(int,void *);
 
diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index 18b85913a0..992553c9cf 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -23,9 +23,20 @@
 #include "call_out.h"
 #include "callback.h"
 #include "gc.h"
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  if HAVE_TIME_H
+#   include <time.h>
+#  endif
+# endif
 #endif
+
 #ifdef HAVE_CRYPT_H
 #include <crypt.h>
 #endif
diff --git a/src/call_out.h b/src/call_out.h
index 7f51b71373..d5b9882b21 100644
--- a/src/call_out.h
+++ b/src/call_out.h
@@ -8,12 +8,23 @@
 
 #include "types.h"
 
-#ifdef HAVE_TIME_H
-/* Needed for time_t */
-#include <time.h>
-#undef HAVE_TIME_H
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  if HAVE_TIME_H
+#   include <time.h>
+#  endif
+# endif
 #endif
 
+#undef HAVE_SYS_TIME_H
+#undef HAVE_TIME_H
+#undef TIME_WITH_SYS_TIME
+
 struct call_out_s
 {
   time_t time;
diff --git a/src/configure b/src/configure
index 6a2c705f86..6b0c0b7669 100755
--- a/src/configure
+++ b/src/configure
@@ -1,52 +1,16 @@
-#!/bin/sh
+#! /bin/sh
 
 # Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 1.119 
-# Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+# Generated automatically using autoconf version 2.7 
+# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
 #
-# This configure script 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 2, or (at your option)
-# any later version.
-#
-# This script 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 this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
 
+# Defaults:
 ac_help=
-
-# Omit some internal or obsolete options to make the list less imposing.
-ac_usage="Usage: configure [options] [host]
-Options: [defaults in brackets after descriptions]
-Configuration:
-  --cache-file=FILE       cache test results in FILE
-  --help                  print this message
-  --no-create             do not create output files
-  --quiet, --silent       do not print \`checking...' messages
-  --version               print the version of autoconf that created configure
-Directory and file names:
-  --exec-prefix=PREFIX    install host dependent files in PREFIX [/usr/local]
-  --prefix=PREFIX         install host independent files in PREFIX [/usr/local]
-  --srcdir=DIR            find the sources in DIR [configure dir or ..]
-  --program-prefix=PREFIX prepend PREFIX to installed program names
-  --program-suffix=SUFFIX append SUFFIX to installed program names
-Host type:
-  --build=BUILD           configure for building on BUILD [BUILD=HOST]
-  --host=HOST             configure for HOST [guessed]
-  --target=TARGET         configure for TARGET [TARGET=HOST]
-Features and packages:
-  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
-  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
-  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
-  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
-  --x-includes=DIR        X include files are in DIR
-  --x-libraries=DIR       X library files are in DIR
---enable and --with options recognized:$ac_help"
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
 
 # Initialize some variables set by options.
 # The variables have the same names as the options, with
@@ -61,16 +25,30 @@ no_recursion=
 prefix=NONE
 program_prefix=NONE
 program_suffix=NONE
-program_transform_name=NONE
+program_transform_name=s,x,x,
 silent=
+site=
 srcdir=
 target=NONE
 verbose=
 x_includes=NONE
 x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
 
 # Initialize some other variables.
 subdirs=
+MFLAGS= MAKEFLAGS=
 
 ac_prev=
 for ac_option
@@ -92,9 +70,14 @@ do
 
   case "$ac_option" in
 
-  -build | --build | --buil | --bui | --bu | --b)
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
     ac_prev=build ;;
-  -build=* | --build=* | --buil=* | --bui=* | --bu=* | --b=*)
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
     build="$ac_optarg" ;;
 
   -cache-file | --cache-file | --cache-fil | --cache-fi \
@@ -104,6 +87,12 @@ do
   | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
     cache_file="$ac_optarg" ;;
 
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
   -disable-* | --disable-*)
     ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
     # Reject names that are not valid shell variable names.
@@ -140,9 +129,58 @@ do
     with_gas=yes ;;
 
   -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
     cat << EOF
-$ac_usage
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
 EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
     exit 0 ;;
 
   -host | --host | --hos | --ho)
@@ -150,6 +188,44 @@ EOF
   -host=* | --host=* | --hos=* | --ho=*)
     host="$ac_optarg" ;;
 
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
   -nfp | --nfp | --nf)
     # Obsolete; use --without-fp.
     with_fp=no ;;
@@ -162,6 +238,15 @@ EOF
   | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
     no_recursion=yes ;;
 
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
   -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
     ac_prev=prefix ;;
   -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
@@ -202,11 +287,40 @@ EOF
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
   -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
     ac_prev=srcdir ;;
   -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
     srcdir="$ac_optarg" ;;
 
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
   -target | --target | --targe | --targ | --tar | --ta | --t)
     ac_prev=target ;;
   -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
@@ -216,7 +330,7 @@ EOF
     verbose=yes ;;
 
   -version | --version | --versio | --versi | --vers)
-    echo "configure generated by autoconf version 1.119"
+    echo "configure generated by autoconf version 2.7"
     exit 0 ;;
 
   -with-* | --with-*)
@@ -262,7 +376,7 @@ EOF
   -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
     ;;
 
-  *) 
+  *)
     if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
       echo "configure: warning: $ac_option: invalid host type" 1>&2
     fi
@@ -279,19 +393,20 @@ if test -n "$ac_prev"; then
   { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
 fi
 
-trap 'rm -fr conftest* confdefs* core $ac_clean_files; exit 1' 1 2 15
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
 
 # File descriptor usage:
-# 0 unused; standard input
+# 0 standard input
 # 1 file creation
 # 2 errors and warnings
-# 3 unused; some systems may open it to /dev/tty
-# 4 checking for... messages and results
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
 # 5 compiler messages saved in config.log
 if test "$silent" = yes; then
-  exec 4>/dev/null
+  exec 6>/dev/null
 else
-  exec 4>&1
+  exec 6>&1
 fi
 exec 5>./config.log
 
@@ -353,17 +468,14 @@ if test ! -r $srcdir/$ac_unique_file; then
     { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
   fi
 fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
 
 # Prefer explicitly selected file to automatically selected ones.
 if test -z "$CONFIG_SITE"; then
   if test "x$prefix" != xNONE; then
-    CONFIG_SITE=$prefix/lib/config.site
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
   else
-    CONFIG_SITE=/usr/local/lib/config.site
-  fi
-  # System dependent files override system independent ones.
-  if test "x$exec_prefix" != xNONE && test "x$exec_prefix" != "x$prefix"; then
-    CONFIG_SITE="$CONFIG_SITE $exec_prefix/lib/config.site"
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
   fi
 fi
 for ac_site_file in $CONFIG_SITE; do
@@ -383,8 +495,12 @@ fi
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_link='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext -o conftest $LIBS 1>&5 2>&5'
+ac_cpp='echo $CPP $CPPFLAGS 1>&5;
+$CPP $CPPFLAGS'
+ac_compile='echo ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5;
+${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5'
+ac_link='echo ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5;
+${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5'
 
 if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
   # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
@@ -401,9 +517,9 @@ fi
 
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_prog_CC'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
@@ -422,19 +538,19 @@ fi
 fi
 CC="$ac_cv_prog_CC"
 if test -n "$CC"; then
-  echo "$ac_t""$CC" 1>&4
+  echo "$ac_t""$CC" 1>&6
 else
-  echo "$ac_t""no" 1>&4
+  echo "$ac_t""no" 1>&6
 fi
 
 
-echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_prog_gcc'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.c <<EOF
 #ifdef __GNUC__
-  yes
+  yes;
 #endif
 EOF
 if ${CC-cc} -E conftest.c 2>&5 | egrep yes >/dev/null 2>&1; then
@@ -443,13 +559,14 @@ else
   ac_cv_prog_gcc=no
 fi
 fi
-echo "$ac_t""$ac_cv_prog_gcc" 1>&4
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
 if test $ac_cv_prog_gcc = yes; then
   GCC=yes
   if test "${CFLAGS+set}" != set; then
-    echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_prog_gcc_g'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+    echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   echo 'void f(){}' > conftest.c
 if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
@@ -460,7 +577,8 @@ fi
 rm -f conftest*
 
 fi
-    echo "$ac_t""$ac_cv_prog_gcc_g" 1>&4
+
+echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6
     if test $ac_cv_prog_gcc_g = yes; then
       CFLAGS="-g -O"
     else
@@ -476,9 +594,9 @@ fi
 # We need some special hacks when running slowaris
 # Extract the first word of "uname", so it can be a program name with args.
 set dummy uname; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_path_uname_prog'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_path_uname_prog'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   case "$uname_prog" in
   /*)
@@ -500,14 +618,14 @@ esac
 fi
 uname_prog="$ac_cv_path_uname_prog"
 if test -n "$uname_prog"; then
-  echo "$ac_t""$uname_prog" 1>&4
+  echo "$ac_t""$uname_prog" 1>&6
 else
-  echo "$ac_t""no" 1>&4
+  echo "$ac_t""no" 1>&6
 fi
 
-echo $ac_n "checking operating system""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_sys_os'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking operating system""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_sys_os'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 if test "$uname_prog" != "no"; then
@@ -524,20 +642,20 @@ fi
 
 fi
 
-echo "$ac_t""$lpc_cv_sys_os" 1>&4
+echo "$ac_t""$lpc_cv_sys_os" 1>&6
 
 
 OLD_CFLAGS="$CFLAGS"
 OPTIMIZE="";
 
-echo $ac_n "checking -O""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_option_opt'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking -O""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_option_opt'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   CFLAGS="$OLD_CFLAGS -O"
   cat > conftest.$ac_ext <<EOF
-#line 541 "configure"
+#line 659 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -561,15 +679,54 @@ fi
 if test "$lpc_cv_option_opt" = "yes" ; then
   CFLAGS="$OLD_CFLAGS -O"
   OPTIMIZE="$OPTIMIZE -O"
-  echo "$ac_t""-O found" 1>&4
+  echo "$ac_t""-O found" 1>&6
 else
-  echo "$ac_t""-O not found" 1>&4
+  echo "$ac_t""-O not found" 1>&6
 fi
 
 CFLAGS="$OLD_CFLAGS"
 
 if test "$GCC" = "yes"; then
-  WARN="-g -pipe -W -Wunused -Wformat"
+  WARN="-g -W -Wunused -Wformat"
+
+  echo $ac_n "checking -pipe""... $ac_c" 1>&6
+  if eval "test \"`echo '$''{'lpc_cv_option_pipe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+    CFLAGS="$OLD_CFLAGS -pipe"
+    cat > conftest.$ac_ext <<EOF
+#line 700 "configure"
+#include "confdefs.h"
+
+int main() { return 0; }
+int t() {
+ exit(0); 
+; return 0; }
+EOF
+if eval $ac_link; then
+  rm -rf conftest*
+  lpc_cv_option_pipe=yes
+else
+  rm -rf conftest*
+  lpc_cv_option_pipe=no
+fi
+rm -f conftest*
+
+  
+fi
+
+
+  if test "$lpc_cv_option_pipe" = "yes" ; then
+    CFLAGS="$OLD_CFLAGS -pipe"
+    OPTIMIZE="$OPTIMIZE -pipe"
+    echo "$ac_t""-pipe found" 1>&6
+  else
+    echo "$ac_t""-pipe not found" 1>&6
+    CFLAGS="$OLD_CFLAGS"
+  fi
+
+
 else
   WARN=""
 #
@@ -579,7 +736,7 @@ else
     OLD_CC="${CC-cc}"
     CC="$CC -Aa -D_HPUX_SOURCE +Olibcalls"
     cat > conftest.$ac_ext <<EOF
-#line 583 "configure"
+#line 740 "configure"
 #include "confdefs.h"
 int foo(int bar);
 int main() { return 0; }
@@ -598,13 +755,13 @@ rm -f conftest*
   fi
 fi
 
-echo $ac_n "checking ansi prototype capability""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_sys_ansi_prototypes'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking ansi prototype capability""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_sys_ansi_prototypes'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 608 "configure"
+#line 765 "configure"
 #include "confdefs.h"
 int foo(int bar);
 int main() { return 0; }
@@ -626,9 +783,9 @@ fi
 
 
 if test "$lpc_cv_sys_ansi_prototypes" = "yes"; then
-  echo "$ac_t""yes" 1>&4
+  echo "$ac_t""yes" 1>&6
 else
-  echo "$ac_t""no" 1>&4
+  echo "$ac_t""no" 1>&6
   exit 1
 fi
 
@@ -662,15 +819,16 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
 # AFS /usr/afsws/bin/install, which mishandles nonexistent args
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
-echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&4
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
 if test -z "$INSTALL"; then
-if eval "test \"`echo '${'ac_cv_path_install'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
     IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
   for ac_dir in $PATH; do
-    case "$ac_dir" in
-    ''|.|/etc|/usr/sbin|/usr/etc|/sbin|/usr/afsws/bin|/usr/ucb) ;;
+    # Account for people who put trailing slashes in PATH elements.
+    case "$ac_dir/" in
+    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
     *)
       # OSF1 and SCO ODT 3.0 have their own names for install.
       for ac_prog in ginstall installbsd scoinst install; do
@@ -690,12 +848,19 @@ else
     esac
   done
   IFS="$ac_save_ifs"
-  # As a last resort, use the slow shell script.
-  test -z "$ac_cv_path_install" && ac_cv_path_install="$ac_install_sh"
+
 fi
-  INSTALL="$ac_cv_path_install"
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
 fi
-echo "$ac_t""$INSTALL" 1>&4
+echo "$ac_t""$INSTALL" 1>&6
 
 # Use test -z because SunOS4 sh mishandles braces in ${var-val}.
 # It thinks the first close brace ends the variable substitution.
@@ -707,9 +872,9 @@ for ac_prog in 'bison -y' byacc
 do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_prog_YACC'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$YACC"; then
   ac_cv_prog_YACC="$YACC" # Let the user override the test.
@@ -727,23 +892,23 @@ fi
 fi
 YACC="$ac_cv_prog_YACC"
 if test -n "$YACC"; then
-  echo "$ac_t""$YACC" 1>&4
+  echo "$ac_t""$YACC" 1>&6
 else
-  echo "$ac_t""no" 1>&4
+  echo "$ac_t""no" 1>&6
 fi
 
 test -n "$YACC" && break
 done
 test -n "$YACC" || YACC="yacc"
 
-echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&4
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
 fi
 if test -z "$CPP"; then
-if eval "test \"`echo '${'ac_cv_prog_CPP'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
     # This must be in double quotes, not single quotes, because CPP may get
   # substituted into the Makefile and "${CC-cc}" will confuse make.
@@ -751,9 +916,9 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 755 "configure"
+#line 920 "configure"
 #include "confdefs.h"
-#include <stdio.h>
+#include <assert.h>
 Syntax Error
 EOF
 eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
@@ -765,9 +930,9 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 769 "configure"
+#line 934 "configure"
 #include "confdefs.h"
-#include <stdio.h>
+#include <assert.h>
 Syntax Error
 EOF
 eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
@@ -784,15 +949,17 @@ fi
 rm -f conftest*
   ac_cv_prog_CPP="$CPP"
 fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
 fi
-CPP="$ac_cv_prog_CPP"
-echo "$ac_t""$CPP" 1>&4
+echo "$ac_t""$CPP" 1>&6
 
 # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_prog_RANLIB'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$RANLIB"; then
   ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
@@ -811,15 +978,15 @@ fi
 fi
 RANLIB="$ac_cv_prog_RANLIB"
 if test -n "$RANLIB"; then
-  echo "$ac_t""$RANLIB" 1>&4
+  echo "$ac_t""$RANLIB" 1>&6
 else
-  echo "$ac_t""no" 1>&4
+  echo "$ac_t""no" 1>&6
 fi
 
-echo $ac_n "checking whether ${MAKE-make} sets \$MAKE""... $ac_c" 1>&4
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
 set dummy ${MAKE-make}; ac_make=$2
-if eval "test \"`echo '${'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftestmake <<\EOF
 all:
@@ -835,17 +1002,17 @@ fi
 rm -f conftestmake
 fi
 if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
-  echo "$ac_t""yes" 1>&4
+  echo "$ac_t""yes" 1>&6
   SET_MAKE=
 else
-  echo "$ac_t""no" 1>&4
+  echo "$ac_t""no" 1>&6
   SET_MAKE="MAKE=${MAKE-make}"
 fi
 
 
-echo $ac_n "checking first yacc define""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_yacc_first'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking first yacc define""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_yacc_first'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 cat >conftest.y <<\EOF
@@ -869,7 +1036,7 @@ fi
 
 fi
 
-echo "$ac_t""$lpc_cv_yacc_first" 1>&4
+echo "$ac_t""$lpc_cv_yacc_first" 1>&6
 cat >> confdefs.h <<EOF
 #define F_OFFSET $lpc_cv_yacc_first
 EOF
@@ -877,54 +1044,50 @@ EOF
 
 rm -rf conftest.y y.tab.c y.tab.h conftest.out
 
-for ac_hdr in sys/rusage.h sys/time.h unistd.h stdlib.h memory.h values.h \
- string.h fcntl.h sys/filio.h sys/sockio.h crypt.h locale.h sys/resource.h \
- sys/select.h netdb.h
-do
-ac_safe=`echo "$ac_hdr" | tr './' '__'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_header_$ac_safe'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 891 "configure"
+#line 1053 "configure"
 #include "confdefs.h"
-#include <$ac_hdr>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() { return 0; }
+int t() {
+struct tm *tp;
+; return 0; }
 EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
+if eval $ac_compile; then
   rm -rf conftest*
-  eval "ac_cv_header_$ac_safe=yes"
+  ac_cv_header_time=yes
 else
-  echo "$ac_err" >&5
   rm -rf conftest*
-  eval "ac_cv_header_$ac_safe=no"
+  ac_cv_header_time=no
 fi
 rm -f conftest*
+
 fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
-  echo "$ac_t""yes" 1>&4
-    ac_tr_hdr=HAVE_`echo $ac_hdr | tr '[a-z]./' '[A-Z]__'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+  cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
 EOF
- 
-else
-  echo "$ac_t""no" 1>&4
+
 fi
-done
 
 # If we cannot run a trivial program, we must be cross compiling.
-echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_c_cross'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test "$cross_compiling" = yes; then
-  ac_cv_cross=yes
+  ac_cv_c_cross=yes
 else
 cat > conftest.$ac_ext <<EOF
-#line 928 "configure"
+#line 1091 "configure"
 #include "confdefs.h"
 main(){return(0);}
 EOF
@@ -937,15 +1100,16 @@ fi
 fi
 rm -fr conftest*
 fi
+
+echo "$ac_t""$ac_cv_c_cross" 1>&6
 cross_compiling=$ac_cv_c_cross
-echo "$ac_t""$ac_cv_c_cross" 1>&4
 
-echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_header_stdc'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 949 "configure"
+#line 1113 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -967,7 +1131,7 @@ rm -f conftest*
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 971 "configure"
+#line 1135 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -985,7 +1149,7 @@ fi
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 989 "configure"
+#line 1153 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -1003,10 +1167,10 @@ fi
 if test $ac_cv_header_stdc = yes; then
   # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
 if test "$cross_compiling" = yes; then
-  ac_cv_header_stdc=no
+  :
 else
 cat > conftest.$ac_ext <<EOF
-#line 1010 "configure"
+#line 1174 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1027,7 +1191,8 @@ fi
 rm -fr conftest*
 fi
 fi
-echo "$ac_t""$ac_cv_header_stdc" 1>&4
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
 if test $ac_cv_header_stdc = yes; then
   cat >> confdefs.h <<\EOF
 #define STDC_HEADERS 1
@@ -1035,16 +1200,54 @@ EOF
 
 fi
 
+for ac_hdr in sys/rusage.h time.h sys/time.h unistd.h stdlib.h memory.h \
+values.h string.h fcntl.h sys/filio.h sys/sockio.h crypt.h locale.h \
+sys/resource.h sys/select.h netdb.h
+do
+ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1214 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
 
-echo $ac_n "checking size of char *""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_sizeof_char_p'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking size of char *""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_sizeof_char_p'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 1048 "configure"
+#line 1251 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -1058,25 +1261,27 @@ EOF
 eval $ac_link
 if test -s conftest && (./conftest; exit) 2>/dev/null; then
   ac_cv_sizeof_char_p=`cat conftestval`
+else
+  ac_cv_sizeof_char_p=0
 fi
 fi
 rm -fr conftest*
 fi
-echo "$ac_t""$ac_cv_sizeof_char_p" 1>&4
+echo "$ac_t""$ac_cv_sizeof_char_p" 1>&6
 cat >> confdefs.h <<EOF
 #define SIZEOF_CHAR_P $ac_cv_sizeof_char_p
 EOF
 
 
-echo $ac_n "checking size of long""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_sizeof_long'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking size of long""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 1080 "configure"
+#line 1285 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -1090,25 +1295,27 @@ EOF
 eval $ac_link
 if test -s conftest && (./conftest; exit) 2>/dev/null; then
   ac_cv_sizeof_long=`cat conftestval`
+else
+  ac_cv_sizeof_long=0
 fi
 fi
 rm -fr conftest*
 fi
-echo "$ac_t""$ac_cv_sizeof_long" 1>&4
+echo "$ac_t""$ac_cv_sizeof_long" 1>&6
 cat >> confdefs.h <<EOF
 #define SIZEOF_LONG $ac_cv_sizeof_long
 EOF
 
 
-echo $ac_n "checking size of int""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_sizeof_int'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking size of int""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 1112 "configure"
+#line 1319 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -1122,25 +1329,27 @@ EOF
 eval $ac_link
 if test -s conftest && (./conftest; exit) 2>/dev/null; then
   ac_cv_sizeof_int=`cat conftestval`
+else
+  ac_cv_sizeof_int=0
 fi
 fi
 rm -fr conftest*
 fi
-echo "$ac_t""$ac_cv_sizeof_int" 1>&4
+echo "$ac_t""$ac_cv_sizeof_int" 1>&6
 cat >> confdefs.h <<EOF
 #define SIZEOF_INT $ac_cv_sizeof_int
 EOF
 
 
-echo $ac_n "checking size of short""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_sizeof_short'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking size of short""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 1144 "configure"
+#line 1353 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -1154,25 +1363,27 @@ EOF
 eval $ac_link
 if test -s conftest && (./conftest; exit) 2>/dev/null; then
   ac_cv_sizeof_short=`cat conftestval`
+else
+  ac_cv_sizeof_short=0
 fi
 fi
 rm -fr conftest*
 fi
-echo "$ac_t""$ac_cv_sizeof_short" 1>&4
+echo "$ac_t""$ac_cv_sizeof_short" 1>&6
 cat >> confdefs.h <<EOF
 #define SIZEOF_SHORT $ac_cv_sizeof_short
 EOF
 
 
-echo $ac_n "checking size of float""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_sizeof_float'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking size of float""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_sizeof_float'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 1176 "configure"
+#line 1387 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -1186,25 +1397,27 @@ EOF
 eval $ac_link
 if test -s conftest && (./conftest; exit) 2>/dev/null; then
   ac_cv_sizeof_float=`cat conftestval`
+else
+  ac_cv_sizeof_float=0
 fi
 fi
 rm -fr conftest*
 fi
-echo "$ac_t""$ac_cv_sizeof_float" 1>&4
+echo "$ac_t""$ac_cv_sizeof_float" 1>&6
 cat >> confdefs.h <<EOF
 #define SIZEOF_FLOAT $ac_cv_sizeof_float
 EOF
 
 
-echo $ac_n "checking size of double""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_sizeof_double'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking size of double""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_sizeof_double'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 1208 "configure"
+#line 1421 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -1218,23 +1431,25 @@ EOF
 eval $ac_link
 if test -s conftest && (./conftest; exit) 2>/dev/null; then
   ac_cv_sizeof_double=`cat conftestval`
+else
+  ac_cv_sizeof_double=0
 fi
 fi
 rm -fr conftest*
 fi
-echo "$ac_t""$ac_cv_sizeof_double" 1>&4
+echo "$ac_t""$ac_cv_sizeof_double" 1>&6
 cat >> confdefs.h <<EOF
 #define SIZEOF_DOUBLE $ac_cv_sizeof_double
 EOF
 
 
 
-echo $ac_n "checking for size_t""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_type_size_t'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1238 "configure"
+#line 1453 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1252,7 +1467,7 @@ fi
 rm -f conftest*
 
 fi
-echo "$ac_t""$ac_cv_type_size_t" 1>&4
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
 if test $ac_cv_type_size_t = no; then
   cat >> confdefs.h <<\EOF
 #define size_t unsigned
@@ -1260,12 +1475,12 @@ EOF
 
 fi
 
-echo $ac_n "checking for pid_t""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_type_pid_t'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for pid_t""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1269 "configure"
+#line 1484 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1283,7 +1498,7 @@ fi
 rm -f conftest*
 
 fi
-echo "$ac_t""$ac_cv_type_pid_t" 1>&4
+echo "$ac_t""$ac_cv_type_pid_t" 1>&6
 if test $ac_cv_type_pid_t = no; then
   cat >> confdefs.h <<\EOF
 #define pid_t int
@@ -1291,12 +1506,12 @@ EOF
 
 fi
 
-echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_type_uid_t'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1300 "configure"
+#line 1515 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 EOF
@@ -1311,7 +1526,8 @@ fi
 rm -f conftest*
 
 fi
-echo "$ac_t""$ac_cv_type_uid_t" 1>&4
+
+echo "$ac_t""$ac_cv_type_uid_t" 1>&6
 if test $ac_cv_type_uid_t = no; then
   cat >> confdefs.h <<\EOF
 #define uid_t int
@@ -1323,25 +1539,30 @@ EOF
 
 fi
 
-echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_type_signal'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1332 "configure"
+#line 1548 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <signal.h>
 #ifdef signal
 #undef signal
 #endif
-extern void (*signal ()) ();
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
 int main() { return 0; }
 int t() {
 int i;
 ; return 0; }
 EOF
-if eval $ac_link; then
+if eval $ac_compile; then
   rm -rf conftest*
   ac_cv_type_signal=void
 else
@@ -1351,18 +1572,19 @@ fi
 rm -f conftest*
 
 fi
-echo "$ac_t""$ac_cv_type_signal" 1>&4
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
 cat >> confdefs.h <<EOF
 #define RETSIGTYPE $ac_cv_type_signal
 EOF
 
 
-echo $ac_n "checking for time_t""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_type_time_t'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for time_t""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_type_time_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1366 "configure"
+#line 1588 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1380,7 +1602,7 @@ fi
 rm -f conftest*
 
 fi
-echo "$ac_t""$ac_cv_type_time_t" 1>&4
+echo "$ac_t""$ac_cv_type_time_t" 1>&6
 if test $ac_cv_type_time_t = no; then
   cat >> confdefs.h <<\EOF
 #define time_t INT32
@@ -1389,14 +1611,15 @@ EOF
 fi
 
 
-echo $ac_n "checking for -lPW""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_lib_PW'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for -lPW""... $ac_c" 1>&6
+ac_lib_var=`echo PW | tr '.-/+' '___p'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="$LIBS -lPW "
+LIBS="-lPW  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1400 "configure"
+#line 1623 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1406,36 +1629,37 @@ alloca()
 EOF
 if eval $ac_link; then
   rm -rf conftest*
-  eval "ac_cv_lib_PW=yes"
+  eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
-  eval "ac_cv_lib_PW=no"
+  eval "ac_cv_lib_$ac_lib_var=no"
 fi
 rm -f conftest*
 LIBS="$ac_save_LIBS"
 
 fi
-if eval "test \"`echo '$ac_cv_lib_'PW`\" = yes"; then
-  echo "$ac_t""yes" 1>&4
-    ac_tr_lib=HAVE_LIB`echo PW | tr '[a-z]' '[A-Z]'`
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo PW | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_lib 1
 EOF
 
-  LIBS="$LIBS -lPW"
+  LIBS="-lPW $LIBS"
 
 else
-  echo "$ac_t""no" 1>&4
+  echo "$ac_t""no" 1>&6
 fi
 
-echo $ac_n "checking for -lm""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_lib_m'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for -lm""... $ac_c" 1>&6
+ac_lib_var=`echo m | tr '.-/+' '___p'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="$LIBS -lm "
+LIBS="-lm  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1439 "configure"
+#line 1663 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1445,36 +1669,41 @@ floor()
 EOF
 if eval $ac_link; then
   rm -rf conftest*
-  eval "ac_cv_lib_m=yes"
+  eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
-  eval "ac_cv_lib_m=no"
+  eval "ac_cv_lib_$ac_lib_var=no"
 fi
 rm -f conftest*
 LIBS="$ac_save_LIBS"
 
 fi
-if eval "test \"`echo '$ac_cv_lib_'m`\" = yes"; then
-  echo "$ac_t""yes" 1>&4
-    ac_tr_lib=HAVE_LIB`echo m | tr '[a-z]' '[A-Z]'`
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo m | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_lib 1
 EOF
 
-  LIBS="$LIBS -lm"
+  LIBS="-lm $LIBS"
 
 else
-  echo "$ac_t""no" 1>&4
+  echo "$ac_t""no" 1>&6
 fi
 
-echo $ac_n "checking for -lsocket""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_lib_socket'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+if test "${ac_cv_lib_m}" = "no" -a "${lpc_cv_sys_os}" = "Linux"; then
+  echo "configure: warning: I will compensate for this by adding -lc -lm" 1>&2
+  LIBS="${LIBS} -lc -lm"
+fi
+echo $ac_n "checking for -lsocket""... $ac_c" 1>&6
+ac_lib_var=`echo socket | tr '.-/+' '___p'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="$LIBS -lsocket "
+LIBS="-lsocket  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1478 "configure"
+#line 1707 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1484,36 +1713,37 @@ socket()
 EOF
 if eval $ac_link; then
   rm -rf conftest*
-  eval "ac_cv_lib_socket=yes"
+  eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
-  eval "ac_cv_lib_socket=no"
+  eval "ac_cv_lib_$ac_lib_var=no"
 fi
 rm -f conftest*
 LIBS="$ac_save_LIBS"
 
 fi
-if eval "test \"`echo '$ac_cv_lib_'socket`\" = yes"; then
-  echo "$ac_t""yes" 1>&4
-    ac_tr_lib=HAVE_LIB`echo socket | tr '[a-z]' '[A-Z]'`
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo socket | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_lib 1
 EOF
 
-  LIBS="$LIBS -lsocket"
+  LIBS="-lsocket $LIBS"
 
 else
-  echo "$ac_t""no" 1>&4
+  echo "$ac_t""no" 1>&6
 fi
 
-echo $ac_n "checking for -lcrypt""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_lib_crypt'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for -lcrypt""... $ac_c" 1>&6
+ac_lib_var=`echo crypt | tr '.-/+' '___p'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="$LIBS -lcrypt "
+LIBS="-lcrypt  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1517 "configure"
+#line 1747 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1523,37 +1753,38 @@ crypt()
 EOF
 if eval $ac_link; then
   rm -rf conftest*
-  eval "ac_cv_lib_crypt=yes"
+  eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
-  eval "ac_cv_lib_crypt=no"
+  eval "ac_cv_lib_$ac_lib_var=no"
 fi
 rm -f conftest*
 LIBS="$ac_save_LIBS"
 
 fi
-if eval "test \"`echo '$ac_cv_lib_'crypt`\" = yes"; then
-  echo "$ac_t""yes" 1>&4
-    ac_tr_lib=HAVE_LIB`echo crypt | tr '[a-z]' '[A-Z]'`
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo crypt | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_lib 1
 EOF
 
-  LIBS="$LIBS -lcrypt"
+  LIBS="-lcrypt $LIBS"
 
 else
-  echo "$ac_t""no" 1>&4
+  echo "$ac_t""no" 1>&6
 fi
 
 if test "$ac_cv_lib_socket" = yes -o "$ac_cv_lib_ucb"; then
- echo $ac_n "checking for -lnsl""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_lib_nsl'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+ echo $ac_n "checking for -lnsl""... $ac_c" 1>&6
+ac_lib_var=`echo nsl | tr '.-/+' '___p'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="$LIBS -lnsl "
+LIBS="-lnsl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1557 "configure"
+#line 1788 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1563,26 +1794,26 @@ main()
 EOF
 if eval $ac_link; then
   rm -rf conftest*
-  eval "ac_cv_lib_nsl=yes"
+  eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
-  eval "ac_cv_lib_nsl=no"
+  eval "ac_cv_lib_$ac_lib_var=no"
 fi
 rm -f conftest*
 LIBS="$ac_save_LIBS"
 
 fi
-if eval "test \"`echo '$ac_cv_lib_'nsl`\" = yes"; then
-  echo "$ac_t""yes" 1>&4
-    ac_tr_lib=HAVE_LIB`echo nsl | tr '[a-z]' '[A-Z]'`
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo nsl | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_lib 1
 EOF
 
-  LIBS="$LIBS -lnsl"
+  LIBS="-lnsl $LIBS"
 
 else
-  echo "$ac_t""no" 1>&4
+  echo "$ac_t""no" 1>&6
 fi
 
 fi
@@ -1590,15 +1821,15 @@ fi
 
 OLD_LIBOBJS="${LIBOBJS}"
 
-echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_func_memcmp'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_func_memcmp'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test "$cross_compiling" = yes; then
   ac_cv_func_memcmp=no
 else
 cat > conftest.$ac_ext <<EOF
-#line 1602 "configure"
+#line 1833 "configure"
 #include "confdefs.h"
 
 main()
@@ -1617,7 +1848,8 @@ fi
 fi
 rm -fr conftest*
 fi
-echo "$ac_t""$ac_cv_func_memcmp" 1>&4
+
+echo "$ac_t""$ac_cv_func_memcmp" 1>&6
 test $ac_cv_func_memcmp = no && LIBOBJS="$LIBOBJS memcmp.o"
 
 
@@ -1630,17 +1862,52 @@ fi
 
 LIBOBJS="${OLD_LIBOBJS}"
 
+echo $ac_n "checking for strcoll""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_func_strcoll'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_func_strcoll=no
+else
+cat > conftest.$ac_ext <<EOF
+#line 1874 "configure"
+#include "confdefs.h"
+#include <string.h>
+main ()
+{
+  exit (strcoll ("abc", "def") >= 0 ||
+	strcoll ("ABC", "DEF") >= 0 ||
+	strcoll ("123", "456") >= 0);
+}
+EOF
+eval $ac_link
+if test -s conftest && (./conftest; exit) 2>/dev/null; then
+  ac_cv_func_strcoll=yes
+else
+  ac_cv_func_strcoll=no
+fi
+fi
+rm -fr conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_strcoll" 1>&6
+if test $ac_cv_func_strcoll = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_STRCOLL 1
+EOF
+
+fi
+
+
 for ac_func in _crypt \
  bcopy \
  bzero \
  clock \
  crypt \
  fchmod \
- getcwd \
  getenv \
  getrlimit \
  getrusage \
- getwd \
  index \
  memchr \
  memcpy \
@@ -1648,6 +1915,8 @@ for ac_func in _crypt \
  rindex \
  setlocale \
  setrlimit \
+ sigaction \
+ sigvec \
  strcasecmp \
  strchr \
  strcspn \
@@ -1658,16 +1927,24 @@ for ac_func in _crypt \
  times \
  vfprintf \
  vsprintf \
+ wait3 \
+ wait4 \
+ waitpid \
 
 do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_func_$ac_func'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1669 "configure"
+#line 1941 "configure"
 #include "confdefs.h"
-#include <ctype.h> /* Arbitrary system header to define __stub macros. */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+char $ac_func();
+
 int main() { return 0; }
 int t() {
 
@@ -1677,8 +1954,7 @@ int t() {
 #if defined (__stub_$ac_func) || defined (__stub___$ac_func)
 choke me
 #else
-/* Override any gcc2 internal prototype to avoid an error.  */
-char $ac_func(); $ac_func();
+$ac_func();
 #endif
 
 ; return 0; }
@@ -1694,14 +1970,14 @@ rm -f conftest*
 
 fi
 if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
-  echo "$ac_t""yes" 1>&4
-    ac_tr_func=HAVE_`echo $ac_func | tr '[a-z]' '[A-Z]'`
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_func 1
 EOF
  
 else
-  echo "$ac_t""no" 1>&4
+  echo "$ac_t""no" 1>&6
 fi
 done
 
@@ -1709,16 +1985,16 @@ done
 
 
 
- echo $ac_n "checking for strchr declaration""... $ac_c" 1>&4
- if eval "test \"`echo '${'lpc_cv_decl_strchr'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+ echo $ac_n "checking for strchr declaration""... $ac_c" 1>&6
+ if eval "test \"`echo '$''{'lpc_cv_decl_strchr'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
    lpc_cv_decl_strchr=nonexistant
    for a in string.h unistd.h stdlib.h
    do
      cat > conftest.$ac_ext <<EOF
-#line 1722 "configure"
+#line 1998 "configure"
 #include "confdefs.h"
 #include <$a>
 EOF
@@ -1733,7 +2009,7 @@ rm -f conftest*
  
 fi
 
- echo "$ac_t""$lpc_cv_decl_strchr" 1>&4
+ echo "$ac_t""$lpc_cv_decl_strchr" 1>&6
  if test "$lpc_cv_decl_strchr" = nonexistant; then
    cat >> confdefs.h <<\EOF
 #define STRCHR_DECL_MISSING 1
@@ -1742,16 +2018,16 @@ EOF
  fi
 
 
- echo $ac_n "checking for malloc declaration""... $ac_c" 1>&4
- if eval "test \"`echo '${'lpc_cv_decl_malloc'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+ echo $ac_n "checking for malloc declaration""... $ac_c" 1>&6
+ if eval "test \"`echo '$''{'lpc_cv_decl_malloc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
    lpc_cv_decl_malloc=nonexistant
    for a in memory.h unistd.h stdlib.h
    do
      cat > conftest.$ac_ext <<EOF
-#line 1755 "configure"
+#line 2031 "configure"
 #include "confdefs.h"
 #include <$a>
 EOF
@@ -1766,7 +2042,7 @@ rm -f conftest*
  
 fi
 
- echo "$ac_t""$lpc_cv_decl_malloc" 1>&4
+ echo "$ac_t""$lpc_cv_decl_malloc" 1>&6
  if test "$lpc_cv_decl_malloc" = nonexistant; then
    cat >> confdefs.h <<\EOF
 #define MALLOC_DECL_MISSING 1
@@ -1775,16 +2051,16 @@ EOF
  fi
 
 
- echo $ac_n "checking for getpeername declaration""... $ac_c" 1>&4
- if eval "test \"`echo '${'lpc_cv_decl_getpeername'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+ echo $ac_n "checking for getpeername declaration""... $ac_c" 1>&6
+ if eval "test \"`echo '$''{'lpc_cv_decl_getpeername'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
    lpc_cv_decl_getpeername=nonexistant
    for a in sys/socket.h sys/socketvar.h sys/socketio.h
    do
      cat > conftest.$ac_ext <<EOF
-#line 1788 "configure"
+#line 2064 "configure"
 #include "confdefs.h"
 #include <$a>
 EOF
@@ -1799,7 +2075,7 @@ rm -f conftest*
  
 fi
 
- echo "$ac_t""$lpc_cv_decl_getpeername" 1>&4
+ echo "$ac_t""$lpc_cv_decl_getpeername" 1>&6
  if test "$lpc_cv_decl_getpeername" = nonexistant; then
    cat >> confdefs.h <<\EOF
 #define GETPEERNAME_DECL_MISSING 1
@@ -1808,16 +2084,16 @@ EOF
  fi
 
 
- echo $ac_n "checking for popen declaration""... $ac_c" 1>&4
- if eval "test \"`echo '${'lpc_cv_decl_popen'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+ echo $ac_n "checking for popen declaration""... $ac_c" 1>&6
+ if eval "test \"`echo '$''{'lpc_cv_decl_popen'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
    lpc_cv_decl_popen=nonexistant
    for a in stdio.h unistd.h
    do
      cat > conftest.$ac_ext <<EOF
-#line 1821 "configure"
+#line 2097 "configure"
 #include "confdefs.h"
 #include <$a>
 EOF
@@ -1832,7 +2108,7 @@ rm -f conftest*
  
 fi
 
- echo "$ac_t""$lpc_cv_decl_popen" 1>&4
+ echo "$ac_t""$lpc_cv_decl_popen" 1>&6
  if test "$lpc_cv_decl_popen" = nonexistant; then
    cat >> confdefs.h <<\EOF
 #define POPEN_DECL_MISSING 1
@@ -1841,16 +2117,16 @@ EOF
  fi
 
 
- echo $ac_n "checking for getenv declaration""... $ac_c" 1>&4
- if eval "test \"`echo '${'lpc_cv_decl_getenv'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+ echo $ac_n "checking for getenv declaration""... $ac_c" 1>&6
+ if eval "test \"`echo '$''{'lpc_cv_decl_getenv'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
    lpc_cv_decl_getenv=nonexistant
    for a in unistd.h stdlib.h
    do
      cat > conftest.$ac_ext <<EOF
-#line 1854 "configure"
+#line 2130 "configure"
 #include "confdefs.h"
 #include <$a>
 EOF
@@ -1865,7 +2141,7 @@ rm -f conftest*
  
 fi
 
- echo "$ac_t""$lpc_cv_decl_getenv" 1>&4
+ echo "$ac_t""$lpc_cv_decl_getenv" 1>&6
  if test "$lpc_cv_decl_getenv" = nonexistant; then
    cat >> confdefs.h <<\EOF
 #define GETENV_DECL_MISSING 1
@@ -1874,16 +2150,16 @@ EOF
  fi
 
 
- echo $ac_n "checking for gethostname declaration""... $ac_c" 1>&4
- if eval "test \"`echo '${'lpc_cv_decl_gethostname'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+ echo $ac_n "checking for gethostname declaration""... $ac_c" 1>&6
+ if eval "test \"`echo '$''{'lpc_cv_decl_gethostname'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
    lpc_cv_decl_gethostname=nonexistant
    for a in unistd.h
    do
      cat > conftest.$ac_ext <<EOF
-#line 1887 "configure"
+#line 2163 "configure"
 #include "confdefs.h"
 #include <$a>
 EOF
@@ -1898,7 +2174,7 @@ rm -f conftest*
  
 fi
 
- echo "$ac_t""$lpc_cv_decl_gethostname" 1>&4
+ echo "$ac_t""$lpc_cv_decl_gethostname" 1>&6
  if test "$lpc_cv_decl_gethostname" = nonexistant; then
    cat >> confdefs.h <<\EOF
 #define GETHOSTNAME_DECL_MISSING 1
@@ -1907,12 +2183,12 @@ EOF
  fi
 
 
-echo $ac_n "checking return type of free""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_sys_free_return'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking return type of free""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_sys_free_return'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1916 "configure"
+#line 2192 "configure"
 #include "confdefs.h"
 
 #ifdef HAVE_STDLIB_H
@@ -1954,18 +2230,18 @@ if test "$lpc_cv_sys_free_return" = void; then
 #define FREE_RETURNS_VOID 1
 EOF
 
-  echo "$ac_t""void" 1>&4;
+  echo "$ac_t""void" 1>&6;
 else
-  echo "$ac_t""not void" 1>&4
+  echo "$ac_t""not void" 1>&6
 fi
 
-echo $ac_n "checking void* or char* from malloc""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_sys_malloc_return'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking void* or char* from malloc""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_sys_malloc_return'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 cat > conftest.$ac_ext <<EOF
-#line 1969 "configure"
+#line 2245 "configure"
 #include "confdefs.h"
 
 #include <sys/types.h>
@@ -2011,7 +2287,7 @@ rm -f conftest*
 fi
 
 
-echo "$ac_t""$lpc_cv_sys_malloc_return" 1>&4
+echo "$ac_t""$lpc_cv_sys_malloc_return" 1>&6
 cat >> confdefs.h <<EOF
 #define POINTER $lpc_cv_sys_malloc_return
 EOF
@@ -2020,12 +2296,12 @@ EOF
 
 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
 # for constant arguments.  Useless!
-echo $ac_n "checking for working alloca.h""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_header_alloca_h'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2029 "configure"
+#line 2305 "configure"
 #include "confdefs.h"
 #include <alloca.h>
 int main() { return 0; }
@@ -2043,7 +2319,8 @@ fi
 rm -f conftest*
 
 fi
-echo "$ac_t""$ac_cv_header_alloca_h" 1>&4
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
 if test $ac_cv_header_alloca_h = yes; then
   cat >> confdefs.h <<\EOF
 #define HAVE_ALLOCA_H 1
@@ -2051,12 +2328,12 @@ EOF
 
 fi
 
-echo $ac_n "checking for alloca""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_func_alloca'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_func_alloca'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2060 "configure"
+#line 2337 "configure"
 #include "confdefs.h"
 
 #ifdef __GNUC__
@@ -2090,7 +2367,8 @@ fi
 rm -f conftest*
 
 fi
-echo "$ac_t""$ac_cv_func_alloca" 1>&4
+
+echo "$ac_t""$ac_cv_func_alloca" 1>&6
 if test $ac_cv_func_alloca = yes; then
   cat >> confdefs.h <<\EOF
 #define HAVE_ALLOCA 1
@@ -2109,12 +2387,12 @@ if test $ac_cv_func_alloca = no; then
 EOF
 
 
-echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_os_cray'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2118 "configure"
+#line 2396 "configure"
 #include "confdefs.h"
 #if defined(CRAY) && ! defined(CRAY2)
 webecray
@@ -2134,148 +2412,70 @@ fi
 rm -f conftest*
 
 fi
-echo "$ac_t""$ac_cv_os_cray" 1>&4
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
 if test $ac_cv_os_cray = yes; then
-echo $ac_n "checking for _getb67""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_func__getb67'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+for ac_func in _getb67 GETB67 getb67; do
+  echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2145 "configure"
+#line 2425 "configure"
 #include "confdefs.h"
-#include <ctype.h> /* Arbitrary system header to define __stub macros. */
-int main() { return 0; }
-int t() {
-
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined (__stub__getb67) || defined (__stub____getb67)
-choke me
-#else
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
 /* Override any gcc2 internal prototype to avoid an error.  */
-char _getb67(); _getb67();
-#endif
-
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  eval "ac_cv_func__getb67=yes"
-else
-  rm -rf conftest*
-  eval "ac_cv_func__getb67=no"
-fi
-rm -f conftest*
-
-fi
-if eval "test \"`echo '$ac_cv_func_'_getb67`\" = yes"; then
-  echo "$ac_t""yes" 1>&4
-  cat >> confdefs.h <<\EOF
-#define CRAY_STACKSEG_END _getb67
-EOF
+char $ac_func();
 
-else
-  echo "$ac_t""no" 1>&4
-echo $ac_n "checking for GETB67""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_func_GETB67'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
-else
-  cat > conftest.$ac_ext <<EOF
-#line 2186 "configure"
-#include "confdefs.h"
-#include <ctype.h> /* Arbitrary system header to define __stub macros. */
 int main() { return 0; }
 int t() {
 
 /* The GNU C library defines this for functions which it implements
     to always fail with ENOSYS.  Some functions are actually named
     something starting with __ and the normal name is an alias.  */
-#if defined (__stub_GETB67) || defined (__stub___GETB67)
-choke me
-#else
-/* Override any gcc2 internal prototype to avoid an error.  */
-char GETB67(); GETB67();
-#endif
-
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  eval "ac_cv_func_GETB67=yes"
-else
-  rm -rf conftest*
-  eval "ac_cv_func_GETB67=no"
-fi
-rm -f conftest*
-
-fi
-if eval "test \"`echo '$ac_cv_func_'GETB67`\" = yes"; then
-  echo "$ac_t""yes" 1>&4
-  cat >> confdefs.h <<\EOF
-#define CRAY_STACKSEG_END GETB67
-EOF
-
-else
-  echo "$ac_t""no" 1>&4
-echo $ac_n "checking for getb67""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_func_getb67'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
-else
-  cat > conftest.$ac_ext <<EOF
-#line 2227 "configure"
-#include "confdefs.h"
-#include <ctype.h> /* Arbitrary system header to define __stub macros. */
-int main() { return 0; }
-int t() {
-
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined (__stub_getb67) || defined (__stub___getb67)
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
 choke me
 #else
-/* Override any gcc2 internal prototype to avoid an error.  */
-char getb67(); getb67();
+$ac_func();
 #endif
 
 ; return 0; }
 EOF
 if eval $ac_link; then
   rm -rf conftest*
-  eval "ac_cv_func_getb67=yes"
+  eval "ac_cv_func_$ac_func=yes"
 else
   rm -rf conftest*
-  eval "ac_cv_func_getb67=no"
+  eval "ac_cv_func_$ac_func=no"
 fi
 rm -f conftest*
 
 fi
-if eval "test \"`echo '$ac_cv_func_'getb67`\" = yes"; then
-  echo "$ac_t""yes" 1>&4
-  cat >> confdefs.h <<\EOF
-#define CRAY_STACKSEG_END getb67
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
 EOF
 
+  break
 else
-  echo "$ac_t""no" 1>&4
-fi
-
-fi
-
+  echo "$ac_t""no" 1>&6
 fi
 
+done
 fi
 
-echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_c_stack_direction'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test "$cross_compiling" = yes; then
   ac_cv_c_stack_direction=0
 else
 cat > conftest.$ac_ext <<EOF
-#line 2279 "configure"
+#line 2479 "configure"
 #include "confdefs.h"
 find_stack_direction ()
 {
@@ -2303,7 +2503,8 @@ fi
 fi
 rm -fr conftest*
 fi
-echo "$ac_t""$ac_cv_c_stack_direction" 1>&4
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
 cat >> confdefs.h <<EOF
 #define STACK_DIRECTION $ac_cv_c_stack_direction
 EOF
@@ -2311,12 +2512,12 @@ EOF
 fi
 
 
-echo $ac_n "checking for working const""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_c_const'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2320 "configure"
+#line 2521 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -2327,6 +2528,9 @@ typedef int charset[2]; const charset x;
 /* SunOS 4.1.1 cc rejects this.  */
 char const *const *ccp;
 char **p;
+/* NEC SVR4.0.2 mips cc rejects this.  */
+struct point {int x, y;};
+static struct point const zero = {0,0};
 /* AIX XL C 1.02.0.0 rejects this.
    It does not let you subtract one const X* pointer from another in an arm
    of an if-expression whose if-part is not a constant expression */
@@ -2363,7 +2567,7 @@ ccp = (char const *const *) p;
 
 ; return 0; }
 EOF
-if eval $ac_link; then
+if eval $ac_compile; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -2373,7 +2577,8 @@ fi
 rm -f conftest*
 
 fi
-echo "$ac_t""$ac_cv_c_const" 1>&4
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
 if test $ac_cv_c_const = no; then
   cat >> confdefs.h <<\EOF
 #define const 
@@ -2381,52 +2586,60 @@ EOF
 
 fi
 
-echo $ac_n "checking for inline""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_c_inline'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
-  if test "$GCC" = yes; then
-cat > conftest.$ac_ext <<EOF
-#line 2391 "configure"
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat > conftest.$ac_ext <<EOF
+#line 2597 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
 int t() {
-} inline foo() {
+} $ac_kw foo() {
 ; return 0; }
 EOF
-if eval $ac_link; then
+if eval $ac_compile; then
   rm -rf conftest*
-  ac_cv_c_inline=yes
-else
-  rm -rf conftest*
-  ac_cv_c_inline=no
+  ac_cv_c_inline=$ac_kw; break
 fi
 rm -f conftest*
 
-else
-  ac_cv_c_inline=no
-fi
-fi
-echo "$ac_t""$ac_cv_c_inline" 1>&4
-if test $ac_cv_c_inline = no; then
-  cat >> confdefs.h <<\EOF
-#define inline __inline
-EOF
+done
 
 fi
 
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+  inline | yes) ;;
+  no) cat >> confdefs.h <<\EOF
+#define inline 
+EOF
+ ;;
+  *)  cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
 
 for ac_func in ualarm
 do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&4
-if eval "test \"`echo '${'ac_cv_func_$ac_func'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2428 "configure"
+#line 2636 "configure"
 #include "confdefs.h"
-#include <ctype.h> /* Arbitrary system header to define __stub macros. */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+char $ac_func();
+
 int main() { return 0; }
 int t() {
 
@@ -2436,8 +2649,7 @@ int t() {
 #if defined (__stub_$ac_func) || defined (__stub___$ac_func)
 choke me
 #else
-/* Override any gcc2 internal prototype to avoid an error.  */
-char $ac_func(); $ac_func();
+$ac_func();
 #endif
 
 ; return 0; }
@@ -2453,10 +2665,10 @@ rm -f conftest*
 
 fi
 if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
-  echo "$ac_t""yes" 1>&4
+  echo "$ac_t""yes" 1>&6
   :
 else
-  echo "$ac_t""no" 1>&4
+  echo "$ac_t""no" 1>&6
 LIBOBJS="$LIBOBJS ${ac_func}.o"
 fi
 
@@ -2473,16 +2685,16 @@ EOF
   ;;
 esac
 
-echo $ac_n "checking byteorder""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_hardware_byteorder'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking byteorder""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_hardware_byteorder'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 2486 "configure"
+#line 2698 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -2525,22 +2737,22 @@ rm -fr conftest*
 fi
 
 
-echo "$ac_t""$lpc_cv_hardware_byteorder" 1>&4
+echo "$ac_t""$lpc_cv_hardware_byteorder" 1>&6
 cat >> confdefs.h <<EOF
 #define BYTEORDER $lpc_cv_hardware_byteorder
 EOF
 
 
-echo $ac_n "checking for working memmem""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_func_memmem'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for working memmem""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_func_memmem'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 2544 "configure"
+#line 2756 "configure"
 #include "confdefs.h"
 
 #include <string.h>
@@ -2572,118 +2784,117 @@ fi
 
 
 if test "$lpc_cv_func_memmem" = yes; then
-  echo "$ac_t""yes" 1>&4
+  echo "$ac_t""yes" 1>&6
   cat >> confdefs.h <<\EOF
 #define HAVE_MEMMEM 1
 EOF
 
 else
-  echo "$ac_t""no" 1>&4
+  echo "$ac_t""no" 1>&6
 fi
 
-echo $ac_n "checking for working strcoll""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_func_strcoll'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for working memmove""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_func_memmove'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 2594 "configure"
+#line 2806 "configure"
 #include "confdefs.h"
 
 #include <string.h>
+char buf[100];
 int main()
 {
-  if(strcoll("a","b")< 0 &&
-     strcoll("a","a")==0 &&
-     strcoll("b","a")> 0)
-    exit(0);
-  exit(1);
+  strcpy(buf,"foo bar gazonk elefantsnabel.");
+  if(strcmp(buf,"foo bar gazonk elefantsnabel.")) exit(1);
+  memmove(buf,buf+1,7);
+  if(strcmp(buf,"oo bar  gazonk elefantsnabel.")) exit(1);
+  memmove(buf+1,buf+1,9);
+  if(strcmp(buf,"oo bar  gazonk elefantsnabel.")) exit(1);
+  memmove(buf+1,buf,11);
+  if(strcmp(buf,"ooo bar  gaznk elefantsnabel.")) exit(1);
+  exit(0);
 }
 
 EOF
 eval $ac_link
 if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  lpc_cv_func_strcoll=yes
+  lpc_cv_func_memmove=yes
 else
-  lpc_cv_func_strcoll=no
+  lpc_cv_func_memmove=no
 fi
 fi
 rm -fr conftest*
 fi
 
 
-if test "$lpc_cv_func_strcoll" = yes; then
-  echo "$ac_t""yes" 1>&4
+if test "$lpc_cv_func_memmove" = yes; then
+  echo "$ac_t""yes" 1>&6
   cat >> confdefs.h <<\EOF
-#define HAVE_STRCOLL 1
+#define HAVE_MEMMOVE 1
 EOF
 
 else
-  echo "$ac_t""no" 1>&4
+  echo "$ac_t""no" 1>&6
 fi
 
-echo $ac_n "checking for working memmove""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_func_memmove'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking how to extract an unsigned char""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_method_extract_uchar'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 2638 "configure"
+#line 2855 "configure"
 #include "confdefs.h"
 
-#include <string.h>
-char buf[100];
 int main()
 {
-  strcpy(buf,"foo bar gazonk elefantsnabel.");
-  if(strcmp(buf,"foo bar gazonk elefantsnabel.")) exit(1);
-  memmove(buf,buf+1,7);
-  if(strcmp(buf,"oo bar  gazonk elefantsnabel.")) exit(1);
-  memmove(buf+1,buf+1,9);
-  if(strcmp(buf,"oo bar  gazonk elefantsnabel.")) exit(1);
-  memmove(buf+1,buf,11);
-  if(strcmp(buf,"ooo bar  gaznk elefantsnabel.")) exit(1);
+  char i,*p;
+  i=-10;
+  p=&i;
+  if(*(unsigned char *)(p)!= 0x100 - 10) exit(1);
   exit(0);
 }
 
 EOF
 eval $ac_link
 if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  lpc_cv_func_memmove=yes
+  lpc_cv_method_extract_uchar=by_cast
 else
-  lpc_cv_func_memmove=no
+  lpc_cv_method_extract_uchar=not_by_cast
 fi
 fi
 rm -fr conftest*
 fi
 
 
-if test "$lpc_cv_func_memmove" = yes; then
-  echo "$ac_t""yes" 1>&4
+if test "$lpc_cv_method_extract_uchar" = by_cast; then
+  echo "$ac_t""by cast" 1>&6
   cat >> confdefs.h <<\EOF
-#define HAVE_MEMMOVE 1
+#define EXTRACT_UCHAR_BY_CAST 1
 EOF
 
 else
-  echo "$ac_t""no" 1>&4
+  echo "$ac_t""not by cast" 1>&6
 fi
 
-echo $ac_n "checking how to extract an unsigned char""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_method_extract_uchar'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking how to extract a signed char""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_method_extract_char'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 2687 "configure"
+#line 2898 "configure"
 #include "confdefs.h"
 
 int main()
@@ -2691,85 +2902,122 @@ int main()
   char i,*p;
   i=-10;
   p=&i;
-  if(*(unsigned char *)(p)!= 0x100 - 10) exit(1);
+  if(*(signed char *)(p)!= -10) exit(1);
   exit(0);
 }
 
 EOF
 eval $ac_link
 if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  lpc_cv_method_extract_uchar=by_cast
+  lpc_cv_method_extract_char=by_cast
 else
-  lpc_cv_method_extract_uchar=not_by_cast
+  lpc_cv_method_extract_char=not_by_cast
 fi
 fi
 rm -fr conftest*
 fi
 
 
-if test "$lpc_cv_method_extract_uchar" = by_cast; then
-  echo "$ac_t""by cast" 1>&4
+if test "$lpc_cv_method_extract_char" = by_cast; then
+  echo "$ac_t""by cast" 1>&6
   cat >> confdefs.h <<\EOF
-#define EXTRACT_UCHAR_BY_CAST 1
+#define EXTRACT_CHAR_BY_CAST 1
 EOF
 
 else
-  echo "$ac_t""not by cast" 1>&4
+  echo "$ac_t""not by cast" 1>&6
 fi
 
-echo $ac_n "checking how to extract a signed char""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_method_extract_char'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+
+echo $ac_n "checking if signal handlers reset automatically""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_sys_signal_oneshot'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 2730 "configure"
+#line 2942 "configure"
 #include "confdefs.h"
 
+#include <signal.h>
+char sigrun=0;
+RETSIGTYPE func(int sig) { sigrun=1; }
+
 int main()
 {
-  char i,*p;
-  i=-10;
-  p=&i;
-  if(*(signed char *)(p)!= -10) exit(1);
+#define sig SIGSEGV
+
+#ifdef HAVE_SIGACTION
+  {
+    struct sigaction action;
+    action.sa_handler= func;
+    sigfillset(&action.sa_mask);
+#ifdef SA_INTERRUPT
+    action.sa_flags=SA_INTERRUPT;
+#endif
+    sigaction(sig,&action,0);
+  }
+#else
+#ifdef HAVE_SIGVEC
+  {
+    struct sigvec action;
+    action.sv_handler= func;
+    action.sv_mask=-1;
+#ifdef SV_INTERRUPT
+    action.sv_flags=SV_INTERRUPT;
+#endif
+    sigvec(sig,&action,0);
+  }
+#else
+  signal(sig, func);
+#endif
+#endif
+
+  kill(getpid(), sig);
+  while(!sigrun) sleep(1);
+  sigrun=0;
+  kill(getpid(), sig);
+  while(!sigrun) sleep(1);
+  sigrun=0;
   exit(0);
 }
 
 EOF
 eval $ac_link
 if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  lpc_cv_method_extract_char=by_cast
+  lpc_cv_sys_signal_oneshot=no
 else
-  lpc_cv_method_extract_char=not_by_cast
+  lpc_cv_sys_signal_oneshot=yes
 fi
 fi
 rm -fr conftest*
 fi
 
 
-if test "$lpc_cv_method_extract_char" = by_cast; then
-  echo "$ac_t""by cast" 1>&4
+if test "$lpc_cv_sys_signal_oneshot" = yes; then
+  echo "$ac_t""yes" 1>&6
   cat >> confdefs.h <<\EOF
-#define EXTRACT_CHAR_BY_CAST 1
+#define SIGNAL_ONESHOT 1
 EOF
 
 else
-  echo "$ac_t""not by cast" 1>&4
+  echo "$ac_t""no" 1>&6
 fi
 
-echo $ac_n "checking available file descriptors""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_max_open_fd'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+
+
+echo $ac_n "checking available file descriptors""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_max_open_fd'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 2773 "configure"
+#line 3021 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -2832,20 +3080,20 @@ fi
 rm -fr conftest*
 fi
 
-echo "$ac_t""$lpc_cv_max_open_fd" 1>&4
+echo "$ac_t""$lpc_cv_max_open_fd" 1>&6
 cat >> confdefs.h <<EOF
 #define MAX_OPEN_FILEDESCRIPTORS $lpc_cv_max_open_fd
 EOF
 
 
 if test "$ac_cv_func_getrusage" = "yes"; then
-echo $ac_n "checking full availability of struct rusage members""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_func_getrusage_full'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking full availability of struct rusage members""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_func_getrusage_full'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 cat > conftest.$ac_ext <<EOF
-#line 2849 "configure"
+#line 3097 "configure"
 #include "confdefs.h"
 
 #include <sys/time.h>
@@ -2895,9 +3143,9 @@ fi
 
 
 if test "$lpc_cv_func_getrusage_full" = yes; then
-  echo "$ac_t""all there" 1>&4
+  echo "$ac_t""all there" 1>&6
 else
-  echo "$ac_t""getrusage is restricted" 1>&4
+  echo "$ac_t""getrusage is restricted" 1>&6
   cat >> confdefs.h <<\EOF
 #define GETRUSAGE_RESTRICTED 1
 EOF
@@ -2906,13 +3154,13 @@ fi
 
 else
 
-echo $ac_n "checking getrusage() through procfs""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_getrusage_procfs'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking getrusage() through procfs""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_getrusage_procfs'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 cat > conftest.$ac_ext <<EOF
-#line 2916 "configure"
+#line 3164 "configure"
 #include "confdefs.h"
 
 #include <sys/procfs.h>
@@ -2943,23 +3191,23 @@ fi
 
 
 if test "$lpc_cv_getrusage_procfs" = yes; then
-  echo "$ac_t""yes" 1>&4
+  echo "$ac_t""yes" 1>&6
   cat >> confdefs.h <<\EOF
 #define GETRUSAGE_THROUGH_PROCFS 1
 EOF
 
 else
-  echo "$ac_t""no" 1>&4
+  echo "$ac_t""no" 1>&6
 fi
 fi
 
-echo $ac_n "checking checking for volatile""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_volatile'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking checking for volatile""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_volatile'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
  cat > conftest.$ac_ext <<EOF
-#line 2963 "configure"
+#line 3211 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -2981,29 +3229,29 @@ fi
 
 
 if test "$lpc_cv_volatile" = yes; then
- echo "$ac_t""yes" 1>&4
+ echo "$ac_t""yes" 1>&6
  cat >> confdefs.h <<\EOF
 #define VOLATILE volatile
 EOF
 
 else
- echo "$ac_t""no" 1>&4
+ echo "$ac_t""no" 1>&6
  cat >> confdefs.h <<\EOF
 #define VOLATILE 
 EOF
 
 fi
 
-echo $ac_n "checking for gcc function attributes""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_gcc_attributes'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking for gcc function attributes""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_gcc_attributes'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 3007 "configure"
+#line 3255 "configure"
 #include "confdefs.h"
 
 #include <stdarg.h>
@@ -3035,7 +3283,7 @@ rm -fr conftest*
 fi
 
 
-echo "$ac_t""$lpc_cv_gcc_attributes" 1>&4
+echo "$ac_t""$lpc_cv_gcc_attributes" 1>&6
 if test "$lpc_cv_gcc_attributes" = yes; then
  cat >> confdefs.h <<\EOF
 #define HAVE_FUNCTION_ATTRIBUTES 1
@@ -3043,16 +3291,16 @@ EOF
 
 fi
 
-echo $ac_n "checking how to set things nonblocking""... $ac_c" 1>&4
-if eval "test \"`echo '${'lpc_cv_sys_nonblock'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&4
+echo $ac_n "checking how to set things nonblocking""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'lpc_cv_sys_nonblock'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 3056 "configure"
+#line 3304 "configure"
 #include "confdefs.h"
 
 #define TESTING
@@ -3068,7 +3316,7 @@ else
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 3072 "configure"
+#line 3320 "configure"
 #include "confdefs.h"
 
 #define TESTING
@@ -3084,7 +3332,7 @@ else
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 3088 "configure"
+#line 3336 "configure"
 #include "confdefs.h"
 
 #define TESTING
@@ -3100,7 +3348,7 @@ else
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 3104 "configure"
+#line 3352 "configure"
 #include "confdefs.h"
 
 #define TESTING
@@ -3130,9 +3378,9 @@ fi
 
 
 if test "${lpc_cv_sys_nonblock}" = ""; then
-  echo "$ac_t""none found" 1>&4
+  echo "$ac_t""none found" 1>&6
 else
- echo "$ac_t""$lpc_cv_sys_nonblock" 1>&4
+ echo "$ac_t""$lpc_cv_sys_nonblock" 1>&6
  cat >> confdefs.h <<EOF
 #define $lpc_cv_sys_nonblock 1
 EOF
@@ -3158,6 +3406,7 @@ done
 
 LIBDIR=`(cd $srcdir/../lib ; pwd)`
 BINDIR=`(cd $srcdir/../bin ; pwd)`
+DOCDIR=`(cd $srcdir/../doc ; pwd)`
 BUILDDIR=`pwd`
 
 subdirs="$dirs"
@@ -3173,10 +3422,9 @@ subdirs="$dirs"
 
 
 
+
 trap '' 1 2 15
-if test -w $cache_file; then
-echo "updating cache $cache_file"
-cat > $cache_file <<\EOF
+cat > confcache <<\EOF
 # This file is a shell script that caches the results of configure
 # tests run on this system so they can be shared between configure
 # scripts and configure runs.  It is not useful on other systems.
@@ -3192,17 +3440,26 @@ cat > $cache_file <<\EOF
 # --recheck option to rerun configure.
 #
 EOF
-# Ultrix sh set writes to stderr and can't be redirected directly.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
 (set) 2>&1 |
-  sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/: \${\1='\2'}/p" \
-  >> $cache_file
+  sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \
+  >> confcache
+if cmp -s $cache_file confcache; then
+  :
 else
-echo "not updating unwritable cache $cache_file"
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
 fi
+rm -f confcache
 
-trap 'rm -fr conftest* confdefs* core $ac_clean_files; exit 1' 1 2 15
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
 
-test "x$prefix" = xNONE && prefix=/usr/local
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
 # Let make expand exec_prefix.
 test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
 
@@ -3223,7 +3480,7 @@ DEFS=-DHAVE_CONFIG_H
 echo creating $CONFIG_STATUS
 rm -f $CONFIG_STATUS
 cat > $CONFIG_STATUS <<EOF
-#!/bin/sh
+#! /bin/sh
 # Generated automatically by configure.
 # Run this file to recreate the current configuration.
 # This directory was configured as follows,
@@ -3242,7 +3499,7 @@ do
     echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
     exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
   -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
-    echo "$CONFIG_STATUS generated by autoconf version 1.119"
+    echo "$CONFIG_STATUS generated by autoconf version 2.7"
     exit 0 ;;
   -help | --help | --hel | --he | --h)
     echo "\$ac_cs_usage"; exit 0 ;;
@@ -3253,11 +3510,13 @@ done
 ac_given_srcdir=$srcdir
 ac_given_INSTALL="$INSTALL"
 
-trap 'rm -fr Makefile machine.h conftest*; exit 1' 1 2 15
+trap 'rm -fr `echo "Makefile machine.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
 
-# Protect against being on the right side of a sed subst in config.status. 
-sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\\\&%]/\\\\&/g; 
- s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
 $ac_vpsub
 $extrasub
 s%@CFLAGS@%$CFLAGS%g
@@ -3268,6 +3527,19 @@ s%@LDFLAGS@%$LDFLAGS%g
 s%@LIBS@%$LIBS%g
 s%@exec_prefix@%$exec_prefix%g
 s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
 s%@CC@%$CC%g
 s%@uname_prog@%$uname_prog%g
 s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
@@ -3287,6 +3559,7 @@ s%@EXTRA_OBJS@%$EXTRA_OBJS%g
 s%@LIBDIR@%$LIBDIR%g
 s%@BINDIR@%$BINDIR%g
 s%@BUILDDIR@%$BUILDDIR%g
+s%@DOCDIR@%$DOCDIR%g
 
 CEOF
 EOF
@@ -3310,7 +3583,7 @@ for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
   if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
     # The file is in a subdirectory.
     test ! -d "$ac_dir" && mkdir "$ac_dir"
-    ac_dir_suffix="/$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
     # A "../" for each directory in $ac_dir_suffix.
     ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
   else
@@ -3385,7 +3658,7 @@ EOF
 
 # Transform confdefs.h into a sed script conftest.vals that substitutes
 # the proper values into config.h.in to produce config.h.  And first:
-# Protect against being on the right side of a sed subst in config.status. 
+# Protect against being on the right side of a sed subst in config.status.
 # Protect against being in an unquoted here document in config.status.
 rm -f conftest.vals
 cat > conftest.hdr <<\EOF
@@ -3456,7 +3729,7 @@ if test ! -d ./modules ; then
   mkdir modules
 fi
 
-echo "$ac_t""creating modlist.h" 1>&4
+echo "$ac_t""creating modlist.h" 1>&6
 echo "void init_main_efuns(void);" >modlist.h
 echo "void init_main_programs(void);" >>modlist.h
 echo "void exit_main(void);" >>modlist.h
@@ -3482,7 +3755,7 @@ exit 0
 EOF
 chmod +x $CONFIG_STATUS
 rm -fr confdefs* $ac_clean_files
-test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
 
 if test "$no_recursion" != yes; then
 
@@ -3556,12 +3829,16 @@ if test "$no_recursion" != yes; then
 
       # Make the cache file name correct relative to the subdirectory.
       # A "../" for each directory in /$ac_config_dir.
-      ac_dots=`echo /$ac_config_dir|sed 's%/[^/]*%../%g'`
+      ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'`
       case "$cache_file" in
       /*) ac_sub_cache_file=$cache_file ;;
       *) # Relative path.
         ac_sub_cache_file="$ac_dots$cache_file" ;;
       esac
+  case "$ac_given_INSTALL" in
+        [/$]*) INSTALL="$ac_given_INSTALL" ;;
+        *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+        esac
 
       echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir"
       # The eval makes quoting arguments work.
diff --git a/src/configure.in b/src/configure.in
index beda26cdae..38d063c1d0 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -132,10 +132,11 @@ AC_DEFINE_UNQUOTED(F_OFFSET,$lpc_cv_yacc_first)
 
 rm -rf conftest.y y.tab.c y.tab.h conftest.out
 
-AC_HAVE_HEADERS(sys/rusage.h time.h sys/time.h unistd.h stdlib.h memory.h values.h \
- string.h fcntl.h sys/filio.h sys/sockio.h crypt.h locale.h sys/resource.h \
- sys/select.h netdb.h)
-AC_STDC_HEADERS
+AC_HEADER_TIME
+AC_HEADER_STDC
+AC_CHECK_HEADERS(sys/rusage.h time.h sys/time.h unistd.h stdlib.h memory.h \
+values.h string.h fcntl.h sys/filio.h sys/sockio.h crypt.h locale.h \
+sys/resource.h sys/select.h netdb.h)
 
 AC_SIZEOF_TYPE(char *)
 AC_SIZEOF_TYPE(long)
@@ -144,10 +145,10 @@ AC_SIZEOF_TYPE(short)
 AC_SIZEOF_TYPE(float)
 AC_SIZEOF_TYPE(double)
 
-AC_SIZE_T
-AC_PID_T
-AC_UID_T
-AC_RETSIGTYPE
+AC_TYPE_SIZE_T
+AC_TYPE_PID_T
+AC_TYPE_UID_T
+AC_TYPE_SIGNAL
 AC_CHECK_TYPE(time_t,INT32)
 
 AC_CHECK_LIB(PW, alloca)
@@ -173,7 +174,9 @@ fi
 
 LIBOBJS="${OLD_LIBOBJS}"
 
-AC_HAVE_FUNCS(
+AC_FUNC_STRCOLL
+
+AC_CHECK_FUNCS(
  _crypt \
  bcopy \
  bzero \
@@ -202,6 +205,7 @@ AC_HAVE_FUNCS(
  times \
  vfprintf \
  vsprintf \
+ wait3 \
  wait4 \
  waitpid \
 )
@@ -214,7 +218,7 @@ define(MY_CHECK_HEADERS,
    lpc_cv_decl_$1=nonexistant
    for a in $2
    do
-     AC_HEADER_EGREP($1,$a,lpc_cv_decl_$1=existant; break)
+     AC_EGREP_HEADER($1,$a,lpc_cv_decl_$1=existant; break)
    done
  ])
  AC_MSG_RESULT($lpc_cv_decl_$1)
@@ -301,8 +305,8 @@ AC_DEFINE_UNQUOTED(POINTER,$lpc_cv_sys_malloc_return)
 
 AC_ALLOCA
 
-AC_CONST
-AC_INLINE
+AC_C_CONST
+AC_C_INLINE
 
 AC_REPLACE_FUNCS(ualarm)
 
@@ -379,28 +383,6 @@ else
   AC_MSG_RESULT(no)
 fi
 
-AC_MSG_CHECKING(for working strcoll)
-AC_CACHE_VAL(lpc_cv_func_strcoll,
-[
-AC_TRY_RUN([
-#include <string.h>
-int main()
-{
-  if(strcoll("a","b")< 0 &&
-     strcoll("a","a")==0 &&
-     strcoll("b","a")> 0)
-    exit(0);
-  exit(1);
-}
-],lpc_cv_func_strcoll=yes,lpc_cv_func_strcoll=no)])
-
-if test "$lpc_cv_func_strcoll" = yes; then
-  AC_MSG_RESULT(yes)
-  AC_DEFINE(HAVE_STRCOLL)
-else
-  AC_MSG_RESULT(no)
-fi
-
 AC_MSG_CHECKING(for working memmove)
 AC_CACHE_VAL(lpc_cv_func_memmove,
 [
diff --git a/src/docode.c b/src/docode.c
index 3eab7112dd..5e1c52e3f8 100644
--- a/src/docode.c
+++ b/src/docode.c
@@ -676,18 +676,6 @@ static int do_docode2(node *n,int flags)
 
   case F_EQ:
   case F_NE:
-    if(flags & DO_POP)
-    {
-      do_pop(do_docode(CAR(n),DO_NOT_COPY|DO_POP)+
-	     do_docode(CDR(n),DO_NOT_COPY|DO_POP));
-      return 0;
-    }
-    tmp1=do_docode(CAR(n),0);
-    if(do_docode(CDR(n),0)!=1)
-      fatal("Compiler internal error (gnng!).\n");
-    ins_f_byte(n->token);
-    return tmp1;
-
   case F_ADD:
   case F_LT:
   case F_LE:
@@ -702,17 +690,10 @@ static int do_docode2(node *n,int flags)
   case F_XOR:
   case F_OR:
   case F_AND:
-    if(flags & DO_POP)
-    {
-      do_pop(do_docode(CAR(n),DO_NOT_COPY|DO_POP)+
-	     do_docode(CDR(n),DO_NOT_COPY|DO_POP));
-      return 0;
-    }
-    tmp1=do_docode(CAR(n),DO_NOT_COPY);
-    if(do_docode(CDR(n),DO_NOT_COPY)!=1)
-      fatal("Compiler internal error.\n");
-    ins_f_byte(n->token);
-    return tmp1;
+  case F_NOT:
+  case F_COMPL:
+  case F_NEGATE:
+    fatal("Optimizer errror.\n");
 
   case F_RANGE:
     tmp1=do_docode(CAR(n),DO_NOT_COPY);
@@ -754,18 +735,6 @@ static int do_docode2(node *n,int flags)
       return 1;
     }
 
-  case F_NOT:
-  case F_COMPL:
-  case F_NEGATE:
-    tmp1=do_docode(CAR(n),DO_NOT_COPY | (flags & ~DO_LVALUE));
-    if(flags & DO_POP)
-    {
-      do_pop(tmp1);
-      return 0;
-    }
-    ins_f_byte(n->token);
-    return tmp1;
-
   case F_FOR:
   {
     struct jump_list brk,cnt;
diff --git a/src/gc.c b/src/gc.c
new file mode 100644
index 0000000000..d4f1cf812d
--- /dev/null
+++ b/src/gc.c
@@ -0,0 +1,89 @@
+/*\
+||| This file a part of uLPC, and is copyright by Fredrik Hubinette
+||| uLPC is distributed as GPL (General Public License)
+||| See the files COPYING and DISCLAIMER for more information.
+\*/
+
+#include "global.h"
+
+#ifdef GC2
+#include "gc.h"
+#include "main.h"
+
+/* Run garbage collect approximate every time we have
+ * 20 percent of all arrays, objects and programs is
+ * garbage.
+ */
+
+#define GC_CONST 20
+#define MIN_ALLOC_THRESHOLD 1000
+#define MULTIPLIER 0.9
+
+void *gc_ptr;
+INT32 gc_refs;
+INT32 num_objects;
+INT32 num_allocs;
+INT32 alloc_threshold = MIN_ALLOC_THRESHOLD;
+
+static double objects_alloced;
+static double objects_freed;
+
+void do_gc()
+{
+  double tmp;
+  INT32 tmp2;
+
+  tmp2=num_objects;
+
+#ifdef DEBUG
+  if(t_flag)
+    fprintf(stderr,"Garbage collecting ... ");
+#endif
+
+  objects_alloced*=MULTIPLIER;
+  objects_alloced += (double) num_allocs;
+  
+  objects_freed*=MULTIPLIER;
+  objects_freed += (double) num_objects;
+  
+  gc_clear_array_marks();
+  gc_clear_object_marks();
+  gc_clear_program_marks();
+  
+  gc_check_all_arrays();
+  gc_check_all_programs();
+  gc_check_all_objects();
+  
+  objects_freed -= (double) num_objects;
+
+  tmp=(double)num_objects;
+  tmp=tmp * GC_CONST/100.0 * (objects_alloced+1.0) / (objects_freed+1.0);
+  
+  if((int)tmp < alloc_threshold + num_allocs)
+  {
+    alloc_threshold=(int)tmp;
+  }else{
+    alloc_threshold+=num_allocs;
+  }
+
+  if(alloc_threshold < MIN_ALLOC_THRESHOLD)
+    alloc_threshold = MIN_ALLOC_THRESHOLD;
+  num_allocs=0;
+
+#ifdef DEBUG
+  if(t_flag)
+    fprintf(stderr,"done (freed %ld of %ld objects).\n",
+	    (long)(tmp2-num_objects),(long)tmp2);
+#endif
+}
+#endif
+
+
+
+
+
+
+
+
+
+
diff --git a/src/gc.h b/src/gc.h
new file mode 100644
index 0000000000..96746616ea
--- /dev/null
+++ b/src/gc.h
@@ -0,0 +1,30 @@
+#ifndef GC_H
+#define GC_H
+
+#ifdef GC2
+
+#include "types.h"
+
+extern void *gc_ptr;
+extern INT32 gc_refs;
+extern INT32 num_objects;
+extern INT32 num_allocs;
+extern INT32 alloc_threshold;
+
+#define GC_ALLOC() do{ num_objects++; if(++num_allocs > alloc_threshold) do_gc(); } while(0);
+#define GC_FREE() num_objects--
+#define GC_MARK 1
+
+#else
+
+#define GC_ALLOC()
+#define GC_FREE()
+#define do_gc()
+
+#endif
+
+/* Prototypes begin here */
+void do_gc();
+/* Prototypes end here */
+
+#endif
diff --git a/src/language.y b/src/language.y
index fc5266f752..528e4714a8 100644
--- a/src/language.y
+++ b/src/language.y
@@ -905,7 +905,7 @@ expr2: expr3
      }
      | F_INC expr4       { $$=mknode(F_INC,$2,0); }
      | F_DEC expr4       { $$=mknode(F_DEC,$2,0); }
-     | F_NOT expr2        { $$=mknode(F_NOT,$2,0); }
+     | F_NOT expr2        { $$=mkopernode("`!",$2,0); }
      | '~' expr2          { $$=mkopernode("`~",$2,0); }
      | '-' expr2          { $$=mkopernode("`-",$2,0); }
      ;
diff --git a/src/las.c b/src/las.c
index 9f3165bdcf..4a34df8a89 100644
--- a/src/las.c
+++ b/src/las.c
@@ -519,7 +519,7 @@ int node_is_false(node *n)
   }
 }
 
-static node **last_cmd(node **a)
+node **last_cmd(node **a)
 {
   node **n;
   if(!a || !*a) return (node **)NULL;
@@ -563,7 +563,7 @@ static node **low_get_arg(node **a,int *nr)
   return 0;
 }
 
-/* static node **my_get_arg(node **a,int n) { return low_get_arg(a,&n); } */
+node **my_get_arg(node **a,int n) { return low_get_arg(a,&n); }
 /* static node **first_arg(node **a) { return my_get_arg(a,0); } */
 
 static void low_print_tree(node *foo,int needlval)
@@ -1163,6 +1163,17 @@ static void optimize(node *n)
 
     switch(n->token)
     {
+    case F_APPLY:
+      if(CAR(n)->token == F_CONSTANT &&
+	 CAR(n)->u.sval.type == T_FUNCTION &&
+	 CAR(n)->u.sval.subtype == -1 && /* driver fun? */
+	 CAR(n)->u.sval.u.efun->optimize)
+      {
+	if(tmp1=CAR(n)->u.sval.u.efun->optimize(n))
+	  goto use_tmp1;
+      }
+      break;
+
     case F_ARG_LIST:
     case F_LVALUE_LIST:
       if(!CAR(n)) goto use_cdr;
@@ -1372,7 +1383,7 @@ static void optimize(node *n)
 	if(inc)
 	{
 	  if(CAR(n)->token==F_LE)
-	    tmp3=mknode(F_ADD,CDAR(n),mkintnode(1));
+	    tmp3=mkopernode("`+",CDAR(n),mkintnode(1));
 	  else if(CAR(n)->token==F_LT)
 	    tmp3=CDAR(n);
 	  else
diff --git a/src/las.h b/src/las.h
index 3d99b7328a..7dd1433ead 100644
--- a/src/las.h
+++ b/src/las.h
@@ -98,6 +98,8 @@ int is_const(node *n);
 int node_is_tossable(node *n);
 int node_is_true(node *n);
 int node_is_false(node *n);
+node **last_cmd(node **a);
+node **my_get_arg(node **a,int n);
 void print_tree(node *n);
 struct used_vars;
 void fix_type_field(node *n);
diff --git a/src/lex.c b/src/lex.c
index 173b4655d5..a1ad1fdb7e 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -27,8 +27,18 @@
 #include <math.h>
 #include <fcntl.h>
 #include <errno.h>
-#ifdef HAVE_TIME_H
-#include <time.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  if HAVE_TIME_H
+#   include <time.h>
+#  endif
+# endif
 #endif
 
 #define LEXDEBUG 0
diff --git a/src/lpc_signal.c b/src/lpc_signal.c
index fdbb2fea86..1195d0388f 100644
--- a/src/lpc_signal.c
+++ b/src/lpc_signal.c
@@ -186,15 +186,20 @@ static int my_signal(int sig, sigfunctype fun)
 
 static RETSIGTYPE sig_child(int arg)
 {
+  /* We carefully reap what we saw */
 #ifdef HAVE_WAITPID
-  waitpid(-1,0,WNOHANG);
+  while(waitpid(-1,0,WNOHANG) > 0); 
 #else
 #ifdef HAVE_WAIT3
-  wait3(-1,0,WNOHANG);
+  while( wait3(0,WNOHANG,0) > 0);
+#else
+#ifdef HAVE_WAIT4
+  while( wait4(-1,0,WNOHANG,0) > 0);
 #else
 
   /* Leave'em hanging */
 
+#endif /* HAVE_WAIT4 */
 #endif /* HAVE_WAIT3 */
 #endif /* HAVE_WAITPID */
 
diff --git a/src/machine.h.in b/src/machine.h.in
index 7340070012..8dd95675d5 100644
--- a/src/machine.h.in
+++ b/src/machine.h.in
@@ -40,6 +40,9 @@
 /* Define if you have the <time.h> header file.  */
 #undef HAVE_TIME_H
 
+/* Define if we may include both time.h and sys/time.h */
+#undef TIME_WITH_SYS_TIME
+
 /* Define if you have the <sys/select.h> header file. */
 #undef HAVE_SYS_SELECT_H
 
diff --git a/src/main.c b/src/main.c
index a5c0b77ef3..c2cb32d47a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -22,9 +22,20 @@
 #ifdef HAVE_LOCALE_H
 #include <locale.h>
 #endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  if HAVE_TIME_H
+#   include <time.h>
+#  endif
+# endif
 #endif
+
 #ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>
 #endif
diff --git a/src/modules/files/configure.in b/src/modules/files/configure.in
index 0a088d195a..0fbedbdda8 100644
--- a/src/modules/files/configure.in
+++ b/src/modules/files/configure.in
@@ -72,11 +72,15 @@ int sig_child(int arg)
   waitpid(-1,0,WNOHANG);
 #else
 #ifdef HAVE_WAIT3
-  wait3(-1,0,WNOHANG);
+  wait3(0,WNOHANG,0);
+#else
+#ifdef HAVE_WAIT4
+  wait3(-1,0,WNOHANG,0);
 #else
 
   /* Leave'em hanging */
 
+#endif /* HAVE_WAIT4 */
 #endif /* HAVE_WAIT3 */
 #endif /* HAVE_WAITPID */
 
diff --git a/src/operators.c b/src/operators.c
index ae7a11c3da..ca9bdbce40 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -21,7 +21,7 @@
 
 #define COMPARISON(ID,NAME,EXPR) \
 void ID(INT32 args) \
-{\
+{ \
   int i; \
   if(args > 2) \
     pop_n_elems(args-2); \
@@ -218,6 +218,58 @@ static int generate_sum(node *n)
   }
 }
 
+static node *optimize_binary(node *n)
+{
+  node **first_arg, **second_arg, *ret;
+  if(count_args(CDR(n))==2)
+  {
+    first_arg=my_get_arg(&CDR(n), 0);
+    second_arg=my_get_arg(&CDR(n), 1);
+
+#ifdef DEBUG
+    if(!first_arg || !second_arg)
+      fatal("Couldn't find argument!\n");
+#endif
+
+    if((*second_arg)->type == (*first_arg)->type)
+    {
+      if((*first_arg)->token == F_APPLY &&
+	 CAR(*first_arg)->token == F_CONSTANT &&
+	 is_eq(& CAR(*first_arg)->u.sval, & CAR(n)->u.sval))
+      {
+	ret=mknode(F_APPLY,
+		   CAR(n),
+		   mknode(F_ARG_LIST,
+			  CDR(*first_arg),
+			  *second_arg));
+	CAR(n)=0;
+	CDR(*first_arg)=0;
+	*second_arg=0;
+	
+	return ret;
+      }
+      
+      if((*second_arg)->token == F_APPLY &&
+	 CAR(*second_arg)->token == F_CONSTANT &&
+	 is_eq(& CAR(*second_arg)->u.sval, & CAR(n)->u.sval))
+      {
+	ret=mknode(F_APPLY,
+		   CAR(n),
+		   mknode(F_ARG_LIST,
+			  *first_arg,
+			  CDR(*second_arg)));
+	CAR(n)=0;
+	*first_arg=0;
+	CDR(*second_arg)=0;
+	
+	return ret;
+      }
+    }
+  }
+  return 0;
+}
+
+
 static int generate_comparison(node *n)
 {
   if(count_args(CDR(n))==2)
@@ -650,7 +702,7 @@ void f_multiply(INT32 args)
   case 0: error("Too few arguments to `*\n");
   case 1: return;
   case 2: o_multiply(); return;
-  case 3: while(--args > 0) o_multiply(); 
+  default: while(--args > 0) o_multiply(); 
   }
 }
 
@@ -902,8 +954,6 @@ void o_range()
 
 void init_operators()
 {
-  
-
   add_efun2("`==",f_eq,"function(mixed,mixed:int)",0,0,generate_comparison);
   add_efun2("`!=",f_ne,"function(mixed,mixed:int)",0,0,generate_comparison);
   add_efun2("`<", f_lt,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison);
@@ -911,20 +961,20 @@ void init_operators()
   add_efun2("`>", f_gt,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison);
   add_efun2("`>=",f_ge,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison);
 
-  add_efun2("`+",f_add,"function(int ...:int)|function(float ...:float)|function(string,string|int|float ...:string)|function(string,string|int|float ...:string)|function(int|float,string,string|int|float:string)|function(array ...:array)|function(mapping ...:mapping)|function(list...:list)",0,0,generate_sum);
+  add_efun2("`+",f_add,"function(int ...:int)|function(float ...:float)|function(string,string|int|float ...:string)|function(string,string|int|float ...:string)|function(int|float,string,string|int|float:string)|function(array ...:array)|function(mapping ...:mapping)|function(list...:list)",0,optimize_binary,generate_sum);
 
   add_efun2("`-",f_minus,"function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(list,list:list)|function(float,float:float)|function(int,int:int)|function(string,string:string)",0,0,generate_minus);
 
-  add_efun2("`&",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,0,generate_and);
+  add_efun2("`&",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_and);
 
-  add_efun2("`|",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,0,generate_or);
+  add_efun2("`|",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_or);
 
-  add_efun2("`^",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,0,generate_xor);
+  add_efun2("`^",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_xor);
 
   add_efun2("`<<",f_lsh,"function(int,int:int)",0,0,generate_lsh);
   add_efun2("`>>",f_rsh,"function(int,int:int)",0,0,generate_rsh);
 
-  add_efun2("`*",f_multiply,"function(int...:int)|function(float...:float)|function(string*,string:string)",0,0,generate_multiply);
+  add_efun2("`*",f_multiply,"function(int...:int)|function(float...:float)|function(string*,string:string)",0,optimize_binary,generate_multiply);
 
   add_efun2("`/",f_divide,"function(int,int:int)|function(float,float:float)|function(string,string:string*)",0,0,generate_divide);
 
diff --git a/src/rusage.c b/src/rusage.c
index 0a93495239..9bfa61195c 100644
--- a/src/rusage.c
+++ b/src/rusage.c
@@ -6,13 +6,21 @@
 #include "global.h"
 #include <sys/types.h>
 #include <sys/stat.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  if HAVE_TIME_H
+#   include <time.h>
+#  endif
+# endif
 #endif
+
 #include <fcntl.h>
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
 #include <errno.h>
 #include "types.h"
 #include "rusage.h"
diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 5dbe7f6a33..e4b46c229d 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -1414,7 +1414,7 @@ test_eq([[implode(explode("foo","o"),"o")]],"foo")
 test_eq([[implode(({"foo","bar"}),"-")]],"foo-bar")
 test_eq([[implode(({"foo",0,"bar"}),"-")]],"foo-bar")
 test_eq([[implode(({1.0,"foo",0,"bar",this_object(),([])}),"-")]],"foo-bar")
-test_eq([[implode(({"f","o","o"}))]],"foo")
+test_eq([[implode(({"f","o","o"}),"")]],"foo")
 
 // - indices
 test_equal(indices("foo"),({0,1,2}))
-- 
GitLab


From 6ea8a45180e4fc1a53f5d36ebadfd3f97b939dae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 25 Feb 1996 17:17:14 +0100
Subject: [PATCH 043/351] begone

Rev: doc/manual/ulpc-inside3.gif:1.2(DEAD)
---
 .gitattributes              |   1 -
 doc/manual/ulpc-inside3.gif | Bin 4392 -> 0 bytes
 2 files changed, 1 deletion(-)
 delete mode 100644 doc/manual/ulpc-inside3.gif

diff --git a/.gitattributes b/.gitattributes
index 8f9eb1d361..a927944032 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,3 +1,2 @@
 [attr]binary -text -crlf -diff -ident
 * text ident
-*.gif binary
diff --git a/doc/manual/ulpc-inside3.gif b/doc/manual/ulpc-inside3.gif
deleted file mode 100644
index 393280fb4cc558a7bc7d72cb080e6aaffd09cbe4..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 4392
zcmZ?wbhEHboWRh;u#^D=)~{c`diCn%%a<=+ym<cn`Lk!wo<4ngVq#)!Y;0s?WN2t;
zU|^uHudk=4r>m>0qobp(t*xb{rKzdui4!L#O`6o#*Von6)z;S5)YMd0S65Y4RaRD3
zR8*9gmzR~5m6n!fU|^u5qobjrp`xOqpr9ZlBO@UpAtEAj`0!x?0fGJd_w(@Z?B2bb
zgM(xH_U$YzESooP204p3toW0Kk%2*kK?kH9<R=EUe-2#*9y(I}CzceQ%(0q(VMU48
z+Nkw6)|8!oTebheh6*3O+2?PBJV>yJxW(pl)M@($-X^gs|2R<t8Ch9*Zb21g6}1j!
zMOC$awRUA8UQTWfSs4jY!<u<PhN6;^a$LMh8U_rj*Q{N)e!YQ)ssJa4G;7uT-7bt`
zQu6$&T3V|%96xb#jg}H02g{xeO+!{Gg;q74Q@8J&QWLwF#v~`8bnEVmm+J)?A13Ou
zOLGW4fA#Gfm-f3@Z8lk6m6$uy73UA{(`B|XkWiekz`2x@FD^6iU^7cHzwshxg^6DF
ztf~fCGCOsX+%+^gY9tgVJ<(3mkn5b_&~&u3>Xq1>l1WYn{<U#h81K?BbZlbb;I`v<
zWx&Nemx+llW5)qTmnQb!Cb{N=h0iC6Nh&S4aN<m4JFh4khk$^x>lE=KGnIk^0+Ag|
zag#Y7TsY9;ETJl=@neGG_32`40xmNO9!+JAt?XR0L%>nnN<v*lVa10-XSx`e4RluQ
z_G)T4;T$C55RkN>OOW3oM&Lo2H}|%!Q@=cZaDb&p;6lLi0}6{0cL{GamU!_dwV`P-
zhk-x@_fL-=9$t$V-98K~oYh(iDG73E&4nV0J!Us9@OgHL-~KGOW5&7G4%RoPGdA!z
z9Bt-fd(tK)sGDJMC{@kngCiqTUtj~r$pZ>Z91>g16<7^xE<~7X{4*$UWZ<1tc%c0D
z0)|GmxeLUYnY2op=dkJTdC<lx8ezf4er)OuhPX=63kM=@&)9H)b?%-Aca^u4Bq&RW
z{V2W3BBQhOJcGa%meZVk2@H{w*KJ^Ms!8B6XtdR_S<pCT_mV3PeH&WL;{+ubZgN>C
z3kWo2^M?p1$!o?KFwS1zBk)vEd0n%bc#@S$)3l2c1?fhr8U+XDiKx6f#gtH&_}p17
z$01Xa?ZWm@4vCZ~7aoB<OiYr@1_q3o-zRKftjrJyP&HE5IPgG7)8IoFQ_2d%21e<U
z1_p;Pt!5{t_BO)<%nh58oY=2wZfsZ;?sNGX*L<;!hZq%HE+|>))C8=R_@}ENpv$1+
za$top=blTAqAUswj4V6`7Y;Jq6%#zb#@AwyH$iUBZ`U^IeVg8722?!g;*t#c$i%F)
zQK6CbuNdQWHXfEOXF2ChT6pllIv?-V!m>Mx4zY@?acnsFE>|I4TT#M*)kdykLXNi5
z4V^ZIm4}j=%7T~N>Ef0?vVeh8(O|)H0Zo^^%NYd@9SS}6PWA!A$&C&M4ifq*2{$<;
z51eVacseD(F?+R3!7VPyC#xG+XErGa8LnYSKf1qG@i7zg*{F$4XPmMdOocMmf9hpq
zUl-IgPih0N17{n5;!7=qC#Si%BoZz%u?fF9<HV#{<al64<Fs7YM+`N}4J?;#IV%0r
zR{r7R$bRhLgRPY_iWj&ta;y9?U~m8Yg>iveN`TEH)#wja+6up4aq)Z(+R*f6^@IS&
zrCqXzHi_vr9JtSNFtf1n$(kt*2j|sYIk;Zn?d8G)47vphm(2M$HO)*t5LD3kf%`=7
zwrR&(#9|%<Ue0!SxlW;hW6vS)WnPV}VhT(i9tqW&7aUmS9h*2S8VWW(zGNnMK~i9g
z6RWgAGwZ5lo6e;+GCL+7WV+z8H9UbUbbSQ_TblV!t|#wB)o0AijQhYaYid4^=81+6
z5f2+!gAy4w6dz^TSH|+&av7^jjVlw^)a@@_Hi{~LV0h)F+#tV>iOJ99I@^WqTp~#a
znRAjF+5c%A-4*)febl-S4IC$b><LrRXLC(y&HTo}aM^>Ir6H+d<pKc)_H9mWXS*(I
z+bOWvyy|C;dGc7Cv7xEyVZa2YAMx5AGo+aI9L$N3Xiz?wv0F2zAzL6pLP$b=z1Oa$
z;_2E?qRcE^xxP&7`JLJ7*Ot)8sgcC!{-%lb#)~HXKt%>eZ+VL;8@9E(_Aqf|+|w`J
z>Fa!HlBmiQ6>T4<My8&LRf!RdO0f&KYxcYe>Q*^qo~+Iy{Oe-n9+?B`Cp{Po*Ey-T
zn0PWOH3&)s81Y=KS;DsLLlc`#&O+}SY5c7Z4CXnePF6|~_{QMi#owW#G?Rsa`N{)^
ziBl40xmO&F^83fuDz39Yl|w;+mE+_^6Dh^+?;=dEeKz|ue7Q7<q2kQfzGu7JF8P>P
zBr-DbTvKP4a5Y#pnaP*8Q)u^GgI1pxSHIMhTZb<QT)kikLx8VvkdTZ6hxCee?oAiD
zBrF~T*yhT5MSE=wv(e)!Y;}0hCJ@e`;lRH}dSyi9PNsIQNer9<oKmd<4Gwb7Og2_c
zE{p-TnlcLtS0^yK%%2c&Msf+KMK0?JqmIdmw}K1BGE~k-6mQ{wvW!V_!=#pN(^;<W
zTC^$9!*Ng4#i{BQTSU`pnF1mmnN~f?m?7%=)-3YC)*c~6R<?u#XA%ky=810eo;{W6
zwa3qvyXzLs{AhEiAXEL{s?ZYEokersC_k?V=96Gz{l_UF-1eK7DUyM)S+U2rbpqq0
zz^$CR20B>_4eqTiFfE)DtgoH)a-L~|0`sPrLj`lKTX-xoMNceTD_Hd_UhT}~<sl_b
zjfn>>=g!+;pu;nztumBRAV=Yl+le&of84GS9S_z#GJPamalETW;D)G@LdJrcYxi%=
z{FotF5hbiupdjY3V5)0^>|BixOss3V8QFpxV#D{ad~wp@IvjhT{rrqYN{h{=GwkSR
zcZzX%bMOJ9fgICosSUD$+osNQ`{CgC@aQRx6Ej3-d}25ma-s27!9`X<1qYAFhENTe
z$jxV@Q`5s9+zstH!1(pR+BwmIN&hZbi7^D%F}*I?q@*yDfn{m4G_%+PMz+>1`vQL$
ztm!SdwQZ~OHK~f_mHh{j84fh8_PHUl;IMS21NTE#$sY}J=T#LF`7O8}N>ArH^He`*
zi3CH*GKRj0i)Tu<E~<BZ@pbz2o_*(?8cSDi(&10%ZIyU(hNYo;-L)OtxU8h7ma(l+
z)V>tk616#+v*k*OaD@5?HG!f#o(=2NGOpT5tS?CKf2p%Ax^-gxZK3l%H<XtwcKD$A
zqga$x{t&l`2KS?%m-v2(1oTc^D17H7Ka1Ri%UgKaLb%fZ91=@EG~dyVRePJ#lc_-t
zhb~Aku(>2L2}}_Ab7g7|15+rgkcR}fNJ8+2f1fTt5Z{+AlI43-vp|;NS=~BTl?jXU
zJ!BXdmmIixb4$a#LkkuZxH<WYcYpm-SouJG-l2+<o-AsInH*-s9$gi-AoW2~)C?}W
zgG@@<ExB3`3aZci6#8R(Juc(`gUR;9$BQeYJI}p7q4(nes~!)7fQ;l}z7q}%CL0)7
z7p&m8&GTExO1m<fQT({8Mgy~#K@<Oyi>vN`oA#rn?fmVa17}t<_#Lo+vrIgtz**x$
ziJJL67UOGnoTll2Hom?ke@XO(kgP`ohsy*GVV?)p)1;H5|G%ot*`>5h{+)yQ{%gw*
z*tc=$otJwz^Mm&*?(pNT0zulw{_7h(#Xd5~BrtsZ=*4yTAH#(WF$SM9<I7S$ZTBpB
zRQ~I8xU)dQ+6N3eOT}j&$+y`UD67VzSSsGa!ps@KaDj<I&wy!{6Qj%uBe?@Ix(^tl
zxA~rP_3+*rxHXtzwn?C~fxiwzj_(HF!(UhyF7-B7HJcflku1i<H$i#k;vmNxo>v(|
z`ioP#T|KN8X6yZ6czV>6)tTk?GmG-&EXEP}N77iXZ%r^0Wsp~36h5Hyv?Nz&f#@>D
zK%N4lso!|ZwsAE*ZQXaIl79-rmPt&l+qw3#uvQ)8GE+~Q)W)K%z`%S!CZmjJYjN{B
zg(i`$se7M=8(GvGduG4ndRTra%g!gs&&y1DpRsgHgs4wu5>4Rb{#U>$^T72ELuLVs
z+xw)X2@woygoC9vxEu~quzJj;_krP-J7eZnOFb6Wg(tfF0vP!mnA9DZuDh^ke=p(+
z^A0Jpzp^Pa_J|c%0b}EL|CNHV%!iqH1k%4>Gb=pC;(pD~tAatifZ=&j8N&z0SE;I3
zjRTYlnI7K=UC>g);J{>agzM(9aLEP+o(~N24Qf&f>N)`#K@*r9p4LY^$jN0%bi83z
z`?=V;A>vRmlgng_t-?Vk1hUSv%DXf8GH9^wH}%WqU=@05rFfIU^*I;k1Zmw3j5Z}f
z=Q3pOPw3Q}p?v44u#ADh16Njg@t7!uz^%%Gt{#jpSQ$##O=TN|c|S1yYy4p`$HJDs
zp?T>Kmb)AbTZ379pK?VkWA#4a>$t+aamIw-;hL|^U8}cDi#_RgNW-V3RZv5~DD*?m
z4>r3rPOoi8x$<XvYX`FkrH56E#4s7OUP`j)EUxzpm{`0i+-Jfxy$K8}zOdwTcrAU|
z6jM4&FQG+u0mFA^cJXb~?l`v#E?}&B;IBG^<ynczCUaKJ3)3$xvWYZ^asHAS<jFXd
zjp50c8iz23xvBkASBTx7sHn7nX`$sTCjn+&1tFmWX`v4$G6WdUn>-_BOUtH8Yo&!V
z#U}LKSQfPU$t3p&?2;dnd^a#Pm4!w*RB&#I_xh3P!x8fQXJM7{<n1DcTQqo-9R8Wa
z1Tb>{WSDm{GDoD=d?(9Bjx2>ufxQ;NOVp>yA26L6Y{mG%S@;)=kcibH(cZ`nOdJ=4
zR0|l5Tv<fD(q+`V<xXZuZ*Vb~kdg90gWowfW<kEq<hK9U8+A9dWr{^QU*+OV=y=GP
z8n3{>uOO87b-~Wm#Pte{pG;XrcSTr>clPhdU-#1ekS5zMagkfhY-?`{?SHr^_`}j1
z55}!!^F#!E9;Yy<-LhikWV@i6;{MntVZ-dkL(62IbM=?kFc;4ec`&gmmEqt8hW#rv
zIVSY1yD&G|plX8w(`F%7yX{<Rg3Pi97=#p<<PQ|sy)f2qm>YJ1N$kM#bp}jR%OyAx
zBsKmu_yl|?^z>k~O_XpwF!Q__o1~D?bgdQ13`<W=T6}f}3*%E3<>d@K0o<QYu<8de
zay#VjGh>t}W@E}U6*pNZ|825{AoGeS)(cx1R0VVm3>eEJ+1Lwm5419{Uub)2WWX!1
zF0G-*T6o^%L+VGj7#kQcE#1WOpNUb0f${n)KKYF<{ZrKSe_5~j#icTVAu=kO-C=2M
z0E5B-p%V#A91a^3C#;QDWcq2Sp!t#U=tQ0r=k<J-nocw@MLJ2x2{K47U{E|DpZkQt
zYa2h)0tRDY?wJ!A<Tq`IyTHV}fKgz>W_}e$nFI6pd|;AwVEWEwD<~i<bDNd1fKl!O
zgK)x@%a^PFo!`Z;9l-c%xsKokMizrb5f}JB2{5XE*m6gV@u!sn`v-<ARXjQZOk4*T
zSF&#LY>+s)P2e>Xw~hg$!UUfcf()_^8##m+Jr6R9J21$fV3}XY(6~TA*<kz0f~@z&
zil4TbGB-*peqh)>gF)^BqtpkH>_i5!35?#24BQtO+74{1GiKySVAQA<Vm!cD?<Az7
zAnazyq?WMrTfsV+2XkjtvnWSz(wn$v?PC4oQG4EPl-jUp4~wA)Zvo@h*L$uVULnM=
z=TbF~UICNv2gW&#dmm{rNL^rfdTZ~g4^6xe7{w>-d{WJN@fTx><K~muN(@QcK60~m
zEMz<$<aj5WU;hUKPeG{K?`XESi+6D<F!p`e{WXzEu|c16LW4o&ff^--;t9K&Con7%
zV08O<P)LB0w}4YRfsy5cnAjZg`5VP_bQl;H?AMezY-DrTB<8SL&0&i<hpqM;77<`!
Gum%7n;jSnE

-- 
GitLab


From d581508465c1e3523321c4867d66ec1691891cee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 25 Feb 1996 21:41:51 +0100
Subject: [PATCH 044/351] operator function documents added

Rev: doc/operators/and:1.1
Rev: doc/operators/complement:1.1
Rev: doc/operators/divide:1.1
Rev: doc/operators/is_equal:1.1
Rev: doc/operators/is_greater_or_equal:1.1
Rev: doc/operators/is_greater_than:1.1
Rev: doc/operators/is_lesser_or_equal:1.1
Rev: doc/operators/is_lesser_than:1.1
Rev: doc/operators/minus:1.1
Rev: doc/operators/modulo:1.1
Rev: doc/operators/mult:1.1
Rev: doc/operators/not:1.1
Rev: doc/operators/not_equal:1.1
Rev: doc/operators/or:1.1
Rev: doc/operators/plus:1.1
Rev: doc/operators/shift_left:1.1
Rev: doc/operators/shift_right:1.1
Rev: doc/operators/xor:1.1
---
 doc/operators/and                 | 24 +++++++++++++++++++++
 doc/operators/complement          | 17 +++++++++++++++
 doc/operators/divide              | 31 ++++++++++++++++++++++++++
 doc/operators/is_equal            | 19 ++++++++++++++++
 doc/operators/is_greater_or_equal | 17 +++++++++++++++
 doc/operators/is_greater_than     | 17 +++++++++++++++
 doc/operators/is_lesser_or_equal  | 17 +++++++++++++++
 doc/operators/is_lesser_than      | 17 +++++++++++++++
 doc/operators/minus               | 36 +++++++++++++++++++++++++++++++
 doc/operators/modulo              | 26 ++++++++++++++++++++++
 doc/operators/mult                | 30 ++++++++++++++++++++++++++
 doc/operators/not                 | 13 +++++++++++
 doc/operators/not_equal           | 19 ++++++++++++++++
 doc/operators/or                  | 24 +++++++++++++++++++++
 doc/operators/plus                | 28 ++++++++++++++++++++++++
 doc/operators/shift_left          | 17 +++++++++++++++
 doc/operators/shift_right         | 17 +++++++++++++++
 doc/operators/xor                 | 24 +++++++++++++++++++++
 18 files changed, 393 insertions(+)
 create mode 100644 doc/operators/and
 create mode 100644 doc/operators/complement
 create mode 100644 doc/operators/divide
 create mode 100644 doc/operators/is_equal
 create mode 100644 doc/operators/is_greater_or_equal
 create mode 100644 doc/operators/is_greater_than
 create mode 100644 doc/operators/is_lesser_or_equal
 create mode 100644 doc/operators/is_lesser_than
 create mode 100644 doc/operators/minus
 create mode 100644 doc/operators/modulo
 create mode 100644 doc/operators/mult
 create mode 100644 doc/operators/not
 create mode 100644 doc/operators/not_equal
 create mode 100644 doc/operators/or
 create mode 100644 doc/operators/plus
 create mode 100644 doc/operators/shift_left
 create mode 100644 doc/operators/shift_right
 create mode 100644 doc/operators/xor

diff --git a/doc/operators/and b/doc/operators/and
new file mode 100644
index 0000000000..2099f48fca
--- /dev/null
+++ b/doc/operators/and
@@ -0,0 +1,24 @@
+NAME
+	`& - intersection
+
+SYNTAX
+	a & b
+	or
+	mixed `&(mixed ... args)
+
+DESCRIPTION
+	This operator does logical intersections. For ints this means
+	bitwise and.
+
+	Arrays and lists are treated as sets, so intersecting two arrays
+	will result in an array with containing all values present in all
+	arguments.
+
+	For mappings, the intersection will be done on the indexes solely,
+	however, the values will be taken from the rightmost mapping.
+
+KEYWORDS
+	operator
+
+SEE ALSO
+	`|, `^
diff --git a/doc/operators/complement b/doc/operators/complement
new file mode 100644
index 0000000000..0c9ff65f25
--- /dev/null
+++ b/doc/operators/complement
@@ -0,0 +1,17 @@
+NAME
+	`~ - bitwise complement
+
+SYNTAX
+	~ a
+	or
+	int `~(int a)
+
+DESCRIPTION
+	This operator inverses all bits in an integer and returns the
+	new integer.
+
+KEYWORDS
+	operator
+
+SEE ALSO
+	`&, `|, `^
\ No newline at end of file
diff --git a/doc/operators/divide b/doc/operators/divide
new file mode 100644
index 0000000000..82cb262e93
--- /dev/null
+++ b/doc/operators/divide
@@ -0,0 +1,31 @@
+NAME
+	`/ - division
+
+SYNTAX
+	a / b
+	or
+	int `/(int a, int b)
+	or
+	float `/(int|float a,int|float b)
+	or
+	string* `/(string a,string b)
+
+DESCRIPTION
+	For ints and floats, this operator simply divide its arguments.
+	If the arguments are strings, the first string will be divided
+	at every occurance of the second string. The resulting pieces
+	are then returned in the form of an array.
+
+EXAMPLES
+	2/2     	returns 1
+	3/2     	returns 1
+	2.0/2.0   	returns 1.0
+	2.0/2    	returns 1.0
+	"foo"/"o"	returns ({"f","",""})
+	`/(2,2) 	returns 1
+
+KEYWORDS
+	operator
+
+SEE ALSO
+	`*, `%
diff --git a/doc/operators/is_equal b/doc/operators/is_equal
new file mode 100644
index 0000000000..12653faeca
--- /dev/null
+++ b/doc/operators/is_equal
@@ -0,0 +1,19 @@
+NAME
+	`== - compare values
+
+SYNTAX
+	a == b
+	or
+	int `==(mixed a, mixed b)
+
+DESCRIPTION
+	This operator compares two values and returns 1 if they are the same,
+	0 otherwise. Note that pointer equivialenec is required for arrays,
+	objects, programs, mappings and lists. (Thus it is not enough that
+	two arrays LOOK alike, it must be the same array.)
+
+KEYWORDS
+	operator
+
+SEE ALSO
+	`!=, `<, `>, `<=, `>=, efuns/equal
diff --git a/doc/operators/is_greater_or_equal b/doc/operators/is_greater_or_equal
new file mode 100644
index 0000000000..1f744793f8
--- /dev/null
+++ b/doc/operators/is_greater_or_equal
@@ -0,0 +1,17 @@
+NAME
+	`>= - is greater than or equal to?
+
+SYNTAX
+	a >= b
+	or
+	int `>=(int|float|string a,int|float|string b)
+
+DESCRIPTION
+	This operator compares two values and returns 1 if the first one
+	is greater than or equal to the second one.
+
+KEYWORDS
+	operator
+
+SEE ALSO
+	`!=, `==, `>, `<, `<=
diff --git a/doc/operators/is_greater_than b/doc/operators/is_greater_than
new file mode 100644
index 0000000000..84ddca8473
--- /dev/null
+++ b/doc/operators/is_greater_than
@@ -0,0 +1,17 @@
+NAME
+	`> - is lesser than?
+
+SYNTAX
+	a > b
+	or
+	int `>(int|float|string a,int|float|string b)
+
+DESCRIPTION
+	This operator compares two values and returns 1 if the first one
+	is greater than the second one.
+
+KEYWORDS
+	operator
+
+SEE ALSO
+	`!=, `==, `<, `<=, `>=
diff --git a/doc/operators/is_lesser_or_equal b/doc/operators/is_lesser_or_equal
new file mode 100644
index 0000000000..e6956a73c6
--- /dev/null
+++ b/doc/operators/is_lesser_or_equal
@@ -0,0 +1,17 @@
+NAME
+	`<= - is lesser or equal than?
+
+SYNTAX
+	a <= b
+	or
+	int `<=(int|float|string a,int|float|string b)
+
+DESCRIPTION
+	This operator compares two values and returns 1 if the first one
+	is lesser than or equal to the second one.
+
+KEYWORDS
+	operator
+
+SEE ALSO
+	`!=, `==, `>, `<, `>=
diff --git a/doc/operators/is_lesser_than b/doc/operators/is_lesser_than
new file mode 100644
index 0000000000..0482284764
--- /dev/null
+++ b/doc/operators/is_lesser_than
@@ -0,0 +1,17 @@
+NAME
+	`< - is lesser than?
+
+SYNTAX
+	a < b
+	or
+	int `<(int|float|string a,int|float|string b)
+
+DESCRIPTION
+	This operator compares two values and returns 1 if the first one
+	is lesser than the second one.
+
+KEYWORDS
+	operator
+
+SEE ALSO
+	`!=, `==, `>, `<=, `>=
diff --git a/doc/operators/minus b/doc/operators/minus
new file mode 100644
index 0000000000..8bb403bf52
--- /dev/null
+++ b/doc/operators/minus
@@ -0,0 +1,36 @@
+NAME
+	`- - subtract/negate
+
+SYNTAX
+	- a
+	or
+	`-(mixed a);
+	or
+	a - b
+	or
+	mixed `-(mixed a, mixed b)
+
+DESCRIPTION
+	This is the negation and subtraction operator, for ints and floats
+	the operation should be obvious.
+
+	For arrays, an array containing all elements present in a and not in
+	b is returne. The order of the remaining values from a will be kept.
+
+	For lists, the same operation is done as for arrays, except order is
+	of course not considered.
+
+	For mappings, a mapping is returned with every key-index pair from
+	a whos index is not present as an index in b.
+	
+EXAMPLES
+	5-10    	returns -5
+	10-2.0   	returns 8.0
+	({1,2})-({2})	returns ({1})
+	([1:2,2:1])-([1:0])	returns ([2:1])
+
+KEYWORDS
+	operator
+
+SEE ALSO
+	`+
diff --git a/doc/operators/modulo b/doc/operators/modulo
new file mode 100644
index 0000000000..6e9561ea8d
--- /dev/null
+++ b/doc/operators/modulo
@@ -0,0 +1,26 @@
+NAME
+	`% - modulo
+
+SYNTAX
+	a % b
+	or
+	int `%(int a, int b)
+	or
+	float `%(int|float a,int|float b)
+
+DESCRIPTION
+	This operator computes the rest of a division. For integers, this
+	is the same as same as computing a-(a/b)*a. For floats, modulo is
+	interpreted as a-floor(a/b)*a
+	
+
+EXAMPLES
+	9%3     	returns 0
+	10%3     	returns 1
+	2%0.3   	returns 0.2
+
+KEYWORDS
+	operator
+
+SEE ALSO
+	`/, `*
diff --git a/doc/operators/mult b/doc/operators/mult
new file mode 100644
index 0000000000..e0ad0603e9
--- /dev/null
+++ b/doc/operators/mult
@@ -0,0 +1,30 @@
+NAME
+	`* - multiplication
+
+SYNTAX
+	a * b
+	or
+	int `*(int ... args)
+	or
+	float `*(int|float ... args)
+	or
+	string `*(string *strings, string delimeter)
+
+DESCRIPTION
+	For ints and floats, this operator simply multiplies its arguments.
+	If the first argument is an array, and the second a string, all
+	strings in the arrays will be concatenated, with the delimiter in
+	between each string and the result will be returned.
+
+EXAMPLES
+	2*2     	returns 4
+	2.0*2.0   	returns 4.0
+	2.0*2    	returns 4.0
+	({"f","",""})*"o")	Returns "foo"
+	`*(2,2,2)	returns 8
+
+KEYWORDS
+	operator
+
+SEE ALSO
+	`/
diff --git a/doc/operators/not b/doc/operators/not
new file mode 100644
index 0000000000..1c251ee35f
--- /dev/null
+++ b/doc/operators/not
@@ -0,0 +1,13 @@
+NAME
+	`! - is not true
+
+SYNTAX
+	! a
+	or
+	int `!(mixed a)
+
+DESCRIPTION
+	Returns 1 if a is zero, 0 otherwise.
+
+KEYWORDS
+	operator
diff --git a/doc/operators/not_equal b/doc/operators/not_equal
new file mode 100644
index 0000000000..d68f40d3d1
--- /dev/null
+++ b/doc/operators/not_equal
@@ -0,0 +1,19 @@
+NAME
+	`!= - check if not equal
+
+SYNTAX
+	a != b
+	or
+	int `!=(mixed a, mixed b)
+
+DESCRIPTION
+	This operator compares two values and returns 0 if they are the same,
+	1 otherwise. Note that pointer equivialenec is required for arrays,
+	objects, programs, mappings and lists. (Thus it is not enough that
+	two arrays LOOK alike, it must be the same array.)
+
+KEYWORDS
+	operator
+
+SEE ALSO
+	`==, `<, `>, `<=, `>=, efuns/equal
diff --git a/doc/operators/or b/doc/operators/or
new file mode 100644
index 0000000000..9985a3860c
--- /dev/null
+++ b/doc/operators/or
@@ -0,0 +1,24 @@
+NAME
+	`| - union
+
+SYNTAX
+	a | b
+	or
+	mixed `|(mixed ... args)
+
+DESCRIPTION
+	This operator does logical unions. For ints this means bitwise or.
+
+	Arrays and lists are treated as sets, so doing a union on two arrays
+	will result in an array with containing all values present in either
+	array. Although values present in both ararys will only be present
+	once in the result.
+
+	For mappings, the intersection will be done on the indexes solely,
+	however, the values will be taken from the rightmost mapping.
+
+KEYWORDS
+	operator
+
+SEE ALSO
+	`&, `^
diff --git a/doc/operators/plus b/doc/operators/plus
new file mode 100644
index 0000000000..6402ad168a
--- /dev/null
+++ b/doc/operators/plus
@@ -0,0 +1,28 @@
+NAME
+	`+ - add things together
+
+SYNTAX
+	a + b
+	or
+	mixed `+(mixed ... args)
+
+DESCRIPTION
+	For ints and floats this operator simply adds the two operators
+	together. For strings and arrays, concatenation is done. For lists
+	and mapping this creates a new list with all indices and data as
+	in a and b. Note that this can cause a list or mapping to contain
+	several equal indices. Also, when adding a string to an int or float
+	the number is converted to a printable string first.
+
+EXAMPLES
+	"a"+10  	returns "a10"
+	10+20   	returns 30
+	({1})+({2})	returns ({1,2})
+	(<1>)+(<1>)	returns (<1,1>)
+	`+(2,2,2)	returns 6
+
+KEYWORDS
+	operator
+
+SEE ALSO
+	`-, `*
diff --git a/doc/operators/shift_left b/doc/operators/shift_left
new file mode 100644
index 0000000000..a354ad32db
--- /dev/null
+++ b/doc/operators/shift_left
@@ -0,0 +1,17 @@
+NAME
+	`<< - shift left
+
+SYNTAX
+	a << b
+	or
+	int `<<(int a, int b)
+
+DESCRIPTION
+	This operator shift the integer a b steps left. This is equal to
+	multiplying a by 2 b times.
+
+KEYWORDS
+	operator
+
+SEE ALSO
+	`>>
diff --git a/doc/operators/shift_right b/doc/operators/shift_right
new file mode 100644
index 0000000000..363e77d63f
--- /dev/null
+++ b/doc/operators/shift_right
@@ -0,0 +1,17 @@
+NAME
+	`>> - shift right
+
+SYNTAX
+	a >> b
+	or
+	int `>>(int a, int b)
+
+DESCRIPTION
+	This operator shift the integer a b steps right. This is equal to
+	dividing a by 2 b times.
+
+KEYWORDS
+	operator
+
+SEE ALSO
+	`<<
diff --git a/doc/operators/xor b/doc/operators/xor
new file mode 100644
index 0000000000..fe9d4e2676
--- /dev/null
+++ b/doc/operators/xor
@@ -0,0 +1,24 @@
+NAME
+	`^ - exclusive or
+
+SYNTAX
+	a ^ b
+	or
+	mixed `^(mixed ... args)
+
+DESCRIPTION
+	This operator does logical exclusive or operations For ints this means
+	bitwise xor.
+
+	Arrays and lists are treated as sets, so xoring two arrays will
+	result in an array with containing all values present in either but
+	not both arrays.
+
+	For mappings, the intersection will be done on the indexes solely,
+	however, the values will be taken from the rightmost mapping.
+
+KEYWORDS
+	operator
+
+SEE ALSO
+	`|, `&
-- 
GitLab


From b7ac3c1133b4df7b3ebbd5ea1f2bdcd349531785 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 25 Feb 1996 21:41:38 +0100
Subject: [PATCH 045/351] operator function documents added

Rev: doc/operators/addition:1.3(DEAD)
---
 doc/operators/addition | 24 ------------------------
 1 file changed, 24 deletions(-)
 delete mode 100644 doc/operators/addition

diff --git a/doc/operators/addition b/doc/operators/addition
deleted file mode 100644
index f7ab8da026..0000000000
--- a/doc/operators/addition
+++ /dev/null
@@ -1,24 +0,0 @@
-NAME
-	addition - add things together
-
-SYNTAX
-	a + b
-	or
-	mixed sum(mixed ...)
-
-DESCRIPTION
-	For ints and floats this operator simply adds the two operators
-	together. For strings and arrays, concatenation is done. For lists
-	and mapping this creates a new list with all indices and data as
-	in a and b. Note that this can cause a list or mapping to contain
-	several equal indices. Also, when adding a string to an int or float
-	the number is converted to a printable string first.
-
-EXAMPLES
-	"a"+10  	returns "a10"
-	10+20   	returns 30
-	({1})+({2})	returns ({1,2})
-	(<1>)+(<1>)	returns (<1,1>)
-
-SEE ALSO
-	subtraction, efun/sum, multiplication
-- 
GitLab


From bce86cd77c173ec0a979d529083959c4b67d88cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 25 Feb 1996 23:53:54 +0100
Subject: [PATCH 046/351] typeof() implemented

Rev: src/ChangeLog:1.19
Rev: src/Makefile.in:1.10
Rev: src/builtin_efuns.c:1.13
Rev: src/language.y:1.11
Rev: src/lex.c:1.8
Rev: src/lpc_types.c:1.3
Rev: src/lpc_types.h:1.2
Rev: src/object.c:1.7
Rev: src/operators.c:1.4
Rev: src/svalue.c:1.7
Rev: src/svalue.h:1.5
---
 src/ChangeLog       |   5 +
 src/Makefile.in     |   6 +
 src/builtin_efuns.c |  11 +-
 src/language.y      |  13 +-
 src/lex.c           |   3 +-
 src/lpc_types.c     | 309 ++++++++++++++++++++++++++++++++------------
 src/lpc_types.h     |   3 +
 src/object.c        |   4 +-
 src/operators.c     |  89 +++++++++----
 src/svalue.c        |  35 +----
 src/svalue.h        |   6 +-
 11 files changed, 339 insertions(+), 145 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index de000c9bf8..1574e91eab 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+Sun Feb 25 22:42:48 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
+
+	* operator functions implemented
+	* typeof() added
+
 Sat Feb 24 04:12:52 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
 
 	* program.c, array.c, object.c, gc.c: 
diff --git a/src/Makefile.in b/src/Makefile.in
index fbfd057af6..41e2f32f64 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -172,6 +172,12 @@ depend: language.c
 	gcc -MM $(PREFLAGS) *.c $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)/Makefile.in
 	for a in $(MODULES) ; do ( cd $$a ; ${MAKE} $(MAKE_FLAGS) depend ) ; done
 
+docs:
+	mkdir docs
+
+html_docs: docs
+	$(RUNULPC) $(TMP_BINDIR)/htmlify_docs $(TMP_DOCDIR) docs
+
 #
 # uLPC internal targets
 #
diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index 992553c9cf..81cc0404a1 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -579,7 +579,14 @@ void f_sizeof(INT32 args)
     tmp=sp[-1].u.list->ind->size;
     free_list(sp[-1].u.list);
     break;
-    
+
+  case T_OBJECT:
+    if(!sp[-1].u.object->prog)
+      error("sizeof() on destructed object.\n");
+    tmp=sp[-1].u.object->prog->num_identifier_indexes;
+    free_object(sp[-1].u.object);
+    break;
+
   default:
     error("Bad argument 1 to sizeof().\n");
     return; /* make apcc happy */
@@ -1263,7 +1270,7 @@ void init_builtin_efuns()
   add_efun("reverse",f_reverse,"function(int:int)|function(string:string)|function(array:array)",0);
   add_efun("rusage", f_rusage, "function(:int *)",OPT_EXTERNAL_DEPEND);
   add_efun("search",f_search,"function(string,string,void|int:int)|function(array,mixed,void|int:int)|function(mapping,mixed:mixed)",0);
-  add_efun("sizeof", f_sizeof, "function(string|list|array|mapping:int)",0);
+  add_efun("sizeof", f_sizeof, "function(string|list|array|mapping|object:int)",0);
   add_efun("sleep", f_sleep, "function(int:void)",OPT_SIDE_EFFECT);
   add_efun("stringp", f_stringp, "function(mixed:int)",0);
 
diff --git a/src/language.y b/src/language.y
index 528e4714a8..0c4ef11bf4 100644
--- a/src/language.y
+++ b/src/language.y
@@ -113,6 +113,7 @@
 %token F_STRING_ID
 %token F_SUBSCRIPT
 %token F_SUB_EQ
+%token F_TYPEOF
 %token F_VAL_LVAL
 %token F_VARARGS 
 %token F_VOID_ID
@@ -223,7 +224,7 @@ void fix_comp_stack(int sp)
 %type <n> for do cond optional_else_part while statements
 %type <n> local_name_list class catch_arg
 %type <n> unused2 foreach unused switch case return expr_list default
-%type <n> continue break block_or_semi
+%type <n> continue break block_or_semi typeof
 %%
 
 all: program;
@@ -920,6 +921,7 @@ expr4: string
      | F_FLOAT { $$=mkfloatnode($1); }
      | catch
      | gauge
+     | typeof
      | sscanf
      | lambda
      | class
@@ -1029,8 +1031,15 @@ gauge: F_GAUGE '(' unused ')'
 				   mkintnode(GAUGE_RUSAGE_INDEX)))),0);
   } ;
 
+typeof: F_TYPEOF '(' expr0 ')'
+      {
+	node *tmp;
+	tmp=mknode(F_ARG_LIST,$3,0);
+        $$=mkstrnode(describe_type($3->type));
+        free_node(tmp);
+      } ;
 
-catch_arg: '(' unused ')'  { $$=$2; }
+catch_arg: '(' comma_expr ')'  { $$=$2; }
          | block
          ; 
 
diff --git a/src/lex.c b/src/lex.c
index a1ad1fdb7e..9738a418ce 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -124,6 +124,7 @@ struct keyword reserved_words[] =
 { "static",	F_STATIC, },
 { "string",	F_STRING_ID, },
 { "switch",	F_SWITCH, },
+{ "typeof",	F_TYPEOF, },
 { "varargs",	F_VARARGS, },
 { "void",	F_VOID_ID, },
 { "while",	F_WHILE, },
@@ -1532,8 +1533,6 @@ static int do_lex2(int literal, YYSTYPE *yylval)
       case '|': tmp="`|"; break;
       case '^': tmp="`^"; break;
       case '~': tmp="`~"; break;
-      case '(':
-	if(GOBBLE(')')) { tmp="`()"; break; }
 
       default:
 	yyerror("Illegal ` identifier.");
diff --git a/src/lpc_types.c b/src/lpc_types.c
index 4cf28ef120..e2186c7974 100644
--- a/src/lpc_types.c
+++ b/src/lpc_types.c
@@ -18,6 +18,8 @@
 #include "macros.h"
 #include "error.h"
 
+static void internal_parse_type(char **s);
+
 /*
  * basic types are represented by just their value in a string
  * basic type are string, int, float, object and program
@@ -80,10 +82,12 @@ static int type_length(char *t)
 
   case T_MAPPING:
   case T_OR:
+  case T_AND:
     t+=type_length(t);
 
   case T_ARRAY:
   case T_LIST:
+  case T_NOT:
     t+=type_length(t);
 
   case T_INT:
@@ -99,7 +103,7 @@ static int type_length(char *t)
   return t-q;
 }
 
-static void internal_parse_type(char **s)
+static void internal_parse_typeA(char **s)
 {
   char buf[80];
   unsigned int len;
@@ -169,8 +173,8 @@ static void internal_parse_type(char **s)
       type_stack_reverse();
       if(**s != ')') error("Missing ')' in function type.\n");
       ++*s;
-      type_stack_reverse();
-    }else{
+      type_stack_reverse(); 
+   }else{
       push_type(T_MIXED);
       push_type(T_MIXED);
       push_type(T_MANY);
@@ -227,19 +231,81 @@ static void internal_parse_type(char **s)
     error("Couldn't parse type. (%s)\n",buf);
 
   while(isspace(**s)) ++*s;
+}
+
+
+static void internal_parse_typeB(char **s)
+{
+  while(isspace(**s)) ++*s;
+  switch(**s)
+  {
+  case '!':
+    ++*s;
+    internal_parse_typeB(s);
+    push_type(T_NOT);
+    break;
+
+  case '(':
+    ++*s;
+    internal_parse_typeB(s);
+    while(isspace(**s)) ++*s;
+    if(**s != ')') error("Expecting ')'.\n");
+    break;
+    
+  default:
+
+    internal_parse_typeA(s);
+  }
+}
+
+static void internal_parse_typeCC(char **s)
+{
+  internal_parse_typeB(s);
+
+  while(isspace(**s)) ++*s;
+  
   while(**s == '*')
   {
     ++*s;
-    push_type(T_ARRAY);
     while(isspace(**s)) ++*s;
+    push_type(T_ARRAY);
   }
+}
+
+static void internal_parse_typeC(char **s)
+{
+  type_stack_mark();
+
+  type_stack_mark();
+  internal_parse_typeCC(s);
+  type_stack_reverse();
 
+  while(isspace(**s)) ++*s;
+  
+  if(**s == '&')
+  {
+    ++*s;
+    type_stack_mark();
+    internal_parse_typeC(s);
+    type_stack_reverse();
+    type_stack_reverse();
+    push_type(T_AND);
+  }else{
+    type_stack_reverse();
+  }
+}
+
+static void internal_parse_type(char **s)
+{
+  internal_parse_typeC(s);
+
+  while(isspace(**s)) ++*s;
+  
   while(**s == '|')
   {
     ++*s;
-    internal_parse_type(s);
+    internal_parse_typeC(s);
     push_type(T_OR);
-    while(isspace(**s)) ++*s;
   }
 }
 
@@ -280,6 +346,8 @@ void stupid_describe_type(char *a,INT32 len)
     case T_UNKNOWN: printf("unknown"); break;
     case T_MANY: printf("many"); break;
     case T_OR: printf("or"); break;
+    case T_AND: printf("and"); break;
+    case T_NOT: printf("not"); break;
     case T_VOID: printf("void"); break;
     case T_MIXED: printf("mixed"); break;
 
@@ -299,33 +367,14 @@ char *low_describe_type(char *t)
 {
   switch(EXTRACT_UCHAR(t++))
   {
-  case T_VOID:
-    my_strcat("void");
-    break;
-
-  case T_MIXED:
-    my_strcat("mixed");
-    break;
-
-  case T_UNKNOWN:
-    my_strcat("unknown");
-    break;
-
-  case T_INT:
-    my_strcat("int");
-    break;
-
-  case T_FLOAT:
-    my_strcat("float");
-    break;
-
-  case T_PROGRAM:
-    my_strcat("program");
-    break;
-
-  case T_OBJECT:
-    my_strcat("object");
-    break;
+  case T_VOID: my_strcat("void"); break;
+  case T_MIXED: my_strcat("mixed"); break;
+  case T_UNKNOWN: my_strcat("unknown"); break;
+  case T_INT: my_strcat("int"); break;
+  case T_FLOAT: my_strcat("float"); break;
+  case T_PROGRAM: my_strcat("program"); break;
+  case T_OBJECT: my_strcat("object"); break;
+  case T_STRING: my_strcat("string"); break;
 
   case T_FUNCTION:
   {
@@ -335,36 +384,49 @@ char *low_describe_type(char *t)
     while(EXTRACT_UCHAR(t) != T_MANY)
     {
       if(s++) my_strcat(", ");
-      low_describe_type(t);
-      t+=type_length(t);
+      t=low_describe_type(t);
     }
     t++;
-    if(EXTRACT_UCHAR(t) != T_VOID)
+    if(EXTRACT_UCHAR(t) == T_VOID)
     {
+      t++;
+    }else{
       if(s++) my_strcat(", ");
-      low_describe_type(t);
+      t=low_describe_type(t);
       my_strcat(" ...");
     }
-    t+=type_length(t);
     my_strcat(" : ");
-    low_describe_type(t);
+    t=low_describe_type(t);
     my_strcat(")");
     break;
   }
 
-  case T_STRING:
-    my_strcat("string");
-    break;
-
   case T_ARRAY:
-    t=low_describe_type(t);
-    my_strcat("*");
+    if(EXTRACT_UCHAR(t)==T_MIXED)
+    {
+      my_strcat("array");
+      t++;
+    }else{
+      t=low_describe_type(t);
+      my_strcat("*");
+    }
     break;
 
   case T_LIST:
-    my_strcat("list (");
+    my_strcat("list");
+    if(EXTRACT_UCHAR(t)!=T_MIXED)
+    {
+      my_strcat("(");
+      t=low_describe_type(t);
+      my_strcat(")");
+    }else{
+      t++;
+    }
+    break;
+
+  case T_NOT:
+    my_strcat("!");
     t=low_describe_type(t);
-    my_strcat(")");
     break;
 
   case T_OR:
@@ -372,28 +434,53 @@ char *low_describe_type(char *t)
     my_strcat(" | ");
     t=low_describe_type(t);
     break;
-    
-  case T_MAPPING:
-    my_strcat("mapping (");
+
+  case T_AND:
     t=low_describe_type(t);
-    my_strcat(":");
+    my_strcat(" & ");
     t=low_describe_type(t);
-    my_strcat(")");
+    break;
+    
+  case T_MAPPING:
+    my_strcat("mapping");
+    if(EXTRACT_UCHAR(t)==T_MIXED && EXTRACT_UCHAR(t+1)==T_MIXED)
+    {
+      t+=2;
+    }else{
+      my_strcat("(");
+      t=low_describe_type(t);
+      my_strcat(":");
+      t=low_describe_type(t);
+      my_strcat(")");
+    }
     break;
   }
   return t;
 }
 
-TYPE_T compile_type_to_runtime_type(struct lpc_string *s)
+struct lpc_string *describe_type(struct lpc_string *type)
 {
-  char *t;
-  t=s->str;
-  
+  if(!type) return make_shared_string("mixed");
+  init_buf();
+  low_describe_type(type->str);
+  return free_buf();
+}
+
+static TYPE_T low_compile_type_to_runtime_type(char *t)
+{
+  TYPE_T tmp;
   switch(EXTRACT_UCHAR(t))
   {
   case T_OR:
+    t++;
+    tmp=low_compile_type_to_runtime_type(t);
+    if(tmp == low_compile_type_to_runtime_type(t+type_length(t)))
+      return tmp;
+
   case T_MANY:
   case T_UNKNOWN:
+  case T_AND:
+  case T_NOT:
     return T_MIXED;
 
   default:
@@ -401,36 +488,70 @@ TYPE_T compile_type_to_runtime_type(struct lpc_string *s)
   }
 }
 
+TYPE_T compile_type_to_runtime_type(struct lpc_string *s)
+{
+  return low_compile_type_to_runtime_type(s->str);
+}
+
+#define A_EXACT 1
+#define B_EXACT 2
+
 /*
  * match two type strings, return zero if they don't match, and return
  * the part of 'a' that _did_ match if it did.
  */
-static char *low_match_types(char *a,char *b)
+static char *low_match_types(char *a,char *b, int flags)
 {
   char *ret;
   if(a == b) return a;
 
-  if(EXTRACT_UCHAR(a) == T_OR)
+  switch(EXTRACT_UCHAR(a))
   {
+  case T_AND:
     a++;
-    ret=low_match_types(a,b);
+    ret=low_match_types(a,b,flags);
+    if(!ret) return 0;
+    a+=type_length(a);
+    return low_match_types(a,b,flags);
+
+  case T_OR:
+    a++;
+    ret=low_match_types(a,b,flags);
     if(ret) return ret;
     a+=type_length(a);
-    return low_match_types(a,b);
+    return low_match_types(a,b,flags);
+
+  case T_NOT:
+    if(low_match_types(a+1,b,flags | B_EXACT))
+      return 0;
+    return a;
   }
 
-  if(EXTRACT_UCHAR(b) == T_OR)
+  switch(EXTRACT_UCHAR(b))
   {
+  case T_AND:
     b++;
-    ret=low_match_types(a,b);
+    ret=low_match_types(a,b,flags);
+    if(!ret) return 0;
+    b+=type_length(b);
+    return low_match_types(a,b,flags);
+
+  case T_OR:
+    b++;
+    ret=low_match_types(a,b,flags);
     if(ret) return ret;
     b+=type_length(b);
-    return low_match_types(a,b);
+    return low_match_types(a,b,flags);
+
+  case T_NOT:
+    if(low_match_types(a,b+1, flags | A_EXACT))
+      return 0;
+    return a;
   }
 
   /* 'mixed' matches anything */
-  if(EXTRACT_UCHAR(a) == T_MIXED) return a;
-  if(EXTRACT_UCHAR(b) == T_MIXED) return a;
+  if(EXTRACT_UCHAR(a) == T_MIXED && !(flags & A_EXACT)) return a;
+  if(EXTRACT_UCHAR(b) == T_MIXED && !(flags & B_EXACT)) return a;
   if(EXTRACT_UCHAR(a) != EXTRACT_UCHAR(b)) return 0;
 
   ret=a;
@@ -458,7 +579,7 @@ static char *low_match_types(char *a,char *b)
 	b+=type_length(b);
       }
 
-      if(!low_match_types(a_tmp, b_tmp)) return 0;
+      if(!low_match_types(a_tmp, b_tmp, flags)) return 0;
     }
     /* check the 'many' type */
     a++;
@@ -468,20 +589,20 @@ static char *low_match_types(char *a,char *b)
       a+=type_length(a);
       b+=type_length(b);
     }else{
-      if(!low_match_types(a,b)) return 0;
+      if(!low_match_types(a,b,flags)) return 0;
     }
     /* check the returntype */
-    if(!low_match_types(a,b)) return 0;
+    if(!low_match_types(a,b,flags)) return 0;
     break;
 
   case T_MAPPING:
-    if(!low_match_types(++a,++b)) return 0;
-    if(!low_match_types(a+type_length(a),b+type_length(b))) return 0;
+    if(!low_match_types(++a,++b,flags)) return 0;
+    if(!low_match_types(a+type_length(a),b+type_length(b),flags)) return 0;
     break;
 
   case T_LIST:
   case T_ARRAY:
-    if(!low_match_types(++a,++b)) return 0;
+    if(!low_match_types(++a,++b,flags)) return 0;
 
   case T_INT:
   case T_FLOAT:
@@ -503,19 +624,25 @@ static char *low_match_types(char *a,char *b)
  */
 static int low_get_return_type(char *a,char *b)
 {
-  if(EXTRACT_UCHAR(a) == T_OR)
+  int tmp;
+  switch(EXTRACT_UCHAR(a))
   {
-    int tmp;
+  case T_OR:
     a++;
     tmp=low_get_return_type(a,b);
     tmp+=low_get_return_type(a+type_length(a),b);
     if(tmp==2) push_type(T_OR);
     return tmp>0;
-  }
 
-  if(EXTRACT_UCHAR(a) == T_ARRAY)
-  {
-    int tmp;
+  case T_AND:
+    a++;
+    type_stack_mark();
+    tmp=low_get_return_type(a,b);
+    type_stack_pop_to_mark();
+    if(!tmp) return 0;
+    return low_get_return_type(a+type_length(a),b);
+
+  case T_ARRAY:
     a++;
     tmp=low_get_return_type(a,b);
     if(!tmp) return 0;
@@ -523,7 +650,7 @@ static int low_get_return_type(char *a,char *b)
     return 1;
   }
 
-  a=low_match_types(a,b);
+  a=low_match_types(a,b,0);
   if(a)
   {
     switch(EXTRACT_UCHAR(a))
@@ -547,7 +674,7 @@ static int low_get_return_type(char *a,char *b)
 
 int match_types(struct lpc_string *a,struct lpc_string *b)
 {
-  return 0!=low_match_types(a->str, b->str);
+  return 0!=low_match_types(a->str, b->str,0);
 }
 
 
@@ -585,6 +712,12 @@ void pop_type_stack()
     fatal("Type stack underflow\n");
 }
 
+void type_stack_pop_to_mark()
+{
+  pop_stack_mark();
+  type_stackp=*mark_stackp;
+}
+
 void type_stack_reverse()
 {
   unsigned char *a,*b,tmp;
@@ -651,6 +784,8 @@ static struct lpc_string *low_index_type(char *t)
     return pop_type();
   }
 
+  case T_AND:
+    return low_index_type(t+type_length(t));
 
   case T_STRING: /* always int */
   case T_LIST: /* always int */
@@ -680,17 +815,24 @@ static int low_check_indexing(char *type, char *index_type)
   case T_OR:
     return low_check_indexing(type,index_type) ||
       low_check_indexing(type+type_length(type),index_type);
-    
+
+  case T_AND:
+    return low_check_indexing(type,index_type) &&
+      low_check_indexing(type+type_length(type),index_type);
+
+  case T_NOT:
+    return !low_check_indexing(type,index_type);
+
   case T_STRING:
   case T_ARRAY:
-    return !!low_match_types(int_type_string->str, index_type);
+    return !!low_match_types(int_type_string->str, index_type,0);
 
   case T_OBJECT:
-    return !!low_match_types(string_type_string->str, index_type);
+    return !!low_match_types(string_type_string->str, index_type,0);
 
   case T_LIST:
   case T_MAPPING:
-    return !!low_match_types(type,index_type);
+    return !!low_match_types(type,index_type,0);
 
   case T_MIXED:
     return 1;
@@ -741,7 +883,6 @@ struct lpc_string *check_call(struct lpc_string *args,
   }
 }
 
-
 void check_array_type(struct array *a)
 {
   push_type(T_MIXED);
diff --git a/src/lpc_types.h b/src/lpc_types.h
index 01ef149734..1e898a8f14 100644
--- a/src/lpc_types.h
+++ b/src/lpc_types.h
@@ -23,13 +23,16 @@ extern struct lpc_string *any_type_string;
 void init_types();
 struct lpc_string *parse_type(char *s);
 void stupid_describe_type(char *a,INT32 len);
+void simple_describe_type(struct lpc_string *s);
 char *low_describe_type(char *t);
+struct lpc_string *describe_type(struct lpc_string *type);
 TYPE_T compile_type_to_runtime_type(struct lpc_string *s);
 int match_types(struct lpc_string *a,struct lpc_string *b);
 void reset_type_stack();
 void type_stack_mark();
 void pop_stack_mark();
 void pop_type_stack();
+void type_stack_pop_to_mark();
 void type_stack_reverse();
 void push_type(unsigned char tmp);
 void push_unfinished_type(char *s);
diff --git a/src/object.c b/src/object.c
index 9d6e0ff087..86174658e9 100644
--- a/src/object.c
+++ b/src/object.c
@@ -657,13 +657,13 @@ void gc_check_object(struct object *o)
     
     i=ID_FROM_INT(o->prog, e);
 
-    if(i->run_time_type & IDENTIFIER_FUNCTION) continue;
+    if(i->flags & IDENTIFIER_FUNCTION) continue;
 
     if(i->run_time_type == T_MIXED)
     {
       gc_check_svalues((struct svalue *)LOW_GET_GLOBAL(o,e,i),1);
     }else{
-      gc_check_short_svalue((struct svalue *)LOW_GET_GLOBAL(o,e,i),
+      gc_check_short_svalue((union anything *)LOW_GET_GLOBAL(o,e,i),
 			    i->run_time_type);
     }
   }
diff --git a/src/operators.c b/src/operators.c
index ca9bdbce40..3a21b0d51f 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -169,6 +169,24 @@ void f_add(INT32 args)
     break;
   }
 
+  case BIT_FLOAT | BIT_INT:
+  {
+    FLOAT_TYPE sum;
+    sum=0.0;
+    for(e=-args; e<0; e++)
+    {
+      if(sp[e].type==T_FLOAT)
+      {
+	sum+=sp[e].u.float_number;
+      }else{
+	sum+=(FLOAT_TYPE)sp[e].u.integer;
+      }
+    }
+    sp-=args-1;
+    sp[-1].u.float_number=sum;
+    break;
+  }
+
   case BIT_ARRAY:
   {
     struct array *a;
@@ -231,7 +249,8 @@ static node *optimize_binary(node *n)
       fatal("Couldn't find argument!\n");
 #endif
 
-    if((*second_arg)->type == (*first_arg)->type)
+    if((*second_arg)->type == (*first_arg)->type &&
+       compile_type_to_runtime_type((*second_arg)->type) != T_MIXED)
     {
       if((*first_arg)->token == F_APPLY &&
 	 CAR(*first_arg)->token == F_CONSTANT &&
@@ -295,10 +314,26 @@ static int generate_comparison(node *n)
   return 0;
 }
 
+static int float_promote()
+{
+  if(sp[-2].type==T_INT)
+  {
+    sp[-2].u.float_number=(FLOAT_TYPE)sp[-2].u.integer;
+    sp[-2].type=T_FLOAT;
+  }
+
+  if(sp[-1].type==T_INT)
+  {
+    sp[-1].u.float_number=(FLOAT_TYPE)sp[-1].u.integer;
+    sp[-1].type=T_FLOAT;
+  }
+
+  return sp[-2].type == sp[-1].type;
+}
 
 void o_subtract()
 {
-  if (sp[-2].type != sp[-1].type )
+  if (sp[-2].type != sp[-1].type && !float_promote())
     error("Subtract on different types.\n");
 
   switch(sp[-1].type)
@@ -659,15 +694,14 @@ static int generate_rsh(node *n)
   return 0;
 }
 
+
+#define TWO_TYPES(X,Y) (((X)<<8)|(Y))
 void o_multiply()
 {
-  switch(sp[-2].type)
+  switch(TWO_TYPES(sp[-2].type,sp[-1].type))
   {
-  case T_ARRAY:
-    if(sp[-1].type!=T_STRING)
+  case TWO_TYPES(T_ARRAY,T_STRING):
     {
-      error("Bad argument 2 to multiply.\n");
-    }else{
       struct lpc_string *ret;
       sp--;
       ret=implode(sp[-1].u.array,sp[0].u.string);
@@ -678,20 +712,30 @@ void o_multiply()
       return;
     }
 
-  case T_FLOAT:
-    if(sp[-1].type!=T_FLOAT) error("Bad argument 2 to multiply.\n");
+  case TWO_TYPES(T_FLOAT,T_FLOAT):
     sp--;
     sp[-1].u.float_number *= sp[0].u.float_number;
     return;
 
-  case T_INT:
-    if(sp[-1].type!=T_INT) error("Bad argument 2 to multiply.\n");
+  case TWO_TYPES(T_FLOAT,T_INT):
+    sp--;
+    sp[-1].u.float_number *= (FLOAT_TYPE)sp[0].u.integer;
+    return;
+
+  case TWO_TYPES(T_INT,T_FLOAT):
+    sp--;
+    sp[-1].u.float_number= 
+      (FLOAT_TYPE) sp[-1].u.integer * (FLOAT_TYPE)sp[0].u.float_number;
+    sp[-1].type=T_FLOAT;
+    return;
+
+  case TWO_TYPES(T_INT,T_INT):
     sp--;
     sp[-1].u.integer *= sp[0].u.integer;
     return;
 
   default:
-    error("Bad argument 1 to multiply.\n");
+    error("Bad arguments to multiply.\n");
   }
 }
 
@@ -726,7 +770,7 @@ static int generate_multiply(node *n)
 
 void o_divide()
 {
-  if(sp[-2].type!=sp[-1].type)
+  if(sp[-2].type!=sp[-1].type && !float_promote())
     error("Division on different types.\n");
 
   switch(sp[-2].type)
@@ -782,7 +826,7 @@ static int generate_divide(node *n)
 
 void o_mod()
 {
-  if(sp[-2].type != sp[-1].type)
+  if(sp[-2].type != sp[-1].type && !float_promote())
     error("Modulo on different types.\n");
 
   switch(sp[-1].type)
@@ -956,14 +1000,14 @@ void init_operators()
 {
   add_efun2("`==",f_eq,"function(mixed,mixed:int)",0,0,generate_comparison);
   add_efun2("`!=",f_ne,"function(mixed,mixed:int)",0,0,generate_comparison);
-  add_efun2("`<", f_lt,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison);
-  add_efun2("`<=",f_le,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison);
-  add_efun2("`>", f_gt,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison);
-  add_efun2("`>=",f_ge,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison);
+  add_efun2("`<", f_lt,"function(int|float,int|float:int)|function(string,string:int)",0,0,generate_comparison);
+  add_efun2("`<=",f_le,"function(int|float,int|float:int)|function(string,string:int)",0,0,generate_comparison);
+  add_efun2("`>", f_gt,"function(int|float,int|float:int)|function(string,string:int)",0,0,generate_comparison);
+  add_efun2("`>=",f_ge,"function(int|float,int|float:int)|function(string,string:int)",0,0,generate_comparison);
 
-  add_efun2("`+",f_add,"function(int ...:int)|function(float ...:float)|function(string,string|int|float ...:string)|function(string,string|int|float ...:string)|function(int|float,string,string|int|float:string)|function(array ...:array)|function(mapping ...:mapping)|function(list...:list)",0,optimize_binary,generate_sum);
+  add_efun2("`+",f_add,"function(int...:int)|!function(int...:mixed)&function(int|float...:float)|!function(int|float...:mixed)&function(string|int|float...:string)|function(array...:array)|function(mapping...:mapping)|function(list...:list)",0,optimize_binary,generate_sum);
 
-  add_efun2("`-",f_minus,"function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(list,list:list)|function(float,float:float)|function(int,int:int)|function(string,string:string)",0,0,generate_minus);
+  add_efun2("`-",f_minus,"function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(list,list:list)|function(float|int,float:float)|function(float,int:float)|function(int,int:int)|function(string,string:string)",0,0,generate_minus);
 
   add_efun2("`&",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_and);
 
@@ -974,13 +1018,12 @@ void init_operators()
   add_efun2("`<<",f_lsh,"function(int,int:int)",0,0,generate_lsh);
   add_efun2("`>>",f_rsh,"function(int,int:int)",0,0,generate_rsh);
 
-  add_efun2("`*",f_multiply,"function(int...:int)|function(float...:float)|function(string*,string:string)",0,optimize_binary,generate_multiply);
+  add_efun2("`*",f_multiply,"function(int...:int)|!function(int...:mixed)&function(float|int...:float)|function(string*,string:string)",0,optimize_binary,generate_multiply);
 
-  add_efun2("`/",f_divide,"function(int,int:int)|function(float,float:float)|function(string,string:string*)",0,0,generate_divide);
+  add_efun2("`/",f_divide,"function(int,int:int)|function(float|int,float:float)|function(float,int:float)|function(string,string:string*)",0,0,generate_divide);
 
   add_efun2("`%",f_mod,"function(int,int:int)|function(float,float:float)",0,0,generate_mod);
 
   add_efun2("`!",f_not,"function(mixed:int)",0,0,generate_not);
   add_efun2("`~",f_compl,"function(int:int)",0,0,generate_compl);
-  
 }
diff --git a/src/svalue.c b/src/svalue.c
index 612ab00302..6793c90527 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -366,7 +366,6 @@ int is_eq(struct svalue *a, struct svalue *b)
   }
 }
 
-
 int low_is_equal(struct svalue *a,
 		 struct svalue *b,
 		 struct processing *p)
@@ -443,8 +442,7 @@ int is_equal(struct svalue *a,struct svalue *b)
   return low_is_equal(a,b,0);
 }
 
-
-int is_gt(const struct svalue *a,const struct svalue *b)
+int is_lt(const struct svalue *a,const struct svalue *b)
 {
   check_type(a->type);
   check_type(b->type);
@@ -453,39 +451,18 @@ int is_gt(const struct svalue *a,const struct svalue *b)
 
   if (a->type != b->type)
   {
-    error("Cannot compare different types.\n");
-  }
-  switch(a->type)
-  {
-  default:
-    error("Bad argument 1 to '>'.\n");
-
-  case T_INT:
-    return a->u.integer > b->u.integer;
-
-  case T_STRING:
-    return my_strcmp(a->u.string, b->u.string) > 0;
+    if(a->type == T_FLOAT && b->type==T_INT)
+      return a->u.float_number < (FLOAT_TYPE)b->u.integer;
 
-  case T_FLOAT:
-    return a->u.float_number > b->u.float_number;
-  }
-}
-
-int is_lt(const struct svalue *a,const struct svalue *b)
-{
-  check_type(a->type);
-  check_type(b->type);
-  check_refs(a);
-  check_refs(b);
+    if(a->type == T_INT && b->type==T_FLOAT)
+      return (FLOAT_TYPE)a->u.integer < b->u.float_number;
 
-  if (a->type != b->type)
-  {
     error("Cannot compare different types.\n");
   }
   switch(a->type)
   {
   default:
-    error("Bad arg 1 to '<'.\n");
+    error("Bad type to comparison.\n");
 
   case T_INT:
     return a->u.integer < b->u.integer;
diff --git a/src/svalue.h b/src/svalue.h
index 9e536ff2f1..80bf0c88f6 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -55,6 +55,8 @@ struct svalue
 #define T_FLOAT 7
 #define T_INT 8
 
+#define T_NOT 247
+#define T_AND 248
 #define T_UNKNOWN 249
 #define T_MANY 250
 #define T_OR 251
@@ -87,6 +89,7 @@ struct svalue
 #define NUMBER_UNDEFINED 1
 #define NUMBER_DESTRUCTED 2
 
+#define is_gt(a,b) is_lt(b,a)
 #define IS_ZERO(X) ((X)->type==T_INT && (X)->u.integer==0)
 
 #define check_destructed(S) \
@@ -163,7 +166,6 @@ int low_short_is_equal(const union anything *a,
 		       TYPE_T type,
 		       struct processing *p);
 int is_equal(struct svalue *a,struct svalue *b);
-int is_gt(const struct svalue *a,const struct svalue *b);
 int is_lt(const struct svalue *a,const struct svalue *b);
 void describe_svalue(struct svalue *s,int indent,struct processing *p);
 void clear_svalues(struct svalue *s, INT32 num);
@@ -173,6 +175,8 @@ void copy_svalues_recursively_no_free(struct svalue *to,
 				      struct processing *p);
 void check_short_svalue(union anything *u,TYPE_T type);
 void check_svalue(struct svalue *s);
+void gc_check_svalues(struct svalue *s, int num);
+void gc_check_short_svalue(union anything *u, TYPE_T type);
 /* Prototypes end here */
 
 #endif
-- 
GitLab


From 27cc2a4775b94a281a35f29d84e935c83a7b76e9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 26 Feb 1996 00:01:01 +0100
Subject: [PATCH 047/351] keywords changed

Rev: doc/builtin/sizeof:1.3
Rev: doc/lpc/preprocessor:1.3
Rev: doc/lpc/sscanf:1.1
Rev: doc/operators/and:1.2
Rev: doc/operators/complement:1.2
Rev: doc/operators/divide:1.2
Rev: doc/operators/is_equal:1.2
Rev: doc/operators/is_greater_or_equal:1.2
Rev: doc/operators/is_greater_than:1.2
Rev: doc/operators/is_lesser_or_equal:1.2
Rev: doc/operators/is_lesser_than:1.2
Rev: doc/operators/minus:1.2
Rev: doc/operators/modulo:1.2
Rev: doc/operators/mult:1.2
Rev: doc/operators/not:1.2
Rev: doc/operators/not_equal:1.2
Rev: doc/operators/or:1.2
Rev: doc/operators/plus:1.2
Rev: doc/operators/shift_left:1.2
Rev: doc/operators/shift_right:1.2
Rev: doc/operators/xor:1.2
Rev: doc/simulated/sum:1.1
Rev: doc/types/array:1.4
Rev: doc/types/float:1.3
Rev: doc/types/function:1.3
Rev: doc/types/int:1.3
Rev: doc/types/list:1.3
Rev: doc/types/mapping:1.3
Rev: doc/types/object:1.3
Rev: doc/types/program:1.3
Rev: doc/types/string:1.3
---
 doc/builtin/sizeof                |  2 +-
 doc/lpc/preprocessor              |  3 +++
 doc/lpc/sscanf                    | 33 +++++++++++++++++++++++++++++++
 doc/operators/and                 |  2 +-
 doc/operators/complement          |  2 +-
 doc/operators/divide              |  2 +-
 doc/operators/is_equal            |  2 +-
 doc/operators/is_greater_or_equal |  2 +-
 doc/operators/is_greater_than     |  2 +-
 doc/operators/is_lesser_or_equal  |  2 +-
 doc/operators/is_lesser_than      |  2 +-
 doc/operators/minus               |  2 +-
 doc/operators/modulo              |  2 +-
 doc/operators/mult                |  2 +-
 doc/operators/not                 |  2 +-
 doc/operators/not_equal           |  2 +-
 doc/operators/or                  |  2 +-
 doc/operators/plus                |  2 +-
 doc/operators/shift_left          |  2 +-
 doc/operators/shift_right         |  2 +-
 doc/operators/xor                 |  2 +-
 doc/simulated/sum                 | 23 +++++++++++++++++++++
 doc/types/array                   |  2 +-
 doc/types/float                   |  2 +-
 doc/types/function                |  2 +-
 doc/types/int                     |  2 +-
 doc/types/list                    |  2 +-
 doc/types/mapping                 |  2 +-
 doc/types/object                  |  2 +-
 doc/types/program                 |  2 +-
 doc/types/string                  |  2 +-
 31 files changed, 87 insertions(+), 28 deletions(-)
 create mode 100644 doc/lpc/sscanf
 create mode 100644 doc/simulated/sum

diff --git a/doc/builtin/sizeof b/doc/builtin/sizeof
index e1e2243586..ec33611317 100644
--- a/doc/builtin/sizeof
+++ b/doc/builtin/sizeof
@@ -2,7 +2,7 @@ NAME
 	sizeof - return the size of an array, string, list or mapping
 
 SYNTAX
-	int sizeof(string|list|mapping|array a);
+	int sizeof(string|list|mapping|array|object a);
 
 DESCRIPTION
 	This function returns the number of indexes available in the argument
diff --git a/doc/lpc/preprocessor b/doc/lpc/preprocessor
index b8e0361be8..3c45c0d9db 100644
--- a/doc/lpc/preprocessor
+++ b/doc/lpc/preprocessor
@@ -22,6 +22,9 @@ PREPROCESSOR DIRECTIVES
 	  #pragma
 	  #undef
 
+KEYWORDS
+	lpc
+
 ============================================================================
 DIRECTIVE
 	#!
diff --git a/doc/lpc/sscanf b/doc/lpc/sscanf
new file mode 100644
index 0000000000..22526c5210
--- /dev/null
+++ b/doc/lpc/sscanf
@@ -0,0 +1,33 @@
+NAME
+	sscanf - scan a string using a format string
+
+SYNTAX
+	int sscanf(string str, string fmt, mixed var1, mixed var2 ...);
+
+DESCRIPTION
+	Parse a string str using the format fmt. fmt can contain strings
+	separated by "%d,%s,%c and %f. Every % corresponds to one of var1,
+	var2...
+
+	%d	gives an integer
+	%o	gives an octal integer
+	%x	gives a hexadecimal integer
+	%D	gives an integer that is either octal (leading zero),
+		hexadecimal (leading 0x) or decimal.
+	%f	gives a float
+	%c	matches one char and returns it as an integer
+	%s	gives a string
+	%[set]	matches a string containing a given set of characters.
+		(thos given inside the brackets) %[^set] means any character
+		ecept those inside brackets. %[0-9H] means any number or 'H'.
+
+	If a * is put between the percent and the operator, the operator
+	will not only match it's argument, not assign any variables.
+
+	Number of matched arguments is returned.
+
+KEYWORDS
+	string
+
+SEE ALSO
+	explode, sprintf
diff --git a/doc/operators/and b/doc/operators/and
index 2099f48fca..849eeae0ce 100644
--- a/doc/operators/and
+++ b/doc/operators/and
@@ -18,7 +18,7 @@ DESCRIPTION
 	however, the values will be taken from the rightmost mapping.
 
 KEYWORDS
-	operator
+	operators
 
 SEE ALSO
 	`|, `^
diff --git a/doc/operators/complement b/doc/operators/complement
index 0c9ff65f25..d3d0413046 100644
--- a/doc/operators/complement
+++ b/doc/operators/complement
@@ -11,7 +11,7 @@ DESCRIPTION
 	new integer.
 
 KEYWORDS
-	operator
+	operators
 
 SEE ALSO
 	`&, `|, `^
\ No newline at end of file
diff --git a/doc/operators/divide b/doc/operators/divide
index 82cb262e93..b4e22ae6b3 100644
--- a/doc/operators/divide
+++ b/doc/operators/divide
@@ -25,7 +25,7 @@ EXAMPLES
 	`/(2,2) 	returns 1
 
 KEYWORDS
-	operator
+	operators
 
 SEE ALSO
 	`*, `%
diff --git a/doc/operators/is_equal b/doc/operators/is_equal
index 12653faeca..71b51e625e 100644
--- a/doc/operators/is_equal
+++ b/doc/operators/is_equal
@@ -13,7 +13,7 @@ DESCRIPTION
 	two arrays LOOK alike, it must be the same array.)
 
 KEYWORDS
-	operator
+	operators
 
 SEE ALSO
 	`!=, `<, `>, `<=, `>=, efuns/equal
diff --git a/doc/operators/is_greater_or_equal b/doc/operators/is_greater_or_equal
index 1f744793f8..ad0f6ab81d 100644
--- a/doc/operators/is_greater_or_equal
+++ b/doc/operators/is_greater_or_equal
@@ -11,7 +11,7 @@ DESCRIPTION
 	is greater than or equal to the second one.
 
 KEYWORDS
-	operator
+	operators
 
 SEE ALSO
 	`!=, `==, `>, `<, `<=
diff --git a/doc/operators/is_greater_than b/doc/operators/is_greater_than
index 84ddca8473..3dc0726f9d 100644
--- a/doc/operators/is_greater_than
+++ b/doc/operators/is_greater_than
@@ -11,7 +11,7 @@ DESCRIPTION
 	is greater than the second one.
 
 KEYWORDS
-	operator
+	operators
 
 SEE ALSO
 	`!=, `==, `<, `<=, `>=
diff --git a/doc/operators/is_lesser_or_equal b/doc/operators/is_lesser_or_equal
index e6956a73c6..a15902e21f 100644
--- a/doc/operators/is_lesser_or_equal
+++ b/doc/operators/is_lesser_or_equal
@@ -11,7 +11,7 @@ DESCRIPTION
 	is lesser than or equal to the second one.
 
 KEYWORDS
-	operator
+	operators
 
 SEE ALSO
 	`!=, `==, `>, `<, `>=
diff --git a/doc/operators/is_lesser_than b/doc/operators/is_lesser_than
index 0482284764..0c40c48944 100644
--- a/doc/operators/is_lesser_than
+++ b/doc/operators/is_lesser_than
@@ -11,7 +11,7 @@ DESCRIPTION
 	is lesser than the second one.
 
 KEYWORDS
-	operator
+	operators
 
 SEE ALSO
 	`!=, `==, `>, `<=, `>=
diff --git a/doc/operators/minus b/doc/operators/minus
index 8bb403bf52..2ec59586af 100644
--- a/doc/operators/minus
+++ b/doc/operators/minus
@@ -30,7 +30,7 @@ EXAMPLES
 	([1:2,2:1])-([1:0])	returns ([2:1])
 
 KEYWORDS
-	operator
+	operators
 
 SEE ALSO
 	`+
diff --git a/doc/operators/modulo b/doc/operators/modulo
index 6e9561ea8d..b9d4eec9c7 100644
--- a/doc/operators/modulo
+++ b/doc/operators/modulo
@@ -20,7 +20,7 @@ EXAMPLES
 	2%0.3   	returns 0.2
 
 KEYWORDS
-	operator
+	operators
 
 SEE ALSO
 	`/, `*
diff --git a/doc/operators/mult b/doc/operators/mult
index e0ad0603e9..8a5c81631c 100644
--- a/doc/operators/mult
+++ b/doc/operators/mult
@@ -24,7 +24,7 @@ EXAMPLES
 	`*(2,2,2)	returns 8
 
 KEYWORDS
-	operator
+	operators
 
 SEE ALSO
 	`/
diff --git a/doc/operators/not b/doc/operators/not
index 1c251ee35f..9f51725779 100644
--- a/doc/operators/not
+++ b/doc/operators/not
@@ -10,4 +10,4 @@ DESCRIPTION
 	Returns 1 if a is zero, 0 otherwise.
 
 KEYWORDS
-	operator
+	operators
diff --git a/doc/operators/not_equal b/doc/operators/not_equal
index d68f40d3d1..faf9368299 100644
--- a/doc/operators/not_equal
+++ b/doc/operators/not_equal
@@ -13,7 +13,7 @@ DESCRIPTION
 	two arrays LOOK alike, it must be the same array.)
 
 KEYWORDS
-	operator
+	operators
 
 SEE ALSO
 	`==, `<, `>, `<=, `>=, efuns/equal
diff --git a/doc/operators/or b/doc/operators/or
index 9985a3860c..0388fa1318 100644
--- a/doc/operators/or
+++ b/doc/operators/or
@@ -18,7 +18,7 @@ DESCRIPTION
 	however, the values will be taken from the rightmost mapping.
 
 KEYWORDS
-	operator
+	operators
 
 SEE ALSO
 	`&, `^
diff --git a/doc/operators/plus b/doc/operators/plus
index 6402ad168a..6fbda79834 100644
--- a/doc/operators/plus
+++ b/doc/operators/plus
@@ -22,7 +22,7 @@ EXAMPLES
 	`+(2,2,2)	returns 6
 
 KEYWORDS
-	operator
+	operators
 
 SEE ALSO
 	`-, `*
diff --git a/doc/operators/shift_left b/doc/operators/shift_left
index a354ad32db..7de5c8782a 100644
--- a/doc/operators/shift_left
+++ b/doc/operators/shift_left
@@ -11,7 +11,7 @@ DESCRIPTION
 	multiplying a by 2 b times.
 
 KEYWORDS
-	operator
+	operators
 
 SEE ALSO
 	`>>
diff --git a/doc/operators/shift_right b/doc/operators/shift_right
index 363e77d63f..8de24822ce 100644
--- a/doc/operators/shift_right
+++ b/doc/operators/shift_right
@@ -11,7 +11,7 @@ DESCRIPTION
 	dividing a by 2 b times.
 
 KEYWORDS
-	operator
+	operators
 
 SEE ALSO
 	`<<
diff --git a/doc/operators/xor b/doc/operators/xor
index fe9d4e2676..e41878d35f 100644
--- a/doc/operators/xor
+++ b/doc/operators/xor
@@ -18,7 +18,7 @@ DESCRIPTION
 	however, the values will be taken from the rightmost mapping.
 
 KEYWORDS
-	operator
+	operators
 
 SEE ALSO
 	`|, `&
diff --git a/doc/simulated/sum b/doc/simulated/sum
new file mode 100644
index 0000000000..2179b3c5cc
--- /dev/null
+++ b/doc/simulated/sum
@@ -0,0 +1,23 @@
+NAME
+	sum - add values together
+
+SYNTAX
+	int sum(int ... i);
+	or
+	float sum(float ... f);
+	or
+	string sum(string|float|int ... p);
+	or
+	array sum(array ... a);
+	or
+	mapping sum(mapping ... m);
+	or
+	list sum(list ... l);
+
+DESCRIPTION
+	This function does exactly the same thing as adding all the arguments
+	together with +. It's just here so you can get a function-pointer to
+	the summation operator.
+
+KEYWORDS
+	int, float, string, array, mapping, list
diff --git a/doc/types/array b/doc/types/array
index 2bbbf51f37..0ffe36945f 100644
--- a/doc/types/array
+++ b/doc/types/array
@@ -43,7 +43,7 @@ DESCRIPTION
 		includes) element d.
 
 KEYWORDS
-	type
+	types
 
 SEE ALSO
 	mapping, list, builtin/allocate, builtin/sizeof, builtin/values
diff --git a/doc/types/float b/doc/types/float
index ca52ca30af..454fe71cb4 100644
--- a/doc/types/float
+++ b/doc/types/float
@@ -31,7 +31,7 @@ NOTA BENE
 	to the same type first.
 
 KEYWORDS
-	type
+	types
 
 SEE ALSO
 	math/sin, math/cos, math/tan, math/sqrt
diff --git a/doc/types/function b/doc/types/function
index ad60ad37a6..f903182769 100644
--- a/doc/types/function
+++ b/doc/types/function
@@ -14,7 +14,7 @@ DESCRIPTION
 	will be returned.
 
 KEYWORDS
-	type
+	types
 
 SEE ALSO
 	object, builtin/call_function, builtin/functionp,
diff --git a/doc/types/int b/doc/types/int
index e174c18023..13014a0eb0 100644
--- a/doc/types/int
+++ b/doc/types/int
@@ -33,7 +33,7 @@ DESCRIPTION
 	a >= b	returns 1 if a is greater or equal to b, 0 otherwise
 
 KEYWORDS
-	type
+	types
 
 SEE ALSO
 	float	
diff --git a/doc/types/list b/doc/types/list
index b361d0915c..cfc2889550 100644
--- a/doc/types/list
+++ b/doc/types/list
@@ -32,7 +32,7 @@ DESCRIPTION
 		present.
 
 KEYWORDS
-	type
+	types
 
 SEE ALSO
 	mapping, array, builtin/indices, builtin/sizeof
diff --git a/doc/types/mapping b/doc/types/mapping
index f009414380..36f63c3ac5 100644
--- a/doc/types/mapping
+++ b/doc/types/mapping
@@ -41,7 +41,7 @@ DESCRIPTION
 		already there.
 
 KEYWORDS
-	type
+	types
 
 SEE ALSO
 	array, list, builtin/sizeof, builtin/indices, builtin/values
diff --git a/doc/types/object b/doc/types/object
index 316e6c185c..c96f0de705 100644
--- a/doc/types/object
+++ b/doc/types/object
@@ -19,7 +19,7 @@ DESCRIPTION
 	o != o2	return 0 if o and o2 are the same object
 
 KEYWORDS
-	type
+	types
 
 SEE ALSO
 	program, function, builtin/clone, builtin/destruct
diff --git a/doc/types/program b/doc/types/program
index b428dbcf85..c653029056 100644
--- a/doc/types/program
+++ b/doc/types/program
@@ -9,7 +9,7 @@ DESCRIPTION
 	are == and !=.
 
 KEYWORDS
-	type
+	types
 
 SEE ALSO
 	object, function, builtin/compile_file, builtin/compile_string,
diff --git a/doc/types/string b/doc/types/string
index 8074d27562..0586b1e690 100644
--- a/doc/types/string
+++ b/doc/types/string
@@ -32,7 +32,7 @@ DESCRIPTION
 	a >= b	returns 1 if a is greater or equal to b, 0 otherwise
 
 KEYWORDS
-	type
+	types
 
 SEE ALSO
 	builtin/indices, builtin/values, builtin/sscanf, builtin/sprintf,
-- 
GitLab


From 0ee44fb4c6d1f21ed5b1901a6c24134b554660ec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 26 Feb 1996 00:00:35 +0100
Subject: [PATCH 048/351] keywords changed

Rev: doc/builtin/sscanf:1.4(DEAD)
Rev: doc/builtin/sum:1.3(DEAD)
---
 doc/builtin/sscanf | 33 ---------------------------------
 doc/builtin/sum    | 23 -----------------------
 2 files changed, 56 deletions(-)
 delete mode 100644 doc/builtin/sscanf
 delete mode 100644 doc/builtin/sum

diff --git a/doc/builtin/sscanf b/doc/builtin/sscanf
deleted file mode 100644
index 22526c5210..0000000000
--- a/doc/builtin/sscanf
+++ /dev/null
@@ -1,33 +0,0 @@
-NAME
-	sscanf - scan a string using a format string
-
-SYNTAX
-	int sscanf(string str, string fmt, mixed var1, mixed var2 ...);
-
-DESCRIPTION
-	Parse a string str using the format fmt. fmt can contain strings
-	separated by "%d,%s,%c and %f. Every % corresponds to one of var1,
-	var2...
-
-	%d	gives an integer
-	%o	gives an octal integer
-	%x	gives a hexadecimal integer
-	%D	gives an integer that is either octal (leading zero),
-		hexadecimal (leading 0x) or decimal.
-	%f	gives a float
-	%c	matches one char and returns it as an integer
-	%s	gives a string
-	%[set]	matches a string containing a given set of characters.
-		(thos given inside the brackets) %[^set] means any character
-		ecept those inside brackets. %[0-9H] means any number or 'H'.
-
-	If a * is put between the percent and the operator, the operator
-	will not only match it's argument, not assign any variables.
-
-	Number of matched arguments is returned.
-
-KEYWORDS
-	string
-
-SEE ALSO
-	explode, sprintf
diff --git a/doc/builtin/sum b/doc/builtin/sum
deleted file mode 100644
index 2179b3c5cc..0000000000
--- a/doc/builtin/sum
+++ /dev/null
@@ -1,23 +0,0 @@
-NAME
-	sum - add values together
-
-SYNTAX
-	int sum(int ... i);
-	or
-	float sum(float ... f);
-	or
-	string sum(string|float|int ... p);
-	or
-	array sum(array ... a);
-	or
-	mapping sum(mapping ... m);
-	or
-	list sum(list ... l);
-
-DESCRIPTION
-	This function does exactly the same thing as adding all the arguments
-	together with +. It's just here so you can get a function-pointer to
-	the summation operator.
-
-KEYWORDS
-	int, float, string, array, mapping, list
-- 
GitLab


From 8f6d52701a64525f1ced223d16678d57219f024e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 26 Feb 1996 22:28:59 +0100
Subject: [PATCH 049/351] mailinglist added

Rev: README:1.2
---
 README | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/README b/README
index 09416d879d..90775bffc8 100644
--- a/README
+++ b/README
@@ -1,8 +1,10 @@
-Micro LPC by Fredrik H�binette 1994-1995
+Micro LPC by Fredrik H�binette 1994-1996
 Permission to copy, modify, and distribute this source
 for any legal purpose granted as long as my name is
 still attatched to it. More specifically the GPL licence
 applies to this software.
 
 Read src/README for details on installation.
-New releases can be found on ftp://ftp.lysator.liu.se:/pub/languages/ulpc/
+New releases can be found on ftp://ftp.signum.se:/pub/uLPC/
+Send bugreports to ulpc-bugs@signum.se
+There is also a mailing list, to subscribe to it mail: ulpc-request@signum.se
-- 
GitLab


From 92a42cffdda235c81b6b109df17de1cbd4fd3d55 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 26 Feb 1996 22:30:03 +0100
Subject: [PATCH 050/351] htmlify_docs.lpc added

Rev: bin/htmlify_docs.lpc:1.1
---
 bin/htmlify_docs.lpc | 485 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 485 insertions(+)
 create mode 100644 bin/htmlify_docs.lpc

diff --git a/bin/htmlify_docs.lpc b/bin/htmlify_docs.lpc
new file mode 100644
index 0000000000..a15d9df5d0
--- /dev/null
+++ b/bin/htmlify_docs.lpc
@@ -0,0 +1,485 @@
+#!/usr/local/bin/ulpc
+
+// Parse BMML (Black Magic Markup Language) to HTML
+// Written by Fredrik Hubinette, dark sourceror and inventor of BMML
+
+mapping efuns = all_efuns();
+mapping pages = ([]);
+mapping short_descs = ([]);
+mapping keywords = ([]);
+mapping subpages = ([]);
+
+string new_path;
+
+/*
+ * Implode an array of strings to an english 'list'
+ * ie. ({"foo","bar","gazonk"}) beomces "foo bar, gazonk"
+ */
+string implode_nicely(string *foo)
+{
+  switch(sizeof(foo))
+  {
+  case 0: return "";
+  case 1: return foo[0];
+  default: return foo[0..sizeof(foo)-2]*", "+" and "+foo[-1];
+  }
+}
+
+/*
+ * Make a 'header'
+ */
+string smallcaps(string foo)
+{
+  string *ret;
+  ret=({"<b>"});
+  foreach(explode(foo," "),foo)
+  {
+    ret+=({"<font size=+1>"+foo[0..0]+"</font><font size=-1>"+foo[1..0x7fffffff]+"</font>"});
+  }
+  return implode(ret," ")+"</b>";
+}
+
+/*
+ * convert original path to internal format
+ */
+string fippel_path(string path)
+{
+  sscanf(path,"./%s",path);
+  return replace(path,"/","_")+".html";
+}
+
+string even_more_magic(string block, int indent)
+{
+  if(-1==search(block,"\t"))
+  {
+    return replace(block,"\n","<br>\n");
+  }else{
+    int e,d;
+    mixed tmp,tmp2;
+
+    tmp=explode(block,"\n")+({});
+    for(e=0;e<sizeof(tmp);e++)
+    {
+      tmp[e]=explode(tmp[e],"\t");
+      if(sscanf(tmp[e][0],"%*[ ]%s",tmp2) && tmp2=="")
+      {
+	int q;
+	for(q=e-1;q>0;q--)
+	{
+	  if(!tmp[q]) continue;
+
+	  if(sizeof(tmp[q])>=sizeof(tmp[e]))
+	  {
+	    for(d=1;d<sizeof(tmp[e]);d++)
+	    {
+	      tmp[q][d]+=" "+tmp[e][d];
+	    }
+	    tmp[e]=0;
+	  }
+	  break;
+	}
+      }
+    }
+    tmp-=({0});
+
+    for(e=0;e<sizeof(tmp);e++)
+    {
+      tmp[e]=implode(tmp[e]," </td><td> ");
+    }
+
+    return "<table border=0 cellpadding=0 cellspacing=0>\n<tr valign=top><td>"+
+      implode(tmp,"<br></td></tr>\n<tr valign=top><td>")+
+	"<br></td></tr>\n</table>\n";
+  }
+}
+
+string more_magic(string s, int quote)
+{
+  int e;
+  string *tmp;
+  int *ilevel=({0});
+  string output="";
+  string accumulator="";
+
+  if(!quote && -1==search("\n"+s,"\n ") && -1==search(s,"\t"))
+  {
+    return s;
+  }
+
+#define FLUSH() output+=even_more_magic(accumulator,ilevel[-1]); accumulator=""
+#define POP() output+="</dl>"; ilevel=ilevel[0..sizeof(ilevel)-2]
+
+  tmp=explode(s,"\n");
+  for(e=0;e<sizeof(tmp);e++)
+  {
+    string spaces, rest;
+
+    sscanf(tmp[e],"%[ ]%s",spaces,rest);
+    if(strlen(spaces) > ilevel[-1])
+    {
+      FLUSH();
+      output+="<dl><dt><dd>";
+      ilevel+=({ strlen(spaces) });
+    }
+    else if(strlen(spaces) < ilevel[-1])
+    {
+      FLUSH();
+      while(strlen(spaces) < ilevel[-1] && strlen(spaces) <= ilevel[-2])
+      {
+	POP();
+      }
+    }
+    accumulator+=rest+"\n";
+  }
+  
+  FLUSH();
+
+  while(sizeof(ilevel)>1)
+  {
+    POP();
+  }
+
+  return output;
+}
+
+string magic(string s, int quote)
+{
+  string *ret;
+  ret=({});
+
+  foreach(explode(s,"\n\n"),s)
+  {
+    sscanf(s,"\t%s",s);
+    s=replace(s,"\n\t","\n");
+    ret += ({ more_magic(s, quote) });
+  }
+
+  return implode(ret,"\n<p>");
+}
+
+inherit "/precompiled/regexp" : lastident;
+inherit "/precompiled/regexp" : megamagic;
+
+string syntax_magic(string s)
+{
+  string *tmp;
+  int e;
+
+  while(tmp=megamagic::split(s))
+  {
+    s=tmp[0]+"<I>"+tmp[1]+"</I>"+tmp[2];
+  }
+
+  tmp=explode(s,"\n");
+  for(e=0;e<sizeof(tmp);e++)
+  {
+    string a,b;
+    if(sscanf(tmp[e],"%s(%s",a,b) && strlen(b)>1 && b[-1]==';' && b[-2]==')')
+    {
+      string *tmp2;
+      int d;
+      tmp2=explode(b[0..strlen(b)-3],",");
+      for(d=0;d<sizeof(tmp2);d++)
+      {
+	string *tmp3;
+//	perror("<"+tmp2[d]+">");
+	if(tmp3=lastident::split(tmp2[d]))
+	{
+	  tmp2[d]=tmp3[0]+"<I>"+tmp3[1]+"</I>"+tmp3[2];
+	}
+      }
+      tmp[e]=a+"("+implode(tmp2,",")+");";
+    }
+  }
+  s=implode(tmp,"\n");
+  return "<tt>"+magic(s,1)+"</tt>";
+}
+
+string html_quote(string s)
+{
+  return replace(s,({"&","<",">"}),({"&amp;","&lt;","&gt;"}));
+}
+
+string html_unquote(string s)
+{
+  return replace(s,({"&amp;","&lt;","&gt;"}),({"&","<",">"}));
+}
+
+string convert_page(string path, string fname)
+{
+  string output, short;
+  int headno;
+  string cont, section, name, part;
+
+  output="";
+
+  cont=read_bytes(path);
+
+  cont=html_quote(cont);
+
+  if(sscanf(cont,"NAME\n\t%s - %s\n",name,short))
+  {
+    int partno;
+
+    short_descs[name]=short;
+
+    string *parts=explode(cont,"============================================================================\n");
+    for(partno=0;partno<sizeof(parts);partno++)
+    {
+      string part_name="error";
+      string *sections;
+      string part;
+      int section;
+
+      part=parts[partno];
+      if(!strlen(part)) continue;
+
+      sections=explode(part,"\n\n");
+      
+      for(section=0;section<sizeof(sections);section++)
+      {
+	if(!strlen(sections[section]) ||
+	   sections[section][0] < 'A' ||
+	   sections[section][0] > 'Z')
+	{
+	  sections[section-1]+="\n\n"+sections[section];
+	  sections=sections[0..section-1]+sections[section+1..0x7fffffff];
+	  section--;
+	}
+      }
+
+      for(headno=0;headno<sizeof(sections);headno++)
+      {
+	string type, rest;
+	mixed a, b;
+	sscanf(sections[headno],"%s\n%s",type,rest);
+
+	switch(type)
+	{
+	case "NAME":
+	  if(sscanf(rest,"\t%s - %s",part_name,b)!=2)
+	    perror("Warning NAME section broken!\n");
+	  rest="\t<tt>"+part_name+"</tt> - "+b;
+
+	case "DESCRIPTION":
+	case "NOTA BENE":
+	case "BUGS":
+	  rest=magic(rest,0);
+	  break;
+
+	default:
+	  perror("Warning: Unknown header: "+type+".\n");
+	  rest=magic(rest,0);
+	  break;
+
+	case "KEYWORDS":
+	  a=replace(rest,({"\n"," ","\t"}),({"","",""}))/",";
+	  b=({});
+	  foreach(a,a)
+	  {
+	    // fixme!!
+	    keywords[a] = ( keywords[a] || ({}) ) + ({ name });
+	    b+=({ "<a href=index.html#"+a+">"+a+"</a>" });
+	  }
+	  rest=implode_nicely(b);
+	  break;
+
+	case "SEE ALSO":
+	  rest=replace(rest,({"\n"," ","\t"}),({"","",""}));
+	  a=rest/",";
+	  b=({});
+	  foreach(a,a)
+	  {
+	    string tmp;
+	    tmp=a;
+	    a=explode(a,"/")[-1];
+	    if(pages[a])
+	    {
+	      b+=({ "<a href="+pages[a]+">" + a + "</a>" });
+	    }else if(subpages[a]){
+	      b+=({ "<a href="+subpages[a]+">" + a + "</a>" });
+	    }else if(subpages[fname+"-&gt;"+a]){
+	      b+=({ "<a href="+subpages[name+"-&gt;"+a]+">" + a + "</a>" });
+	    }else{
+	      perror("Warning, unlinked SEE ALSO: "+a+"\n");
+	      b+=({ tmp });
+	    }
+	  }
+	  rest=implode_nicely(b);
+	  break;
+
+	case "SYNTAX":
+	case "SYNTAX EXAMPLE":
+	  rest=syntax_magic(rest);
+	  break;
+
+	case "EXAMPLES":
+	case "EXAMPLE":
+	case "DIRECTIVE":
+	case "PREPROCESSOR DIRECTIVES":
+	  rest="<tt>"+magic(rest,1)+"</tt>";
+	}
+
+	sections[headno]="<dt>"+
+	  smallcaps(type)+
+	    "<dd>\n"+rest+"\n<p>";
+      }
+      parts[partno]="<dl>\n"+implode(sections,"\n")+"\n</dl>\n";
+      if(part_name)
+      {
+	parts[partno]="<a name="+part_name+">\n"+
+	  parts[partno]+
+	  "\n</a>\n";
+      }
+    }
+    output="<html><title>uLPC: "+name+"</title>"+
+      implode(parts,"<hr noshade size=1>\n");
+  }
+  return output;
+}
+
+void scanfiles(string path, string fname)
+{
+  string nf,np;
+  nf=convert_page(path, fname);
+
+  if(nf && strlen(nf))
+  {
+    np=combine_path(new_path,fippel_path(path));
+    write("Writing "+np+".\n");
+    if(file_size(np)>=0)
+      rm (np);
+    write_file(np,nf);
+  }
+}
+
+void scanlinks(string path, string fname)
+{
+  string cont,name;
+  cont=read_bytes(path);
+  cont=html_quote(cont);
+
+  if(sscanf(cont,"NAME\n\t%s -",name))
+  {
+    path=fippel_path(path);
+    pages[name]=path;
+
+    int e;
+    string *parts=explode(cont,"============================================================================\n");
+    for(e=1;e<sizeof(parts);e++)
+    {
+      string part_name;
+      if(sscanf(parts[e],"NAME\n\t%s -",part_name))
+      {
+	subpages[fname+"-&gt;"+part_name]=path+"#"+part_name;
+      }
+    }
+  }else{
+    perror("Warning: not converting "+path+".\n");
+  }
+}
+
+void traversedir(string path,function fun)
+{
+  string file;
+  foreach(get_dir(path) - ({"CVS","RCS"}),file)
+  {
+    string tmp;
+    if(file[-1]=='~') continue;
+    if(file[0]=='#' && file[-1]=='#') continue;
+    if(file[0]=='.' && file[1]=='#') continue;
+
+    tmp=path+"/"+file;
+
+    if(file_size(tmp)==-2)
+    {
+      traversedir(tmp,fun);
+    }else{
+      fun(tmp,file);
+    }
+  }
+}
+
+string mkindex()
+{
+  string ret;
+  string a,b;
+  mapping tmp=pages+([]);
+
+  ret="";
+
+  ret+="<H1>"+version()+"</h1>\n";
+  
+  ret+="<H1>Keyword lists</H1>\n<dl>\n";
+  foreach(sort_array(m_indices(keywords)),b)
+  {
+    ret+="<a name="+b+">";
+    ret+="<dt><h2>"+capitalize(b);
+    if(short_descs[b]) ret+=" - "+short_descs[b];
+    ret+="</h2><dd>\n";
+    ret+="<ul>\n";
+    foreach(keywords[b],a)
+    {
+      ret+="<li><a href="+pages[a]+">"+a+"</a> - "+short_descs[a]+"\n";
+      m_delete(tmp,a);
+    }
+    ret+="</ul></a>\n";
+  }
+  ret+="</dl>\n";
+
+  ret+="<H1>All builtin functions:</H1>\n<ul>\n";
+  
+  foreach(sort_array(m_indices(all_efuns())),a)
+  {
+    a=html_quote(a);
+    if(pages[a])
+    {
+      ret+="<li><a href="+pages[a]+">"+a+"</a> - "+short_descs[a]+"\n";
+    }else{
+      perror("Warning: no page for function: "+a+".\n");
+    }
+    m_delete(tmp,a);
+  }
+  ret+="</ul>\n";
+
+  ret+="</dl><H1>Builtin programs:</H1>\n<ul>\n";
+  foreach(sort_array(m_indices(tmp)),a)
+  {
+    if(-1 == search(a,"/")) continue;
+
+    ret+="<li><a href="+pages[a]+">"+a+"</a> - "+short_descs[a]+"\n";
+    m_delete(tmp,a);
+  }
+  
+  ret+="</ul>\n";
+
+  ret+="<H1>Other pages</H1>\n<ul>\n";
+  foreach(sort_array(m_indices(tmp)),a)
+  {
+    ret+="<li><a href="+pages[a]+">"+a+"</a> - "+short_descs[a]+"\n";
+  }
+  
+  ret+="</ul>\n";
+  return ret;
+}
+
+int main(int argc, string *argv)
+{
+  string np;
+
+  megamagic::create("^(.*)&lt;([a-z_0-9][a-z_0-9]*)&gt;(.*)$");
+  lastident::create("^(.*[^<>a-z_0-9])([a-z_0-9][a-z_0-9]*)([^<>a-z_0-9]*)$");
+
+  write("Scanning links.\n");
+  new_path=combine_path(getcwd(),argv[2]);
+  cd(argv[1]);
+  traversedir(".",scanlinks);
+  write("Processing pages.\n");
+  traversedir(".",scanfiles);
+
+  write("Making index.\n");
+  np=combine_path(new_path,"index.html");
+  if(file_size(np)>=0)
+    rm(np);
+  write_file(np,mkindex());
+}
-- 
GitLab


From 0b2df34aa10b2d7ab6905a303e5d80beb9d5e0c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 26 Feb 1996 22:32:51 +0100
Subject: [PATCH 051/351] typeof doc added

Rev: doc/lpc/typeof:1.1
---
 doc/lpc/typeof | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 doc/lpc/typeof

diff --git a/doc/lpc/typeof b/doc/lpc/typeof
new file mode 100644
index 0000000000..a78cb5fe19
--- /dev/null
+++ b/doc/lpc/typeof
@@ -0,0 +1,21 @@
+NAME
+	typeof - check return type of expression
+
+SYNTAX
+	typeof ( expression )
+
+DESCRIPTION
+	This is a not really a function even if it looks like it, it returns
+	a human readable (almost) representation of the type that the
+	expression would return without actually evaluating it.
+	The representation is in the form of a string.
+
+EXAMPLE
+	> typeof(`sizeof);
+	Result: function(object | mapping | array | list | string : int)
+	> typeof(sizeof(({})));
+	Result: int
+	> 
+
+KEYWORDS
+	lpc
-- 
GitLab


From 8f42881d5de3224cb619dbc525a7de16e512df27 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 1 Mar 1996 00:59:12 +0100
Subject: [PATCH 052/351] added test for pure_parser

Rev: src/ChangeLog:1.20
Rev: src/Makefile.in:1.11
Rev: src/configure:1.3(DEAD)
Rev: src/configure.in:1.8
---
 src/ChangeLog    |    4 +
 src/Makefile.in  |    1 +
 src/configure    | 3857 ----------------------------------------------
 src/configure.in |   23 +
 4 files changed, 28 insertions(+), 3857 deletions(-)
 delete mode 100755 src/configure

diff --git a/src/ChangeLog b/src/ChangeLog
index 1574e91eab..a3a5e731b3 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+Fri Mar  1 00:35:40 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
+
+	* configure.in: added test for %pure_parser
+
 Sun Feb 25 22:42:48 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
 
 	* operator functions implemented
diff --git a/src/Makefile.in b/src/Makefile.in
index 41e2f32f64..f25e385a16 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -165,6 +165,7 @@ run_hilfe:
 # make export archive (requires compiled uLPC)
 # Do not compile in source tree if you want to use this!
 export: $(SRCDIR)/test/testsuite
+	chmod +x $(TMP_SRCDIR)/install-sh
 	$(RUNULPC) $(TMP_BINDIR)/export.lpc
 
 # make dependencies (requires compiled uLPC)
diff --git a/src/configure b/src/configure
deleted file mode 100755
index 6b0c0b7669..0000000000
--- a/src/configure
+++ /dev/null
@@ -1,3857 +0,0 @@
-#! /bin/sh
-
-# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.7 
-# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-
-# Defaults:
-ac_help=
-ac_default_prefix=/usr/local
-# Any additions from configure.in:
-
-# Initialize some variables set by options.
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-build=NONE
-cache_file=./config.cache
-exec_prefix=NONE
-host=NONE
-no_create=
-nonopt=NONE
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-target=NONE
-verbose=
-x_includes=NONE
-x_libraries=NONE
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datadir='${prefix}/share'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-libdir='${exec_prefix}/lib'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-infodir='${prefix}/info'
-mandir='${prefix}/man'
-
-# Initialize some other variables.
-subdirs=
-MFLAGS= MAKEFLAGS=
-
-ac_prev=
-for ac_option
-do
-
-  # If the previous option needs an argument, assign it.
-  if test -n "$ac_prev"; then
-    eval "$ac_prev=\$ac_option"
-    ac_prev=
-    continue
-  fi
-
-  case "$ac_option" in
-  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
-  *) ac_optarg= ;;
-  esac
-
-  # Accept the important Cygnus configure options, so we can diagnose typos.
-
-  case "$ac_option" in
-
-  -bindir | --bindir | --bindi | --bind | --bin | --bi)
-    ac_prev=bindir ;;
-  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
-    bindir="$ac_optarg" ;;
-
-  -build | --build | --buil | --bui | --bu)
-    ac_prev=build ;;
-  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
-    build="$ac_optarg" ;;
-
-  -cache-file | --cache-file | --cache-fil | --cache-fi \
-  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
-    ac_prev=cache_file ;;
-  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
-  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
-    cache_file="$ac_optarg" ;;
-
-  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
-    ac_prev=datadir ;;
-  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
-  | --da=*)
-    datadir="$ac_optarg" ;;
-
-  -disable-* | --disable-*)
-    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
-    # Reject names that are not valid shell variable names.
-    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
-      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
-    fi
-    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
-    eval "enable_${ac_feature}=no" ;;
-
-  -enable-* | --enable-*)
-    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
-    # Reject names that are not valid shell variable names.
-    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
-      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
-    fi
-    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
-    case "$ac_option" in
-      *=*) ;;
-      *) ac_optarg=yes ;;
-    esac
-    eval "enable_${ac_feature}='$ac_optarg'" ;;
-
-  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
-  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
-  | --exec | --exe | --ex)
-    ac_prev=exec_prefix ;;
-  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
-  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
-  | --exec=* | --exe=* | --ex=*)
-    exec_prefix="$ac_optarg" ;;
-
-  -gas | --gas | --ga | --g)
-    # Obsolete; use --with-gas.
-    with_gas=yes ;;
-
-  -help | --help | --hel | --he)
-    # Omit some internal or obsolete options to make the list less imposing.
-    # This message is too long to be a string in the A/UX 3.1 sh.
-    cat << EOF
-Usage: configure [options] [host]
-Options: [defaults in brackets after descriptions]
-Configuration:
-  --cache-file=FILE       cache test results in FILE
-  --help                  print this message
-  --no-create             do not create output files
-  --quiet, --silent       do not print \`checking...' messages
-  --version               print the version of autoconf that created configure
-Directory and file names:
-  --prefix=PREFIX         install architecture-independent files in PREFIX
-                          [$ac_default_prefix]
-  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
-                          [same as prefix]
-  --bindir=DIR            user executables in DIR [EPREFIX/bin]
-  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
-  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
-  --datadir=DIR           read-only architecture-independent data in DIR
-                          [PREFIX/share]
-  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
-  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
-                          [PREFIX/com]
-  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
-  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
-  --includedir=DIR        C header files in DIR [PREFIX/include]
-  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
-  --infodir=DIR           info documentation in DIR [PREFIX/info]
-  --mandir=DIR            man documentation in DIR [PREFIX/man]
-  --srcdir=DIR            find the sources in DIR [configure dir or ..]
-  --program-prefix=PREFIX prepend PREFIX to installed program names
-  --program-suffix=SUFFIX append SUFFIX to installed program names
-  --program-transform-name=PROGRAM
-                          run sed PROGRAM on installed program names
-EOF
-    cat << EOF
-Host type:
-  --build=BUILD           configure for building on BUILD [BUILD=HOST]
-  --host=HOST             configure for HOST [guessed]
-  --target=TARGET         configure for TARGET [TARGET=HOST]
-Features and packages:
-  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
-  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
-  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
-  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
-  --x-includes=DIR        X include files are in DIR
-  --x-libraries=DIR       X library files are in DIR
-EOF
-    if test -n "$ac_help"; then
-      echo "--enable and --with options recognized:$ac_help"
-    fi
-    exit 0 ;;
-
-  -host | --host | --hos | --ho)
-    ac_prev=host ;;
-  -host=* | --host=* | --hos=* | --ho=*)
-    host="$ac_optarg" ;;
-
-  -includedir | --includedir | --includedi | --included | --include \
-  | --includ | --inclu | --incl | --inc)
-    ac_prev=includedir ;;
-  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
-  | --includ=* | --inclu=* | --incl=* | --inc=*)
-    includedir="$ac_optarg" ;;
-
-  -infodir | --infodir | --infodi | --infod | --info | --inf)
-    ac_prev=infodir ;;
-  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
-    infodir="$ac_optarg" ;;
-
-  -libdir | --libdir | --libdi | --libd)
-    ac_prev=libdir ;;
-  -libdir=* | --libdir=* | --libdi=* | --libd=*)
-    libdir="$ac_optarg" ;;
-
-  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
-  | --libexe | --libex | --libe)
-    ac_prev=libexecdir ;;
-  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
-  | --libexe=* | --libex=* | --libe=*)
-    libexecdir="$ac_optarg" ;;
-
-  -localstatedir | --localstatedir | --localstatedi | --localstated \
-  | --localstate | --localstat | --localsta | --localst \
-  | --locals | --local | --loca | --loc | --lo)
-    ac_prev=localstatedir ;;
-  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
-  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
-  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
-    localstatedir="$ac_optarg" ;;
-
-  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
-    ac_prev=mandir ;;
-  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
-    mandir="$ac_optarg" ;;
-
-  -nfp | --nfp | --nf)
-    # Obsolete; use --without-fp.
-    with_fp=no ;;
-
-  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
-  | --no-cr | --no-c)
-    no_create=yes ;;
-
-  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
-  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
-    no_recursion=yes ;;
-
-  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
-  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
-  | --oldin | --oldi | --old | --ol | --o)
-    ac_prev=oldincludedir ;;
-  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
-  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
-  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
-    oldincludedir="$ac_optarg" ;;
-
-  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
-    ac_prev=prefix ;;
-  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
-    prefix="$ac_optarg" ;;
-
-  -program-prefix | --program-prefix | --program-prefi | --program-pref \
-  | --program-pre | --program-pr | --program-p)
-    ac_prev=program_prefix ;;
-  -program-prefix=* | --program-prefix=* | --program-prefi=* \
-  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
-    program_prefix="$ac_optarg" ;;
-
-  -program-suffix | --program-suffix | --program-suffi | --program-suff \
-  | --program-suf | --program-su | --program-s)
-    ac_prev=program_suffix ;;
-  -program-suffix=* | --program-suffix=* | --program-suffi=* \
-  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
-    program_suffix="$ac_optarg" ;;
-
-  -program-transform-name | --program-transform-name \
-  | --program-transform-nam | --program-transform-na \
-  | --program-transform-n | --program-transform- \
-  | --program-transform | --program-transfor \
-  | --program-transfo | --program-transf \
-  | --program-trans | --program-tran \
-  | --progr-tra | --program-tr | --program-t)
-    ac_prev=program_transform_name ;;
-  -program-transform-name=* | --program-transform-name=* \
-  | --program-transform-nam=* | --program-transform-na=* \
-  | --program-transform-n=* | --program-transform-=* \
-  | --program-transform=* | --program-transfor=* \
-  | --program-transfo=* | --program-transf=* \
-  | --program-trans=* | --program-tran=* \
-  | --progr-tra=* | --program-tr=* | --program-t=*)
-    program_transform_name="$ac_optarg" ;;
-
-  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
-  | -silent | --silent | --silen | --sile | --sil)
-    silent=yes ;;
-
-  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
-    ac_prev=sbindir ;;
-  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
-  | --sbi=* | --sb=*)
-    sbindir="$ac_optarg" ;;
-
-  -sharedstatedir | --sharedstatedir | --sharedstatedi \
-  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
-  | --sharedst | --shareds | --shared | --share | --shar \
-  | --sha | --sh)
-    ac_prev=sharedstatedir ;;
-  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
-  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
-  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
-  | --sha=* | --sh=*)
-    sharedstatedir="$ac_optarg" ;;
-
-  -site | --site | --sit)
-    ac_prev=site ;;
-  -site=* | --site=* | --sit=*)
-    site="$ac_optarg" ;;
-
-  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
-    ac_prev=srcdir ;;
-  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
-    srcdir="$ac_optarg" ;;
-
-  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
-  | --syscon | --sysco | --sysc | --sys | --sy)
-    ac_prev=sysconfdir ;;
-  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
-  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
-    sysconfdir="$ac_optarg" ;;
-
-  -target | --target | --targe | --targ | --tar | --ta | --t)
-    ac_prev=target ;;
-  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
-    target="$ac_optarg" ;;
-
-  -v | -verbose | --verbose | --verbos | --verbo | --verb)
-    verbose=yes ;;
-
-  -version | --version | --versio | --versi | --vers)
-    echo "configure generated by autoconf version 2.7"
-    exit 0 ;;
-
-  -with-* | --with-*)
-    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
-    # Reject names that are not valid shell variable names.
-    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
-      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
-    fi
-    ac_package=`echo $ac_package| sed 's/-/_/g'`
-    case "$ac_option" in
-      *=*) ;;
-      *) ac_optarg=yes ;;
-    esac
-    eval "with_${ac_package}='$ac_optarg'" ;;
-
-  -without-* | --without-*)
-    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
-    # Reject names that are not valid shell variable names.
-    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
-      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
-    fi
-    ac_package=`echo $ac_package| sed 's/-/_/g'`
-    eval "with_${ac_package}=no" ;;
-
-  --x)
-    # Obsolete; use --with-x.
-    with_x=yes ;;
-
-  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
-  | --x-incl | --x-inc | --x-in | --x-i)
-    ac_prev=x_includes ;;
-  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
-  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
-    x_includes="$ac_optarg" ;;
-
-  -x-libraries | --x-libraries | --x-librarie | --x-librari \
-  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
-    ac_prev=x_libraries ;;
-  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
-  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
-    x_libraries="$ac_optarg" ;;
-
-  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
-    ;;
-
-  *)
-    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
-      echo "configure: warning: $ac_option: invalid host type" 1>&2
-    fi
-    if test "x$nonopt" != xNONE; then
-      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
-    fi
-    nonopt="$ac_option"
-    ;;
-
-  esac
-done
-
-if test -n "$ac_prev"; then
-  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
-fi
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-# File descriptor usage:
-# 0 standard input
-# 1 file creation
-# 2 errors and warnings
-# 3 some systems may open it to /dev/tty
-# 4 used on the Kubota Titan
-# 6 checking for... messages and results
-# 5 compiler messages saved in config.log
-if test "$silent" = yes; then
-  exec 6>/dev/null
-else
-  exec 6>&1
-fi
-exec 5>./config.log
-
-echo "\
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-" 1>&5
-
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Also quote any args containing shell metacharacters.
-ac_configure_args=
-for ac_arg
-do
-  case "$ac_arg" in
-  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
-  | --no-cr | --no-c) ;;
-  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
-  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
-  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
-  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
-  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
-  esac
-done
-
-# NLS nuisances.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
-if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo > confdefs.h
-
-# A filename unique to this package, relative to the directory that
-# configure is in, which we can look for to find out if srcdir is correct.
-ac_unique_file=interpret.c
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
-  ac_srcdir_defaulted=yes
-  # Try the directory containing this script, then its parent.
-  ac_prog=$0
-  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
-  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
-  srcdir=$ac_confdir
-  if test ! -r $srcdir/$ac_unique_file; then
-    srcdir=..
-  fi
-else
-  ac_srcdir_defaulted=no
-fi
-if test ! -r $srcdir/$ac_unique_file; then
-  if test "$ac_srcdir_defaulted" = yes; then
-    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
-  else
-    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
-  fi
-fi
-srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
-
-# Prefer explicitly selected file to automatically selected ones.
-if test -z "$CONFIG_SITE"; then
-  if test "x$prefix" != xNONE; then
-    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
-  else
-    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
-  fi
-fi
-for ac_site_file in $CONFIG_SITE; do
-  if test -r "$ac_site_file"; then
-    echo "loading site script $ac_site_file"
-    . "$ac_site_file"
-  fi
-done
-
-if test -r "$cache_file"; then
-  echo "loading cache $cache_file"
-  . $cache_file
-else
-  echo "creating cache $cache_file"
-  > $cache_file
-fi
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='echo $CPP $CPPFLAGS 1>&5;
-$CPP $CPPFLAGS'
-ac_compile='echo ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5;
-${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5'
-ac_link='echo ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5;
-${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5'
-
-if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
-  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
-  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
-    ac_n= ac_c='
-' ac_t='	'
-  else
-    ac_n=-n ac_c= ac_t=
-  fi
-else
-  ac_n= ac_c='\c' ac_t=
-fi
-
-
-# Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
-  for ac_dir in $PATH; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      ac_cv_prog_CC="gcc"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-  test -z "$ac_cv_prog_CC" && ac_cv_prog_CC="cc"
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
-  echo "$ac_t""$CC" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-
-echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.c <<EOF
-#ifdef __GNUC__
-  yes;
-#endif
-EOF
-if ${CC-cc} -E conftest.c 2>&5 | egrep yes >/dev/null 2>&1; then
-  ac_cv_prog_gcc=yes
-else
-  ac_cv_prog_gcc=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gcc" 1>&6
-if test $ac_cv_prog_gcc = yes; then
-  GCC=yes
-  if test "${CFLAGS+set}" != set; then
-    echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  echo 'void f(){}' > conftest.c
-if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
-  ac_cv_prog_gcc_g=yes
-else
-  ac_cv_prog_gcc_g=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6
-    if test $ac_cv_prog_gcc_g = yes; then
-      CFLAGS="-g -O"
-    else
-      CFLAGS="-O"
-    fi
-  fi
-else
-  GCC=
-  test "${CFLAGS+set}" = set || CFLAGS="-g"
-fi
-
-
-# We need some special hacks when running slowaris
-# Extract the first word of "uname", so it can be a program name with args.
-set dummy uname; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_path_uname_prog'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  case "$uname_prog" in
-  /*)
-  ac_cv_path_uname_prog="$uname_prog" # Let the user override the test with a path.
-  ;;
-  *)
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
-  for ac_dir in $PATH; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      ac_cv_path_uname_prog="$ac_dir/$ac_word"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-  test -z "$ac_cv_path_uname_prog" && ac_cv_path_uname_prog="no"
-  ;;
-esac
-fi
-uname_prog="$ac_cv_path_uname_prog"
-if test -n "$uname_prog"; then
-  echo "$ac_t""$uname_prog" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-echo $ac_n "checking operating system""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_sys_os'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-if test "$uname_prog" != "no"; then
-  lpc_cv_sys_os="`uname`"
-
-  if test "$lpc_cv_sys_os" = "SunOS"; then
-    case "`uname -r`" in
-      5.*) lpc_cv_sys_os="Solaris";
-    esac
-  fi
-else
-  lpc_cv_sys_os="Not Solaris"
-fi
-
-fi
-
-echo "$ac_t""$lpc_cv_sys_os" 1>&6
-
-
-OLD_CFLAGS="$CFLAGS"
-OPTIMIZE="";
-
-echo $ac_n "checking -O""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_option_opt'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-  CFLAGS="$OLD_CFLAGS -O"
-  cat > conftest.$ac_ext <<EOF
-#line 659 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
- exit(0); 
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  lpc_cv_option_opt=yes
-else
-  rm -rf conftest*
-  lpc_cv_option_opt=no
-fi
-rm -f conftest*
-
-
-fi
-
-
-if test "$lpc_cv_option_opt" = "yes" ; then
-  CFLAGS="$OLD_CFLAGS -O"
-  OPTIMIZE="$OPTIMIZE -O"
-  echo "$ac_t""-O found" 1>&6
-else
-  echo "$ac_t""-O not found" 1>&6
-fi
-
-CFLAGS="$OLD_CFLAGS"
-
-if test "$GCC" = "yes"; then
-  WARN="-g -W -Wunused -Wformat"
-
-  echo $ac_n "checking -pipe""... $ac_c" 1>&6
-  if eval "test \"`echo '$''{'lpc_cv_option_pipe'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-    CFLAGS="$OLD_CFLAGS -pipe"
-    cat > conftest.$ac_ext <<EOF
-#line 700 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
- exit(0); 
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  lpc_cv_option_pipe=yes
-else
-  rm -rf conftest*
-  lpc_cv_option_pipe=no
-fi
-rm -f conftest*
-
-  
-fi
-
-
-  if test "$lpc_cv_option_pipe" = "yes" ; then
-    CFLAGS="$OLD_CFLAGS -pipe"
-    OPTIMIZE="$OPTIMIZE -pipe"
-    echo "$ac_t""-pipe found" 1>&6
-  else
-    echo "$ac_t""-pipe not found" 1>&6
-    CFLAGS="$OLD_CFLAGS"
-  fi
-
-
-else
-  WARN=""
-#
-# Special hack for HP-UX stupid cc
-#
-  if test "$lpc_cv_sys_os" = "HP-UX"; then
-    OLD_CC="${CC-cc}"
-    CC="$CC -Aa -D_HPUX_SOURCE +Olibcalls"
-    cat > conftest.$ac_ext <<EOF
-#line 740 "configure"
-#include "confdefs.h"
-int foo(int bar);
-int main() { return 0; }
-int t() {
- exit(0); 
-; return 0; }
-EOF
-if eval $ac_link; then
-  :
-else
-  rm -rf conftest*
-  CC="$OLD_CC"
-fi
-rm -f conftest*
-
-  fi
-fi
-
-echo $ac_n "checking ansi prototype capability""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_sys_ansi_prototypes'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-  cat > conftest.$ac_ext <<EOF
-#line 765 "configure"
-#include "confdefs.h"
-int foo(int bar);
-int main() { return 0; }
-int t() {
- exit(0); 
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  lpc_cv_sys_ansi_prototypes=yes
-else
-  rm -rf conftest*
-  lpc_cv_sys_ansi_prototypes=no
-fi
-rm -f conftest*
-
-
-fi
-
-
-if test "$lpc_cv_sys_ansi_prototypes" = "yes"; then
-  echo "$ac_t""yes" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-  exit 1
-fi
-
-
-ac_aux_dir=
-for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
-  if test -f $ac_dir/install-sh; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install-sh -c"
-    break
-  elif test -f $ac_dir/install.sh; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install.sh -c"
-    break
-  fi
-done
-if test -z "$ac_aux_dir"; then
-  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
-fi
-ac_config_guess=$ac_aux_dir/config.guess
-ac_config_sub=$ac_aux_dir/config.sub
-ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
-
-# Find a good install program.  We prefer a C program (faster),
-# so one script is as good as another.  But avoid the broken or
-# incompatible versions:
-# SysV /etc/install, /usr/sbin/install
-# SunOS /usr/etc/install
-# IRIX /sbin/install
-# AIX /bin/install
-# AFS /usr/afsws/bin/install, which mishandles nonexistent args
-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
-# ./install, which can be erroneously created by make from ./install.sh.
-echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-if test -z "$INSTALL"; then
-if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
-  for ac_dir in $PATH; do
-    # Account for people who put trailing slashes in PATH elements.
-    case "$ac_dir/" in
-    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
-    *)
-      # OSF1 and SCO ODT 3.0 have their own names for install.
-      for ac_prog in ginstall installbsd scoinst install; do
-        if test -f $ac_dir/$ac_prog; then
-	  if test $ac_prog = install &&
-            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
-	    # AIX install.  It has an incompatible calling convention.
-	    # OSF/1 installbsd also uses dspmsg, but is usable.
-	    :
-	  else
-	    ac_cv_path_install="$ac_dir/$ac_prog -c"
-	    break 2
-	  fi
-	fi
-      done
-      ;;
-    esac
-  done
-  IFS="$ac_save_ifs"
-
-fi
-  if test "${ac_cv_path_install+set}" = set; then
-    INSTALL="$ac_cv_path_install"
-  else
-    # As a last resort, use the slow shell script.  We don't cache a
-    # path for INSTALL within a source directory, because that will
-    # break other packages using the cache if that directory is
-    # removed, or if the path is relative.
-    INSTALL="$ac_install_sh"
-  fi
-fi
-echo "$ac_t""$INSTALL" 1>&6
-
-# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
-# It thinks the first close brace ends the variable substitution.
-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
-
-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-
-for ac_prog in 'bison -y' byacc
-do
-# Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test -n "$YACC"; then
-  ac_cv_prog_YACC="$YACC" # Let the user override the test.
-else
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
-  for ac_dir in $PATH; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      ac_cv_prog_YACC="$ac_prog"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-fi
-fi
-YACC="$ac_cv_prog_YACC"
-if test -n "$YACC"; then
-  echo "$ac_t""$YACC" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-test -n "$YACC" && break
-done
-test -n "$YACC" || YACC="yacc"
-
-echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
-  CPP=
-fi
-if test -z "$CPP"; then
-if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-    # This must be in double quotes, not single quotes, because CPP may get
-  # substituted into the Makefile and "${CC-cc}" will confuse make.
-  CPP="${CC-cc} -E"
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp.
-  cat > conftest.$ac_ext <<EOF
-#line 920 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
-  :
-else
-  echo "$ac_err" >&5
-  rm -rf conftest*
-  CPP="${CC-cc} -E -traditional-cpp"
-  cat > conftest.$ac_ext <<EOF
-#line 934 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
-  :
-else
-  echo "$ac_err" >&5
-  rm -rf conftest*
-  CPP=/lib/cpp
-fi
-rm -f conftest*
-fi
-rm -f conftest*
-  ac_cv_prog_CPP="$CPP"
-fi
-  CPP="$ac_cv_prog_CPP"
-else
-  ac_cv_prog_CPP="$CPP"
-fi
-echo "$ac_t""$CPP" 1>&6
-
-# Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test -n "$RANLIB"; then
-  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
-  for ac_dir in $PATH; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      ac_cv_prog_RANLIB="ranlib"
-      break
-    fi
-  done
-  IFS="$ac_save_ifs"
-  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
-fi
-fi
-RANLIB="$ac_cv_prog_RANLIB"
-if test -n "$RANLIB"; then
-  echo "$ac_t""$RANLIB" 1>&6
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-set dummy ${MAKE-make}; ac_make=$2
-if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftestmake <<\EOF
-all:
-	@echo 'ac_maketemp="${MAKE}"'
-EOF
-# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
-eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
-if test -n "$ac_maketemp"; then
-  eval ac_cv_prog_make_${ac_make}_set=yes
-else
-  eval ac_cv_prog_make_${ac_make}_set=no
-fi
-rm -f conftestmake
-fi
-if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-  SET_MAKE=
-else
-  echo "$ac_t""no" 1>&6
-  SET_MAKE="MAKE=${MAKE-make}"
-fi
-
-
-echo $ac_n "checking first yacc define""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_yacc_first'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-cat >conftest.y <<\EOF
-%token GURKA
-%%
-all: GURKA
-%%
-EOF
-lpc_cv_yacc_first=257;
-if $YACC -d conftest.y ; then
-  if test -f y.tab.h; then
-    lpc_cv_yacc_first=`egrep GURKA y.tab.h | sed 's/^#[^0-9]*\([0-9]*\)[^0-9]*$/\1/'`
-    echo $lpc_cv_yacc_first >conftest.out
-    if egrep '^(0|1|2|3|4|5|6|7|8|9)+$' conftest.out >/dev/null 2>&1; then
-      echo >/dev/null
-    else
-      lpc_cv_yacc_first=257
-    fi
-  fi
-fi
-
-fi
-
-echo "$ac_t""$lpc_cv_yacc_first" 1>&6
-cat >> confdefs.h <<EOF
-#define F_OFFSET $lpc_cv_yacc_first
-EOF
-
-
-rm -rf conftest.y y.tab.c y.tab.h conftest.out
-
-echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 1053 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <sys/time.h>
-#include <time.h>
-int main() { return 0; }
-int t() {
-struct tm *tp;
-; return 0; }
-EOF
-if eval $ac_compile; then
-  rm -rf conftest*
-  ac_cv_header_time=yes
-else
-  rm -rf conftest*
-  ac_cv_header_time=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_header_time" 1>&6
-if test $ac_cv_header_time = yes; then
-  cat >> confdefs.h <<\EOF
-#define TIME_WITH_SYS_TIME 1
-EOF
-
-fi
-
-# If we cannot run a trivial program, we must be cross compiling.
-echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test "$cross_compiling" = yes; then
-  ac_cv_c_cross=yes
-else
-cat > conftest.$ac_ext <<EOF
-#line 1091 "configure"
-#include "confdefs.h"
-main(){return(0);}
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  ac_cv_c_cross=no
-else
-  ac_cv_c_cross=yes
-fi
-fi
-rm -fr conftest*
-fi
-
-echo "$ac_t""$ac_cv_c_cross" 1>&6
-cross_compiling=$ac_cv_c_cross
-
-echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 1113 "configure"
-#include "confdefs.h"
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
-  rm -rf conftest*
-  ac_cv_header_stdc=yes
-else
-  echo "$ac_err" >&5
-  rm -rf conftest*
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-if test $ac_cv_header_stdc = yes; then
-  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-cat > conftest.$ac_ext <<EOF
-#line 1135 "configure"
-#include "confdefs.h"
-#include <string.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "memchr" >/dev/null 2>&1; then
-  :
-else
-  rm -rf conftest*
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-cat > conftest.$ac_ext <<EOF
-#line 1153 "configure"
-#include "confdefs.h"
-#include <stdlib.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "free" >/dev/null 2>&1; then
-  :
-else
-  rm -rf conftest*
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-if test "$cross_compiling" = yes; then
-  :
-else
-cat > conftest.$ac_ext <<EOF
-#line 1174 "configure"
-#include "confdefs.h"
-#include <ctype.h>
-#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int main () { int i; for (i = 0; i < 256; i++)
-if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
-exit (0); }
-
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  :
-else
-  ac_cv_header_stdc=no
-fi
-fi
-rm -fr conftest*
-fi
-fi
-
-echo "$ac_t""$ac_cv_header_stdc" 1>&6
-if test $ac_cv_header_stdc = yes; then
-  cat >> confdefs.h <<\EOF
-#define STDC_HEADERS 1
-EOF
-
-fi
-
-for ac_hdr in sys/rusage.h time.h sys/time.h unistd.h stdlib.h memory.h \
-values.h string.h fcntl.h sys/filio.h sys/sockio.h crypt.h locale.h \
-sys/resource.h sys/select.h netdb.h
-do
-ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 1214 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
-  rm -rf conftest*
-  eval "ac_cv_header_$ac_safe=yes"
-else
-  echo "$ac_err" >&5
-  rm -rf conftest*
-  eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
- 
-else
-  echo "$ac_t""no" 1>&6
-fi
-done
-
-
-echo $ac_n "checking size of char *""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_sizeof_char_p'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 1251 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-main()
-{
-  FILE *f=fopen("conftestval", "w");
-  if (!f) exit(1);
-  fprintf(f, "%d\n", sizeof(char *));
-  exit(0);
-}
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  ac_cv_sizeof_char_p=`cat conftestval`
-else
-  ac_cv_sizeof_char_p=0
-fi
-fi
-rm -fr conftest*
-fi
-echo "$ac_t""$ac_cv_sizeof_char_p" 1>&6
-cat >> confdefs.h <<EOF
-#define SIZEOF_CHAR_P $ac_cv_sizeof_char_p
-EOF
-
-
-echo $ac_n "checking size of long""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 1285 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-main()
-{
-  FILE *f=fopen("conftestval", "w");
-  if (!f) exit(1);
-  fprintf(f, "%d\n", sizeof(long));
-  exit(0);
-}
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  ac_cv_sizeof_long=`cat conftestval`
-else
-  ac_cv_sizeof_long=0
-fi
-fi
-rm -fr conftest*
-fi
-echo "$ac_t""$ac_cv_sizeof_long" 1>&6
-cat >> confdefs.h <<EOF
-#define SIZEOF_LONG $ac_cv_sizeof_long
-EOF
-
-
-echo $ac_n "checking size of int""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 1319 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-main()
-{
-  FILE *f=fopen("conftestval", "w");
-  if (!f) exit(1);
-  fprintf(f, "%d\n", sizeof(int));
-  exit(0);
-}
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  ac_cv_sizeof_int=`cat conftestval`
-else
-  ac_cv_sizeof_int=0
-fi
-fi
-rm -fr conftest*
-fi
-echo "$ac_t""$ac_cv_sizeof_int" 1>&6
-cat >> confdefs.h <<EOF
-#define SIZEOF_INT $ac_cv_sizeof_int
-EOF
-
-
-echo $ac_n "checking size of short""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 1353 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-main()
-{
-  FILE *f=fopen("conftestval", "w");
-  if (!f) exit(1);
-  fprintf(f, "%d\n", sizeof(short));
-  exit(0);
-}
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  ac_cv_sizeof_short=`cat conftestval`
-else
-  ac_cv_sizeof_short=0
-fi
-fi
-rm -fr conftest*
-fi
-echo "$ac_t""$ac_cv_sizeof_short" 1>&6
-cat >> confdefs.h <<EOF
-#define SIZEOF_SHORT $ac_cv_sizeof_short
-EOF
-
-
-echo $ac_n "checking size of float""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_sizeof_float'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 1387 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-main()
-{
-  FILE *f=fopen("conftestval", "w");
-  if (!f) exit(1);
-  fprintf(f, "%d\n", sizeof(float));
-  exit(0);
-}
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  ac_cv_sizeof_float=`cat conftestval`
-else
-  ac_cv_sizeof_float=0
-fi
-fi
-rm -fr conftest*
-fi
-echo "$ac_t""$ac_cv_sizeof_float" 1>&6
-cat >> confdefs.h <<EOF
-#define SIZEOF_FLOAT $ac_cv_sizeof_float
-EOF
-
-
-echo $ac_n "checking size of double""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_sizeof_double'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 1421 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-main()
-{
-  FILE *f=fopen("conftestval", "w");
-  if (!f) exit(1);
-  fprintf(f, "%d\n", sizeof(double));
-  exit(0);
-}
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  ac_cv_sizeof_double=`cat conftestval`
-else
-  ac_cv_sizeof_double=0
-fi
-fi
-rm -fr conftest*
-fi
-echo "$ac_t""$ac_cv_sizeof_double" 1>&6
-cat >> confdefs.h <<EOF
-#define SIZEOF_DOUBLE $ac_cv_sizeof_double
-EOF
-
-
-
-echo $ac_n "checking for size_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 1453 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "size_t" >/dev/null 2>&1; then
-  rm -rf conftest*
-  ac_cv_type_size_t=yes
-else
-  rm -rf conftest*
-  ac_cv_type_size_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_size_t" 1>&6
-if test $ac_cv_type_size_t = no; then
-  cat >> confdefs.h <<\EOF
-#define size_t unsigned
-EOF
-
-fi
-
-echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 1484 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "pid_t" >/dev/null 2>&1; then
-  rm -rf conftest*
-  ac_cv_type_pid_t=yes
-else
-  rm -rf conftest*
-  ac_cv_type_pid_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_pid_t" 1>&6
-if test $ac_cv_type_pid_t = no; then
-  cat >> confdefs.h <<\EOF
-#define pid_t int
-EOF
-
-fi
-
-echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 1515 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "uid_t" >/dev/null 2>&1; then
-  rm -rf conftest*
-  ac_cv_type_uid_t=yes
-else
-  rm -rf conftest*
-  ac_cv_type_uid_t=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_type_uid_t" 1>&6
-if test $ac_cv_type_uid_t = no; then
-  cat >> confdefs.h <<\EOF
-#define uid_t int
-EOF
-
-  cat >> confdefs.h <<\EOF
-#define gid_t int
-EOF
-
-fi
-
-echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 1548 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <signal.h>
-#ifdef signal
-#undef signal
-#endif
-#ifdef __cplusplus
-extern "C" void (*signal (int, void (*)(int)))(int);
-#else
-void (*signal ()) ();
-#endif
-
-int main() { return 0; }
-int t() {
-int i;
-; return 0; }
-EOF
-if eval $ac_compile; then
-  rm -rf conftest*
-  ac_cv_type_signal=void
-else
-  rm -rf conftest*
-  ac_cv_type_signal=int
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_type_signal" 1>&6
-cat >> confdefs.h <<EOF
-#define RETSIGTYPE $ac_cv_type_signal
-EOF
-
-
-echo $ac_n "checking for time_t""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_type_time_t'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 1588 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "time_t" >/dev/null 2>&1; then
-  rm -rf conftest*
-  ac_cv_type_time_t=yes
-else
-  rm -rf conftest*
-  ac_cv_type_time_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_time_t" 1>&6
-if test $ac_cv_type_time_t = no; then
-  cat >> confdefs.h <<\EOF
-#define time_t INT32
-EOF
-
-fi
-
-
-echo $ac_n "checking for -lPW""... $ac_c" 1>&6
-ac_lib_var=`echo PW | tr '.-/+' '___p'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-lPW  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1623 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
-alloca()
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo PW | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
-  LIBS="-lPW $LIBS"
-
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-echo $ac_n "checking for -lm""... $ac_c" 1>&6
-ac_lib_var=`echo m | tr '.-/+' '___p'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-lm  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1663 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
-floor()
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo m | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
-  LIBS="-lm $LIBS"
-
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-if test "${ac_cv_lib_m}" = "no" -a "${lpc_cv_sys_os}" = "Linux"; then
-  echo "configure: warning: I will compensate for this by adding -lc -lm" 1>&2
-  LIBS="${LIBS} -lc -lm"
-fi
-echo $ac_n "checking for -lsocket""... $ac_c" 1>&6
-ac_lib_var=`echo socket | tr '.-/+' '___p'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-lsocket  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1707 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
-socket()
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo socket | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
-  LIBS="-lsocket $LIBS"
-
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-echo $ac_n "checking for -lcrypt""... $ac_c" 1>&6
-ac_lib_var=`echo crypt | tr '.-/+' '___p'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-lcrypt  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1747 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
-crypt()
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo crypt | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
-  LIBS="-lcrypt $LIBS"
-
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-if test "$ac_cv_lib_socket" = yes -o "$ac_cv_lib_ucb"; then
- echo $ac_n "checking for -lnsl""... $ac_c" 1>&6
-ac_lib_var=`echo nsl | tr '.-/+' '___p'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-lnsl  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1788 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
-main()
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo nsl | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
-  LIBS="-lnsl $LIBS"
-
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-fi
-
-
-OLD_LIBOBJS="${LIBOBJS}"
-
-echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_func_memcmp'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test "$cross_compiling" = yes; then
-  ac_cv_func_memcmp=no
-else
-cat > conftest.$ac_ext <<EOF
-#line 1833 "configure"
-#include "confdefs.h"
-
-main()
-{
-  char c0 = 0x40, c1 = 0x80, c2 = 0x81;
-  exit(memcmp(&c0, &c2, 1) < 0 && memcmp(&c1, &c2, 1) < 0 ? 0 : 1);
-}
-
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  ac_cv_func_memcmp=yes
-else
-  ac_cv_func_memcmp=no
-fi
-fi
-rm -fr conftest*
-fi
-
-echo "$ac_t""$ac_cv_func_memcmp" 1>&6
-test $ac_cv_func_memcmp = no && LIBOBJS="$LIBOBJS memcmp.o"
-
-
-if test "${OLD_LIBOBJS}" = "${LIBOBJS}" ; then
-  cat >> confdefs.h <<\EOF
-#define HAVE_MEMCMP 1
-EOF
-
-fi
-
-LIBOBJS="${OLD_LIBOBJS}"
-
-echo $ac_n "checking for strcoll""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_func_strcoll'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test "$cross_compiling" = yes; then
-  ac_cv_func_strcoll=no
-else
-cat > conftest.$ac_ext <<EOF
-#line 1874 "configure"
-#include "confdefs.h"
-#include <string.h>
-main ()
-{
-  exit (strcoll ("abc", "def") >= 0 ||
-	strcoll ("ABC", "DEF") >= 0 ||
-	strcoll ("123", "456") >= 0);
-}
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  ac_cv_func_strcoll=yes
-else
-  ac_cv_func_strcoll=no
-fi
-fi
-rm -fr conftest*
-fi
-
-echo "$ac_t""$ac_cv_func_strcoll" 1>&6
-if test $ac_cv_func_strcoll = yes; then
-  cat >> confdefs.h <<\EOF
-#define HAVE_STRCOLL 1
-EOF
-
-fi
-
-
-for ac_func in _crypt \
- bcopy \
- bzero \
- clock \
- crypt \
- fchmod \
- getenv \
- getrlimit \
- getrusage \
- index \
- memchr \
- memcpy \
- memset \
- rindex \
- setlocale \
- setrlimit \
- sigaction \
- sigvec \
- strcasecmp \
- strchr \
- strcspn \
- strrchr \
- strtod \
- strtok \
- strtol \
- times \
- vfprintf \
- vsprintf \
- wait3 \
- wait4 \
- waitpid \
-
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 1941 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $ac_func(); below.  */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error.  */
-char $ac_func();
-
-int main() { return 0; }
-int t() {
-
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  eval "ac_cv_func_$ac_func=yes"
-else
-  rm -rf conftest*
-  eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-
-fi
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
- 
-else
-  echo "$ac_t""no" 1>&6
-fi
-done
-
-
-
-
-
- echo $ac_n "checking for strchr declaration""... $ac_c" 1>&6
- if eval "test \"`echo '$''{'lpc_cv_decl_strchr'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-   lpc_cv_decl_strchr=nonexistant
-   for a in string.h unistd.h stdlib.h
-   do
-     cat > conftest.$ac_ext <<EOF
-#line 1998 "configure"
-#include "confdefs.h"
-#include <$a>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "strchr" >/dev/null 2>&1; then
-  rm -rf conftest*
-  lpc_cv_decl_strchr=existant; break
-fi
-rm -f conftest*
-
-   done
- 
-fi
-
- echo "$ac_t""$lpc_cv_decl_strchr" 1>&6
- if test "$lpc_cv_decl_strchr" = nonexistant; then
-   cat >> confdefs.h <<\EOF
-#define STRCHR_DECL_MISSING 1
-EOF
-
- fi
-
-
- echo $ac_n "checking for malloc declaration""... $ac_c" 1>&6
- if eval "test \"`echo '$''{'lpc_cv_decl_malloc'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-   lpc_cv_decl_malloc=nonexistant
-   for a in memory.h unistd.h stdlib.h
-   do
-     cat > conftest.$ac_ext <<EOF
-#line 2031 "configure"
-#include "confdefs.h"
-#include <$a>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "malloc" >/dev/null 2>&1; then
-  rm -rf conftest*
-  lpc_cv_decl_malloc=existant; break
-fi
-rm -f conftest*
-
-   done
- 
-fi
-
- echo "$ac_t""$lpc_cv_decl_malloc" 1>&6
- if test "$lpc_cv_decl_malloc" = nonexistant; then
-   cat >> confdefs.h <<\EOF
-#define MALLOC_DECL_MISSING 1
-EOF
-
- fi
-
-
- echo $ac_n "checking for getpeername declaration""... $ac_c" 1>&6
- if eval "test \"`echo '$''{'lpc_cv_decl_getpeername'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-   lpc_cv_decl_getpeername=nonexistant
-   for a in sys/socket.h sys/socketvar.h sys/socketio.h
-   do
-     cat > conftest.$ac_ext <<EOF
-#line 2064 "configure"
-#include "confdefs.h"
-#include <$a>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "getpeername" >/dev/null 2>&1; then
-  rm -rf conftest*
-  lpc_cv_decl_getpeername=existant; break
-fi
-rm -f conftest*
-
-   done
- 
-fi
-
- echo "$ac_t""$lpc_cv_decl_getpeername" 1>&6
- if test "$lpc_cv_decl_getpeername" = nonexistant; then
-   cat >> confdefs.h <<\EOF
-#define GETPEERNAME_DECL_MISSING 1
-EOF
-
- fi
-
-
- echo $ac_n "checking for popen declaration""... $ac_c" 1>&6
- if eval "test \"`echo '$''{'lpc_cv_decl_popen'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-   lpc_cv_decl_popen=nonexistant
-   for a in stdio.h unistd.h
-   do
-     cat > conftest.$ac_ext <<EOF
-#line 2097 "configure"
-#include "confdefs.h"
-#include <$a>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "popen" >/dev/null 2>&1; then
-  rm -rf conftest*
-  lpc_cv_decl_popen=existant; break
-fi
-rm -f conftest*
-
-   done
- 
-fi
-
- echo "$ac_t""$lpc_cv_decl_popen" 1>&6
- if test "$lpc_cv_decl_popen" = nonexistant; then
-   cat >> confdefs.h <<\EOF
-#define POPEN_DECL_MISSING 1
-EOF
-
- fi
-
-
- echo $ac_n "checking for getenv declaration""... $ac_c" 1>&6
- if eval "test \"`echo '$''{'lpc_cv_decl_getenv'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-   lpc_cv_decl_getenv=nonexistant
-   for a in unistd.h stdlib.h
-   do
-     cat > conftest.$ac_ext <<EOF
-#line 2130 "configure"
-#include "confdefs.h"
-#include <$a>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "getenv" >/dev/null 2>&1; then
-  rm -rf conftest*
-  lpc_cv_decl_getenv=existant; break
-fi
-rm -f conftest*
-
-   done
- 
-fi
-
- echo "$ac_t""$lpc_cv_decl_getenv" 1>&6
- if test "$lpc_cv_decl_getenv" = nonexistant; then
-   cat >> confdefs.h <<\EOF
-#define GETENV_DECL_MISSING 1
-EOF
-
- fi
-
-
- echo $ac_n "checking for gethostname declaration""... $ac_c" 1>&6
- if eval "test \"`echo '$''{'lpc_cv_decl_gethostname'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-   lpc_cv_decl_gethostname=nonexistant
-   for a in unistd.h
-   do
-     cat > conftest.$ac_ext <<EOF
-#line 2163 "configure"
-#include "confdefs.h"
-#include <$a>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "gethostname" >/dev/null 2>&1; then
-  rm -rf conftest*
-  lpc_cv_decl_gethostname=existant; break
-fi
-rm -f conftest*
-
-   done
- 
-fi
-
- echo "$ac_t""$lpc_cv_decl_gethostname" 1>&6
- if test "$lpc_cv_decl_gethostname" = nonexistant; then
-   cat >> confdefs.h <<\EOF
-#define GETHOSTNAME_DECL_MISSING 1
-EOF
-
- fi
-
-
-echo $ac_n "checking return type of free""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_sys_free_return'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 2192 "configure"
-#include "confdefs.h"
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H)
-#include <memory.h>
-#endif
-
-void free();
-
-
-int main() { return 0; }
-int t() {
-
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  lpc_cv_sys_free_return='char *'
-
-else
-  rm -rf conftest*
-  lpc_cv_sys_free_return='void'
-
-fi
-rm -f conftest*
-
-fi
-
-
-if test "$lpc_cv_sys_free_return" = void; then
-  cat >> confdefs.h <<\EOF
-#define FREE_RETURNS_VOID 1
-EOF
-
-  echo "$ac_t""void" 1>&6;
-else
-  echo "$ac_t""not void" 1>&6
-fi
-
-echo $ac_n "checking void* or char* from malloc""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_sys_malloc_return'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-cat > conftest.$ac_ext <<EOF
-#line 2245 "configure"
-#include "confdefs.h"
-
-#include <sys/types.h>
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H)
-#include <memory.h>
-#endif
-
-#define POINTER void *
-POINTER malloc(size_t);
-
-#ifdef FREE_RETURNS_VOID
-void free(POINTER);
-#else
-int free(POINTER);
-#endif
-
-
-int main() { return 0; }
-int t() {
-
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  lpc_cv_sys_malloc_return="void *"
-
-else
-  rm -rf conftest*
-  lpc_cv_sys_malloc_return="char *"
-
-fi
-rm -f conftest*
-
-fi
-
-
-echo "$ac_t""$lpc_cv_sys_malloc_return" 1>&6
-cat >> confdefs.h <<EOF
-#define POINTER $lpc_cv_sys_malloc_return
-EOF
-
-
-
-# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
-# for constant arguments.  Useless!
-echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 2305 "configure"
-#include "confdefs.h"
-#include <alloca.h>
-int main() { return 0; }
-int t() {
-char *p = alloca(2 * sizeof(int));
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  ac_cv_header_alloca_h=yes
-else
-  rm -rf conftest*
-  ac_cv_header_alloca_h=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
-if test $ac_cv_header_alloca_h = yes; then
-  cat >> confdefs.h <<\EOF
-#define HAVE_ALLOCA_H 1
-EOF
-
-fi
-
-echo $ac_n "checking for alloca""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_func_alloca'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 2337 "configure"
-#include "confdefs.h"
-
-#ifdef __GNUC__
-# define alloca __builtin_alloca
-#else
-# if HAVE_ALLOCA_H
-#  include <alloca.h>
-# else
-#  ifdef _AIX
- #pragma alloca
-#  else
-#   ifndef alloca /* predefined by HP cc +Olibcalls */
-char *alloca ();
-#   endif
-#  endif
-# endif
-#endif
-
-int main() { return 0; }
-int t() {
-char *p = (char *) alloca(1);
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  ac_cv_func_alloca=yes
-else
-  rm -rf conftest*
-  ac_cv_func_alloca=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_func_alloca" 1>&6
-if test $ac_cv_func_alloca = yes; then
-  cat >> confdefs.h <<\EOF
-#define HAVE_ALLOCA 1
-EOF
-
-fi
-
-if test $ac_cv_func_alloca = no; then
-  # The SVR3 libPW and SVR4 libucb both contain incompatible functions
-  # that cause trouble.  Some versions do not even contain alloca or
-  # contain a buggy version.  If you still want to use their alloca,
-  # use ar to extract alloca.o from them instead of compiling alloca.c.
-  ALLOCA=alloca.o
-  cat >> confdefs.h <<\EOF
-#define C_ALLOCA 1
-EOF
-
-
-echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 2396 "configure"
-#include "confdefs.h"
-#if defined(CRAY) && ! defined(CRAY2)
-webecray
-#else
-wenotbecray
-#endif
-
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  egrep "webecray" >/dev/null 2>&1; then
-  rm -rf conftest*
-  ac_cv_os_cray=yes
-else
-  rm -rf conftest*
-  ac_cv_os_cray=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_os_cray" 1>&6
-if test $ac_cv_os_cray = yes; then
-for ac_func in _getb67 GETB67 getb67; do
-  echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 2425 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $ac_func(); below.  */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error.  */
-char $ac_func();
-
-int main() { return 0; }
-int t() {
-
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  eval "ac_cv_func_$ac_func=yes"
-else
-  rm -rf conftest*
-  eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-
-fi
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-  cat >> confdefs.h <<EOF
-#define CRAY_STACKSEG_END $ac_func
-EOF
-
-  break
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-done
-fi
-
-echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test "$cross_compiling" = yes; then
-  ac_cv_c_stack_direction=0
-else
-cat > conftest.$ac_ext <<EOF
-#line 2479 "configure"
-#include "confdefs.h"
-find_stack_direction ()
-{
-  static char *addr = 0;
-  auto char dummy;
-  if (addr == 0)
-    {
-      addr = &dummy;
-      return find_stack_direction ();
-    }
-  else
-    return (&dummy > addr) ? 1 : -1;
-}
-main ()
-{
-  exit (find_stack_direction() < 0);
-}
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  ac_cv_c_stack_direction=1
-else
-  ac_cv_c_stack_direction=-1
-fi
-fi
-rm -fr conftest*
-fi
-
-echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
-cat >> confdefs.h <<EOF
-#define STACK_DIRECTION $ac_cv_c_stack_direction
-EOF
-
-fi
-
-
-echo $ac_n "checking for working const""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 2521 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
-
-/* Ultrix mips cc rejects this.  */
-typedef int charset[2]; const charset x;
-/* SunOS 4.1.1 cc rejects this.  */
-char const *const *ccp;
-char **p;
-/* NEC SVR4.0.2 mips cc rejects this.  */
-struct point {int x, y;};
-static struct point const zero = {0,0};
-/* AIX XL C 1.02.0.0 rejects this.
-   It does not let you subtract one const X* pointer from another in an arm
-   of an if-expression whose if-part is not a constant expression */
-const char *g = "string";
-ccp = &g + (g ? g-g : 0);
-/* HPUX 7.0 cc rejects these. */
-++ccp;
-p = (char**) ccp;
-ccp = (char const *const *) p;
-{ /* SCO 3.2v4 cc rejects this.  */
-  char *t;
-  char const *s = 0 ? (char *) 0 : (char const *) 0;
-
-  *t++ = 0;
-}
-{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
-  int x[] = {25, 17};
-  const int *foo = &x[0];
-  ++foo;
-}
-{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
-  typedef const int *iptr;
-  iptr p = 0;
-  ++p;
-}
-{ /* AIX XL C 1.02.0.0 rejects this saying
-     "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
-  struct s { int j; const int *ap[3]; };
-  struct s *b; b->j = 5;
-}
-{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
-  const int foo = 10;
-}
-
-; return 0; }
-EOF
-if eval $ac_compile; then
-  rm -rf conftest*
-  ac_cv_c_const=yes
-else
-  rm -rf conftest*
-  ac_cv_c_const=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_c_const" 1>&6
-if test $ac_cv_c_const = no; then
-  cat >> confdefs.h <<\EOF
-#define const 
-EOF
-
-fi
-
-echo $ac_n "checking for inline""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_cv_c_inline=no
-for ac_kw in inline __inline__ __inline; do
-  cat > conftest.$ac_ext <<EOF
-#line 2597 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
-} $ac_kw foo() {
-; return 0; }
-EOF
-if eval $ac_compile; then
-  rm -rf conftest*
-  ac_cv_c_inline=$ac_kw; break
-fi
-rm -f conftest*
-
-done
-
-fi
-
-echo "$ac_t""$ac_cv_c_inline" 1>&6
-case "$ac_cv_c_inline" in
-  inline | yes) ;;
-  no) cat >> confdefs.h <<\EOF
-#define inline 
-EOF
- ;;
-  *)  cat >> confdefs.h <<EOF
-#define inline $ac_cv_c_inline
-EOF
- ;;
-esac
-
-
-for ac_func in ualarm
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 2636 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $ac_func(); below.  */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error.  */
-char $ac_func();
-
-int main() { return 0; }
-int t() {
-
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  eval "ac_cv_func_$ac_func=yes"
-else
-  rm -rf conftest*
-  eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-
-fi
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-  :
-else
-  echo "$ac_t""no" 1>&6
-LIBOBJS="$LIBOBJS ${ac_func}.o"
-fi
-
-done
-
-
-case "$LIBOBJS" in
-   *ualarm.o*) ;;
-  *)
-    cat >> confdefs.h <<\EOF
-#define HAVE_UALARM 1
-EOF
-
-  ;;
-esac
-
-echo $ac_n "checking byteorder""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_hardware_byteorder'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 2698 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-
-int main()
-{
-#if SIZEOF_INT == 4
-#define T int
-#else
-#define T long
-#endif
-  FILE *f;
-  T a;
-  int e;
-  for(e=0;e<sizeof(T);e++)
-    ((char *)&a)[e]=(e+1) % 10;
-
-  f=fopen("conftest.out.2","w");
-  for(e=0;e<sizeof(T);e++)
-  {
-    fprintf(f,"%d",(int)(a & 255));
-    a>>=8;
-  }
-  fprintf(f,"\n");
-  fclose(f);
-  
-  return 0;
-}
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  lpc_cv_hardware_byteorder=`cat conftest.out.2`
-
-else
-  lpc_cv_hardware_byteorder=0
-
-fi
-fi
-rm -fr conftest*
-fi
-
-
-echo "$ac_t""$lpc_cv_hardware_byteorder" 1>&6
-cat >> confdefs.h <<EOF
-#define BYTEORDER $lpc_cv_hardware_byteorder
-EOF
-
-
-echo $ac_n "checking for working memmem""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_func_memmem'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 2756 "configure"
-#include "confdefs.h"
-
-#include <string.h>
-char *a="foo bar gazonk";
-char *b="foo";
-char *c="bar";
-char *d="gazonk";
-int main()
-{
-  if(memmem(b,strlen(b),a,strlen(a))!=a ||
-     memmem(c,strlen(c),a,strlen(a))!=(a+4) ||
-     memmem(d,strlen(d),a,strlen(a))!=(a+8) ||
-     memmem(d,0,a,strlen(a))!=a ||
-     memmem(d,strlen(d)+1,a,strlen(a))!=0)
-    exit(1);
-  exit(0);
-}
-
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  lpc_cv_func_memmem=yes
-else
-  lpc_cv_func_memmem=no
-fi
-fi
-rm -fr conftest*
-fi
-
-
-if test "$lpc_cv_func_memmem" = yes; then
-  echo "$ac_t""yes" 1>&6
-  cat >> confdefs.h <<\EOF
-#define HAVE_MEMMEM 1
-EOF
-
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-echo $ac_n "checking for working memmove""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_func_memmove'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 2806 "configure"
-#include "confdefs.h"
-
-#include <string.h>
-char buf[100];
-int main()
-{
-  strcpy(buf,"foo bar gazonk elefantsnabel.");
-  if(strcmp(buf,"foo bar gazonk elefantsnabel.")) exit(1);
-  memmove(buf,buf+1,7);
-  if(strcmp(buf,"oo bar  gazonk elefantsnabel.")) exit(1);
-  memmove(buf+1,buf+1,9);
-  if(strcmp(buf,"oo bar  gazonk elefantsnabel.")) exit(1);
-  memmove(buf+1,buf,11);
-  if(strcmp(buf,"ooo bar  gaznk elefantsnabel.")) exit(1);
-  exit(0);
-}
-
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  lpc_cv_func_memmove=yes
-else
-  lpc_cv_func_memmove=no
-fi
-fi
-rm -fr conftest*
-fi
-
-
-if test "$lpc_cv_func_memmove" = yes; then
-  echo "$ac_t""yes" 1>&6
-  cat >> confdefs.h <<\EOF
-#define HAVE_MEMMOVE 1
-EOF
-
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-echo $ac_n "checking how to extract an unsigned char""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_method_extract_uchar'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 2855 "configure"
-#include "confdefs.h"
-
-int main()
-{
-  char i,*p;
-  i=-10;
-  p=&i;
-  if(*(unsigned char *)(p)!= 0x100 - 10) exit(1);
-  exit(0);
-}
-
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  lpc_cv_method_extract_uchar=by_cast
-else
-  lpc_cv_method_extract_uchar=not_by_cast
-fi
-fi
-rm -fr conftest*
-fi
-
-
-if test "$lpc_cv_method_extract_uchar" = by_cast; then
-  echo "$ac_t""by cast" 1>&6
-  cat >> confdefs.h <<\EOF
-#define EXTRACT_UCHAR_BY_CAST 1
-EOF
-
-else
-  echo "$ac_t""not by cast" 1>&6
-fi
-
-echo $ac_n "checking how to extract a signed char""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_method_extract_char'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 2898 "configure"
-#include "confdefs.h"
-
-int main()
-{
-  char i,*p;
-  i=-10;
-  p=&i;
-  if(*(signed char *)(p)!= -10) exit(1);
-  exit(0);
-}
-
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  lpc_cv_method_extract_char=by_cast
-else
-  lpc_cv_method_extract_char=not_by_cast
-fi
-fi
-rm -fr conftest*
-fi
-
-
-if test "$lpc_cv_method_extract_char" = by_cast; then
-  echo "$ac_t""by cast" 1>&6
-  cat >> confdefs.h <<\EOF
-#define EXTRACT_CHAR_BY_CAST 1
-EOF
-
-else
-  echo "$ac_t""not by cast" 1>&6
-fi
-
-
-echo $ac_n "checking if signal handlers reset automatically""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_sys_signal_oneshot'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 2942 "configure"
-#include "confdefs.h"
-
-#include <signal.h>
-char sigrun=0;
-RETSIGTYPE func(int sig) { sigrun=1; }
-
-int main()
-{
-#define sig SIGSEGV
-
-#ifdef HAVE_SIGACTION
-  {
-    struct sigaction action;
-    action.sa_handler= func;
-    sigfillset(&action.sa_mask);
-#ifdef SA_INTERRUPT
-    action.sa_flags=SA_INTERRUPT;
-#endif
-    sigaction(sig,&action,0);
-  }
-#else
-#ifdef HAVE_SIGVEC
-  {
-    struct sigvec action;
-    action.sv_handler= func;
-    action.sv_mask=-1;
-#ifdef SV_INTERRUPT
-    action.sv_flags=SV_INTERRUPT;
-#endif
-    sigvec(sig,&action,0);
-  }
-#else
-  signal(sig, func);
-#endif
-#endif
-
-  kill(getpid(), sig);
-  while(!sigrun) sleep(1);
-  sigrun=0;
-  kill(getpid(), sig);
-  while(!sigrun) sleep(1);
-  sigrun=0;
-  exit(0);
-}
-
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  lpc_cv_sys_signal_oneshot=no
-else
-  lpc_cv_sys_signal_oneshot=yes
-fi
-fi
-rm -fr conftest*
-fi
-
-
-if test "$lpc_cv_sys_signal_oneshot" = yes; then
-  echo "$ac_t""yes" 1>&6
-  cat >> confdefs.h <<\EOF
-#define SIGNAL_ONESHOT 1
-EOF
-
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-
-
-echo $ac_n "checking available file descriptors""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_max_open_fd'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 3021 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif
-
-#ifndef MAX_FD
-#define MAX_FD 256
-#endif
-
-int main()
-{
-  FILE *f;
-  long limit;
-
-#if !defined(RLIMIT_NOFILE) && defined(RLIMIT_OFILE)
-#define RLIMIT_NOFILE RLIMIT_OFILE
-#endif
-
-#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
-  struct rlimit lim;
-
-  if(getrlimit(RLIMIT_NOFILE,&lim))
-  {
-    limit = MAX_FD;
-  }else{
-    if(lim.rlim_max == RLIM_INFINITY)
-    {
-      limit=16384; /* noone needs more */
-    }else{
-      limit=lim.rlim_max;
-      if(limit > 16384) limit=16384;
-    }
-  }
-#else
-  limit = MAX_FD;
-#endif
-
-  f=fopen("conftest.out.2","w");
-  fprintf(f,"%ld\n",(long)limit);
-  fclose(f);
-
-  return 0;
-}
-
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  lpc_cv_max_open_fd=`cat conftest.out.2`
-
-else
-  lpc_cv_max_open_fd=256
-
-fi
-fi
-rm -fr conftest*
-fi
-
-echo "$ac_t""$lpc_cv_max_open_fd" 1>&6
-cat >> confdefs.h <<EOF
-#define MAX_OPEN_FILEDESCRIPTORS $lpc_cv_max_open_fd
-EOF
-
-
-if test "$ac_cv_func_getrusage" = "yes"; then
-echo $ac_n "checking full availability of struct rusage members""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_func_getrusage_full'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-cat > conftest.$ac_ext <<EOF
-#line 3097 "configure"
-#include "confdefs.h"
-
-#include <sys/time.h>
-#ifdef HAVE_SYS_RUSAGE_H
-#include <sys/rusage.h>
-#endif
-#include <sys/resource.h>
-#ifndef RUSAGE_SELF
-#define RUSAGE_SELF     0
-#endif
-
-int main() { return 0; }
-int t() {
-
-    struct rusage rus;
-    long *v = (long *)main;
-    getrusage(RUSAGE_SELF, &rus);
-    *v++ = rus.ru_maxrss;
-    *v++ = rus.ru_ixrss;
-    *v++ = rus.ru_idrss;
-    *v++ = rus.ru_isrss;
-    *v++ = rus.ru_minflt;
-    *v++ = rus.ru_majflt;
-    *v++ = rus.ru_nswap;
-    *v++ = rus.ru_inblock;
-    *v++ = rus.ru_oublock;
-    *v++ = rus.ru_msgsnd;
-    *v++ = rus.ru_msgrcv;
-    *v++ = rus.ru_nsignals;
-    *v++ = rus.ru_nvcsw;
-    *v++ = rus.ru_nivcsw;
-
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  lpc_cv_func_getrusage_full=yes
-
-else
-  rm -rf conftest*
-  lpc_cv_func_getrusage_full=no
-
-fi
-rm -f conftest*
-
-fi
-
-
-if test "$lpc_cv_func_getrusage_full" = yes; then
-  echo "$ac_t""all there" 1>&6
-else
-  echo "$ac_t""getrusage is restricted" 1>&6
-  cat >> confdefs.h <<\EOF
-#define GETRUSAGE_RESTRICTED 1
-EOF
-
-fi
-
-else
-
-echo $ac_n "checking getrusage() through procfs""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_getrusage_procfs'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-cat > conftest.$ac_ext <<EOF
-#line 3164 "configure"
-#include "confdefs.h"
-
-#include <sys/procfs.h>
-#include <sys/fcntl.h>
-int proc_fd;
-char proc_name[20];
-
-int main() { return 0; }
-int t() {
-
-  sprintf(proc_name, "/proc/%05d", getpid());
-  proc_fd = open(proc_name, O_RDONLY);
-
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  lpc_cv_getrusage_procfs=yes
-
-else
-  rm -rf conftest*
-  lpc_cv_getrusage_procfs=no
-
-fi
-rm -f conftest*
-
-fi
-
-
-if test "$lpc_cv_getrusage_procfs" = yes; then
-  echo "$ac_t""yes" 1>&6
-  cat >> confdefs.h <<\EOF
-#define GETRUSAGE_THROUGH_PROCFS 1
-EOF
-
-else
-  echo "$ac_t""no" 1>&6
-fi
-fi
-
-echo $ac_n "checking checking for volatile""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_volatile'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
- cat > conftest.$ac_ext <<EOF
-#line 3211 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
- volatile int foo=1;
-; return 0; }
-EOF
-if eval $ac_link; then
-  rm -rf conftest*
-  lpc_cv_volatile=yes
-else
-  rm -rf conftest*
-  lpc_cv_volatile=no
-fi
-rm -f conftest*
-
-
-fi
-
-
-if test "$lpc_cv_volatile" = yes; then
- echo "$ac_t""yes" 1>&6
- cat >> confdefs.h <<\EOF
-#define VOLATILE volatile
-EOF
-
-else
- echo "$ac_t""no" 1>&6
- cat >> confdefs.h <<\EOF
-#define VOLATILE 
-EOF
-
-fi
-
-echo $ac_n "checking for gcc function attributes""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_gcc_attributes'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 3255 "configure"
-#include "confdefs.h"
-
-#include <stdarg.h>
-void fatal(char *foo,...) __attribute__ ((noreturn,format (printf,1,2)));
-int sqr(int x) __attribute__ ((const));
-
-int sqr(int x) { return x*x; }
-
-void fatal(char *foo,...)
-{
-  va_list args;
-  va_start(foo,args);
-  printf(foo,args);
-  va_end(args);
-  exit(2);
-}
-main() {  exit(0); }
-
-
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  lpc_cv_gcc_attributes=yes
-else
-  lpc_cv_gcc_attributes=no
-fi
-fi
-rm -fr conftest*
-fi
-
-
-echo "$ac_t""$lpc_cv_gcc_attributes" 1>&6
-if test "$lpc_cv_gcc_attributes" = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_FUNCTION_ATTRIBUTES 1
-EOF
-
-fi
-
-echo $ac_n "checking how to set things nonblocking""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'lpc_cv_sys_nonblock'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 3304 "configure"
-#include "confdefs.h"
-
-#define TESTING
-#define USE_FCNTL_FNDELAY
-#include "$srcdir/fd_control.c"
-
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  lpc_cv_sys_nonblock=USE_FCNTL_FNDELAY
-else
-  if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 3320 "configure"
-#include "confdefs.h"
-
-#define TESTING
-#define USE_FCNTL_O_NDELAY
-#include "$srcdir/fd_control.c"
-
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  lpc_cv_sys_nonblock=USE_FCNTL_O_NDELAY
-else
-  if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 3336 "configure"
-#include "confdefs.h"
-
-#define TESTING
-#define USE_FCNTL_O_NONBLOCK
-#include "$srcdir/fd_control.c"
-
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  lpc_cv_sys_nonblock=USE_FCNTL_O_NONBLOCK
-else
-  if test "$cross_compiling" = yes; then
-    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 3352 "configure"
-#include "confdefs.h"
-
-#define TESTING
-#define USE_IOCTL_FIONBIO
-#include "$srcdir/fd_control.c"
-
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  lpc_cv_sys_nonblock=USE_IOCTL_FIONBIO
-else
-  unset lpc_cv_sys_nonblock
-
-fi
-fi
-rm -fr conftest*
-fi
-fi
-rm -fr conftest*
-fi
-fi
-rm -fr conftest*
-fi
-fi
-rm -fr conftest*
-fi
-
-
-if test "${lpc_cv_sys_nonblock}" = ""; then
-  echo "$ac_t""none found" 1>&6
-else
- echo "$ac_t""$lpc_cv_sys_nonblock" 1>&6
- cat >> confdefs.h <<EOF
-#define $lpc_cv_sys_nonblock 1
-EOF
-
-fi
-
-rm -f core
-
-
-dirs=
-MODULE_OBJS=
-module_names=
-for a in `(cd $srcdir/modules ; echo *)`
-do
-  if test "$a" != "CVS" -a "$a" != "RCS" ; then
-    if test -d "$srcdir/modules/$a" ; then
-      dirs="$dirs modules/$a"
-      MODULE_OBJS="$MODULE_OBJS modules/$a/$a.a"
-      module_names="$module_names $a"
-    fi
-  fi
-done
-
-LIBDIR=`(cd $srcdir/../lib ; pwd)`
-BINDIR=`(cd $srcdir/../bin ; pwd)`
-DOCDIR=`(cd $srcdir/../doc ; pwd)`
-BUILDDIR=`pwd`
-
-subdirs="$dirs"
-
-
-
-
-
-
-
-
-
-
-
-
-
-trap '' 1 2 15
-cat > confcache <<\EOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs.  It is not useful on other systems.
-# If it contains results you don't want to keep, you may remove or edit it.
-#
-# By default, configure uses ./config.cache as the cache file,
-# creating it if it does not exist already.  You can give configure
-# the --cache-file=FILE option to use a different cache file; that is
-# what configure does when it calls configure scripts in
-# subdirectories, so they share the cache.
-# Giving --cache-file=/dev/null disables caching, for debugging configure.
-# config.status only pays attention to the cache file if you give it the
-# --recheck option to rerun configure.
-#
-EOF
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(set) 2>&1 |
-  sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \
-  >> confcache
-if cmp -s $cache_file confcache; then
-  :
-else
-  if test -w $cache_file; then
-    echo "updating cache $cache_file"
-    cat confcache > $cache_file
-  else
-    echo "not updating unwritable cache $cache_file"
-  fi
-fi
-rm -f confcache
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-# Any assignment to VPATH causes Sun make to only execute
-# the first set of double-colon rules, so remove it if not needed.
-# If there is a colon in the path, we need to keep it.
-if test "x$srcdir" = x.; then
-  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
-fi
-
-trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
-
-DEFS=-DHAVE_CONFIG_H
-
-# Without the "./", some shells look in PATH for config.status.
-: ${CONFIG_STATUS=./config.status}
-
-echo creating $CONFIG_STATUS
-rm -f $CONFIG_STATUS
-cat > $CONFIG_STATUS <<EOF
-#! /bin/sh
-# Generated automatically by configure.
-# Run this file to recreate the current configuration.
-# This directory was configured as follows,
-# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-#
-# $0 $ac_configure_args
-#
-# Compiler output produced by configure, useful for debugging
-# configure, is in ./config.log if it exists.
-
-ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
-for ac_option
-do
-  case "\$ac_option" in
-  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
-    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
-    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
-  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
-    echo "$CONFIG_STATUS generated by autoconf version 2.7"
-    exit 0 ;;
-  -help | --help | --hel | --he | --h)
-    echo "\$ac_cs_usage"; exit 0 ;;
-  *) echo "\$ac_cs_usage"; exit 1 ;;
-  esac
-done
-
-ac_given_srcdir=$srcdir
-ac_given_INSTALL="$INSTALL"
-
-trap 'rm -fr `echo "Makefile machine.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-# Protect against being on the right side of a sed subst in config.status.
-sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
- s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
-$ac_vpsub
-$extrasub
-s%@CFLAGS@%$CFLAGS%g
-s%@CPPFLAGS@%$CPPFLAGS%g
-s%@CXXFLAGS@%$CXXFLAGS%g
-s%@DEFS@%$DEFS%g
-s%@LDFLAGS@%$LDFLAGS%g
-s%@LIBS@%$LIBS%g
-s%@exec_prefix@%$exec_prefix%g
-s%@prefix@%$prefix%g
-s%@program_transform_name@%$program_transform_name%g
-s%@bindir@%$bindir%g
-s%@sbindir@%$sbindir%g
-s%@libexecdir@%$libexecdir%g
-s%@datadir@%$datadir%g
-s%@sysconfdir@%$sysconfdir%g
-s%@sharedstatedir@%$sharedstatedir%g
-s%@localstatedir@%$localstatedir%g
-s%@libdir@%$libdir%g
-s%@includedir@%$includedir%g
-s%@oldincludedir@%$oldincludedir%g
-s%@infodir@%$infodir%g
-s%@mandir@%$mandir%g
-s%@CC@%$CC%g
-s%@uname_prog@%$uname_prog%g
-s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
-s%@INSTALL_DATA@%$INSTALL_DATA%g
-s%@YACC@%$YACC%g
-s%@CPP@%$CPP%g
-s%@RANLIB@%$RANLIB%g
-s%@SET_MAKE@%$SET_MAKE%g
-s%@LIBOBJS@%$LIBOBJS%g
-s%@ALLOCA@%$ALLOCA%g
-s%@subdirs@%$subdirs%g
-s%@MODULE_OBJS@%$MODULE_OBJS%g
-s%@INSTALL@%$INSTALL%g
-s%@WARN@%$WARN%g
-s%@OPTIMIZE@%$OPTIMIZE%g
-s%@EXTRA_OBJS@%$EXTRA_OBJS%g
-s%@LIBDIR@%$LIBDIR%g
-s%@BINDIR@%$BINDIR%g
-s%@BUILDDIR@%$BUILDDIR%g
-s%@DOCDIR@%$DOCDIR%g
-
-CEOF
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
-  # Support "outfile[:infile]", defaulting infile="outfile.in".
-  case "$ac_file" in
-  *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
-       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
-  *) ac_file_in="${ac_file}.in" ;;
-  esac
-
-  # Adjust relative srcdir, etc. for subdirectories.
-
-  # Remove last slash and all that follows it.  Not all systems have dirname.
-  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
-  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
-    # The file is in a subdirectory.
-    test ! -d "$ac_dir" && mkdir "$ac_dir"
-    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
-    # A "../" for each directory in $ac_dir_suffix.
-    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
-  else
-    ac_dir_suffix= ac_dots=
-  fi
-
-  case "$ac_given_srcdir" in
-  .)  srcdir=.
-      if test -z "$ac_dots"; then top_srcdir=.
-      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
-  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
-  *) # Relative path.
-    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
-    top_srcdir="$ac_dots$ac_given_srcdir" ;;
-  esac
-
-  case "$ac_given_INSTALL" in
-  [/$]*) INSTALL="$ac_given_INSTALL" ;;
-  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
-  esac
-  echo creating "$ac_file"
-  rm -f "$ac_file"
-  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
-  case "$ac_file" in
-  *Makefile*) ac_comsub="1i\\
-# $configure_input" ;;
-  *) ac_comsub= ;;
-  esac
-  sed -e "$ac_comsub
-s%@configure_input@%$configure_input%g
-s%@srcdir@%$srcdir%g
-s%@top_srcdir@%$top_srcdir%g
-s%@INSTALL@%$INSTALL%g
-" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file
-fi; done
-rm -f conftest.subs
-
-# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
-# NAME is the cpp macro being defined and VALUE is the value it is being given.
-#
-# ac_d sets the value in "#define NAME VALUE" lines.
-ac_dA='s%^\([ 	]*\)#\([ 	]*define[ 	][ 	]*\)'
-ac_dB='\([ 	][ 	]*\)[^ 	]*%\1#\2'
-ac_dC='\3'
-ac_dD='%g'
-# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
-ac_uA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
-ac_uB='\([ 	]\)%\1#\2define\3'
-ac_uC=' '
-ac_uD='\4%g'
-# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
-ac_eA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
-ac_eB='$%\1#\2define\3'
-ac_eC=' '
-ac_eD='%g'
-
-CONFIG_HEADERS=${CONFIG_HEADERS-"machine.h"}
-for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
-  # Support "outfile[:infile]", defaulting infile="outfile.in".
-  case "$ac_file" in
-  *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
-       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
-  *) ac_file_in="${ac_file}.in" ;;
-  esac
-
-  echo creating $ac_file
-
-  rm -f conftest.frag conftest.in conftest.out
-  cp $ac_given_srcdir/$ac_file_in conftest.in
-
-EOF
-
-# Transform confdefs.h into a sed script conftest.vals that substitutes
-# the proper values into config.h.in to produce config.h.  And first:
-# Protect against being on the right side of a sed subst in config.status.
-# Protect against being in an unquoted here document in config.status.
-rm -f conftest.vals
-cat > conftest.hdr <<\EOF
-s/[\\&%]/\\&/g
-s%[\\$`]%\\&%g
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
-s%ac_d%ac_u%gp
-s%ac_u%ac_e%gp
-EOF
-sed -n -f conftest.hdr confdefs.h > conftest.vals
-rm -f conftest.hdr
-
-# This sed command replaces #undef with comments.  This is necessary, for
-# example, in the case of _POSIX_SOURCE, which is predefined and required
-# on some systems where configure will not decide to define it.
-cat >> conftest.vals <<\EOF
-s%^[ 	]*#[ 	]*undef[ 	][ 	]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
-EOF
-
-# Break up conftest.vals because some shells have a limit on
-# the size of here documents, and old seds have small limits too.
-# Maximum number of lines to put in a single here document.
-ac_max_here_lines=12
-
-rm -f conftest.tail
-while :
-do
-  ac_lines=`grep -c . conftest.vals`
-  # grep -c gives empty output for an empty file on some AIX systems.
-  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
-  # Write a limited-size here document to conftest.frag.
-  echo '  cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
-  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
-  echo 'CEOF
-  sed -f conftest.frag conftest.in > conftest.out
-  rm -f conftest.in
-  mv conftest.out conftest.in
-' >> $CONFIG_STATUS
-  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
-  rm -f conftest.vals
-  mv conftest.tail conftest.vals
-done
-rm -f conftest.vals
-
-cat >> $CONFIG_STATUS <<\EOF
-  rm -f conftest.frag conftest.h
-  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
-  cat conftest.in >> conftest.h
-  rm -f conftest.in
-  if cmp -s $ac_file conftest.h 2>/dev/null; then
-    echo "$ac_file is unchanged"
-    rm -f conftest.h
-  else
-    rm -f $ac_file
-    mv conftest.h $ac_file
-  fi
-fi; done
-
-EOF
-cat >> $CONFIG_STATUS <<EOF
-dirs="$module_names"
-
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-
-echo "FOO" >stamp-h
-if test ! -d ./modules ; then
-  mkdir modules
-fi
-
-echo "$ac_t""creating modlist.h" 1>&6
-echo "void init_main_efuns(void);" >modlist.h
-echo "void init_main_programs(void);" >>modlist.h
-echo "void exit_main(void);" >>modlist.h
-
-for a in $dirs
-do
-  echo "void init_"$a"_efuns(void);" >>modlist.h
-  echo "void init_"$a"_programs(void);" >>modlist.h
-  echo "void exit_"$a"(void);" >>modlist.h
-done
-echo "" >>modlist.h
-echo "struct module module_list UGLY_WORKAROUND={" >>modlist.h
-
-echo "  { \"main\", init_main_efuns, init_main_programs, exit_main, 0 }" >>modlist.h
-for a in $dirs
-do
-  echo " ,{ \"$a\", init_"$a"_efuns, init_"$a"_programs, exit_$a, 0 }" >>modlist.h
-done
-echo "};" >>modlist.h
-
-
-exit 0
-EOF
-chmod +x $CONFIG_STATUS
-rm -fr confdefs* $ac_clean_files
-test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
-
-if test "$no_recursion" != yes; then
-
-  # Remove --cache-file and --srcdir arguments so they do not pile up.
-  ac_sub_configure_args=
-  ac_prev=
-  for ac_arg in $ac_configure_args; do
-    if test -n "$ac_prev"; then
-      ac_prev=
-      continue
-    fi
-    case "$ac_arg" in
-    -cache-file | --cache-file | --cache-fil | --cache-fi \
-    | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
-      ac_prev=cache_file ;;
-    -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
-    | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
-      ;;
-    -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
-      ac_prev=srcdir ;;
-    -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
-      ;;
-    *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;;
-    esac
-  done
-
-  for ac_config_dir in $dirs; do
-
-    # Do not complain, so a configure script can configure whichever
-    # parts of a large source tree are present.
-    if test ! -d $srcdir/$ac_config_dir; then
-      continue
-    fi
-
-    echo configuring in $ac_config_dir
-
-    case "$srcdir" in
-    .) ;;
-    *)
-      if test -d ./$ac_config_dir || mkdir ./$ac_config_dir; then :;
-      else
-        { echo "configure: error: can not create `pwd`/$ac_config_dir" 1>&2; exit 1; }
-      fi
-      ;;
-    esac
-
-    ac_popdir=`pwd`
-    cd $ac_config_dir
-
-    case "$srcdir" in
-    .) # No --srcdir option.  We are building in place.
-      ac_sub_srcdir=$srcdir ;;
-    /*) # Absolute path.
-      ac_sub_srcdir=$srcdir/$ac_config_dir ;;
-    *) # Relative path.
-      ac_sub_srcdir=../$srcdir/$ac_config_dir ;;
-    esac
-
-    # Check for guested configure; otherwise get Cygnus style configure.
-    if test -f $ac_sub_srcdir/configure; then
-      ac_sub_configure=$ac_sub_srcdir/configure
-    elif test -f $ac_sub_srcdir/configure.in; then
-      ac_sub_configure=$ac_configure
-    else
-      echo "configure: warning: no configuration information is in $ac_config_dir" 1>&2
-      ac_sub_configure=
-    fi
-
-    # The recursion is here.
-    if test -n "$ac_sub_configure"; then
-
-      # Make the cache file name correct relative to the subdirectory.
-      # A "../" for each directory in /$ac_config_dir.
-      ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'`
-      case "$cache_file" in
-      /*) ac_sub_cache_file=$cache_file ;;
-      *) # Relative path.
-        ac_sub_cache_file="$ac_dots$cache_file" ;;
-      esac
-  case "$ac_given_INSTALL" in
-        [/$]*) INSTALL="$ac_given_INSTALL" ;;
-        *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
-        esac
-
-      echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir"
-      # The eval makes quoting arguments work.
-      if eval ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir
-      then :
-      else
-        { echo "configure: error: $ac_sub_configure failed for $ac_config_dir" 1>&2; exit 1; }
-      fi
-    fi
-
-    cd $ac_popdir
-  done
-fi
-
-
-
diff --git a/src/configure.in b/src/configure.in
index 38d063c1d0..95aaad69e2 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -104,6 +104,29 @@ AC_PROG_YACC
 AC_PROG_CPP
 AC_PROG_RANLIB
 AC_SET_MAKE
+AC_CHECK_PROG(has_strings, strings, yes, no)
+
+if test "$has_strings" = "yes"; then
+  yacc_prog=`echo $YACC | sed 's/^\([^ ]*\) .*$/\1/'`
+  AC_PATH_PROG(yacc_prog,$yacc_prog,/bin/true)
+
+  AC_MSG_CHECKING(if $YACC handles pure_parser)
+  AC_CACHE_VAL(lpc_cv_yacc_pure_parser,
+  [
+    lpc_cv_yacc_pure_parser=no
+    strings $yacc_prog >conftest.bar
+    if egrep pure_parser conftest.bar >/dev/null; then
+      lpc_cv_yacc_pure_parser=yes
+    fi
+  ])
+
+  if test "$lpc_cv_yacc_pure_parser" = "yes"; then
+    AC_MSG_RESULT(yes)
+  else
+    AC_MSG_RESULT([[no, get bison and retry... (giving up)]])
+    exit 1
+  fi
+fi
 
 AC_MSG_CHECKING(first yacc define)
 AC_CACHE_VAL(lpc_cv_yacc_first,
-- 
GitLab


From 558796d877068468bec21efd721110574c55a7c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 1 Mar 1996 01:03:00 +0100
Subject: [PATCH 053/351] typeof added

Rev: doc/lpc/reserved:1.2
---
 doc/lpc/reserved | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/lpc/reserved b/doc/lpc/reserved
index bb53824df5..e20b6b5b17 100644
--- a/doc/lpc/reserved
+++ b/doc/lpc/reserved
@@ -2,4 +2,4 @@ RESERVED WORDS
    array break case catch continue default do efun else float for foreach
    function gauge if inherit inline int lambda list mapping mixed nomask
    object private program protected public return sscanf static string
-   switch varargs void while
+   switch typeof varargs void while
-- 
GitLab


From 936d2bfd6ac112c8278eb06187473859a78668a3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 2 Mar 1996 18:58:29 +0100
Subject: [PATCH 054/351] cleaned up

Rev: bin/rsif:1.2
---
 bin/rsif | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/bin/rsif b/bin/rsif
index 14055d9e6e..46712729cd 100755
--- a/bin/rsif
+++ b/bin/rsif
@@ -1,17 +1,17 @@
 #!/usr/local/bin/ulpc
 
-int main(int argc,string *argv)
+int main(int argc, string *argv)
 {
   int i;
   string file;
 
   if(argc<4)
   {
-    write("Usage: rsif <from> <to> <files>\n");
-    return 0;
+    perror("Usage: rsif <from> <to> <files>\n");
+    return 1;
   }
 
-  for(i=3; i<sizeof(argv); i++)
+  for(i=3; i<argc; i++)
   {
     if(file=read_bytes(argv[i]))
     {
@@ -29,4 +29,6 @@ int main(int argc,string *argv)
       }
     }
   }
+
+  return 0;
 }
-- 
GitLab


From 93bc182488c5db8d3a321f9be5f8ad9f71da87b1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 2 Mar 1996 18:59:47 +0100
Subject: [PATCH 055/351] example files added

Rev: doc/manual/example1:1.1
Rev: doc/manual/example2:1.1
Rev: doc/manual/example3:1.1
---
 doc/manual/example1 | 138 +++++++++++++++++++++++
 doc/manual/example2 | 136 ++++++++++++++++++++++
 doc/manual/example3 | 269 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 543 insertions(+)
 create mode 100644 doc/manual/example1
 create mode 100644 doc/manual/example2
 create mode 100644 doc/manual/example3

diff --git a/doc/manual/example1 b/doc/manual/example1
new file mode 100644
index 0000000000..6384295490
--- /dev/null
+++ b/doc/manual/example1
@@ -0,0 +1,138 @@
+1. Let's write a small uLPC program:
+
+	int main()
+	{
+	  write("hello world\n");
+	  return 0;
+	}
+
+  Let's call this file hello_world.ulpc, and then we try to run it:
+
+	$ ulpc hello_world.lpc
+	hello world
+	$ 
+
+1.1 Pretty simple, Let's see what everything means:
+
+	int main()
+
+  This begins the function main. Before the function name the type of value
+  it returns is declared, in this case 'int'. The empty space between the
+  parethesis indicates that this function takes no arguments. The function
+  main is special in the sense that it is the first function called when
+  your program starts. Everything your program does should start in main.
+
+	{
+	  write("hello world\n");
+	  return 0;
+	}
+
+  This is the body of the function. The brackets group together a series of
+  statements into a block which will be executed when this function is called.
+  The statements aer separated by semi-colons.
+
+	write("hello world\n");
+
+  The first statement is a call to the builtin function write. To this
+  function the constant string "hello world\n" is sent. write then of
+  course writes this string to stdout when executed.
+
+	return 0;
+
+  This statement aborts the function and returns the value zero. Any statements
+  following the return statements (not that there are any in this example)
+  will not be executed.
+
+1.2 Improving hello_world.lpc
+  Typing 'ulpc hello_world.lpc' to run our program may seem a bit unpractical,
+  fortunately, UNIX provides us with a way of automating this somewhat.
+  If we modify hello_world.lpc to look like this:
+
+	#!/usr/local/bin/ulpc
+
+	int main()
+	{
+	  write("hello world\n");
+	}
+
+  And then we tell UNIX that hello_world.lpc is executable:
+
+	$ chmod +x hello_world.lpc
+
+  Now we can run hello_world.lpc without having to bother about running
+  ulpc:
+
+	$ ./hello_wold.lpc
+	hello world
+	$ 
+
+
+  NB. The hash bang (#!) must be absolutely first in the file, no empty
+      lines or whitespaces can precede it for this to work. The file after
+      the hash bang must also be the complete filename to the ulpc binary,
+      and it may not exceed 30 characters.
+
+1.3 A better hello_world.lpc
+  Now, wouldn't it be nice if it said "Hello world!" instead of "hello world" ?
+  But of course we don't want to make our program incompatible, so we'll add
+  a command line option that will make it type the old "hello world".
+  This is what it could look like:
+
+	#!/usr/local/bin/ulpc
+
+	int main(int argc, string *argv)
+	{
+	  if(argc > 2 && argv[1]=="--traditional")
+	  {
+	    write("hello world\n"); // old stype
+	  }else{
+	    write("Hello world!\n"); // new style
+	  }
+	  return 0;
+	}
+
+  Let's run it:
+
+	$ chmod +x hello_world.lpc
+	$ ./hello_world.lpc
+	Hello world!
+	$ ./hello_world.lpc --traditional
+	hello world
+	$ 
+
+  What's been added?
+
+	int main(int argc, string *argv)
+
+  Here the space between the parentesis has been filled. What it means
+  is that main now takes two arguments. One is called argc, and is of the
+  type 'int'. The other is called 'argv' and is a 'string *'. The star
+  means that the argument is an array, in this case an array of strings.
+
+  The arguments to main are taken from the command line when the uLPC program
+  is executed. The first argument, argc, is how many words were written on
+  the command line (including the command itself) and argv is an array formed
+  by these words.
+
+	  if(argc > 2 && argv[1] == "--traditional")
+	  {
+	    write("hello world\n"); // old stype
+	  }else{
+	    write("Hello world!\n"); // new style
+	  }
+
+  This is an if-else statement, it will execute what's between the first set
+  of brackets if the expression between the parenthesis evaluate to something
+  other than zero. Otherwise what's between the second set of brackets will
+  be executed. Let's look at that expression:
+
+	argc > 2 && argv[1] == "--traditional"
+
+  Loosely translated, this means: argc is greater than two and the second
+  element in the array argv is equal to the string "--traditional".
+
+  Also note the comments:
+  
+	    write("hello world\n"); // old stype
+
+  The // begins a comment which continues to the end of the line.
diff --git a/doc/manual/example2 b/doc/manual/example2
new file mode 100644
index 0000000000..394bc08f6f
--- /dev/null
+++ b/doc/manual/example2
@@ -0,0 +1,136 @@
+  Now we will look at a slightly more useful example:
+
+	#!/usr/local/bin/ulpc
+
+	int main(int argc,string *argv)
+	{
+	  int i;
+	  string file;
+	
+	  if(argc<4)
+	  {
+	    perror("Usage: rsif <from> <to> <files>\n");
+	    return 1;
+	  }
+	
+	  for(i=3; i<argc; i++)
+	  {
+	    if(file=read_bytes(argv[i]))
+	    {
+	      if(-1!=strstr(file,argv[1]))
+	      {
+		write("Processing "+argv[i]+".\n");
+		file=replace(file,argv[1],argv[2]);
+	
+		if( mv(argv[i],argv[i]+"~") )
+		{
+		  write_file(argv[i],file);
+		}else{
+		  write("Failed to create backup file.\n");
+		}
+	      }
+	    }
+	  }
+
+	  return 0;
+	}
+	
+  This program is called 'rsif' and comes with the uLPC distribution.
+  What it does is that it takes two strings and a bunch of files and
+  replaces every occurance of the first string with the second one in
+  each of these files. As you might have guessed 'rsif' is short for
+  Replace String In File. Line by line, this is how the program works:
+
+	#!/usr/local/bin/ulpc
+
+  Make UNIX run ulpc to interpret this program.
+
+	int main(int argc,string *argv)
+	{
+
+  Start the function main, it will return an int, and take the command line
+  arguments into the parameters argc and argv.
+
+	  int i;
+	  string file;
+
+  Declare two temporary variables to use later. The first one 'i' is an
+  integer, and the second one 'file' is a string.
+	
+	  if(argc<4)
+	  {
+	    perror("Usage: rsif <from> <to> <files>\n");
+	    return 1;
+	  }
+
+  If argc is lesser than four it means that the program received less than
+  three arguments. Since rsif needs at least three arguments we write how
+  to use rsif to stderr using the function perror and then exit this function
+  with the return value 1. Nothing after the return will be executed if
+  argc is lesser than 4.
+  
+	
+	  for(i=3; i<argc; i++)
+	  {
+
+  This statement starts a loop. It will first set i to three, then execute
+  everything within the brackets for as long as i is lesser than argc. After
+  each time the block between the brackets the final statement, i++, will
+  be executed. ++ is the increment operator, it will increase i by one.
+
+	    if(file=read_bytes(argv[i]))
+	    {
+
+  Look closely, the experssion in this if-statement is not a comparison, it
+  is in fact an assignment. Thus file will be assigned the value returned by
+  read_bytes. When an assignment is used as an expression it has the same
+  value as the left hand side of the assignment. (in this case the return
+  value from read_bytes) So what this does is: it reads the contents of the
+  file with the filename taken from argv[i] and assigns the contents to the
+  variable file. If there is no file with that name, zero will be returned
+  and then the block within the brackets will not be executed.
+
+	      if(-1!=strstr(file,argv[1]))
+	      {
+
+  The function strstr searches for a string in in a string and returns the
+  first position where it is found and -1 if not. This if statement simply
+  checks if argv[1] (the 'from' string) is present in the file. If it is
+  not we won't need to do anything more about this file. The != operator
+  means 'not equal to'.
+
+		write("Processing "+argv[i]+".\n");
+
+  Write that we are processing this file to stdout.
+
+		file=replace(file,argv[1],argv[2]);
+
+  Call the builtin function replace and replace oall occurances of the 'from'
+  string with the 'to' string and assign the new result to the variable 'file'.
+
+		if( mv(argv[i],argv[i]+"~") )
+		{
+  Try moving the file argv[i] to a backup file by adding a tilde to the end
+  of the name. Then choose action depending on weather it worked or not.
+
+		  write_file(argv[i],file);
+
+  If it worked we re-create the file argv[i] by writing the string 'file' to
+  it.
+
+		}else{
+		  write("Failed to create backup file.\n");
+
+  If the mv didn't work we write a message stating so to stdout.
+
+		}
+	      }
+	    }
+	  }
+
+	  return 0;
+	}
+
+
+  Then we end all the blocks and return zero. A return value of zero from main
+  indicates success, 1 or more means failiure.
diff --git a/doc/manual/example3 b/doc/manual/example3
new file mode 100644
index 0000000000..2323435af7
--- /dev/null
+++ b/doc/manual/example3
@@ -0,0 +1,269 @@
+  This example is a very simple www-server.
+
+
+	#!/usr/local/bin/ulpc
+	
+	/* A very small httpd capable of fetching files only.
+	 * Written by Fredrik H�binette as a demonstration of uLPC.
+	 */
+
+  A comment, /* begins the comment, and */ ends it.
+	
+	inherit "/precompiled/port";
+
+  Inherit copies all the functionality of /precompiled/port into this program.
+  /precompiled/port makes it possible to bind a TCP socket to accept incoming
+  connections.
+
+  Next are some constants that will affect how uHTTPD will operate. This uses
+  the preprocessor directive #define. As an example, after the first define
+  below, BLOCK will be replaced with 16060.
+	
+	/* number of bytes to read for each write */
+	#define BLOCK 16060
+	
+	/* Where do we have the html files ? */
+	#define BASE "/home/hubbe/ulpc/src/"
+	
+	/* File to return when we can't find the file requested */
+	#define NOFILE "/home/hubbe/www/html/nofile.html"
+	
+	/* Port to open */
+	#define PORT 1905
+
+  Next we declare a global variable of the type program called output_class,
+  and then we use the class construct to assign a program to it. class {}
+  defines a clonable program. (or class for you C++ freaks)
+
+	program output_class=class
+	{
+	  inherit "/precompiled/file" : socket;
+	  inherit "/precompiled/file" : file;
+
+  Our new class inherits /precompile/file twice. To be able to separate them
+  they are then named 'socket' and 'file'.
+
+	  int offset=0;
+
+  Then ther is a global variable called offset which is initalized to zero.
+  (each instance of this class will have it's own instance of this variable,
+   so it is not truly global, but..) 
+  Note that the initalization is done when the clas is cloned. (or instanciated
+  if you prefer C++ terminology)
+
+
+  Next we define the function write_callback(). 'void' means that it does not
+  return a value. Write callback will be used further down as a callback and
+  will be called whenever there is room in the socket output buffer.
+	
+	  void write_callback()
+	  {
+	    int written;
+	    string data;
+	
+	    file::seek(offset);
+
+  Move the file pointer to the where we want to the position we want to read
+  from.
+
+	    data=file::read(BLOCK);
+
+  Read BLOCK (16060) bytes from the file. If there are less that that left to
+  read only that many bytes will be returned.
+
+	    if(strlen(data))
+	    {
+
+   If we managed to read someting...
+
+	      written=socket::write(data);
+
+   ... we try to write it to the socket.
+
+	      if(written >= 0)
+	      {
+		offset+=written;
+		return;
+	      }
+
+   Update offset if we managed to write to the socket without errors.
+
+	      perror("Error: "+socket::errno()+".\n");
+	    }
+
+   If something went wront during writing, or there was nothing left to read
+   we destruct this instance of this class.
+
+	    destruct(this_object());
+	  }
+
+   That was the end of write_callback()
+
+
+   Next we need a variable to buffer the input received in. We initialize it
+   to an empty string.
+	
+	  string input="";
+
+   And then we define the function that will be called when there is something
+   in the socket input buffer. Ignore the argument 'id' for now. The second
+   argument is the contents of the input buffer.
+
+	  void read_callback(mixed id,string data)
+	  {
+	    string cmd;
+	
+	    input+=data;
+
+  Append data to the string input. Then we check if we have received a
+  a complete line yet. If so we parse this and start ouputting the file.
+
+	    if(sscanf(input,"%s %s%*[\012\015 \t]",cmd,input))
+	    {
+
+  This sscanf is pretty complicated, but in essense it means: put the
+  first word in 'input' in 'cmd' and the second in 'input' and return 2
+  if successfull, 0 otherwise.
+
+	      if(cmd!="GET")
+	      {
+		perror("Only method GET is supported.\n");
+		destruct(this_object());
+		return;
+	      }
+
+  If the first word isn't GET print an error message and terminate
+  this instance of the program. (and thus the connection)
+	
+	      sscanf(input,"%*[/]%s",input);
+
+  Remove the leading slash.
+
+	      input=combine_path(BASE,input);
+
+  Combine the requested file with the base of the HTML tree, this gives
+  us a full filename beginning with a slash.
+	      
+	      if(!file::open(input,"r"))
+	      {
+
+  Try opening the file in read-only mode. If this fails, try opening NOFILE
+  instead. 
+
+		if(!file::open(NOFILE,"r"))
+		{
+
+  If this fails too. Write an error message and destruct this object.
+
+		  perror("Couldn't find default file.\n");
+		  destruct(this_object());
+		  return;
+		}
+	      }
+
+  Ok, now we set up the socket so we can write the data back.
+	
+	      socket::set_buffer(65536,"w");
+
+  Set the buffer size to 64 kilobytes.
+
+	      socket::set_nonblocking(0,write_callback,0);
+
+  Make it so that write_callback is called when it is time to write more
+  data to the socket.
+
+	      write_callback();
+
+  Jump-start the writing.
+	    }
+	  }
+
+  That was the end of read_callback().
+
+
+  This function is called if the connection is closed while we are reading
+  from the socket.
+	  void selfdestruct() { destruct(this_object()); }
+
+
+  This function is called when the program is instanciated. It is used
+  to set up data the way we want it. Extra arguments to clone() will be
+  sent to this function. In this case it is the object representing the
+  new connection.
+
+	  void create(object f)
+	  {
+	    socket::assign(f);
+
+  We insert the data from the file f into 'socket'.
+
+	    socket::set_nonblocking(read_callback,0,selfdestruct);
+
+  Then we set up the callback functions. (And sets the file nonblocking.)
+  Nonblocking mode means that read() and write() will rather return that
+  wait for I/O to finish. Then we sit back and wait for read_callback to
+  be called.
+
+	  }
+
+  End of create()
+
+	};
+
+  End of the new class.
+	
+
+  Next we define the function called when someone connects.
+
+	void accept_callback()
+	{
+	  object tmp_output;
+	  tmp_output=accept();
+
+  The function accept clones a /precompiled/file and makes this equal to the
+  newly connected socket.
+
+	  if(!tmp_output) return;
+
+  If it failed we just return.
+
+	  clone(output_class, tmp_output);
+
+  Otherwise we clone an instanec of 'output_class' and let it take care of the
+  connection.
+
+	  destruct(tmp_output);
+
+  Destruct the object returned by accept(), output_class has already copied
+  the contents of this object.
+
+	}
+
+
+  Then there is main, the function that gets it all started.
+  	
+	int main(int argc, string *argv)
+	{
+	  perror("Starting minimal httpd\n");
+
+  Write an encouraging message to stderr.
+	
+	  if(!bind(PORT, accept_callback))
+	  {
+	    perror("Failed to open socket (already bound?)\n");
+	    return 17;
+	  }
+
+
+  Bind PORT and set it up to call accept_callback as soon as someone connects
+  to it. If the bind() fails we write an error message and return the 17 to
+  indicate failiure.
+	
+	  return - 17; /* Keep going */
+
+  If everything went ok, we return -17, any negative value returned by main()
+  means that the program WONT exit, it will hang around waiting for events
+  instead. (like someone connecting)
+	}
+
+  End of uhttpd.lpc
-- 
GitLab


From 08c66359aaae0a34f70c13e14b7dec44cb6d7328 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 3 Mar 1996 22:00:19 +0100
Subject: [PATCH 056/351] Added support for a[..n] and a[n..]

Rev: src/language.y:1.12
---
 src/language.y | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/src/language.y b/src/language.y
index 0c4ef11bf4..0fde89d6f4 100644
--- a/src/language.y
+++ b/src/language.y
@@ -217,12 +217,12 @@ void fix_comp_stack(int sp)
 
 /* The following symbos return type information */
 
-%type <n> string expr01 expr00 comma_expr
+%type <n> string expr01 expr00 comma_expr comma_expr_or_zero
 %type <n> expr2 expr1 expr3 expr0 expr4 catch lvalue_list
 %type <n> lambda for_expr block  assoc_pair new_local_name
 %type <n> expr_list2 m_expr_list m_expr_list2 statement gauge sscanf
 %type <n> for do cond optional_else_part while statements
-%type <n> local_name_list class catch_arg
+%type <n> local_name_list class catch_arg comma_expr_or_maxint
 %type <n> unused2 foreach unused switch case return expr_list default
 %type <n> continue break block_or_semi typeof
 %%
@@ -244,7 +244,7 @@ string_constant: low_string
            }
            ;
 
-optional_rename_inherit: ':' F_IDENTIFIER { $$=$2 }
+optional_rename_inherit: ':' F_IDENTIFIER { $$=$2; }
                        | { $$=0; }
                        ;
           
@@ -957,7 +957,7 @@ expr4: string
      }
      | expr4 '(' expr_list ')' { $$=mkapplynode($1,$3); }
      | expr4 '[' expr0 ']' { $$=mknode(F_INDEX,$1,$3); }
-     | expr4 '['  comma_expr F_DOT_DOT comma_expr ']'
+     | expr4 '['  comma_expr_or_zero F_DOT_DOT comma_expr_or_maxint ']'
      {
        $$=mknode(F_RANGE,$1,mknode(F_ARG_LIST,$3,$5));
      }
@@ -1019,7 +1019,15 @@ expr4: string
        free_string($2);
      }
      ;
-  
+
+comma_expr_or_zero: /* empty */ { $$=mkintnode(0); }
+                  | comma_expr
+                  ;
+
+comma_expr_or_maxint: /* empty */ { $$=mkintnode(0x7fffffff); }
+                    | comma_expr
+                    ;
+
 gauge: F_GAUGE '(' unused ')'
   {
     $$=mknode(F_NEGATE,
-- 
GitLab


From 482bba24812c3c508a556ca0dd23dd89b290779b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 3 Mar 1996 22:02:48 +0100
Subject: [PATCH 057/351] small bugfix

Rev: src/configure.in:1.9
---
 src/configure.in | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/configure.in b/src/configure.in
index 95aaad69e2..8070285c90 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -182,7 +182,7 @@ if test "${ac_cv_lib_m}" = "no" -a "${lpc_cv_sys_os}" = "Linux"; then
 fi
 AC_CHECK_LIB(socket, socket)
 AC_CHECK_LIB(crypt, crypt)
-if test "$ac_cv_lib_socket" = yes -o "$ac_cv_lib_ucb"; then
+if test "$ac_cv_lib_socket" = yes -o "${ac_cv_lib_ucb}" = yes; then
  AC_CHECK_LIB(nsl, main)
 fi
 
-- 
GitLab


From 79e374747af12c6a0d45190f101d132b30562c75 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 3 Mar 1996 22:03:13 +0100
Subject: [PATCH 058/351] entries addedd

Rev: src/ChangeLog:1.21
---
 src/ChangeLog | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index a3a5e731b3..13b2da0a0f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,6 @@
 Fri Mar  1 00:35:40 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
 
+	* language.y: Added support for a[..n] and a[n..]
 	* configure.in: added test for %pure_parser
 
 Sun Feb 25 22:42:48 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
@@ -11,16 +12,14 @@ Sat Feb 24 04:12:52 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
 
 	* program.c, array.c, object.c, gc.c: 
 	  Added routines to remove cyclic structures.
+	* sprintf: added support for %2c
+	* removed compact arrays
 
 Fri Feb 23 02:39:11 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
 
         * version 1.7E-12 released
 	* file->close() fixed to handle unknown errors
 
-Sat Feb 17 23:05:24 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
-
-	* sprintf: added support for %2c
-
 Sun Feb 11 01:04:38 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
 
 	* export.lpc: now updates configure files if needed
-- 
GitLab


From c71e648330bad9726c3cea0aef7497bef72fb626 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 3 Mar 1996 22:04:19 +0100
Subject: [PATCH 059/351] nothing much changed...

Rev: src/error.c:1.3
---
 src/error.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/error.c b/src/error.c
index e90c7c81c0..60b938a67e 100644
--- a/src/error.c
+++ b/src/error.c
@@ -24,7 +24,7 @@ jmp_buf *init_recovery(JMP_BUF *r)
   r->previous=recoveries;
   r->onerror=onerror_stack;
   recoveries=r;
-  return & r->recovery;
+  return & ( r->recovery );
 }
 
 void throw()
-- 
GitLab


From f170fa6f7a76c56925ab513a1629924ec7d75679 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 4 Mar 1996 00:01:39 +0100
Subject: [PATCH 060/351] error.c fixed for lesser warnings

Rev: src/error.c:1.4
Rev: src/error.h:1.2
---
 src/error.c | 2 +-
 src/error.h | 6 ++++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/error.c b/src/error.c
index 60b938a67e..b027f8d6c8 100644
--- a/src/error.c
+++ b/src/error.c
@@ -16,7 +16,7 @@ char *automatic_fatal;
 JMP_BUF *recoveries=0;
 ONERROR *onerror_stack=0;
 
-jmp_buf *init_recovery(JMP_BUF *r)
+my_jmp_buf *init_recovery(JMP_BUF *r)
 {
   r->fp=fp;
   r->sp=sp;
diff --git a/src/error.h b/src/error.h
index 616925f0d7..9dce4c7787 100644
--- a/src/error.h
+++ b/src/error.h
@@ -23,10 +23,12 @@ typedef struct ONERROR
   void *arg;
 } ONERROR;
 
+typedef jmp_buf my_jmp_buf; /* Maybe I'll get less warnings like this */
+
 typedef struct JMP_BUF
 {
   struct JMP_BUF *previous;
-  jmp_buf recovery;
+  my_jmp_buf recovery;
   struct frame *fp;
   struct svalue *sp;
   struct svalue **mark_sp;
@@ -51,7 +53,7 @@ extern char *automatic_fatal;
 
 #define UNSET_ONERROR(X) onerror_stack=X.previous
 
-jmp_buf *init_recovery(JMP_BUF *r);
+my_jmp_buf *init_recovery(JMP_BUF *r);
 int fix_recovery(int i, JMP_BUF *r);
 void throw() ATTRIBUTE((noreturn));
 void va_error(char *fmt, va_list args) ATTRIBUTE((noreturn));
-- 
GitLab


From 0f462c6b46b667167b43abb2cae6c2201e66d5e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 4 Mar 1996 00:02:45 +0100
Subject: [PATCH 061/351] int i=1; now works

Rev: bin/hilfe.lpc:1.2
Rev: src/ChangeLog:1.22
---
 bin/hilfe.lpc | 41 +++++++++++++++++++++++++----------------
 src/ChangeLog |  4 ++++
 2 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/bin/hilfe.lpc b/bin/hilfe.lpc
index bce12e7987..4d7fa1bb63 100755
--- a/bin/hilfe.lpc
+++ b/bin/hilfe.lpc
@@ -113,14 +113,16 @@ int find_next_comma(string s)
   return 0;
 }
 
-string get_name(string f)
+string *get_name(string f)
 {
   int e,d;
+  string rest;
   
   f=skipwhite(f);
   if(sscanf(f,"*%s",f)) f=skipwhite(f);
-  sscanf(f,"%[a-zA-Z0-9_]",f);
-  return f;
+  sscanf(f,"%[a-zA-Z0-9_]%s",f,rest);
+  rest=skipwhite(rest);
+  return ({f,rest});
 }
 
 string first_word=0;
@@ -331,17 +333,19 @@ mixed parse_function(string fun)
     /* parse function */
     if(eq_pos!=-1) break;  /* it's a variable */
     sscanf(fun,first_word+"%s",name);
-    name=get_name(name);
-    
-    if(sscanf(fun,"%s"+name+"%s(",c,c) && skipwhite(c)=="")
+
+    c=get_name(name);
+    name=c[0];
+    c=c[1];
+
+    if(c[0]=='(')
     {
       int i;
       if((i=member_array(name,function_names))!=-1)
       {
 	b=functions[i];
 	functions[i]=fun;
-	if(!eval(""))
-	  functions[i]=b;
+	if(!eval(""))  functions[i]=b;
       }else{
 	if(eval(fun))
 	{
@@ -350,6 +354,8 @@ mixed parse_function(string fun)
 	}
       }
       return 1;
+    }else{
+      write("Syntax error.\n");
     }
   }
 }
@@ -394,7 +400,9 @@ mixed parse_statement(string ex)
     /* parse variable def. */
     sscanf(ex,first_word+"%s",b);
     b=skipwhite(b);
-    name=get_name(b);
+    c=get_name(b);
+    name=c[0];
+    c=c[1];
 
 #ifdef DEBUG
     write("Variable def.\n");
@@ -406,24 +414,25 @@ mixed parse_statement(string ex)
       string f;
       variables[name]=0;
 
-      if(sscanf(ex,"%s"+name+"%s=%s",c,f,c)==3 && skipwhite(f)=="")
+      if(sscanf(c,"=%s",c))
       {
 #ifdef DEBUG
 	write("Variable def. with assign. ("+name+")\n");
 #endif
 	if(e=find_next_comma(c))
+	{
 	  return name+"="+c[0..e-1]+";\n"+
-		     first_word+" "+c[e+1..strlen(c)-1];
-	else
+	    first_word+" "+c[e+1..strlen(c)-1];
+	}else{
 	  return name+"="+c;
+	}
 #ifdef DEBUG
 	write("Input buffer = '"+input+"'\n");
 #endif
 
       }else{
-	sscanf(b,"%s"+name+"%s",b,b);
-	sscanf(b,",%s",b);
-	return first_word+" "+b;
+	sscanf(c,",%s",c);
+	return first_word+" "+c;
       }
     }
     
@@ -506,7 +515,7 @@ void main(int argc,string *argv)
   signal(signum("SIGINT"),signal_trap);
 
   write(version()+
-	" Running Hilfe v1.2 (Hubbe's Incremental LPC FrontEnd)\n");
+	" Running Hilfe v1.3 (Hubbe's Incremental LPC FrontEnd)\n");
   write("> ");
 
   read_input();
diff --git a/src/ChangeLog b/src/ChangeLog
index 13b2da0a0f..38563d3c04 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+Mon Mar  4 00:00:19 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
+
+	* hilfe.lpc: fixed a bug when doing 'mapping m=([]);'
+
 Fri Mar  1 00:35:40 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
 
 	* language.y: Added support for a[..n] and a[n..]
-- 
GitLab


From 473515622df05534f824d9adbf2fefba078e35cf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 4 Mar 1996 22:59:57 +0100
Subject: [PATCH 062/351] added tests for range

Rev: src/test/create_testsuite:1.10
---
 src/test/create_testsuite | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index e4b46c229d..419f561d78 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -440,6 +440,11 @@ test_eq("foo"[-100..0],"f")
 test_eq("foo"[-100..100],"foo")
 test_eq("foo"[1..0],"")
 test_eq("foo"[0..-100],"")
+test_eq("foobargazonk"[0..],"foobargazonk")
+test_eq("foobargazonk"[1..],"oobargazonk")
+test_eq("foobargazonk"[5..],"rgazonk")
+test_eq("foobargazonk"[..2],"foo")
+test_eq("foobargazonk"[..5],"foobar")
 test_equal(({1,2,3})[0..0],({1}))
 test_equal(({1,2,3})[1..2],({2,3}))
 test_equal(({1,2,3})[2..10],({3}))
-- 
GitLab


From 7b02268b8404b67d8e906e0b7cea5824a658f7a5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 22 Mar 1996 20:53:43 +0100
Subject: [PATCH 063/351] fixed some quirks

Rev: bin/hilfe.lpc:1.3
---
 bin/hilfe.lpc | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/bin/hilfe.lpc b/bin/hilfe.lpc
index 4d7fa1bb63..89470e7ea2 100755
--- a/bin/hilfe.lpc
+++ b/bin/hilfe.lpc
@@ -5,7 +5,8 @@
 /* todo:
  *  return (void)1; will give me problems.
  *  strstr(string,string *) -> return first occurance of first string...
- *
+ *  inherit doesn't work
+ *  preprocessor stuff
  */
 
 #!define catch(X) ((X),0)
@@ -200,7 +201,7 @@ int do_parse()
 	{
 	case "quit":
 	  write("Exiting.\n");
-	  exit(1);
+	  exit(0);
 	case ".":
 	  clean_buffer();
 	  write("Input buffer flushed.\n");
@@ -330,6 +331,8 @@ mixed parse_function(string fun)
   case "list":
   case "float":
   case "mixed":
+  case "program":
+  case "function":
     /* parse function */
     if(eq_pos!=-1) break;  /* it's a variable */
     sscanf(fun,first_word+"%s",name);
@@ -397,6 +400,8 @@ mixed parse_statement(string ex)
   case "list":
   case "float":
   case "mixed":
+  case "program":
+  case "function":
     /* parse variable def. */
     sscanf(ex,first_word+"%s",b);
     b=skipwhite(b);
-- 
GitLab


From 57145a56dfa2cda19bbc35e4da0bbf1cf1da107a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 22 Mar 1996 20:53:51 +0100
Subject: [PATCH 064/351] added <body>

Rev: bin/htmlify_docs.lpc:1.2
---
 bin/htmlify_docs.lpc | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/bin/htmlify_docs.lpc b/bin/htmlify_docs.lpc
index a15d9df5d0..b2eb33edfe 100644
--- a/bin/htmlify_docs.lpc
+++ b/bin/htmlify_docs.lpc
@@ -205,6 +205,18 @@ string html_unquote(string s)
   return replace(s,({"&amp;","&lt;","&gt;"}),({"&","<",">"}));
 }
 
+string mkdocument(string s,string title)
+{
+  return ("<html>"+
+	  "<title>"+
+	  html_quote(title)+
+	  "</title>"+
+	  "<body bgcolor=\"#A0E0C0\">"+
+	  s+
+	  "</body>"+
+	  "</html>");
+}
+
 string convert_page(string path, string fname)
 {
   string output, short;
@@ -332,8 +344,7 @@ string convert_page(string path, string fname)
 	  "\n</a>\n";
       }
     }
-    output="<html><title>uLPC: "+name+"</title>"+
-      implode(parts,"<hr noshade size=1>\n");
+    output=mkdocument(implode(parts,"<hr noshade size=1>\n"),"uLPC: "+name);
   }
   return output;
 }
@@ -408,9 +419,9 @@ string mkindex()
 
   ret="";
 
-  ret+="<H1>"+version()+"</h1>\n";
+  ret+="<H1>"+version()+" index</h1>\n";
   
-  ret+="<H1>Keyword lists</H1>\n<dl>\n";
+  ret+="<H2><b>Keyword lists</b></H2>\n<dl>\n";
   foreach(sort_array(m_indices(keywords)),b)
   {
     ret+="<a name="+b+">";
@@ -460,7 +471,7 @@ string mkindex()
   }
   
   ret+="</ul>\n";
-  return ret;
+  return mkdocument(ret,"uLPC documentation index");
 }
 
 int main(int argc, string *argv)
-- 
GitLab


From 90a1afb6a5773e2c5534f4d743fa82915033aaf9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 22 Mar 1996 20:54:31 +0100
Subject: [PATCH 065/351] added values to see also

Rev: doc/types/array:1.5
Rev: doc/types/mapping:1.4
---
 doc/types/array   | 2 +-
 doc/types/mapping | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/types/array b/doc/types/array
index 0ffe36945f..d07e772eeb 100644
--- a/doc/types/array
+++ b/doc/types/array
@@ -46,4 +46,4 @@ KEYWORDS
 	types
 
 SEE ALSO
-	mapping, list, builtin/allocate, builtin/sizeof, builtin/values
+	mapping, list, builtin/allocate, builtin/sizeof
diff --git a/doc/types/mapping b/doc/types/mapping
index 36f63c3ac5..0077a6ce05 100644
--- a/doc/types/mapping
+++ b/doc/types/mapping
@@ -16,7 +16,7 @@ DESCRIPTION
 	Here follows a list of operators that applies to mappings:
 	In this list a and b is used to represent a mapping expression:
 
-	a + b	summation ( ([1:1]) + ([2:2,2:2]) returns ([1:1,2:2]) )
+	a + b	summation ( ([1:1]) + ([2:2,2:2]) returns ([1:1,2:2,2:2]) )
 	a - b	subtraction, returns a copy of a with all pairs whos
 		index is present in b removed.
 	a & b	intersection, return a mapping with all indices that are
-- 
GitLab


From ae0b38881dd3f97f33e8cb2355fc2a37d94be211 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 22 Mar 1996 20:54:45 +0100
Subject: [PATCH 066/351] fixed $(SRCDIR)

Rev: src/Makefile.in:1.12
---
 src/Makefile.in | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Makefile.in b/src/Makefile.in
index f25e385a16..60e69e1afd 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -165,7 +165,7 @@ run_hilfe:
 # make export archive (requires compiled uLPC)
 # Do not compile in source tree if you want to use this!
 export: $(SRCDIR)/test/testsuite
-	chmod +x $(TMP_SRCDIR)/install-sh
+	chmod +x $(SRCDIR)/install-sh
 	$(RUNULPC) $(TMP_BINDIR)/export.lpc
 
 # make dependencies (requires compiled uLPC)
-- 
GitLab


From 865c66788072b8b51074ba61d2dfba5074b762af Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 22 Mar 1996 20:55:01 +0100
Subject: [PATCH 067/351] implemented + and 8-bit-chars

Rev: doc/regexp/regexp:1.1.1.3
Rev: src/modules/regexp/regexp.c:1.2
---
 doc/regexp/regexp           |  12 +++--
 src/modules/regexp/regexp.c | 103 ++++++++++++++++++++++--------------
 2 files changed, 71 insertions(+), 44 deletions(-)

diff --git a/doc/regexp/regexp b/doc/regexp/regexp
index f2c5b06389..8c82853c4b 100644
--- a/doc/regexp/regexp
+++ b/doc/regexp/regexp
@@ -10,14 +10,16 @@ DESCRIPTION
 	[abc]	Matches a, b or c
 	[a-z]	Matches any character a to z inclusive
 	[^ac]	Matches any character except a and c
-	(x)	Matches x (x might be any regexp)
-	x*	Matches zero or more occurances of 'x' (x may be anything)
+	(x)	Matches x (x might be any regexp) If used with split, this
+		also puts the string matching x into the result array.
+	x*	Matches zero or more occurances of 'x' (x may be any regexp)
+	x+	Matches one or more occurances of 'x' (x may be any regexp)
 	x|y	Matches x or y. (x or y may be any regexp)
 	xy	Matches xy (x and y may be any regexp)
 	^	Matches beginning of string (but no characters)
 	$	Matches end of string (but no characters)
-	<x>	Used with split() to put the string matching x into the
-		result array.
+	\<	matches the beginning of a word (but no characters)
+	\>	matches the end of a word (but no characters)
 
 	Note that \ can be used to quote these characters in which case
 	they match themselves, nothing else. Also note that when quoting
@@ -76,7 +78,7 @@ SYNTAX
 
 DESCRIPTION
 	Works as regexp->match, but returns an array of the strings that
-	matched the subregexps. Subregexps are those contained in < > in
+	matched the subregexps. Subregexps are those contained in ( ) in
 	the regexp. Subregexps that were not matched will contain zero.
 	If the total regexp didn't match, zero is returned.
 
diff --git a/src/modules/regexp/regexp.c b/src/modules/regexp/regexp.c
index 49b3b6bda6..962dd8233c 100644
--- a/src/modules/regexp/regexp.c
+++ b/src/modules/regexp/regexp.c
@@ -40,6 +40,10 @@
  * maximum number of bytes that can be written to the memory region
  * pointed to by dest
  *
+ * Also altered by Fredrik Hubinette to handle the + operator and
+ * eight-bit chars. Mars 22 1996
+ * 
+ *
  * 	Beware that some of this code is subtly aware of the way operator
  * 	precedence is structured in regular expressions.  Serious changes in
  * 	regular-expression syntax might require a total rethink.
@@ -169,6 +173,7 @@
 #define LBRAC	('('|SPECIAL)
 #define RBRAC	(')'|SPECIAL)
 #define ASTERIX	('*'|SPECIAL)
+#define PLUS	('+'|SPECIAL)
 #define OR_OP	('|'|SPECIAL)
 #define DOLLAR	('$'|SPECIAL)
 #define DOT	('.'|SPECIAL)
@@ -178,8 +183,8 @@
 #define LSHBRAC ('<'|SPECIAL)
 #define RSHBRAC ('>'|SPECIAL)
 #define	FAIL(m)	{ regerror(m); return(NULL); }
-#define	ISMULT(c)	((c) == ASTERIX)
-#define	META	"^$.[()|*\\"
+#define	ISMULT(c)	((c) == ASTERIX || (c)==PLUS)
+#define	META	"^$.[()|*+\\"
 #ifndef CHARBITS
 #define CHARBITS	0xff
 #define	UCHARAT(p)	((int)*(unsigned char *)(p))
@@ -238,17 +243,17 @@ STATIC void     regoptail();
  * of the structure of the compiled regexp.
  */
 regexp *regcomp(exp,excompat)
-char           *exp;
+unsigned char   *exp;
 int		excompat;	/* \( \) operators like in unix ex */
 {
     register regexp *r;
-    register char  *scan;
+    register unsigned char  *scan;
     register char  *longest;
     register int    len;
     int             flags;
     short	   *exp2,*dest,c;
 
-    if (exp == (char *)NULL)
+    if (exp == (unsigned char *)NULL)
 	FAIL("NULL argument");
 
     exp2=(short*)xalloc( (strlen(exp)+1) * (sizeof(short[8])/sizeof(char[8])) );
@@ -260,6 +265,7 @@ int		excompat;	/* \( \) operators like in unix ex */
 		break;
 	    case '.':
 	    case '*':
+	    case '+':
 	    case '|':
 	    case '$':
 	    case '^':
@@ -477,41 +483,60 @@ int            *flagp;
 static char *regpiece(flagp)
 int            *flagp;
 {
-    register char  *ret;
-    register short  op;
-    /* register char  *nxt; */
-    int             flags;
-
-    ret = regatom(&flags);
-    if (ret == (char *)NULL)
-	return ((char *)NULL);
-
-    op = *regparse;
-    if (!ISMULT(op)) {
-	*flagp = flags;
-	return (ret);
+  register char  *ret;
+  register short  op;
+  /* register char  *nxt; */
+  int             flags;
+
+  ret = regatom(&flags);
+  if (ret == (char *)NULL)
+    return ((char *)NULL);
+
+  op = *regparse;
+  if (!ISMULT(op)) {
+    *flagp = flags;
+    return (ret);
+  }
+  if (!(flags & HASWIDTH))
+    FAIL("* or + operand could be empty");
+  *flagp = (WORST | SPSTART);
+
+  if(op == ASTERIX)
+  {
+    if (flags & SIMPLE)
+    {
+      reginsert(STAR, ret);
     }
-    if (!(flags & HASWIDTH))
-	FAIL("* operand could be empty");
-    *flagp = (WORST | SPSTART);
-
-    if (op == ASTERIX && (flags & SIMPLE))
-	reginsert(STAR, ret);
-    else if (op == ASTERIX) {
-	/* Emit x* as (x&|), where & means "self". */
-	reginsert(BRANCH, ret);	/* Either x */
-	regoptail(ret, regnode(BACK));	/* and loop */
-	regoptail(ret, ret);	/* back */
-	regtail(ret, regnode(BRANCH));	/* or */
-	regtail(ret, regnode(NOTHING));	/* null. */
+    else
+    {
+      /* Emit x* as (x&|), where & means "self". */
+      reginsert(BRANCH, ret);	/* Either x */
+      regoptail(ret, regnode(BACK)); /* and loop */
+      regoptail(ret, ret);	/* back */
+      regtail(ret, regnode(BRANCH)); /* or */
+      regtail(ret, regnode(NOTHING)); /* null. */
     } 
-    regparse++;
-    if (ISMULT(*regparse))
-	FAIL("nested *");
-
-    return (ret);
+  }
+  else if(op == PLUS)
+  {
+    /*  Emit a+ as (a&) where & means "self" /Fredrik Hubinette */
+    char *tmp;
+    tmp=regnode(BACK);
+    reginsert(BRANCH, tmp);
+    regtail(ret, tmp);
+    regoptail(tmp, ret);
+    regtail(ret, regnode(BRANCH));
+    regtail(ret, regnode(NOTHING));
+  }
+    
+  regparse++;
+  if (ISMULT(*regparse))
+    FAIL("nested * or +");
+    
+  return (ret);
 }
 
+
 /*
  - regatom - the lowest level
  *
@@ -601,9 +626,9 @@ int            *flagp;
 	    for (len=0; regparse[len] &&
 	        !(regparse[len]&SPECIAL) && regparse[len] != RSQBRAC; len++) ;
 	    if (len <= 0)
-		{
-		FAIL("internal disaster");
-		}
+	    {
+	      FAIL("internal disaster");
+	    }
 	    ender = *(regparse + len);
 	    if (len > 1 && ISMULT(ender))
 		len--;		/* Back off clear of * operand. */
-- 
GitLab


From 3829274e48966ce638861a700ec0ccf6e3f41060 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 22 Mar 1996 21:40:33 +0100
Subject: [PATCH 068/351] added new tar file

Rev: .cvsignore:1.3
---
 .cvsignore | 1 +
 .gitignore | 1 +
 2 files changed, 2 insertions(+)

diff --git a/.cvsignore b/.cvsignore
index 796d6bf45a..35e9d80097 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -1,5 +1,6 @@
 test
 test.lpc
+uLPC_v1.0E-10.tar.gz
 uLPC_v1.0E-12.tar.gz
 uLPC_v1.0E-13.tar.gz
 uLPC_v1.1E-12.tar.gz
diff --git a/.gitignore b/.gitignore
index a03e4059f2..5031a7f789 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,6 +32,7 @@ _$*
 core
 /test
 /test.lpc
+/uLPC_v1.0E-10.tar.gz
 /uLPC_v1.0E-12.tar.gz
 /uLPC_v1.0E-13.tar.gz
 /uLPC_v1.1E-12.tar.gz
-- 
GitLab


From afc9d82b66763050426e7de16c801de25392ce9b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 22 Mar 1996 21:40:51 +0100
Subject: [PATCH 069/351] added tests for + in regexps

Rev: src/test/create_testsuite:1.11
---
 src/test/create_testsuite | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 419f561d78..56718befc1 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -1201,6 +1201,12 @@ test_eq(clone((program)"/precompiled/regexp","^[^abc]$")->match("-"),1)
 test_eq(clone((program)"/precompiled/regexp","^[^abc]$")->match("a"),0)
 test_eq(clone((program)"/precompiled/regexp","^[^abc]$")->match("c"),0)
 test_eq(clone((program)"/precompiled/regexp","^a*$")->match("aaaa"),1)
+test_eq(clone((program)"/precompiled/regexp","^(a|bb)*$")->match("aabbabb"),1)
+test_eq(clone((program)"/precompiled/regexp","^(a|bb)*$")->match(""),1)
+test_eq(clone((program)"/precompiled/regexp","^(a|bb)+$")->match(""),0)
+test_eq(clone((program)"/precompiled/regexp","^(a|bb)+$")->match("aaa"),1)
+test_eq(clone((program)"/precompiled/regexp","^(a|bb)+$")->match("bbb"),0)
+test_eq(clone((program)"/precompiled/regexp","^(a|bb)+$")->match("bbaabba"),1)
 test_eq(clone((program)"/precompiled/regexp","^a|b$")->match("a"),1)
 test_eq(clone((program)"/precompiled/regexp","^a|b$")->match("b"),1)
 
-- 
GitLab


From a650f2883d3a4aad1c87988ec4355a64bd867aea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 22 Mar 1996 21:57:12 +0100
Subject: [PATCH 070/351] fixed some bugs in operators involving ints and
 floats

Rev: src/operators.c:1.5
---
 src/operators.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/operators.c b/src/operators.c
index 3a21b0d51f..fe9859685b 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -183,6 +183,7 @@ void f_add(INT32 args)
       }
     }
     sp-=args-1;
+    sp[-1].type=T_FLOAT;
     sp[-1].u.float_number=sum;
     break;
   }
@@ -1022,7 +1023,7 @@ void init_operators()
 
   add_efun2("`/",f_divide,"function(int,int:int)|function(float|int,float:float)|function(float,int:float)|function(string,string:string*)",0,0,generate_divide);
 
-  add_efun2("`%",f_mod,"function(int,int:int)|function(float,float:float)",0,0,generate_mod);
+  add_efun2("`%",f_mod,"function(int,int:int)|!function(int,int:mixed)&function(int|float,int|float:float)",0,0,generate_mod);
 
   add_efun2("`!",f_not,"function(mixed:int)",0,0,generate_not);
   add_efun2("`~",f_compl,"function(int:int)",0,0,generate_compl);
-- 
GitLab


From 7e60d9a58a61b7057e5f1be07547241e616657fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 22 Mar 1996 21:57:29 +0100
Subject: [PATCH 071/351] added tests for operators involving ints and floats

Rev: src/test/create_testsuite:1.12
---
 src/test/create_testsuite | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 56718befc1..53ebd3d924 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -216,6 +216,8 @@ test_true($1>=$1) ]])
 
 test_cmp(1,2)
 test_cmp(1.0,2.0)
+test_cmp(1,2.0)
+test_cmp(1.0,2)
 test_cmp("a","b")
 test_cmp("","b")
 
@@ -258,6 +260,12 @@ test_eq("a"+"b"+"c"+"d"+"e"+"f"+"g"+"h"+"i"+"j"+"k"+"l"+"m"+"n"+"o"+"p"+"q"+"r"+
 test_eq(1.0+1.0,2.0)
 test_eq(1.0+(-1.0),0.0)
 test_eq((-1.0)+(-1.0),-2.0)
+test_eq(1.0+1,2.0)
+test_eq(1+1.0,2.0)
+test_eq(1+(-1.0),0.0)
+test_eq(1.0+(-1),0.0)
+test_eq((-1)+(-1.0),-2.0)
+test_eq((-1.0)+(-1),-2.0)
 test_equal(({1,2,3})+({4,5,6}),({1,2,3,4,5,6}))
 test_equal((<1,2,3,4>)+(<4,5,6>),(<1,2,3,4,4,5,6>))
 test_equal(([0:1,3:6])+([5:2,3:6]),([0:1,3:6,3:6,5:2]))
@@ -268,6 +276,10 @@ test_eq(10-3,7)
 test_eq(3-10,-7)
 test_eq(10.0-3.0,7.0)
 test_eq(3.0-10.0,-7.0)
+test_eq(10-3.0,7.0)
+test_eq(3-10.0,-7.0)
+test_eq(10.0-3,7.0)
+test_eq(3.0-10,-7.0)
 test_eq("foobargazonk"-"o","fbargaznk")
 test_equal(({"foo","bar","gazonk"})-({"foo","gazonk"}),({"bar"}))
 test_equal(({"c","foo","bar","gazonk","a","b",})-({"foo","gazonk"}),({"c","bar","a","b"}))
@@ -285,6 +297,12 @@ test_eq(2*2*2*2*2,32)
 test_eq(3.0*4.0,12.0)
 test_eq(4.0*3.0,12.0)
 test_eq(2.0*2.0*2.0*2.0*2.0,32.0)
+test_eq(3*4.0,12.0)
+test_eq(4*3.0,12.0)
+test_eq(2*2.0*2.0*2.0*2.0,32.0)
+test_eq(3.0*4,12.0)
+test_eq(4.0*3,12.0)
+test_eq(2.0*2*2.0*2*2.0,32.0)
 test_eq(({"foo","bar","gazonk"})*"-","foo-bar-gazonk")
 
 // testing /
@@ -296,6 +314,12 @@ test_eval_error(return 15/0)
 test_eq(12.0/3.0,4.0)
 test_eq(14.0/4.0,3.5)
 test_eq(15.0/3.0,5.0)
+test_eq(12/3.0,4.0)
+test_eq(14/4.0,3.5)
+test_eq(15/3.0,5.0)
+test_eq(12.0/3,4.0)
+test_eq(14.0/4,3.5)
+test_eq(15.0/3,5.0)
 test_eval_error(return 15.0/0.0)
 test_equal("foo-bar-gazonk"/"-",({"foo","bar","gazonk"}))
 test_equal("foobargazonk"/"",({"f","o","o","b","a","r","g","a","z","o","n","k"}))
@@ -311,6 +335,11 @@ test_eq(13.0 % 3.0,1.0)
 test_eq(14.0 % 3.0,2.0)
 test_eq(14.5 % 3.0,2.5)
 test_eq(15.0 % 3.0,0.0)
+test_eq(13 % 3.0,1.0)
+test_eq(14 % 3.0,2.0)
+test_eq(13.0 % 3,1.0)
+test_eq(14.0 % 3,2.0)
+test_eq(14.5 % 3,2.5)
 test_eval_error(return 15.0 % 0.0)
 
 // testing &&
-- 
GitLab


From ecbba40c391d57df53cb3f3ba8e6609d03d76a3c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 22 Mar 1996 21:59:11 +0100
Subject: [PATCH 072/351] entry added

Rev: src/ChangeLog:1.23
---
 src/ChangeLog | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 38563d3c04..1e6210ab4b 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+Fri Mar 22 21:57:43 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
+
+	* regexp.c: added + operator, and added support for 8-bit
+	  characters.
+
 Mon Mar  4 00:00:19 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
 
 	* hilfe.lpc: fixed a bug when doing 'mapping m=([]);'
-- 
GitLab


From 99b670b9df8ebbb375f2674b9e963c04b5cc6dbd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 24 Mar 1996 15:17:31 +0100
Subject: [PATCH 073/351] can not handle examples

Rev: bin/htmlify_docs.lpc:1.3
---
 bin/htmlify_docs.lpc | 146 +++++++++++++++++++++++++++++++++++++++----
 1 file changed, 133 insertions(+), 13 deletions(-)

diff --git a/bin/htmlify_docs.lpc b/bin/htmlify_docs.lpc
index b2eb33edfe..837f9fb302 100644
--- a/bin/htmlify_docs.lpc
+++ b/bin/htmlify_docs.lpc
@@ -45,9 +45,15 @@ string smallcaps(string foo)
 string fippel_path(string path)
 {
   sscanf(path,"./%s",path);
-  return replace(path,"/","_")+".html";
+  path=replace(path,"/","_");
+  if(path[strlen(path)-5..]!=".html") path+=".html";
+
+  return path;
 }
 
+/*
+ * Three step conversion process...
+ */
 string even_more_magic(string block, int indent)
 {
   if(-1==search(block,"\t"))
@@ -157,6 +163,10 @@ string magic(string s, int quote)
   return implode(ret,"\n<p>");
 }
 
+
+/*
+ * Magic to convert SYNTAX sections
+ */
 inherit "/precompiled/regexp" : lastident;
 inherit "/precompiled/regexp" : megamagic;
 
@@ -195,6 +205,9 @@ string syntax_magic(string s)
   return "<tt>"+magic(s,1)+"</tt>";
 }
 
+
+/* HTML quoting / unquoting */
+
 string html_quote(string s)
 {
   return replace(s,({"&","<",">"}),({"&amp;","&lt;","&gt;"}));
@@ -217,6 +230,9 @@ string mkdocument(string s,string title)
 	  "</html>");
 }
 
+inherit "/precompiled/regexp":is_example;
+
+/* Convert a page */
 string convert_page(string path, string fname)
 {
   string output, short;
@@ -227,13 +243,12 @@ string convert_page(string path, string fname)
 
   cont=read_bytes(path);
 
-  cont=html_quote(cont);
-
   if(sscanf(cont,"NAME\n\t%s - %s\n",name,short))
   {
     int partno;
 
-    short_descs[name]=short;
+    cont=html_quote(cont);
+    short_descs[html_quote(name)]=short;
 
     string *parts=explode(cont,"============================================================================\n");
     for(partno=0;partno<sizeof(parts);partno++)
@@ -346,9 +361,60 @@ string convert_page(string path, string fname)
     }
     output=mkdocument(implode(parts,"<hr noshade size=1>\n"),"uLPC: "+name);
   }
+  else if(path[strlen(path)-5..]==".html")
+  {
+    if(sscanf(cont,"<title>%s</title>",part))
+      short_descs[(path/"/")[-1]]=part;
+    output=cont;
+  }
+  else if(is_example::match(cont))
+  {
+    /** Hmm, this looks like an example file to me... */
+    string line,tmp;
+    int pre,p;
+
+    if(sscanf(cont,"%*[0-9.] %s\n",part)==2)
+      short_descs[(path/"/")[-1]]=part;
+
+    tmp="";
+    pre=2;
+    cont=html_quote(cont);
+    foreach(cont/"\n"+({"."}),line)
+    {
+      if(strlen(line))
+      {
+	switch(line[0])
+	{
+	case ' ': p=0; sscanf(line,"  %s",line); break;
+	case '\t': p=1; sscanf(line,"\t",line); break;
+	default: p=2; break;
+	}
+	
+	if(p!=pre)
+	{
+	  switch(pre)
+	  {
+	  case 2: output+="<h2>"+tmp+"</h2>"; break;
+	  case 1:
+	    if(tmp[-1]=='\n' && tmp[-2]=='\n')
+	      tmp=tmp[..strlen(tmp)-2];
+	    output+="<pre>\n"+tmp+"</pre>\n";
+	    break;
+	  case 0: output+=replace(tmp,"\n\n","\n<p>\n"); break;
+	  }
+	  pre=p;
+	  tmp="";
+	}
+      }
+      tmp+=line+"\n";
+    }
+    output=mkdocument(output,"uLPC: "+
+		      replace(explode(fname,"/")[-1],"_"," "));
+  }
   return output;
 }
 
+
 void scanfiles(string path, string fname)
 {
   string nf,np;
@@ -357,13 +423,16 @@ void scanfiles(string path, string fname)
   if(nf && strlen(nf))
   {
     np=combine_path(new_path,fippel_path(path));
-    write("Writing "+np+".\n");
+//    write("Writing "+np+".\n");
     if(file_size(np)>=0)
       rm (np);
     write_file(np,nf);
   }
 }
 
+/*
+ * Pre-read all files and sort out where to link it to
+ */
 void scanlinks(string path, string fname)
 {
   string cont,name;
@@ -385,11 +454,48 @@ void scanlinks(string path, string fname)
 	subpages[fname+"-&gt;"+part_name]=path+"#"+part_name;
       }
     }
-  }else{
+  }
+  else if(path[strlen(path)-5..]==".html")
+  {
+    pages[(path[..strlen(path)-6]/"/")[-1]]=fippel_path(path);
+  }
+  else if(is_example::match(cont))
+  {
+    pages[(path/"/")[-1]]=fippel_path(path);
+  }
+  else
+  {
+    string tmp;
+    int l, i;
+
+    foreach(cont/"\n", tmp)
+    {
+      if(is_example::match(tmp+"\n"))
+      {
+	l++;
+      }else{
+	i++;
+      }
+    }
+
+    if(l > i*2)
+    {
+      l=0;
+      foreach(cont/"\n", tmp)
+      {
+	l++;
+	if(!is_example::match(tmp+"\n"))
+	{
+	  perror(path+":"+l+": not on example form.\n");
+	}
+      }
+    }
     perror("Warning: not converting "+path+".\n");
   }
 }
 
+
+/** Traverse directory **/
 void traversedir(string path,function fun)
 {
   string file;
@@ -411,6 +517,11 @@ void traversedir(string path,function fun)
   }
 }
 
+string short(string s)
+{
+  return short_descs[s] ? " - "+short_descs[s] : "";
+}
+/** Create an index for our newly created stuff **/
 string mkindex()
 {
   string ret;
@@ -426,12 +537,13 @@ string mkindex()
   {
     ret+="<a name="+b+">";
     ret+="<dt><h2>"+capitalize(b);
-    if(short_descs[b]) ret+=" - "+short_descs[b];
+    ret+=short(b);
     ret+="</h2><dd>\n";
     ret+="<ul>\n";
     foreach(keywords[b],a)
     {
-      ret+="<li><a href="+pages[a]+">"+a+"</a> - "+short_descs[a]+"\n";
+      a=html_quote(a);
+      ret+="<li><a href="+pages[a]+">"+a+"</a>"+ short(a) +"\n";
       m_delete(tmp,a);
     }
     ret+="</ul></a>\n";
@@ -445,7 +557,7 @@ string mkindex()
     a=html_quote(a);
     if(pages[a])
     {
-      ret+="<li><a href="+pages[a]+">"+a+"</a> - "+short_descs[a]+"\n";
+      ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
     }else{
       perror("Warning: no page for function: "+a+".\n");
     }
@@ -458,7 +570,7 @@ string mkindex()
   {
     if(-1 == search(a,"/")) continue;
 
-    ret+="<li><a href="+pages[a]+">"+a+"</a> - "+short_descs[a]+"\n";
+    ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
     m_delete(tmp,a);
   }
   
@@ -467,7 +579,7 @@ string mkindex()
   ret+="<H1>Other pages</H1>\n<ul>\n";
   foreach(sort_array(m_indices(tmp)),a)
   {
-    ret+="<li><a href="+pages[a]+">"+a+"</a> - "+short_descs[a]+"\n";
+    ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
   }
   
   ret+="</ul>\n";
@@ -478,8 +590,16 @@ int main(int argc, string *argv)
 {
   string np;
 
-  megamagic::create("^(.*)&lt;([a-z_0-9][a-z_0-9]*)&gt;(.*)$");
-  lastident::create("^(.*[^<>a-z_0-9])([a-z_0-9][a-z_0-9]*)([^<>a-z_0-9]*)$");
+  megamagic::create("^(.*)&lt;([a-z_0-9]+)&gt;(.*)$");
+  lastident::create("^(.*[^<>a-z_0-9])([a-z_0-9]+)([^<>a-z_0-9]*)$");
+
+#define BEGIN1 "[0-9]+(\\.[0-9]+)*(\\.|) "
+#define BEGIN2 "\t"
+#define BEGIN3 "  "
+#define LEND "[^\n]*"
+#define LINE "(" BEGIN1 LEND ")|(" BEGIN2 LEND ")|(" BEGIN3 LEND ")|()\n"
+
+  is_example::create("^(" LINE ")+$");
 
   write("Scanning links.\n");
   new_path=combine_path(getcwd(),argv[2]);
-- 
GitLab


From 24881c87dcc06400da17237007facbd581cbf995 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 24 Mar 1996 15:18:00 +0100
Subject: [PATCH 074/351] small fix

Rev: doc/manual/example1:1.2
---
 doc/manual/example1 | 1 -
 1 file changed, 1 deletion(-)

diff --git a/doc/manual/example1 b/doc/manual/example1
index 6384295490..df87470cfb 100644
--- a/doc/manual/example1
+++ b/doc/manual/example1
@@ -66,7 +66,6 @@
 	hello world
 	$ 
 
-
   NB. The hash bang (#!) must be absolutely first in the file, no empty
       lines or whitespaces can precede it for this to work. The file after
       the hash bang must also be the complete filename to the ulpc binary,
-- 
GitLab


From fb5c4fec1f415edf0cb4fd343e6134552b9d1038 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 24 Mar 1996 15:18:51 +0100
Subject: [PATCH 075/351] fixed small bug when garbage collecting

Rev: src/operators.c:1.6
---
 src/operators.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/operators.c b/src/operators.c
index fe9859685b..b280c5a9ef 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -382,13 +382,13 @@ void o_subtract()
   case T_STRING:
   {
     struct lpc_string *s,*ret;
-    sp--;
     s=make_shared_string("");
-    ret=string_replace(sp[-1].u.string,sp[0].u.string,s);
+    ret=string_replace(sp[-2].u.string,sp[-1].u.string,s);
+    free_string(sp[-2].u.string);
     free_string(sp[-1].u.string);
-    free_string(sp[0].u.string);
     free_string(s);
-    sp[-1].u.string=ret;
+    sp[-2].u.string=ret;
+    sp--;
     return;
   }
 
@@ -704,12 +704,12 @@ void o_multiply()
   case TWO_TYPES(T_ARRAY,T_STRING):
     {
       struct lpc_string *ret;
+      ret=implode(sp[-2].u.array,sp[-1].u.string);
+      free_string(sp[-1].u.string);
+      free_array(sp[-2].u.array);
+      sp[-2].type=T_STRING;
+      sp[-2].u.string=ret;
       sp--;
-      ret=implode(sp[-1].u.array,sp[0].u.string);
-      free_string(sp[0].u.string);
-      free_array(sp[-1].u.array);
-      sp[-1].type=T_STRING;
-      sp[-1].u.string=ret;
       return;
     }
 
@@ -779,12 +779,12 @@ void o_divide()
   case T_STRING:
   {
     struct array *ret;
-    sp--;
-    ret=explode(sp[-1].u.string,sp[0].u.string);
+    ret=explode(sp[-2].u.string,sp[-1].u.string);
+    free_string(sp[-2].u.string);
     free_string(sp[-1].u.string);
-    free_string(sp[0].u.string);
-    sp[-1].type=T_ARRAY;
-    sp[-1].u.array=ret;
+    sp[-2].type=T_ARRAY;
+    sp[-2].u.array=ret;
+    sp--;
     return;
   }
 
-- 
GitLab


From 2a129b32b237a4d9cbd927dfc4a5f8bfe0e7c889 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 24 Mar 1996 15:19:47 +0100
Subject: [PATCH 076/351] now resets all allocated arrays to zero

Rev: src/array.c:1.8
Rev: src/array.h:1.5
---
 src/array.c | 22 ++++++++--------------
 src/array.h |  5 +++--
 2 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/src/array.c b/src/array.c
index 2697bdeb8b..88237a175e 100644
--- a/src/array.c
+++ b/src/array.c
@@ -37,9 +37,10 @@ struct array empty_array=
  * NOTE: the new array have zero references
  */
 
-struct array *allocate_array_no_init(INT32 size,INT32 extra_space)
+struct array *low_allocate_array(INT32 size,INT32 extra_space)
 {
   struct array *v;
+  INT32 e;
 
   if(size == 0)
   {
@@ -67,21 +68,14 @@ struct array *allocate_array_no_init(INT32 size,INT32 extra_space)
   empty_array.next=v;
   v->next->prev=v;
 
-  return v;
-}
-
-struct array *allocate_array(INT32 size)
-{
-  INT32 e;
-  struct array *a;
-  a=allocate_array_no_init(size,0);
-  for(e=0;e<a->size;e++)
+  for(e=0;e<v->size;e++)
   {
-    ITEM(a)[e].type=T_INT;
-    ITEM(a)[e].subtype=NUMBER_NUMBER;
-    ITEM(a)[e].u.integer=0;
+    ITEM(v)[e].type=T_INT;
+    ITEM(v)[e].subtype=NUMBER_NUMBER;
+    ITEM(v)[e].u.integer=0;
   }
-  return a;
+
+  return v;
 }
 
 /*
diff --git a/src/array.h b/src/array.h
index 758fc6cbad..a0a058021f 100644
--- a/src/array.h
+++ b/src/array.h
@@ -47,6 +47,8 @@ struct array
 
 #define free_array(V) do{ struct array *v_=(V); if(!--v_->refs) really_free_array(v_); }while(0)
 
+#define allocate_array(X) low_allocate_array((X),0)
+#define allocate_array_no_init(X,Y) low_allocate_array((X),(Y))
 
 typedef int (*cmpfun)(struct svalue *,struct svalue *);
 typedef int (*short_cmpfun)(union anything *, union anything *);
@@ -54,8 +56,7 @@ typedef short_cmpfun (*cmpfun_getter)(TYPE_T);
 
 
 /* Prototypes begin here */
-struct array *allocate_array_no_init(INT32 size,INT32 extra_space);
-struct array *allocate_array(INT32 size);
+struct array *low_allocate_array(INT32 size,INT32 extra_space);
 void really_free_array(struct array *v);
 void array_index_no_free(struct svalue *s,struct array *v,INT32 index);
 void array_index(struct svalue *s,struct array *v,INT32 index);
-- 
GitLab


From 33f5467965b098f73b5dd34c35009e70cc123ce4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 24 Mar 1996 15:20:08 +0100
Subject: [PATCH 077/351] entry added

Rev: src/ChangeLog:1.24
---
 src/ChangeLog | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 1e6210ab4b..8faef889d6 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+Sat Mar 23 19:02:40 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
+
+	* array.c: arrays are always initalized to zero to avoid
+	  gc() blowups
+
 Fri Mar 22 21:57:43 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
 
 	* regexp.c: added + operator, and added support for 8-bit
-- 
GitLab


From 849d3324ba3c24f7fd55fb728ff8ded6ca20580d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 24 Mar 1996 21:03:28 +0100
Subject: [PATCH 078/351] draft for real tutorial

Rev: doc/manual/tutorial:1.1
---
 doc/manual/tutorial | 149 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 149 insertions(+)
 create mode 100644 doc/manual/tutorial

diff --git a/doc/manual/tutorial b/doc/manual/tutorial
new file mode 100644
index 0000000000..0a5014d718
--- /dev/null
+++ b/doc/manual/tutorial
@@ -0,0 +1,149 @@
+Contents
+
+BEGIN(What is uLPC)
+{
+  BEGIN(Introduction)
+  {
+    uLPC (Micro L.P.C., sometimes written ulpc or uLPC) is an interpreted,
+    object-oriented programming language for flexible and yet efficient
+    application development and prototyping. It features multiple
+    inheritance, data abstraction, advanced built-in datatypes, such as
+    associative arrays, dynamic arrays and multi-sets, and high-level
+    character string and array operations.
+  }
+
+  BEGIN(uLPC vs. C and C++)
+  {
+    uLPC syntax is very similar to C. Some things has also been borrowed
+    from C++. The certainly biggest differance is that uLPC is interpreted.
+    This gives uLPC some advantages, but also some disadvantages compared
+    to C:
+
+    LIST(Advantages:)
+    {
+      No compilation times
+      Powerful data types
+    }
+  }
+
+  BEGIN(Data types)
+  BEGIN(Object orientation)
+}
+
+BEGIN(Getting started)
+{
+  BEGIN(A short example)
+  {
+    LPC
+    {
+      #!/usr/local/bin/ulpc
+
+      int main()
+      {
+        write("hello world\n");
+      }
+    }
+
+
+    Assume this file is called 'hello_world.lpc', then this might be seen
+    at your unix prompt:
+
+    PRE
+    {
+      $ ./hello_world.lpc
+      hello world
+      $ 
+    }
+  }
+
+  BEGIN(Line by line)
+  {
+    The first line is a unix-trick which causes /usr/local/bin/ulpc to run
+    the hello world program for you when you type it's name at the unix
+    prompt.
+
+    
+  }
+
+  BEGIN(variables)
+  BEGIN(loops)
+}
+
+BEGIN(Program structure)
+{
+  BEGIN(functions)
+  BEGIN(Loops)
+  {
+    BEGIN(while)
+    BEGIN(for)
+    BEGIN(do-while)
+    BEGIN(foreach)
+  }
+  BEGIN(Skips and Jumps)
+  {
+    BEGIN(if)
+    BEGIN(switch)
+    BEGIN(continue)
+    BEGIN(break)
+  }
+}
+
+BEGIN(objects and programs)
+{
+  BEGIN(variable spaces)
+
+  BEGIN(inheritance)
+  {
+    BEGIN(multiple inheritance)
+  }
+}
+
+
+BEGIN(data types)
+{
+  BEGIN(int)
+  {
+    Ints, or <integers> are simple whole numbers 0, 1, 2 ... They are fast
+    and used for all arethmics where fractions of numbers aren't needed.
+  }
+  BEGIN(float)
+  {
+    Floats can be used to represent any number, not just whole numbers.
+    Floats are slower than integers and can not be used where a whole
+    number is expected. (When indexing an array for instance.) Floats
+    are commonly used for mathematical calulations such as averages and
+    trigonometrics.
+  }
+  BEGIN(string)
+  {
+    Strings hold text, or more precicely; sequences of 8-bit characters.
+    Strings can be manipulated in many ways, the simples of which is
+    <indexing>; picking out the ascii value of one of the characters in
+    the string.
+  }
+  BEGIN(array)
+  {
+    Arrays simply hold values.
+  }
+  BEGIN(mapping)
+  {
+    Mappings, or associative arrays, work similar to arrays, but can be
+    indexed on any type of value, not just integers.
+  }
+  BEGIN(list)
+  {
+    A list is essentially what mathematicians call a 'set'. It is a bunch
+    of values without any particular order. Arrays could replace lists
+    in all respects but one: lists are much faster.
+  }
+  BEGIN(object)
+  {
+    Objects hold data.
+  }
+  BEGIN(program)
+  {
+    Programs are the templates for objects.
+  }
+}
+
+
-- 
GitLab


From 98f332d3d65376a66427910618af386561ec31d7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 24 Mar 1996 21:03:58 +0100
Subject: [PATCH 079/351] new index page for the manual

Rev: doc/index.bmml:1.1
---
 doc/index.bmml | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)
 create mode 100644 doc/index.bmml

diff --git a/doc/index.bmml b/doc/index.bmml
new file mode 100644
index 0000000000..ce25fe83f5
--- /dev/null
+++ b/doc/index.bmml
@@ -0,0 +1,58 @@
+$version manual
+
+  This manual is far from complete, it still needs a lot of work to cover
+  all the aspects required of a good manual. However, I hope that it is
+  still useful in it's present state.
+
+ getting started
+
+  For now this section is made up of example code with line by line
+  explanations. If there is a word you don't understand I suggest you
+  look it up in the index first time you encouter it because it might
+  be essential to understanding that piece of code.
+
+	KEYWORD_INDEX examples
+
+ Control structures
+
+  Control structures groups code into blocks and they control the order in
+  which statements are executed. Control structures in uLPC are basically
+  the same as those in C, with a few exceptions.
+
+	KEYWORD_INDEX control_structures
+
+ Types
+
+  uLPC types are part of what makes uLPC a powerful language. They make
+  it easy to handle data without worrying about memory management and
+  other programming obstacles.
+
+	KEYWORD_INDEX types
+
+ uLPC and object orientation
+
+  This section is about the more fundamental workings of uLPC, such as
+  how uLPC compiles code and object orientation.
+
+	KEYWORD_INDEX lpc
+
+ Operators
+
+  uLPC operators behave much like the onces in C, but have many many additional
+  features. Most of this added functionality is related to the new data types.
+
+	KEYWORD_INDEX operators
+
+ Keyword index
+
+  The rest of the written documentation is gathered here, without much
+  thought about order. Hopefully you should be able to use this section
+  anyway once you've looked at the sections above.
+
+	KEYWORD_INDEX file
+
+	KEYWORD_INDEX programs
+
+	KEYWORD_INDEX efuns
+
+	KEYWORD_INDEX other
-- 
GitLab


From f5c90a728f5f277863ab1a0fac4489f0b178779a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 24 Mar 1996 21:04:39 +0100
Subject: [PATCH 080/351] new index handling using bmml files

Rev: bin/htmlify_docs.lpc:1.4
---
 bin/htmlify_docs.lpc | 248 +++++++++++++++++++++++++++++--------------
 1 file changed, 169 insertions(+), 79 deletions(-)

diff --git a/bin/htmlify_docs.lpc b/bin/htmlify_docs.lpc
index 837f9fb302..1671350ce0 100644
--- a/bin/htmlify_docs.lpc
+++ b/bin/htmlify_docs.lpc
@@ -46,6 +46,7 @@ string fippel_path(string path)
 {
   sscanf(path,"./%s",path);
   path=replace(path,"/","_");
+  if(path[strlen(path)-5..]==".bmml") path=path[..strlen(path)-6];
   if(path[strlen(path)-5..]!=".html") path+=".html";
 
   return path;
@@ -210,7 +211,7 @@ string syntax_magic(string s)
 
 string html_quote(string s)
 {
-  return replace(s,({"&","<",">"}),({"&amp;","&lt;","&gt;"}));
+  return replace(s,({"uLPC","&","<",">"}),({"�LPC","&amp;","&lt;","&gt;"}));
 }
 
 string html_unquote(string s)
@@ -232,6 +233,83 @@ string mkdocument(string s,string title)
 
 inherit "/precompiled/regexp":is_example;
 
+list(string) indexes_done=(<>);
+string mkindex(string topic, int head)
+{
+  string head;
+  string a,ret;
+  ret="";
+
+  indexes_done[topic]=1;
+
+  switch(topic)
+  {
+  case "programs":
+    head="<b>Builtin programs:</b>\n";
+    ret="<ul>\n";
+    foreach(sort_array(m_indices(pages)),a)
+    {
+      if(-1 == search(a,"/")) continue;
+      
+      ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
+    }
+    
+    ret+="</ul>\n";
+    break;
+    
+  case "other":
+    head="<b>Other pages</b>\n";
+    ret="<ul>\n";
+    foreach(sort_array(m_indices(pages) - `+(@m_values(keywords))),a)
+    {
+      if(-1 != search(a,"/")) continue;
+      ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
+    }
+    ret+="</ul>\n";
+    break;
+    
+  case "efuns":
+    head="<b>All builtin functions:</b>\n";
+    ret="<ul>\n";
+    foreach(sort_array(m_indices(all_efuns())),a)
+    {
+      a=html_quote(a);
+      if(pages[a])
+      {
+	ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
+      }else{
+	perror("Warning: no page for function: "+a+".\n");
+      }
+    }
+    ret+="</ul>\n";
+    break;
+    
+  default:
+    if(!keywords[topic])
+    {
+      perror("Unknown keyword "+topic+".\n");
+      return "";
+    }
+
+    head="<a name="+topic+">";
+    head+="<b>"+capitalize(b)+"</a>";
+    head+=short(b);
+    head+="</b>\n";
+    ret="<ul>\n";
+    foreach(keywords[b],a)
+    {
+      a=html_quote(a);
+      ret+="<li><a href="+pages[a]+">"+a+"</a>"+ short(a) +"\n";
+    }
+    ret+="</ul></a>\n";
+    break;
+  }
+
+  if(head) ret=head+ret;
+
+  return ret;
+}
+
 /* Convert a page */
 string convert_page(string path, string fname)
 {
@@ -263,6 +341,7 @@ string convert_page(string path, string fname)
 
       sections=explode(part,"\n\n");
       
+      /* Merge sections that does not have a header together */
       for(section=0;section<sizeof(sections);section++)
       {
 	if(!strlen(sections[section]) ||
@@ -345,6 +424,11 @@ string convert_page(string path, string fname)
 	case "DIRECTIVE":
 	case "PREPROCESSOR DIRECTIVES":
 	  rest="<tt>"+magic(rest,1)+"</tt>";
+
+	case "RELATED FUNCTIONS":
+	  a=name;
+	  sscanf(rest,"%*skeyword %[a-z/A-Z0-9]",a);
+	  rest=mkindex(a, 0);
 	}
 
 	sections[headno]="<dt>"+
@@ -361,6 +445,57 @@ string convert_page(string path, string fname)
     }
     output=mkdocument(implode(parts,"<hr noshade size=1>\n"),"uLPC: "+name);
   }
+  else if(path[strlen(path)-5..]==".bmml")
+  {
+    string *sections;
+    string title;
+    int section;
+
+    cont=replace(cont,"$version",version());
+    cont=html_quote(cont);
+    sections=explode(cont,"\n\n");
+    
+    for(section=0;section<sizeof(sections);section++)
+    {
+      string tmp,pre,a;
+      tmp=sections[section];
+      sscanf(tmp,"%[\t ]",per);
+      
+      switch(space)
+      {
+      case "":
+	tmp="<h1><center>"+tmp+"</center></h1>";
+	title=tmp;
+	break;
+	
+      case " ":
+	sscanf(tmp," %s",tmp);
+	tmp="<h2>"+tmp+"</h2>";
+	break;
+	
+      case "  ":
+	sscanf(tmp,"  %s",tmp);
+	tmp=replace(tmp,"\n  ","\n");
+	tmp=more_magic(tmp);
+	break;
+	
+      case "\t":
+	sscanf(tmp,"\t%s %s",pre, a);
+	switch(pre)
+	{
+	case "KEYWORD_INDEX":
+	  tmp=mkindex(a, 1);
+
+	default:
+	  perror("Unknown directive: "+pre+".\n");
+	}
+
+      }
+    }
+    cont=implode(sections,"\n<p>\n");
+
+    return mkdocument(cont, title || "uLPC manual");
+  }
   else if(path[strlen(path)-5..]==".html")
   {
     if(sscanf(cont,"<title>%s</title>",part))
@@ -415,12 +550,31 @@ string convert_page(string path, string fname)
 }
 
 
+string short(string s)
+{
+  return short_descs[s] ? " - "+short_descs[s] : "";
+}
+
+string convert_dot_bmml(string path, string fname)
+{
+  string output;
+  
+  output="";
+  
+  if(path[strlen(path)-5..]==".bmml")
+  {
+  }
+  return 0;
+}
+
+int writepages;
+
 void scanfiles(string path, string fname)
 {
   string nf,np;
-  nf=convert_page(path, fname);
+  nf=convert(path, fname);
 
-  if(nf && strlen(nf))
+  if(nf && strlen(nf) && writepages)
   {
     np=combine_path(new_path,fippel_path(path));
 //    write("Writing "+np+".\n");
@@ -499,7 +653,7 @@ void scanlinks(string path, string fname)
 void traversedir(string path,function fun)
 {
   string file;
-  foreach(get_dir(path) - ({"CVS","RCS"}),file)
+  foreach(get_dir(path) - ({"CVS","RCS",".cvsignore"}),file)
   {
     string tmp;
     if(file[-1]=='~') continue;
@@ -517,75 +671,6 @@ void traversedir(string path,function fun)
   }
 }
 
-string short(string s)
-{
-  return short_descs[s] ? " - "+short_descs[s] : "";
-}
-/** Create an index for our newly created stuff **/
-string mkindex()
-{
-  string ret;
-  string a,b;
-  mapping tmp=pages+([]);
-
-  ret="";
-
-  ret+="<H1>"+version()+" index</h1>\n";
-  
-  ret+="<H2><b>Keyword lists</b></H2>\n<dl>\n";
-  foreach(sort_array(m_indices(keywords)),b)
-  {
-    ret+="<a name="+b+">";
-    ret+="<dt><h2>"+capitalize(b);
-    ret+=short(b);
-    ret+="</h2><dd>\n";
-    ret+="<ul>\n";
-    foreach(keywords[b],a)
-    {
-      a=html_quote(a);
-      ret+="<li><a href="+pages[a]+">"+a+"</a>"+ short(a) +"\n";
-      m_delete(tmp,a);
-    }
-    ret+="</ul></a>\n";
-  }
-  ret+="</dl>\n";
-
-  ret+="<H1>All builtin functions:</H1>\n<ul>\n";
-  
-  foreach(sort_array(m_indices(all_efuns())),a)
-  {
-    a=html_quote(a);
-    if(pages[a])
-    {
-      ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
-    }else{
-      perror("Warning: no page for function: "+a+".\n");
-    }
-    m_delete(tmp,a);
-  }
-  ret+="</ul>\n";
-
-  ret+="</dl><H1>Builtin programs:</H1>\n<ul>\n";
-  foreach(sort_array(m_indices(tmp)),a)
-  {
-    if(-1 == search(a,"/")) continue;
-
-    ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
-    m_delete(tmp,a);
-  }
-  
-  ret+="</ul>\n";
-
-  ret+="<H1>Other pages</H1>\n<ul>\n";
-  foreach(sort_array(m_indices(tmp)),a)
-  {
-    ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
-  }
-  
-  ret+="</ul>\n";
-  return mkdocument(ret,"uLPC documentation index");
-}
-
 int main(int argc, string *argv)
 {
   string np;
@@ -605,12 +690,17 @@ int main(int argc, string *argv)
   new_path=combine_path(getcwd(),argv[2]);
   cd(argv[1]);
   traversedir(".",scanlinks);
-  write("Processing pages.\n");
+
+  write("Scanning pages.\n");
+  writepages=0;
+  traversedir(".",scanfiles);
+
+  write("Writing html.\n");
+  writepages=0;
   traversedir(".",scanfiles);
 
-  write("Making index.\n");
-  np=combine_path(new_path,"index.html");
-  if(file_size(np)>=0)
-    rm(np);
-  write_file(np,mkindex());
+  foreach(indices(keywords) - indices(indexes_done),np)
+  {
+    perror("Keywords never indexed: "+np+"\n");
+  }
 }
-- 
GitLab


From b35679468d428489e55ac05930ebacbbe4d847fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 24 Mar 1996 21:05:23 +0100
Subject: [PATCH 081/351] range manual page

Rev: doc/operators/range:1.1
---
 doc/operators/range | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 doc/operators/range

diff --git a/doc/operators/range b/doc/operators/range
new file mode 100644
index 0000000000..97e6922cfb
--- /dev/null
+++ b/doc/operators/range
@@ -0,0 +1,30 @@
+NAME
+	range - cut a slice of an array or string
+
+SYNTAX
+	a [ b .. c ]
+	or
+	a [ .. c ]
+	or
+	a [ b .. ]
+
+DESCRIPTION
+	This operator cuts out a piece of an array or string. If a is an array
+	a[b..c] will return an array containing a[b], a[b+1], a[b+2] to a[c].
+	Given a string about the same thing will happen, except the the result
+	will be a string of course. If b is omitted, everything from the
+	beginning up to and including c will be included. If c is omitted
+	the result will include everything from (and including) b to the end.
+
+EXAMPLES
+	"foobar"[0..3]	returns "foo"
+	"foobar"[4..6]	returns "bar"
+	({1,2,3})[..2]	returns ({1,2})
+	({1,2,3})[2..]	returns ({2,3})
+	({1,2,3})[..]	returns ({1,2,3})
+
+KEYWORDS
+	operators
+
+SEE ALSO
+	index
-- 
GitLab


From 8e20469a51da8fa08568ac073385a65b4e56e58f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 28 Mar 1996 22:32:34 +0100
Subject: [PATCH 082/351] not yet finished

Rev: bin/htmlify_docs.lpc:1.5
---
 bin/htmlify_docs.lpc | 163 ++++++++++++++++++-------------------------
 1 file changed, 69 insertions(+), 94 deletions(-)

diff --git a/bin/htmlify_docs.lpc b/bin/htmlify_docs.lpc
index 1671350ce0..dd5db67656 100644
--- a/bin/htmlify_docs.lpc
+++ b/bin/htmlify_docs.lpc
@@ -231,6 +231,12 @@ string mkdocument(string s,string title)
 	  "</html>");
 }
 
+string short(string s)
+{
+  return short_descs[s] ? " - "+short_descs[s] : "";
+}
+
+
 inherit "/precompiled/regexp":is_example;
 
 list(string) indexes_done=(<>);
@@ -292,11 +298,11 @@ string mkindex(string topic, int head)
     }
 
     head="<a name="+topic+">";
-    head+="<b>"+capitalize(b)+"</a>";
-    head+=short(b);
+    head+="<b>"+capitalize(topic)+"</a>";
+    head+=short(topic);
     head+="</b>\n";
     ret="<ul>\n";
-    foreach(keywords[b],a)
+    foreach(keywords[topic],a)
     {
       a=html_quote(a);
       ret+="<li><a href="+pages[a]+">"+a+"</a>"+ short(a) +"\n";
@@ -310,6 +316,8 @@ string mkindex(string topic, int head)
   return ret;
 }
 
+int writepages;
+
 /* Convert a page */
 string convert_page(string path, string fname)
 {
@@ -321,12 +329,17 @@ string convert_page(string path, string fname)
 
   cont=read_bytes(path);
 
+//  perror("foo: "+path[strlen(path)-5..]+".\n");
   if(sscanf(cont,"NAME\n\t%s - %s\n",name,short))
   {
     int partno;
 
     cont=html_quote(cont);
+    path=fippel_path(path);
+
     short_descs[html_quote(name)]=short;
+    pages[html_quote(name)]=path;
+
 
     string *parts=explode(cont,"============================================================================\n");
     for(partno=0;partno<sizeof(parts);partno++)
@@ -367,6 +380,11 @@ string convert_page(string path, string fname)
 	    perror("Warning NAME section broken!\n");
 	  rest="\t<tt>"+part_name+"</tt> - "+b;
 
+	  if(partno)
+	  {
+	    subpages[fname+"-&gt;"+part_name]=path+"#"+part_name;
+	  }
+
 	case "DESCRIPTION":
 	case "NOTA BENE":
 	case "BUGS":
@@ -407,6 +425,7 @@ string convert_page(string path, string fname)
 	    }else if(subpages[fname+"-&gt;"+a]){
 	      b+=({ "<a href="+subpages[name+"-&gt;"+a]+">" + a + "</a>" });
 	    }else{
+	      if(writepages)
 	      perror("Warning, unlinked SEE ALSO: "+a+"\n");
 	      b+=({ tmp });
 	    }
@@ -424,6 +443,7 @@ string convert_page(string path, string fname)
 	case "DIRECTIVE":
 	case "PREPROCESSOR DIRECTIVES":
 	  rest="<tt>"+magic(rest,1)+"</tt>";
+	  break;
 
 	case "RELATED FUNCTIONS":
 	  a=name;
@@ -451,6 +471,8 @@ string convert_page(string path, string fname)
     string title;
     int section;
 
+    pages[(path[..strlen(path)-6]/"/")[-1]]=fippel_path(path);
+
     cont=replace(cont,"$version",version());
     cont=html_quote(cont);
     sections=explode(cont,"\n\n");
@@ -459,9 +481,9 @@ string convert_page(string path, string fname)
     {
       string tmp,pre,a;
       tmp=sections[section];
-      sscanf(tmp,"%[\t ]",per);
+      sscanf(tmp,"%[\t ]",pre);
       
-      switch(space)
+      switch(pre)
       {
       case "":
 	tmp="<h1><center>"+tmp+"</center></h1>";
@@ -476,7 +498,7 @@ string convert_page(string path, string fname)
       case "  ":
 	sscanf(tmp,"  %s",tmp);
 	tmp=replace(tmp,"\n  ","\n");
-	tmp=more_magic(tmp);
+	tmp=more_magic(tmp,0);
 	break;
 	
       case "\t":
@@ -484,7 +506,9 @@ string convert_page(string path, string fname)
 	switch(pre)
 	{
 	case "KEYWORD_INDEX":
+	  sscanf(a,"%s\n",a);
 	  tmp=mkindex(a, 1);
+	  break;
 
 	default:
 	  perror("Unknown directive: "+pre+".\n");
@@ -498,6 +522,8 @@ string convert_page(string path, string fname)
   }
   else if(path[strlen(path)-5..]==".html")
   {
+    pages[(path[..strlen(path)-6]/"/")[-1]]=fippel_path(path);
+
     if(sscanf(cont,"<title>%s</title>",part))
       short_descs[(path/"/")[-1]]=part;
     output=cont;
@@ -508,6 +534,8 @@ string convert_page(string path, string fname)
     string line,tmp;
     int pre,p;
 
+    pages[(path/"/")[-1]]=fippel_path(path);
+
     if(sscanf(cont,"%*[0-9.] %s\n",part)==2)
       short_descs[(path/"/")[-1]]=part;
 
@@ -546,33 +574,47 @@ string convert_page(string path, string fname)
     output=mkdocument(output,"uLPC: "+
 		      replace(explode(fname,"/")[-1],"_"," "));
   }
-  return output;
-}
-
-
-string short(string s)
-{
-  return short_descs[s] ? " - "+short_descs[s] : "";
-}
-
-string convert_dot_bmml(string path, string fname)
-{
-  string output;
-  
-  output="";
-  
-  if(path[strlen(path)-5..]==".bmml")
+  else
   {
+    if(writepages)
+    {
+      string tmp;
+      int l, i;
+      
+      foreach(cont/"\n", tmp)
+      {
+	if(is_example::match(tmp+"\n"))
+	{
+	  l++;
+	}else{
+	  i++;
+	}
+      }
+      
+      if(l > i*2)
+      {
+	l=0;
+	foreach(cont/"\n", tmp)
+	{
+	  l++;
+	  if(!is_example::match(tmp+"\n"))
+	  {
+	    perror(path+":"+l+": not on example form.\n");
+	  }
+	}
+      }
+      perror("Warning: not converting "+path+".\n");
+    }
+    output="";
   }
-  return 0;
+  return output;
 }
 
-int writepages;
 
 void scanfiles(string path, string fname)
 {
   string nf,np;
-  nf=convert(path, fname);
+  nf=convert_page(path, fname);
 
   if(nf && strlen(nf) && writepages)
   {
@@ -584,71 +626,6 @@ void scanfiles(string path, string fname)
   }
 }
 
-/*
- * Pre-read all files and sort out where to link it to
- */
-void scanlinks(string path, string fname)
-{
-  string cont,name;
-  cont=read_bytes(path);
-  cont=html_quote(cont);
-
-  if(sscanf(cont,"NAME\n\t%s -",name))
-  {
-    path=fippel_path(path);
-    pages[name]=path;
-
-    int e;
-    string *parts=explode(cont,"============================================================================\n");
-    for(e=1;e<sizeof(parts);e++)
-    {
-      string part_name;
-      if(sscanf(parts[e],"NAME\n\t%s -",part_name))
-      {
-	subpages[fname+"-&gt;"+part_name]=path+"#"+part_name;
-      }
-    }
-  }
-  else if(path[strlen(path)-5..]==".html")
-  {
-    pages[(path[..strlen(path)-6]/"/")[-1]]=fippel_path(path);
-  }
-  else if(is_example::match(cont))
-  {
-    pages[(path/"/")[-1]]=fippel_path(path);
-  }
-  else
-  {
-    string tmp;
-    int l, i;
-
-    foreach(cont/"\n", tmp)
-    {
-      if(is_example::match(tmp+"\n"))
-      {
-	l++;
-      }else{
-	i++;
-      }
-    }
-
-    if(l > i*2)
-    {
-      l=0;
-      foreach(cont/"\n", tmp)
-      {
-	l++;
-	if(!is_example::match(tmp+"\n"))
-	{
-	  perror(path+":"+l+": not on example form.\n");
-	}
-      }
-    }
-    perror("Warning: not converting "+path+".\n");
-  }
-}
-
-
 /** Traverse directory **/
 void traversedir(string path,function fun)
 {
@@ -686,16 +663,14 @@ int main(int argc, string *argv)
 
   is_example::create("^(" LINE ")+$");
 
-  write("Scanning links.\n");
   new_path=combine_path(getcwd(),argv[2]);
   cd(argv[1]);
-  traversedir(".",scanlinks);
 
-  write("Scanning pages.\n");
+  write("Scanning pages for links and keywords.\n");
   writepages=0;
   traversedir(".",scanfiles);
 
-  write("Writing html.\n");
+  write("Writing html files.\n");
   writepages=0;
   traversedir(".",scanfiles);
 
-- 
GitLab


From c94c37ca405654c667395ccd4f30008bc38aeb17 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 28 Mar 1996 22:33:36 +0100
Subject: [PATCH 083/351] garbage collect rewritten

Rev: src/array.c:1.9
Rev: src/array.h:1.6
Rev: src/gc.c:1.2
Rev: src/gc.h:1.2
Rev: src/list.c:1.3
Rev: src/list.h:1.2
Rev: src/mapping.c:1.4
Rev: src/mapping.h:1.3
Rev: src/object.c:1.8
Rev: src/object.h:1.5
Rev: src/program.c:1.8
Rev: src/program.h:1.4
Rev: src/svalue.c:1.8
---
 src/array.c   |  81 ++++++++++-----------
 src/array.h   |   8 ++-
 src/gc.c      | 193 ++++++++++++++++++++++++++++++++++++++++++++++----
 src/gc.h      |   9 ++-
 src/list.c    |  51 ++++++++++++-
 src/list.h    |   4 ++
 src/mapping.c |  60 +++++++++++++++-
 src/mapping.h |   4 ++
 src/object.c  |  98 ++++++++++++++++---------
 src/object.h  |   7 +-
 src/program.c |  45 ++++++------
 src/program.h |   6 +-
 src/svalue.c  |  81 ++++++++++++++++-----
 13 files changed, 501 insertions(+), 146 deletions(-)

diff --git a/src/array.c b/src/array.c
index 88237a175e..b5dc886fb8 100644
--- a/src/array.c
+++ b/src/array.c
@@ -27,7 +27,6 @@ struct array empty_array=
   0,                     /* malloced Size = 0 */
   0,                     /* no types */
   T_MIXED,                 /* mixed array */
-  0,                     /* no flags */
 };
 
 
@@ -61,7 +60,6 @@ struct array *low_allocate_array(INT32 size,INT32 extra_space)
 
   v->malloced_size=size+extra_space;
   v->size=size;
-  v->flags=0;
   v->refs=1;
   v->prev=&empty_array;
   v->next=empty_array.next;
@@ -1286,69 +1284,64 @@ void check_all_arrays()
 
 #ifdef GC2
 
-void gc_check_array(struct array *a)
+void gc_mark_array_as_referenced(struct array *a)
 {
-  if(a == gc_ptr) gc_refs++;
-  if(a->flags & GC_MARK) return;
-  a->flags |= GC_MARK;
-  if(!(a->type_field & BIT_COMPLEX)) return;
-  gc_check_svalues(ITEM(a), a->size);
+  if(gc_mark(a))
+    if(a->type_field & BIT_COMPLEX)
+      gc_mark_svalues(ITEM(a), a->size);
 }
 
-
 void gc_check_all_arrays()
 {
-  struct array *a,*n;
-
+  struct array *a;
   a=&empty_array;
   do
   {
-    if(!(a->flags & GC_MARK) && a->type_field & BIT_COMPLEX)
-    {
-      gc_ptr=a;
-      gc_refs=0;
-      
-      gc_check_array(a);
-      
-      a->refs++;
-      
-      if(gc_refs == a->refs)
-      {
-	/* This structure contains as many references to itself as
-	 * it has referenes, which means that it is circular and
-	 * should be destroyed, so please go away.
-	 */
-	
-	free_svalues(ITEM(a), a->size, a->type_field);
-	
-	a->size=0;
-	
-      }
-      
-      if(!(n=a->next))
-	fatal("Null pointer in array list.\n");
-      
-      free_array(a);
-      a=n;
-    }else{
-      a=a->next;
-    }
+    if(a->type_field & BIT_COMPLEX)
+      gc_check_svalues(ITEM(a), a->size);
+
+    a=a->next;
   } while (a != & empty_array);
 }
 
-void gc_clear_array_marks()
+
+void gc_mark_all_arrays()
 {
   struct array *a;
 
   a=&empty_array;
   do
   {
-    a->flags &=~ GC_MARK;
+    if(gc_is_referenced(a))
+      gc_mark_array_as_referenced(a);
+            
     a=a->next;
-
   } while (a != & empty_array);
 }
 
+void gc_free_all_unreferenced_arrays()
+{
+  struct array *a,*next;
+
+  a=&empty_array;
+  do
+  {
+    if(gc_do_free(a))
+    {
+      a->refs++;
+      free_svalues(ITEM(a), a->size, a->type_field);
+      a->size=0;
+
+      if(!(next=a->next))
+	fatal("Null pointer in array list.\n");
+
+      free_array(a);
+      a=next;
+    }else{
+      a=a->next;
+    }
+  } while (a != & empty_array);
+}
 
 
 #endif /* GC2 */
diff --git a/src/array.h b/src/array.h
index a0a058021f..526120e763 100644
--- a/src/array.h
+++ b/src/array.h
@@ -20,11 +20,12 @@ struct array
 			 * Bits can be set that don't exist in the array
 			 * though.
 			 */
-  INT16 flags;		/* flags, like gc_cycle */
   struct svalue item[1];
 };
 
 
+extern struct array empty_array;
+
 #define ITEM(X) ((X)->item)
 
 /* These are arguments for the function 'merge' which merges two sorted
@@ -120,9 +121,10 @@ void array_replace(struct array *a,
 		   struct svalue *to);
 void check_array(struct array *a);
 void check_all_arrays();
-void gc_check_array(struct array *a);
+void gc_mark_array_as_referenced(struct array *a);
 void gc_check_all_arrays();
-void gc_clear_array_marks();
+void gc_mark_all_arrays();
+void gc_free_all_unreferenced_arrays();
 /* Prototypes end here */
 
 
diff --git a/src/gc.c b/src/gc.c
index d4f1cf812d..4e86c01b2e 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -7,6 +7,13 @@
 #include "global.h"
 
 #ifdef GC2
+
+#include "array.h"
+#include "list.h"
+#include "mapping.h"
+#include "object.h"
+#include "program.h"
+
 #include "gc.h"
 #include "main.h"
 
@@ -17,10 +24,10 @@
 
 #define GC_CONST 20
 #define MIN_ALLOC_THRESHOLD 1000
+#defien MAX_ALLOC_THRESHOLD 10000000
 #define MULTIPLIER 0.9
+#define MARKER_CHUNK_SIZE 1023
 
-void *gc_ptr;
-INT32 gc_refs;
 INT32 num_objects;
 INT32 num_allocs;
 INT32 alloc_threshold = MIN_ALLOC_THRESHOLD;
@@ -28,10 +35,143 @@ INT32 alloc_threshold = MIN_ALLOC_THRESHOLD;
 static double objects_alloced;
 static double objects_freed;
 
+#define GC_REFERENCED 1
+
+struct marker
+{
+  struct marker *next;
+  void *marked;
+  INT32 refs;
+  INT32 flags;
+};
+
+struct marker_chunk
+{
+  struct marker_chunk *next;
+  struct marker markers[MARKER_CHUNK_SIZE];
+};
+
+static struct marker_chunk *chunk=0;
+static int markers_left_in_chunk=0;
+
+static struct marker *new_marker()
+{
+  if(!markers_left_in_chunk)
+  {
+    struct marker_chunk *m;
+    m=(struct marker_chunk *)xalloc(sizeof(struct marker_chunk));
+    m->next=chunk;
+    chunk=m;
+    markers_left_in_chunk=MARKER_CHUNK_SIZE;
+  }
+  markers_left_in_chunk--;
+
+  return chunk->markers + markers_left_in_chunk;
+}
+
+static struct marker **hash=0;
+static int hashsize=0;
+
+static struct marker *getmark(void *a)
+{
+  int hashval;
+  struct marker *m;
+
+  hashval=((long)a)%hashsize;
+
+  for(m=hash[hashval];m;m=m->next)
+    if(m->marked == a)
+      return m;
+
+  m=new_marker();
+  m->marked=a;
+  m->refs=0;
+  m->flags=0;
+  m->next=hash[hashval];
+  hash[hashval]=m;
+
+  return m;
+}
+
+void gc_check(void *a)
+{
+  getmark(a)->refs++;
+}
+
+int gc_is_referenced(void *a)
+{
+  struct marker *m;
+  m=getmark(a);
+#ifdef DEBUG
+  if(m->refs > *(INT32 *)a)
+    fatal("Ref counts are totally wrong!!!\n");
+#endif
+  return m->refs < *(INT32 *)a;
+}
+
+int gc_mark(void *a)
+{
+  struct marker *m;
+  m=getmark(a);
+
+  if(m->flags & GC_REFERENCED)
+  {
+    return 0;
+  }else{
+    m->flags |= GC_REFERENCED;
+    return 1;
+  }
+}
+
+int gc_do_free(void *a)
+{
+  struct marker *m;
+  m=getmark(a);
+  return !(m->flags & GC_REFERENCED);
+}
+
+/* Not all of these are primes, but they should be adequate */
+static INT32 hashprimes[] =
+{
+  31,        /* ~ 2^0  = 1 */
+  31,        /* ~ 2^1  = 2 */
+  31,        /* ~ 2^2  = 4 */
+  31,        /* ~ 2^3  = 8 */
+  31,        /* ~ 2^4  = 16 */
+  31,        /* ~ 2^5  = 32 */
+  61,        /* ~ 2^6  = 64 */
+  127,       /* ~ 2^7  = 128 */
+  251,       /* ~ 2^8  = 256 */
+  541,       /* ~ 2^9  = 512 */
+  1151,      /* ~ 2^10 = 1024 */
+  2111,      /* ~ 2^11 = 2048 */
+  4327,      /* ~ 2^12 = 4096 */
+  8803,      /* ~ 2^13 = 8192 */
+  17903,     /* ~ 2^14 = 16384 */
+  32321,     /* ~ 2^15 = 32768 */
+  65599,     /* ~ 2^16 = 65536 */
+  133153,    /* ~ 2^17 = 131072 */
+  270001,    /* ~ 2^18 = 264144 */
+  547453,    /* ~ 2^19 = 524288 */
+  1109891,   /* ~ 2^20 = 1048576 */
+  2000143,   /* ~ 2^21 = 2097152 */
+  4561877,   /* ~ 2^22 = 4194304 */
+  9248339,   /* ~ 2^23 = 8388608 */
+  16777215,  /* ~ 2^24 = 16777216 */
+  33554431,  /* ~ 2^25 = 33554432 */
+  67108863,  /* ~ 2^26 = 67108864 */
+  134217727, /* ~ 2^27 = 134217728 */
+  268435455, /* ~ 2^28 = 268435456 */
+  536870911, /* ~ 2^29 = 536870912 */
+  1073741823,/* ~ 2^30 = 1073741824 */
+  2147483647,/* ~ 2^31 = 2147483648 */
+};
+
 void do_gc()
 {
   double tmp;
   INT32 tmp2;
+  struct marker_chunk *m;
 
   tmp2=num_objects;
 
@@ -45,14 +185,45 @@ void do_gc()
   
   objects_freed*=MULTIPLIER;
   objects_freed += (double) num_objects;
-  
-  gc_clear_array_marks();
-  gc_clear_object_marks();
-  gc_clear_program_marks();
+
+
+  /* init hash , hashsize will be a prime between num_objects/8 and
+   * num_objects/4, this will assure that no re-hashing is needed.
+   */
+  hashsize=my_log2(num_objects);
+  hashsize-=2;
+  if(hashsize<0) hashsize=0;
+  hashsize=hashprimes[hashsize];
+  hash=(struct marker **)xalloc(sizeof(struct marker **)*hashsize);
+  MEMSET((char *)hash,0,sizeof(struct marker **)*hashsize);
+  markers_left_in_chunk=0;
   
   gc_check_all_arrays();
+  gc_check_all_lists();
+  gc_check_all_mappings();
   gc_check_all_programs();
   gc_check_all_objects();
+
+  gc_mark_all_arrays();
+  gc_mark_all_lists();
+  gc_mark_all_mappings();
+  gc_mark_all_programs();
+  gc_mark_all_objects();
+
+  gc_free_all_unreferenced_arrays();
+  gc_free_all_unreferenced_lists();
+  gc_free_all_unreferenced_mappings();
+  gc_free_all_unreferenced_programs();
+  gc_free_all_unreferenced_objects();
+
+
+  /* Free hash table */
+  free((char *)hash);
+  while(m=chunk)
+  {
+    chunk=m->next;
+    free((char *)m);
+  }
   
   objects_freed -= (double) num_objects;
 
@@ -76,14 +247,6 @@ void do_gc()
 	    (long)(tmp2-num_objects),(long)tmp2);
 #endif
 }
-#endif
-
-
-
-
-
-
-
-
 
+#endif
 
diff --git a/src/gc.h b/src/gc.h
index 96746616ea..cffbd118c2 100644
--- a/src/gc.h
+++ b/src/gc.h
@@ -5,15 +5,12 @@
 
 #include "types.h"
 
-extern void *gc_ptr;
-extern INT32 gc_refs;
 extern INT32 num_objects;
 extern INT32 num_allocs;
 extern INT32 alloc_threshold;
 
 #define GC_ALLOC() do{ num_objects++; if(++num_allocs > alloc_threshold) do_gc(); } while(0);
 #define GC_FREE() num_objects--
-#define GC_MARK 1
 
 #else
 
@@ -24,6 +21,12 @@ extern INT32 alloc_threshold;
 #endif
 
 /* Prototypes begin here */
+struct marker;
+struct marker_chunk;
+void gc_check(void *a);
+int gc_is_referenced(void *a);
+int gc_mark(void *a);
+int gc_do_free(void *a);
 void do_gc();
 /* Prototypes end here */
 
diff --git a/src/list.c b/src/list.c
index c2a968482e..8975acc464 100644
--- a/src/list.c
+++ b/src/list.c
@@ -14,6 +14,7 @@
 #include "dynamic_buffer.h"
 #include "interpret.h"
 #include "builtin_efuns.h"
+#include "gc.h"
 
 struct list *first_list;
 
@@ -28,6 +29,7 @@ int list_member(struct list *l, struct svalue *ind)
 static struct list *allocate_list(struct array *ind)
 {
   struct list *l;
+  GC_ALLOC();
   l=ALLOC_STRUCT(list);
   l->next = first_list;
   l->prev = 0;
@@ -56,6 +58,7 @@ void really_free_list(struct list *l)
   if(first_list == l) first_list = 0;
 
   free((char *)l);
+  GC_FREE();
 }
 
 static void order_list(struct list *l)
@@ -247,7 +250,7 @@ struct list *copy_list_recursively(struct list *l,
     }
   }
 
-  ret=allocate_list(0);
+  ret=allocate_list( & empty_array );
   doing.pointer_b=(void *)ret;
 
   ret->ind=copy_array_recursively(l->ind,&doing);
@@ -256,3 +259,49 @@ struct list *copy_list_recursively(struct list *l,
 
   return ret;
 }
+
+
+#ifdef GC2
+
+void gc_mark_list_as_referenced(struct list *l)
+{
+  if(gc_mark(l))
+    gc_mark_array_as_referenced(l->ind);
+}
+
+void gc_check_all_lists()
+{
+  struct list *l;
+  for(l=first_list;l;l=l->next)
+    gc_check(l->ind);
+}
+
+void gc_mark_all_lists()
+{
+  struct list *l;
+  for(l=first_list;l;l=l->next)
+    if(gc_is_referenced(l))
+      gc_mark_list_as_referenced(l);
+}
+
+void gc_free_all_unreferenced_lists()
+{
+  struct list *l,*next;
+
+  for(l=first_list;l;l=next)
+  {
+    if(gc_do_free(l))
+    {
+      l->refs++;
+      free_svalues(ITEM(l->ind), l->ind->size, l->ind->type_field);
+      l->ind->size=0;
+      next=l->next;
+
+      free_list(l);
+    }else{
+      next=l->next;
+    }
+  }
+}
+
+#endif /* GC2 */
diff --git a/src/list.h b/src/list.h
index da66aaee93..e072f0af66 100644
--- a/src/list.h
+++ b/src/list.h
@@ -37,6 +37,10 @@ node * make_node_from_list(struct list *l);
 void f_aggregate_list(INT32 args);
 struct list *copy_list_recursively(struct list *l,
 				   struct processing *p);
+void gc_mark_list_as_referenced(struct list *l);
+void gc_check_all_lists();
+void gc_mark_all_lists();
+void gc_free_all_unreferenced_lists();
 /* Prototypes end here */
 
 #endif
diff --git a/src/mapping.c b/src/mapping.c
index b23d2bdff5..5f566a0cc8 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -14,6 +14,7 @@
 #include "memory.h"
 #include "dynamic_buffer.h"
 #include "interpret.h"
+#include "gc.h"
 
 struct mapping *first_mapping;
 
@@ -67,6 +68,7 @@ void mapping_index(struct svalue *dest,
 static struct mapping *allocate_mapping(struct array *ind, struct array *val)
 {
   struct mapping *m;
+  GC_ALLOC();
   m=ALLOC_STRUCT(mapping);
   m->next = first_mapping;
   m->prev = 0;
@@ -97,6 +99,8 @@ void really_free_mapping(struct mapping *m)
   if(first_mapping == m) first_mapping = 0;
 
   free((char *)m);
+
+  GC_FREE();
 }
 
 static void order_mapping(struct mapping *m)
@@ -369,7 +373,7 @@ struct mapping *copy_mapping_recursively(struct mapping *m,
     }
   }
 
-  ret=allocate_mapping(0,0);
+  ret=allocate_mapping(&empty_array, &empty_array);
   doing.pointer_b=(void *)ret;
 
   ret->ind=copy_array_recursively(m->ind,&doing);
@@ -436,3 +440,57 @@ void check_all_mappings()
     check_mapping(m);
 }
 #endif
+
+
+#ifdef GC2
+
+void gc_mark_mapping_as_referenced(struct mapping *m)
+{
+  if(gc_mark(m))
+  {
+    gc_mark_array_as_referenced(m->ind);
+    gc_mark_array_as_referenced(m->val);
+  }
+}
+
+void gc_check_all_mappings()
+{
+  struct mapping *m;
+  for(m=first_mapping;m;m=m->next)
+  {
+    gc_check(m->ind);
+    gc_check(m->val);
+  }
+}
+
+void gc_mark_all_mappings()
+{
+  struct mapping *m;
+  for(m=first_mapping;m;m=m->next)
+    if(gc_is_referenced(m))
+      gc_mark_mapping_as_referenced(m);
+}
+
+void gc_free_all_unreferenced_mappings()
+{
+  struct mapping *m,*next;
+
+  for(m=first_mapping;m;m=next)
+  {
+    if(gc_do_free(m))
+    {
+      m->refs++;
+      free_svalues(ITEM(m->ind), m->ind->size, m->ind->type_field);
+      free_svalues(ITEM(m->val), m->val->size, m->val->type_field);
+      m->ind->size=0;
+      m->val->size=0;
+      next=m->next;
+
+      free_mapping(m);
+    }else{
+      next=m->next;
+    }
+  }
+}
+
+#endif /* GC2 */
diff --git a/src/mapping.h b/src/mapping.h
index 8eb88ae873..8132d4cae5 100644
--- a/src/mapping.h
+++ b/src/mapping.h
@@ -55,5 +55,9 @@ void mapping_search_no_free(struct svalue *to,
 			    struct svalue *start);
 void check_mapping(struct mapping *m);
 void check_all_mappings();
+void gc_mark_mapping_as_referenced(struct mapping *m);
+void gc_check_all_mappings();
+void gc_mark_all_mappings();
+void gc_free_all_unreferenced_mappings();
 /* Prototypes end here */
 #endif
diff --git a/src/object.c b/src/object.c
index 86174658e9..e61c203dcd 100644
--- a/src/object.c
+++ b/src/object.c
@@ -644,45 +644,83 @@ struct array *object_values(struct object *o)
 
 void gc_check_object(struct object *o)
 {
-  INT32 e;
-  if(o == gc_ptr) gc_refs++;
-  if(o->flags & GC_MARK) return;
-  o->flags |= GC_MARK;
-
-  if(!o->prog) return;
+}
 
-  for(e=0;e<(int)o->prog->num_identifier_indexes;e++)
+void gc_mark_object_as_referenced(struct object *o)
+{
+  if(gc_mark(o))
   {
-    struct identifier *i;
-    
-    i=ID_FROM_INT(o->prog, e);
-
-    if(i->flags & IDENTIFIER_FUNCTION) continue;
-
-    if(i->run_time_type == T_MIXED)
+    if(o->prog)
     {
-      gc_check_svalues((struct svalue *)LOW_GET_GLOBAL(o,e,i),1);
-    }else{
-      gc_check_short_svalue((union anything *)LOW_GET_GLOBAL(o,e,i),
-			    i->run_time_type);
+      INT32 e;
+      
+      for(e=0;e<(int)o->prog->num_identifier_indexes;e++)
+      {
+	struct identifier *i;
+	
+	i=ID_FROM_INT(o->prog, e);
+	
+	if(i->flags & IDENTIFIER_FUNCTION) continue;
+	
+	if(i->run_time_type == T_MIXED)
+	{
+	  gc_mark_svalues((struct svalue *)LOW_GET_GLOBAL(o,e,i),1);
+	}else{
+	  gc_mark_short_svalue((union anything *)LOW_GET_GLOBAL(o,e,i),
+			       i->run_time_type);
+	}
+      }
     }
   }
 }
 
 void gc_check_all_objects()
 {
-  struct object *o, *next;
+  struct object *o;
+  for(o=first_object;o;o=o->next)
+  {
+    if(o->prog)
+    {
+      INT32 e;
+
+      for(e=0;e<(int)o->prog->num_identifier_indexes;e++)
+      {
+	struct identifier *i;
+	
+	i=ID_FROM_INT(o->prog, e);
+	
+	if(i->flags & IDENTIFIER_FUNCTION) continue;
+	
+	if(i->run_time_type == T_MIXED)
+	{
+	  gc_check_svalues((struct svalue *)LOW_GET_GLOBAL(o,e,i),1);
+	}else{
+	  gc_check_short_svalue((union anything *)LOW_GET_GLOBAL(o,e,i),
+				i->run_time_type);
+	}
+      }
+    }
+  }
+}
+
+void gc_mark_all_objects()
+{
+  struct object *o;
+  for(o=first_object;o;o=o->next)
+    if(gc_is_referenced(o))
+      gc_mark_object_as_referenced(o);
+}
+
+void gc_free_all_unreferenced_objects()
+{
+  struct object *o,*next;
+
   for(o=first_object;o;o=next)
   {
-    if(!(o->flags & GC_MARK))
+    if(gc_do_free(o))
     {
-      gc_ptr=o;
-      gc_refs=0;
-      
       o->refs++;
-      
-      if(gc_refs == o->refs) destruct(o);
-      
+      destruct(o);
       next=o->next;
       free_object(o);
     }else{
@@ -691,11 +729,5 @@ void gc_check_all_objects()
   }
 }
 
-void gc_clear_object_marks()
-{
-  struct object *o;
-
-  for(o=first_object;o;o=o->next) o->flags &=~ GC_MARK;
-}
-
 #endif /* GC2 */
+
diff --git a/src/object.h b/src/object.h
index 32608e56ed..e4bb8cd0dd 100644
--- a/src/object.h
+++ b/src/object.h
@@ -14,9 +14,6 @@
 struct object
 {
   INT32 refs;                    /* Reference count, must be first. */
-#ifdef GC2
-  INT16 flags;
-#endif
   struct program *prog;
   struct object *next;
   struct object *prev;
@@ -63,8 +60,10 @@ void cleanup_objects();
 struct array *object_indices(struct object *o);
 struct array *object_values(struct object *o);
 void gc_check_object(struct object *o);
+void gc_mark_object_as_referenced(struct object *o);
 void gc_check_all_objects();
-void gc_clear_object_marks();
+void gc_mark_all_objects();
+void gc_free_all_unreferenced_objects();
 /* Prototypes end here */
 
 #endif /* OBJECT_H */
diff --git a/src/program.c b/src/program.c
index 85de0f4f96..ec2f5f9442 100644
--- a/src/program.c
+++ b/src/program.c
@@ -1303,31 +1303,37 @@ void cleanup_program()
 
 #ifdef GC2
 
-void gc_check_program(struct program *p)
+void gc_mark_program_as_referenced(struct program *p)
 {
-  if(p==gc_ptr) gc_refs++;
-  if(p->flags & GC_MARK) return;
-  p->flags |= GC_MARK;
-  gc_check_svalues(p->constants, p->num_constants);
+  if(gc_mark(p))
+    gc_mark_svalues(p->constants, p->num_constants);
 }
 
 void gc_check_all_programs()
 {
-  struct program *p, *next;
+  struct program *p;
+  for(p=first_program;p;p=p->next)
+    gc_check_svalues(p->constants, p->num_constants);
+}
+
+void gc_mark_all_programs()
+{
+  struct program *p;
+  for(p=first_program;p;p=p->next)
+    if(gc_is_referenced(p))
+      gc_mark_program_as_referenced(p);
+}
+
+void gc_free_all_unreferenced_programs()
+{
+  struct program *p,*next;
+
   for(p=first_program;p;p=next)
   {
-    if(!(p->flags & GC_MARK))
+    if(gc_do_free(p))
     {
-      gc_ptr=p;
-      gc_refs=0;
-
-      gc_check_program(p);
-      
       p->refs++;
-      
-      if(gc_refs == p->refs)
-	free_svalues(p->constants, p->num_constants, -1);
-      
+      free_svalues(p->constants, p->num_constants, -1);
       next=p->next;
       free_program(p);
     }else{
@@ -1336,11 +1342,4 @@ void gc_check_all_programs()
   }
 }
 
-void gc_clear_program_marks()
-{
-  struct program *p;
-
-  for(p=first_program;p;p=p->next) p->flags &=~ GC_MARK;
-}
-
 #endif /* GC2 */
diff --git a/src/program.h b/src/program.h
index fe1c265aab..b8a8fed9fd 100644
--- a/src/program.h
+++ b/src/program.h
@@ -93,7 +93,6 @@ struct inherit
 struct program
 {
   INT32 refs;
-  INT32 flags;
   INT32 id;             /* used to identify program in caches */
   INT32 storage_needed; /* storage needed in the object struct */
 
@@ -182,9 +181,10 @@ struct program *end_c_program(char *name);
 void add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags);
 void check_all_programs();
 void cleanup_program();
-void gc_check_program(struct program *p);
+void gc_mark_program_as_referenced(struct program *p);
 void gc_check_all_programs();
-void gc_clear_program_marks();
+void gc_mark_all_programs();
+void gc_free_all_unreferenced_programs();
 /* Prototypes end here */
 
 
diff --git a/src/svalue.c b/src/svalue.c
index 6793c90527..58b8d82b81 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -641,23 +641,24 @@ void gc_check_svalues(struct svalue *s, int num)
   {
     switch(s->type)
     {
-    case T_ARRAY: gc_check_array(s->u.array); break;
-    case T_LIST:
-      gc_check_array(s->u.list->ind);
-      break;
-    case T_MAPPING:
-      gc_check_array(s->u.mapping->ind);
-      gc_check_array(s->u.mapping->val);
-      break;
+    case T_FUNCTION:
+      if(s->subtype == -1) break;
+
     case T_OBJECT:
       if(s->u.object->prog)
       {
-	gc_check_object(s->u.object);
+	gc_check(s->u.object);
       }else{
 	free_svalue(s);
       }
       break;
-    case T_PROGRAM: gc_check_program(s->u.program); break;
+
+    case T_PROGRAM:
+    case T_ARRAY:
+    case T_LIST:
+    case T_MAPPING:
+      gc_check(s->u.refs);
+      break;
     }
   }
 }
@@ -667,21 +668,69 @@ void gc_check_short_svalue(union anything *u, TYPE_T type)
   if(!u->refs) return;
   switch(type)
   {
-  case T_ARRAY: gc_check_array(u->array); break;
-  case T_LIST: gc_check_array(u->list->ind); break;
+  case T_OBJECT:
+    if(u->object->prog)
+    {
+      gc_check(u->object);
+    }else{
+      free_short_svalue(u,T_OBJECT);
+    }
+    break;
+
+  case T_ARRAY:
+  case T_LIST:
   case T_MAPPING:
-    gc_check_array(u->mapping->ind);
-    gc_check_array(u->mapping->val);
+  case T_PROGRAM:
+    gc_check(u->refs);
     break;
+  }
+}
+
+void gc_mark_svalues(struct svalue *s, int num)
+{
+  INT32 e;
+  for(e=0;e<num;e++,s++)
+  {
+    switch(s->type)
+    {
+    case T_ARRAY:   gc_mark_array_as_referenced(s->u.array);     break;
+    case T_LIST:    gc_mark_list_as_referenced(s->u.list);       break;
+    case T_MAPPING: gc_mark_mapping_as_referenced(s->u.mapping); break;
+    case T_PROGRAM: gc_mark_program_as_referenced(s->u.program); break;
+
+    case T_FUNCTION:
+      if(s->subtype == -1) break;
+
+    case T_OBJECT:
+      if(s->u.object->prog)
+      {
+	gc_mark_object_as_referenced(s->u.object);
+      }else{
+	free_svalue(s);
+      }
+      break;
+    }
+  }
+}
+
+void gc_mark_short_svalue(union anything *u, TYPE_T type)
+{
+  if(!u->refs) return;
+  switch(type)
+  {
+  case T_ARRAY:   gc_mark_array_as_referenced(u->array);     break;
+  case T_LIST:    gc_mark_list_as_referenced(u->list);       break;
+  case T_MAPPING: gc_mark_mapping_as_referenced(u->mapping); break;
+  case T_PROGRAM: gc_mark_program_as_referenced(u->program); break;
+
   case T_OBJECT:
     if(u->object->prog)
     {
-      gc_check_object(u->object);
+      gc_mark_object_as_referenced(u->object);
     }else{
       free_short_svalue(u,T_OBJECT);
     }
     break;
-  case T_PROGRAM: gc_check_program(u->program); break;
   }
 }
 #endif /* GC2 */
-- 
GitLab


From b95bef21286f5e56ec8a9559ab96cf7694287616 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 29 Mar 1996 23:32:03 +0100
Subject: [PATCH 084/351] various bugfixes

Rev: src/array.c:1.10
Rev: src/gc.c:1.3
Rev: src/las.c:1.6
Rev: src/operators.c:1.7
Rev: src/svalue.c:1.9
Rev: src/svalue.h:1.6
---
 src/array.c     |  2 +-
 src/gc.c        |  4 +++-
 src/las.c       |  3 +++
 src/operators.c |  4 ++--
 src/svalue.c    | 24 +++++++++++++++---------
 src/svalue.h    |  4 +++-
 6 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/src/array.c b/src/array.c
index b5dc886fb8..512914eb68 100644
--- a/src/array.c
+++ b/src/array.c
@@ -1298,7 +1298,7 @@ void gc_check_all_arrays()
   do
   {
     if(a->type_field & BIT_COMPLEX)
-      gc_check_svalues(ITEM(a), a->size);
+      a->type_field = gc_check_svalues(ITEM(a), a->size);
 
     a=a->next;
   } while (a != & empty_array);
diff --git a/src/gc.c b/src/gc.c
index 4e86c01b2e..e2ca81baa8 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -24,7 +24,7 @@
 
 #define GC_CONST 20
 #define MIN_ALLOC_THRESHOLD 1000
-#defien MAX_ALLOC_THRESHOLD 10000000
+#define MAX_ALLOC_THRESHOLD 10000000
 #define MULTIPLIER 0.9
 #define MARKER_CHUNK_SIZE 1023
 
@@ -239,6 +239,8 @@ void do_gc()
 
   if(alloc_threshold < MIN_ALLOC_THRESHOLD)
     alloc_threshold = MIN_ALLOC_THRESHOLD;
+  if(alloc_threshold > MAX_ALLOC_THRESHOLD)
+    alloc_threshold = MAX_ALLOC_THRESHOLD;
   num_allocs=0;
 
 #ifdef DEBUG
diff --git a/src/las.c b/src/las.c
index 4a34df8a89..81bbf3aa32 100644
--- a/src/las.c
+++ b/src/las.c
@@ -108,6 +108,9 @@ INT32 count_args(node *n)
     return tmp2;
   }
 
+  case F_PUSH_ARRAY:
+    return -1;
+
   default:
     if(n->type == void_type_string) return 0;
     return 1;
diff --git a/src/operators.c b/src/operators.c
index b280c5a9ef..60047105fb 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -1012,9 +1012,9 @@ void init_operators()
 
   add_efun2("`&",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_and);
 
-  add_efun2("`|",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_or);
+  add_efun2("`|",f_or,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_or);
 
-  add_efun2("`^",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_xor);
+  add_efun2("`^",f_xor,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_xor);
 
   add_efun2("`<<",f_lsh,"function(int,int:int)",0,0,generate_lsh);
   add_efun2("`>>",f_rsh,"function(int,int:int)",0,0,generate_rsh);
diff --git a/src/svalue.c b/src/svalue.c
index 58b8d82b81..3c75166201 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -149,24 +149,25 @@ void free_svalues(struct svalue *s,INT32 num, INT32 type_hint)
   case BIT_FLOAT | BIT_INT:
     return;
 
-#define DOTYPE(X,Y,Z) case X:while(--num>=0)if(s->u.refs--==0) Y(s->u.Z); return
-    DOTYPE(BIT_STRING, really_free_string, string);
-    DOTYPE(BIT_ARRAY, really_free_array, array);
-    DOTYPE(BIT_MAPPING, really_free_mapping, mapping);
-    DOTYPE(BIT_LIST, really_free_list, list);
-    DOTYPE(BIT_OBJECT, really_free_object, object);
-    DOTYPE(BIT_PROGRAM, really_free_program, program);
+#define DOTYPE(X,Y,Z) case X:while(--num>=0) { Y(s->u.Z); s++; }return
+    DOTYPE(BIT_STRING, free_string, string);
+    DOTYPE(BIT_ARRAY, free_array, array);
+    DOTYPE(BIT_MAPPING, free_mapping, mapping);
+    DOTYPE(BIT_LIST, free_list, list);
+    DOTYPE(BIT_OBJECT, free_object, object);
+    DOTYPE(BIT_PROGRAM, free_program, program);
 
   case BIT_FUNCTION:
     while(--num>=0)
     {
-      if(s->u.refs--==0)
+      if(s->u.refs[0]--==0)
       {
 	if(s->subtype == -1)
 	  really_free_callable(s->u.efun);
 	else
 	  really_free_object(s->u.object);
       }
+      s++;
     }
     return;
 
@@ -634,11 +635,14 @@ void check_svalue(struct svalue *s)
 #endif
 
 #ifdef GC2
-void gc_check_svalues(struct svalue *s, int num)
+TYPE_FIELD gc_check_svalues(struct svalue *s, int num)
 {
   INT32 e;
+  TYPE_FIELD f;
+  f=0;
   for(e=0;e<num;e++,s++)
   {
+    f|= 1 << s->type;
     switch(s->type)
     {
     case T_FUNCTION:
@@ -661,6 +665,8 @@ void gc_check_svalues(struct svalue *s, int num)
       break;
     }
   }
+
+  return f;
 }
 
 void gc_check_short_svalue(union anything *u, TYPE_T type)
diff --git a/src/svalue.h b/src/svalue.h
index 80bf0c88f6..0609503933 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -175,8 +175,10 @@ void copy_svalues_recursively_no_free(struct svalue *to,
 				      struct processing *p);
 void check_short_svalue(union anything *u,TYPE_T type);
 void check_svalue(struct svalue *s);
-void gc_check_svalues(struct svalue *s, int num);
+TYPE_FIELD gc_check_svalues(struct svalue *s, int num);
 void gc_check_short_svalue(union anything *u, TYPE_T type);
+void gc_mark_svalues(struct svalue *s, int num);
+void gc_mark_short_svalue(union anything *u, TYPE_T type);
 /* Prototypes end here */
 
 #endif
-- 
GitLab


From 06a71c51d5e97e2a2ded4f74f25733aa90e1fdd0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 29 Mar 1996 23:32:45 +0100
Subject: [PATCH 085/351] now works

Rev: bin/htmlify_docs.lpc:1.6
---
 bin/htmlify_docs.lpc | 70 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 57 insertions(+), 13 deletions(-)

diff --git a/bin/htmlify_docs.lpc b/bin/htmlify_docs.lpc
index dd5db67656..4fb63f0c94 100644
--- a/bin/htmlify_docs.lpc
+++ b/bin/htmlify_docs.lpc
@@ -10,6 +10,8 @@ mapping keywords = ([]);
 mapping subpages = ([]);
 
 string new_path;
+int writepages;
+
 
 /*
  * Implode an array of strings to an english 'list'
@@ -240,7 +242,7 @@ string short(string s)
 inherit "/precompiled/regexp":is_example;
 
 list(string) indexes_done=(<>);
-string mkindex(string topic, int head)
+string mkindex(string topic, int usehead)
 {
   string head;
   string a,ret;
@@ -250,12 +252,34 @@ string mkindex(string topic, int head)
 
   switch(topic)
   {
+  case "pages":
+    head="<b>All pages:</b>\n";
+    ret="<ul>\n";
+    foreach(sort_array(m_indices(pages)),a)
+      ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
+    
+    ret+="</ul>\n";
+    break;
+    
   case "programs":
     head="<b>Builtin programs:</b>\n";
     ret="<ul>\n";
     foreach(sort_array(m_indices(pages)),a)
     {
-      if(-1 == search(a,"/")) continue;
+      if(a[0]!='/') continue;
+      
+      ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
+    }
+    
+    ret+="</ul>\n";
+    break;
+
+  case "examples":
+    head="<b>examples:</b>\n";
+    ret="<ul>\n";
+    foreach(sort_array(m_indices(pages)),a)
+    {
+      if(search(a,"example")==-1) continue;
       
       ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
     }
@@ -266,9 +290,13 @@ string mkindex(string topic, int head)
   case "other":
     head="<b>Other pages</b>\n";
     ret="<ul>\n";
-    foreach(sort_array(m_indices(pages) - `+(@m_values(keywords))),a)
+    foreach(sort_array(m_indices(pages) -
+		       map_array(`|(@m_values(keywords)),html_quote) -
+		       map_array(m_indices(all_efuns()),html_quote)),a)
     {
-      if(-1 != search(a,"/")) continue;
+      if(a[0]=='/') continue;
+      if(a[0..4]=="index") continue;
+      if(search(a,"example")!=-1) continue;
       ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
     }
     ret+="</ul>\n";
@@ -284,7 +312,8 @@ string mkindex(string topic, int head)
       {
 	ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
       }else{
-	perror("Warning: no page for function: "+a+".\n");
+	if(writepages)
+	  perror("Warning: no page for function: "+a+".\n");
       }
     }
     ret+="</ul>\n";
@@ -302,7 +331,7 @@ string mkindex(string topic, int head)
     head+=short(topic);
     head+="</b>\n";
     ret="<ul>\n";
-    foreach(keywords[topic],a)
+    foreach(sort_array(keywords[topic]),a)
     {
       a=html_quote(a);
       ret+="<li><a href="+pages[a]+">"+a+"</a>"+ short(a) +"\n";
@@ -311,13 +340,11 @@ string mkindex(string topic, int head)
     break;
   }
 
-  if(head) ret=head+ret;
+  if(usehead) ret=head+ret;
 
   return ret;
 }
 
-int writepages;
-
 /* Convert a page */
 string convert_page(string path, string fname)
 {
@@ -402,7 +429,7 @@ string convert_page(string path, string fname)
 	  foreach(a,a)
 	  {
 	    // fixme!!
-	    keywords[a] = ( keywords[a] || ({}) ) + ({ name });
+	    keywords[a] = ( keywords[a] || ({}) ) | ({ name });
 	    b+=({ "<a href=index.html#"+a+">"+a+"</a>" });
 	  }
 	  rest=implode_nicely(b);
@@ -455,6 +482,12 @@ string convert_page(string path, string fname)
 	  smallcaps(type)+
 	    "<dd>\n"+rest+"\n<p>";
       }
+      if(keywords[part_name])
+      {
+	sections+=({"<dt>"+
+	  smallcaps("RELATED PAGES")+"\n"+
+	    mkindex(part_name,0)+"<p>"});
+      }
       parts[partno]="<dl>\n"+implode(sections,"\n")+"\n</dl>\n";
       if(part_name)
       {
@@ -479,15 +512,15 @@ string convert_page(string path, string fname)
     
     for(section=0;section<sizeof(sections);section++)
     {
-      string tmp,pre,a;
+      string tmp,pre,a,b;
       tmp=sections[section];
       sscanf(tmp,"%[\t ]",pre);
       
       switch(pre)
       {
       case "":
-	tmp="<h1><center>"+tmp+"</center></h1>";
 	title=tmp;
+	tmp="<h1><center>"+tmp+"</center></h1>";
 	break;
 	
       case " ":
@@ -510,11 +543,22 @@ string convert_page(string path, string fname)
 	  tmp=mkindex(a, 1);
 	  break;
 
+	case "KEYWORD_LIST":
+	  sscanf(a,"%s\n",a);
+	  tmp=mkindex(a, 0);
+	  break;
+
+	case "LINK":
+	  sscanf(a,"%s %s",a,b);
+	  tmp="<a href="+a+".html>"+b+"</a>";
+	  break;
+
 	default:
 	  perror("Unknown directive: "+pre+".\n");
 	}
 
       }
+      sections[section]=tmp;
     }
     cont=implode(sections,"\n<p>\n");
 
@@ -671,7 +715,7 @@ int main(int argc, string *argv)
   traversedir(".",scanfiles);
 
   write("Writing html files.\n");
-  writepages=0;
+  writepages=1;
   traversedir(".",scanfiles);
 
   foreach(indices(keywords) - indices(indexes_done),np)
-- 
GitLab


From 3cf7de67d636cf64282f50d07fb0dd34fd3c8ee2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 29 Mar 1996 23:33:22 +0100
Subject: [PATCH 086/351] new index pages

Rev: doc/lpc/all.bmml:1.1
Rev: doc/lpc/efuns.bmml:1.1
---
 doc/lpc/all.bmml   | 3 +++
 doc/lpc/efuns.bmml | 3 +++
 2 files changed, 6 insertions(+)
 create mode 100644 doc/lpc/all.bmml
 create mode 100644 doc/lpc/efuns.bmml

diff --git a/doc/lpc/all.bmml b/doc/lpc/all.bmml
new file mode 100644
index 0000000000..eba151eb17
--- /dev/null
+++ b/doc/lpc/all.bmml
@@ -0,0 +1,3 @@
+All uLPC manual pages:
+
+	KEYWORD_LIST pages
diff --git a/doc/lpc/efuns.bmml b/doc/lpc/efuns.bmml
new file mode 100644
index 0000000000..e035e385c9
--- /dev/null
+++ b/doc/lpc/efuns.bmml
@@ -0,0 +1,3 @@
+All builtin functions:
+
+	KEYWORD_INDEX efuns
-- 
GitLab


From 345039dc01af31a06019061209eb461bf625729c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 29 Mar 1996 23:33:54 +0100
Subject: [PATCH 087/351] index page improved

Rev: doc/index.bmml:1.2
---
 doc/index.bmml | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/doc/index.bmml b/doc/index.bmml
index ce25fe83f5..0135bc189c 100644
--- a/doc/index.bmml
+++ b/doc/index.bmml
@@ -4,14 +4,14 @@ $version manual
   all the aspects required of a good manual. However, I hope that it is
   still useful in it's present state.
 
- getting started
+ Getting started
 
   For now this section is made up of example code with line by line
   explanations. If there is a word you don't understand I suggest you
   look it up in the index first time you encouter it because it might
   be essential to understanding that piece of code.
 
-	KEYWORD_INDEX examples
+	KEYWORD_LIST examples
 
  Control structures
 
@@ -19,7 +19,7 @@ $version manual
   which statements are executed. Control structures in uLPC are basically
   the same as those in C, with a few exceptions.
 
-	KEYWORD_INDEX control_structures
+	KEYWORD_LIST control
 
  Types
 
@@ -27,21 +27,28 @@ $version manual
   it easy to handle data without worrying about memory management and
   other programming obstacles.
 
-	KEYWORD_INDEX types
+	KEYWORD_LIST types
 
  uLPC and object orientation
 
   This section is about the more fundamental workings of uLPC, such as
   how uLPC compiles code and object orientation.
 
-	KEYWORD_INDEX lpc
+	KEYWORD_LIST lpc
+
+ Builtin functions
+
+  uLPC has a wide range of builtin functions. Most of these are implemented
+  in C, but some are implemented in uLPC using the add_efun function.
+
+	LINK lpc_efuns Here's a list of all built-in functions.
 
  Operators
 
   uLPC operators behave much like the onces in C, but have many many additional
   features. Most of this added functionality is related to the new data types.
 
-	KEYWORD_INDEX operators
+	KEYWORD_LIST operators
 
  Keyword index
 
@@ -53,6 +60,6 @@ $version manual
 
 	KEYWORD_INDEX programs
 
-	KEYWORD_INDEX efuns
-
 	KEYWORD_INDEX other
+
+	LINK lpc_all Here's a list of all pages.
-- 
GitLab


From b50e38c31bfc80787e58cbe4f70186fd948a17f1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 30 Mar 1996 22:39:14 +0100
Subject: [PATCH 088/351] old files removed

Rev: doc/manual/i-overview.html:1.2(DEAD)
Rev: doc/manual/index.html:1.2(DEAD)
Rev: doc/manual/t-hello.html:1.2(DEAD)
---
 doc/manual/i-overview.html | 88 --------------------------------------
 doc/manual/index.html      | 75 --------------------------------
 doc/manual/t-hello.html    | 66 ----------------------------
 3 files changed, 229 deletions(-)
 delete mode 100644 doc/manual/i-overview.html
 delete mode 100644 doc/manual/index.html
 delete mode 100644 doc/manual/t-hello.html

diff --git a/doc/manual/i-overview.html b/doc/manual/i-overview.html
deleted file mode 100644
index 006c42110f..0000000000
--- a/doc/manual/i-overview.html
+++ /dev/null
@@ -1,88 +0,0 @@
-<h1>Design overview</h1>
-
-In this document, we will describe how �LPC works and why it was made that
-way. Examples in this chapgter will be in C because �LPC is written in C,
-so some knowledge of C syntax and semantics is required.
-
-<p>As mentioned earlier, �LPC is interpreted. To be more precise the �LPC
-interpreter compiles �LPC source into <b>byte-code</b>. <b>Byte-code</b> can
-be compared to machine language, which the �LPC interpreter will later
-execute. For instance, our simple "Hello world" program would roughly 
-compile to the following bytecode:
-
-<pre>
-	mark
-	push "Hello world\n"
-	write
-</pre>
-
-<p>For now we don't have to know how these instructions are stored,
-instead we will concentrate at what these instructions do. But first
-we have to know about the two stacks that �LPC uses. One is a stack of
-values each can hold an �LPC value of any type. You could say that it
-is an mixed * to use �LPC terminology. This stack hold local
-variables, function arguments and much more.  This stack will be
-refered to as the <b>value stack</b> so not to confuse it with the
-<b>marker stack</b>. The marker stack can only hold pointers to
-elements in the first stack and is used to remember the start of an
-argument list.
-
-<p>What <b>mark</b> does is that it pushes the number of elements on the
-value stack onto the marker stack. Then <b>push</b> will push the string
-"Hello world\n" onto the value stack. Then <b>write</b> will take the top
-value from the marker stack and the differance between this value and the
-number of values on the value stack will tell <b>write</b> how many
-arguments it has received. Write will then write the string to stdout and
-remove all it's arguments from the stack.
-
-<p>All functions in �LPC receives their arguments on the stack like this,
-builtin and user-defined.
-
-<h2>The value stack</h2>
-
-As mentioned the value stack is an array of elements that can hold any value.
-Each of these elements is a 'struct svalue' which looks like this:
-
-<pre>
-	struct svalue
-	{
-		short	type;
-		short	subtype;
-		union	anything;
-	};
-</pre>
-
-<p>The type is a number representing the type, defines like T_ARRAY
-or T_STRING are made to specify which type has which number. The subtype
-field is not used by most types and can be ignored for now. The 'union
-anything' is a union that can contain a float, integer or a pointer to
-a struct containing additional data.
-
-<p> ... (To be continued)
-
-<h2>The different types (draft)</h2>
-
-<dl>
-<dt>Integers and Floats
-<dd>Integers and Floats are stored directly in the union.
-<dt>Strings
-<dd>For string values, the union contains a pointer to a struct lpc_string,
-this struct is a part of a shared string table. That means that all equal
-strings actually point to the same struct. This makes string comparison very
-fast, but creating new strings somewhat slow.
-<dt>Arrays
-<dd>In an array value, the union contains a pointer to a struct array, which
-in it's turn contains a number of struct svalues.
-<dt>Mappings
-<dd>Mappings are structs which contains one pointer to an array of indices
-and one pointer to an array of values. These two arrays are sorted so that
-lookup can use a binary search algorithm for speed.
-<dt>Lists
-<dd>Lists works just like mappings, except there is no value array.
-<dt>Objects
-<dd>Objects are merely structs containing a pointer to the program for this
-object and any global variables needed this object needs.
-<dt>Programs
-<dd>Programs are pointers to a 'struct program'. This struct contains the
-<b>byte-code</b> and additional information needed by the interpreter.
-</ul>
\ No newline at end of file
diff --git a/doc/manual/index.html b/doc/manual/index.html
deleted file mode 100644
index 13d0a9c00e..0000000000
--- a/doc/manual/index.html
+++ /dev/null
@@ -1,75 +0,0 @@
-<h1>The �LPC Programming Language</h1>
-<h2>by Lars Aronsson and Fredrik H�binette</h2>
-
-<h3>What is this?</h3>
-
-�LPC (Micro L.P.C., sometimes written ulpc or uLPC) is an interpreted,
-object-oriented programming language for flexible and yet efficient
-application development and prototyping. It features multiple
-inheritance, data abstraction, advanced built-in datatypes, such as
-associative arrays, dynamic arrays and multi-sets, and high-level
-character string and array operations.
-
-<p>The following documents describe the language:
-
-<dl>
-<dt>�LPC Tutorial
-<dt>�LPC Language Reference Manual
-<dt>The Design and Implementation of �LPC
-</dl>
-
-<h3>�LPC Tutorial</h3>
-
-<blockquote><i>This is an introduction to programming in the �LPC
-language. Some previous programming experience is
-required.</i></blockquote>
-
-<dl>
-<dt><a href="t-hello.html">Hello world</a>
-<dt>Variables and Loops
-<dt>Strings
-<dt>Arrays
-<dt>Using files
-<dt>Objects and Inheritance
-<dt>Spinner
-<dt>Appendix A: Where and how to get �LPC
-<dt>Appendix B: How to Install the �LPC Distribution
-</dl>
-
-<h3>�LPC Language Reference Manual</h3>
-
-<blockquote><i>This document describes the details of the �LPC
-programming language, in a somewhat semi-cryptic way.</i></blockquote>
-
-<dl>
-<dt>Introduction
-<dt>Lexical Conventions
-<dt>Syntax Notation
-<dt>Identifiers
-<dt>Objects and Lvalues
-<dt>Type conversion
-<dt>Expressions
-<dt>Declarations
-<dt>Statements
-<dt>External Declarations
-<dt>Scope and Binding
-<dt>Preprocessor
-<dt>Grammar
-<dt>Standard Library
-</dl>
-
-
-<h3>The Design and Implementation of �LPC</h3>
-
-
-<blockquote><i>This document describes the inner workings of the �LPC
-implementation, and some of the design decisions we have made. This
-can be interesting if you are into computer science, if you have found
-strange behavior, or if you want to add your own modules in C that
-become part of the �LPC language.</i></blockquote>
-
-<dl>
-<dt>Overview
-<dt>Adding Modules to �LPC
-<dt>Some Design Decisions
-</dl>
diff --git a/doc/manual/t-hello.html b/doc/manual/t-hello.html
deleted file mode 100644
index 93075cfdaa..0000000000
--- a/doc/manual/t-hello.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<h1>Hello world!</h1>
-
-In this chapter, you will learn to write a complete program in the
-�LPC language. All this program does is to print "Hello world!" on
-your screen. You can then make additions and changes to the program,
-as you learn to handle more features of the language in the following
-chapters.
-
-<p>This is typical for how you develop programs in �LPC: step by step,
-making them more advanced, adding functionality, as you go.  Since
-�LPC is an interpreted language, you don't get lagged by frequent
-recompilations.  You just change the program, and it is ready to run.
-
-<p>Enough said!  Let's take a look at the program now:
-
-<pre>
-        #!/usr/local/bin/ulpc
-
-        int main(int argc, string *argv)
-        {
-          write ("Hello world!\n");
-	  return 0;
-        }
-</pre>
-
-<p>That's all there is!  Use your favorite text editor and save the
-results in a file called <b>hello.lpc</b>.
-
-<p>We are not quite ready to run yet.  First, you must use the
-<b>chmod</b> command to make your program executable.  You only have
-to do this once for each program.  Here, the dollar sign is your UNIX
-prompt, which could also be any odd character (such as % or #).
-
-<pre>
-        $ chmod +x hello.lpc
-        $ hello.lpc
-        Hello world!
-        $
-</pre>
-
-<p>Obviously, our program is a success!  Let's try and understand why.
-
-<p>The first line of <b>hello.lpc</b> starts with the two characters
-<b>#!</b> (hash bang) followed by a file name. This is a UNIX trick to
-make script programs executable.  Normally, scripts are written in
-shell commands, awk or perl.  All script programs need an interpreter
-to read the script commands and execute them.  The "hash bang" tells
-UNIX that the this is a script file and that the file name of an
-interpreter follows.  For example, shell scripts use a UNIX shell
-/bin/sh as their interpreter, so their first line should be #!/bin/sh.
-
-<dl>
-<dt>NOTE:
-
-<dd>For this to work properly, the "hash bang" (#!) must be the first
-two characters of the file.  There must not be any white space before
-or empty line above them!
-
-</dl>
-
-<p>For �LPC programs, the interpreter is the <b>ulpc</b> program,
-which we shall assume is installed in <b>/usr/local/bin</b>
-directory.  Turn to appendices A and B if this program is not
-properly installed on your computer.
-
-<p>The next few lines of the program ... (to be continued)
-- 
GitLab


From 9d66455d4f9764b6dddbc97b68fd22de347607c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 31 Mar 1996 06:10:29 +0200
Subject: [PATCH 089/351] improved

Rev: bin/htmlify_docs.lpc:1.7
Rev: bin/rsif:1.3
---
 bin/htmlify_docs.lpc | 28 +++++++++++++++++++---------
 bin/rsif             |  6 +++---
 2 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/bin/htmlify_docs.lpc b/bin/htmlify_docs.lpc
index 4fb63f0c94..ed754b5ef2 100644
--- a/bin/htmlify_docs.lpc
+++ b/bin/htmlify_docs.lpc
@@ -242,6 +242,8 @@ string short(string s)
 inherit "/precompiled/regexp":is_example;
 
 list(string) indexes_done=(<>);
+list(string) pages_done=(<>);
+
 string mkindex(string topic, int usehead)
 {
   string head;
@@ -256,7 +258,9 @@ string mkindex(string topic, int usehead)
     head="<b>All pages:</b>\n";
     ret="<ul>\n";
     foreach(sort_array(m_indices(pages)),a)
-      ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
+      {	
+	ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
+      }
     
     ret+="</ul>\n";
     break;
@@ -268,6 +272,7 @@ string mkindex(string topic, int usehead)
     {
       if(a[0]!='/') continue;
       
+      pages_done[a]=1;
       ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
     }
     
@@ -280,6 +285,8 @@ string mkindex(string topic, int usehead)
     foreach(sort_array(m_indices(pages)),a)
     {
       if(search(a,"example")==-1) continue;
+
+      pages_done[a]=1;
       
       ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
     }
@@ -290,13 +297,9 @@ string mkindex(string topic, int usehead)
   case "other":
     head="<b>Other pages</b>\n";
     ret="<ul>\n";
-    foreach(sort_array(m_indices(pages) -
-		       map_array(`|(@m_values(keywords)),html_quote) -
-		       map_array(m_indices(all_efuns()),html_quote)),a)
+    foreach(sort_array(m_indices(pages) - indices(pages_done) ),a)
     {
-      if(a[0]=='/') continue;
       if(a[0..4]=="index") continue;
-      if(search(a,"example")!=-1) continue;
       ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
     }
     ret+="</ul>\n";
@@ -310,6 +313,7 @@ string mkindex(string topic, int usehead)
       a=html_quote(a);
       if(pages[a])
       {
+	pages_done[a]=1;
 	ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
       }else{
 	if(writepages)
@@ -334,6 +338,7 @@ string mkindex(string topic, int usehead)
     foreach(sort_array(keywords[topic]),a)
     {
       a=html_quote(a);
+      pages_done[a]=1;
       ret+="<li><a href="+pages[a]+">"+a+"</a>"+ short(a) +"\n";
     }
     ret+="</ul></a>\n";
@@ -443,7 +448,8 @@ string convert_page(string path, string fname)
 	  {
 	    string tmp;
 	    tmp=a;
-	    a=explode(a,"/")[-1];
+	    if(a[0]!='`' && a[0]!='/')
+	      a=explode(a,"/")[-1];
 	    if(pages[a])
 	    {
 	      b+=({ "<a href="+pages[a]+">" + a + "</a>" });
@@ -453,7 +459,7 @@ string convert_page(string path, string fname)
 	      b+=({ "<a href="+subpages[name+"-&gt;"+a]+">" + a + "</a>" });
 	    }else{
 	      if(writepages)
-	      perror("Warning, unlinked SEE ALSO: "+a+"\n");
+		perror(path+": Warning, unlinked SEE ALSO: "+a+"\n");
 	      b+=({ tmp });
 	    }
 	  }
@@ -474,6 +480,7 @@ string convert_page(string path, string fname)
 
 	case "RELATED FUNCTIONS":
 	  a=name;
+
 	  sscanf(rest,"%*skeyword %[a-z/A-Z0-9]",a);
 	  rest=mkindex(a, 0);
 	}
@@ -550,7 +557,8 @@ string convert_page(string path, string fname)
 
 	case "LINK":
 	  sscanf(a,"%s %s",a,b);
-	  tmp="<a href="+a+".html>"+b+"</a>";
+	  pages_done[(a/"/")[-1]]=1;
+	  tmp="<a href="+fippel_path(a)+".html>"+b+"</a>";
 	  break;
 
 	default:
@@ -637,6 +645,7 @@ string convert_page(string path, string fname)
       
       if(l > i*2)
       {
+	int err;
 	l=0;
 	foreach(cont/"\n", tmp)
 	{
@@ -644,6 +653,7 @@ string convert_page(string path, string fname)
 	  if(!is_example::match(tmp+"\n"))
 	  {
 	    perror(path+":"+l+": not on example form.\n");
+	    if(++err == 5) break;
 	  }
 	}
       }
diff --git a/bin/rsif b/bin/rsif
index 46712729cd..83228a4e37 100755
--- a/bin/rsif
+++ b/bin/rsif
@@ -13,16 +13,16 @@ int main(int argc, string *argv)
 
   for(i=3; i<argc; i++)
   {
-    if(file=read_bytes(argv[i]))
+    if(file_contents=read_bytes(argv[i]))
     {
       if(-1!=strstr(file,argv[1]))
       {
 	write("Processing "+argv[i]+".\n");
-	file=replace(file,argv[1],argv[2]);
+	file_contents=replace(file_contents,argv[1],argv[2]);
 
 	if( mv(argv[i],argv[i]+"~") )
 	{
-	  write_file(argv[i],file);
+	  write_file(argv[i],file_contents);
 	}else{
 	  write("Failed to create backup file.\n");
 	}
-- 
GitLab


From da0bbdc44db26eea467e1534f85c6cf6df65dc61 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 31 Mar 1996 06:14:14 +0200
Subject: [PATCH 090/351] documentation fixed

Rev: doc/index.bmml:1.3
Rev: doc/lpc/cast:1.1
Rev: doc/lpc/functions:1.2
Rev: doc/lpc/modifier:1.1
Rev: doc/lpc/reserved:1.3(DEAD)
Rev: doc/lpc/reserved.bmml:1.1
Rev: doc/manual/example1:1.3
Rev: doc/manual/example2:1.2
Rev: doc/manual/example3:1.2
Rev: doc/simulated/write_file:1.3
Rev: doc/types/mixed:1.1
Rev: doc/types/program:1.4
Rev: doc/types/string:1.4
---
 doc/index.bmml           | 12 +++---
 doc/lpc/cast             | 30 ++++++++++++++
 doc/lpc/functions        |  6 ++-
 doc/lpc/modifier         | 17 ++++++++
 doc/lpc/reserved         |  5 ---
 doc/lpc/reserved.bmml    |  6 +++
 doc/manual/example1      | 18 +++++----
 doc/manual/example2      | 58 +++++++++++++++------------
 doc/manual/example3      | 85 ++++++++++++++++++++++++++++++----------
 doc/simulated/write_file |  2 +-
 doc/types/mixed          | 15 +++++++
 doc/types/program        |  5 +++
 doc/types/string         | 17 +++++++-
 13 files changed, 210 insertions(+), 66 deletions(-)
 create mode 100644 doc/lpc/cast
 create mode 100644 doc/lpc/modifier
 delete mode 100644 doc/lpc/reserved
 create mode 100644 doc/lpc/reserved.bmml
 create mode 100644 doc/types/mixed

diff --git a/doc/index.bmml b/doc/index.bmml
index 0135bc189c..53fdda3470 100644
--- a/doc/index.bmml
+++ b/doc/index.bmml
@@ -23,9 +23,11 @@ $version manual
 
  Types
 
-  uLPC types are part of what makes uLPC a powerful language. They make
-  it easy to handle data without worrying about memory management and
-  other programming obstacles.
+  Data is stored in different ways, integers (eg. 1, 2, 3, 4 etc.) are
+  are stored in one way, real numbers (1.0, 1.1, etc.) in another. Each
+  different way get its own name. uLPC types are part of what makes uLPC
+  a powerful language. They make it easy to handle data without worrying
+  about memory management and other programming obstacles.
 
 	KEYWORD_LIST types
 
@@ -41,7 +43,7 @@ $version manual
   uLPC has a wide range of builtin functions. Most of these are implemented
   in C, but some are implemented in uLPC using the add_efun function.
 
-	LINK lpc_efuns Here's a list of all built-in functions.
+	LINK lpc/efuns Here's a list of all built-in functions.
 
  Operators
 
@@ -62,4 +64,4 @@ $version manual
 
 	KEYWORD_INDEX other
 
-	LINK lpc_all Here's a list of all pages.
+	LINK lpc/all Here's a list of all pages.
diff --git a/doc/lpc/cast b/doc/lpc/cast
new file mode 100644
index 0000000000..0ce25fc9fb
--- /dev/null
+++ b/doc/lpc/cast
@@ -0,0 +1,30 @@
+NAME
+	cast - convert one type to another
+
+SYNTAX
+	( <type> ) <expression>
+
+DESCRIPTION
+	Casts convert types, in most cases it just tells the compiler what
+	type the expression has, but it can also be used to actually convert
+	the value of the expression into something else.
+
+	Casting from float or int to string will convert the given number
+	into a decimal ascii string representation.
+
+	Casting from string to float or int will do the opposite. IE.
+	Read a decimal number from the string and return that.
+
+	Casting from string to program will call cast_to_program in the
+	master object and request a program to return. The standard master
+	object will consider the string a file name and compile the program
+	given by that string. It will then put the program in a chache in
+	case you cast the same string to a program again later.
+
+	In all other cases, casts are just compiler hints.
+
+KEYWORDS
+	lpc
+
+SEE ALSO
+	compile_file, sscanf
diff --git a/doc/lpc/functions b/doc/lpc/functions
index 9b1c71d06d..0449087399 100644
--- a/doc/lpc/functions
+++ b/doc/lpc/functions
@@ -8,6 +8,10 @@ SYNTAX
 	}
 
 DESCRIPTION
+	A function is basically a piece of code which takes some data
+	does some things, and hands some data back. Data sent to a
+	a function is called an 'argument'.
+
 	This defines a function called 'function_name' returning the type
 	'type'. The argument_specification is a comma separated list of
 	arguments. Each argument is specified with a type, whitespace and
@@ -68,4 +72,4 @@ KEYWORDS
 	lpc
 
 SEE ALSO
-	lambda, return, modifier
\ No newline at end of file
+	lambda, return, modifier
diff --git a/doc/lpc/modifier b/doc/lpc/modifier
new file mode 100644
index 0000000000..1943996b80
--- /dev/null
+++ b/doc/lpc/modifier
@@ -0,0 +1,17 @@
+NAME
+	modifier - modify function / variable definitions
+
+DESCRIPTION
+	Modifiers makes it possible to give functions and gobal variables
+	certain characteristics. A list of modifiers follows:
+
+	static	make this identifier unavailable by indexing
+	inline	allow inlining this function
+	private	hide this identifier to inheriting programs
+	nomask	don't allow this identifier to be re-defined
+
+KEYWORDS
+	lpc
+
+SEE ALSO
+	functions, variables
\ No newline at end of file
diff --git a/doc/lpc/reserved b/doc/lpc/reserved
deleted file mode 100644
index e20b6b5b17..0000000000
--- a/doc/lpc/reserved
+++ /dev/null
@@ -1,5 +0,0 @@
-RESERVED WORDS
-   array break case catch continue default do efun else float for foreach
-   function gauge if inherit inline int lambda list mapping mixed nomask
-   object private program protected public return sscanf static string
-   switch typeof varargs void while
diff --git a/doc/lpc/reserved.bmml b/doc/lpc/reserved.bmml
new file mode 100644
index 0000000000..1facad0a80
--- /dev/null
+++ b/doc/lpc/reserved.bmml
@@ -0,0 +1,6 @@
+Reserved Words
+
+  array break case catch continue default do efun else float for foreach
+  function gauge if inherit inline int lambda list mapping mixed nomask
+  object private program protected public return sscanf static string
+  switch typeof varargs void while
diff --git a/doc/manual/example1 b/doc/manual/example1
index df87470cfb..5600124036 100644
--- a/doc/manual/example1
+++ b/doc/manual/example1
@@ -33,8 +33,9 @@
 
 	write("hello world\n");
 
-  The first statement is a call to the builtin function write. To this
-  function the constant string "hello world\n" is sent. write then of
+  The first statement is a call to the builtin function write. This will
+  execute the code in the function write with the arguments as input data.
+  In this case, the constant string "hello world\n" is sent. write() then of
   course writes this string to stdout when executed.
 
 	return 0;
@@ -59,8 +60,7 @@
 
 	$ chmod +x hello_world.lpc
 
-  Now we can run hello_world.lpc without having to bother about running
-  ulpc:
+  Now we can run hello_world.lpc without having to bother with running ulpc:
 
 	$ ./hello_wold.lpc
 	hello world
@@ -73,9 +73,10 @@
 
 1.3 A better hello_world.lpc
   Now, wouldn't it be nice if it said "Hello world!" instead of "hello world" ?
-  But of course we don't want to make our program incompatible, so we'll add
-  a command line option that will make it type the old "hello world".
-  This is what it could look like:
+  But of course we don't want to make our program incompatible with the old
+  version. Someone might NEED the program to work the same as before. 
+  Therefore we'll add a command line option that will make it type the old
+  "hello world". This is what it could look like:
 
 	#!/usr/local/bin/ulpc
 
@@ -135,3 +136,6 @@
 	    write("hello world\n"); // old stype
 
   The // begins a comment which continues to the end of the line.
+  Comments lets you type in text in the program which will be ignored by the
+  computer. This is to inform whoever might read your code (like yourself) of
+  what the program does to make it easier to understand.
diff --git a/doc/manual/example2 b/doc/manual/example2
index 394bc08f6f..11fffb14b1 100644
--- a/doc/manual/example2
+++ b/doc/manual/example2
@@ -1,11 +1,11 @@
-  Now we will look at a slightly more useful example:
+2. Now we will look at a slightly more useful example:
 
 	#!/usr/local/bin/ulpc
 
 	int main(int argc,string *argv)
 	{
 	  int i;
-	  string file;
+	  string file_contents;
 	
 	  if(argc<4)
 	  {
@@ -15,16 +15,16 @@
 	
 	  for(i=3; i<argc; i++)
 	  {
-	    if(file=read_bytes(argv[i]))
+	    if(file_contents=read_bytes(argv[i]))
 	    {
-	      if(-1!=strstr(file,argv[1]))
+	      if(-1!=strstr(file_contents,argv[1]))
 	      {
 		write("Processing "+argv[i]+".\n");
-		file=replace(file,argv[1],argv[2]);
+		file_contents=replace(file_contents,argv[1],argv[2]);
 	
 		if( mv(argv[i],argv[i]+"~") )
 		{
-		  write_file(argv[i],file);
+		  write_file(argv[i],file_contents);
 		}else{
 		  write("Failed to create backup file.\n");
 		}
@@ -43,7 +43,13 @@
 
 	#!/usr/local/bin/ulpc
 
-  Make UNIX run ulpc to interpret this program.
+  Make UNIX run ulpc to interpret this program. Interpret in this case
+  means to read the program, convert it to an internal representation and
+  then run the instructions in this internal representation. Note that uLPC
+  does not use the same low-level representation as for example C does,
+  instead it uses a simple and compact representation which are parsed by
+  a C program which actually implements the instructions in that
+  representation.
 
 	int main(int argc,string *argv)
 	{
@@ -52,10 +58,10 @@
   arguments into the parameters argc and argv.
 
 	  int i;
-	  string file;
+	  string file_contents;
 
   Declare two temporary variables to use later. The first one 'i' is an
-  integer, and the second one 'file' is a string.
+  integer, and the second one 'file_contents' is a string.
 	
 	  if(argc<4)
 	  {
@@ -65,20 +71,21 @@
 
   If argc is lesser than four it means that the program received less than
   three arguments. Since rsif needs at least three arguments we write how
-  to use rsif to stderr using the function perror and then exit this function
-  with the return value 1. Nothing after the return will be executed if
-  argc is lesser than 4.
+  to use rsif to stderr (Standard error channel) using the function perror
+  and then exit this function with the return value 1. Nothing after the
+  return will be executed if argc is lesser than 4.
   
 	
 	  for(i=3; i<argc; i++)
 	  {
 
-  This statement starts a loop. It will first set i to three, then execute
-  everything within the brackets for as long as i is lesser than argc. After
-  each time the block between the brackets the final statement, i++, will
-  be executed. ++ is the increment operator, it will increase i by one.
+  This statement starts a loop. (Loop means code repetition) It will first
+  set i to three, then execute everything within the brackets for as long as
+  i is lesser than argc. After each time the block between the brackets the
+  final statement, i++, will be executed. ++ is the increment operator, it
+  will increase i by one.
 
-	    if(file=read_bytes(argv[i]))
+	    if(file_contents=read_bytes(argv[i]))
 	    {
 
   Look closely, the experssion in this if-statement is not a comparison, it
@@ -90,7 +97,7 @@
   variable file. If there is no file with that name, zero will be returned
   and then the block within the brackets will not be executed.
 
-	      if(-1!=strstr(file,argv[1]))
+	      if(-1!=strstr(file_contents,argv[1]))
 	      {
 
   The function strstr searches for a string in in a string and returns the
@@ -101,22 +108,25 @@
 
 		write("Processing "+argv[i]+".\n");
 
-  Write that we are processing this file to stdout.
+  Write that we are processing this file to stdout. Stdout means
+  "Standard output channel" and is normally your screen unless you 'redirect'
+  it to somewhere else.
 
-		file=replace(file,argv[1],argv[2]);
+		file_contents=replace(file_contents,argv[1],argv[2]);
 
   Call the builtin function replace and replace oall occurances of the 'from'
-  string with the 'to' string and assign the new result to the variable 'file'.
+  string with the 'to' string and assign the new result to the variable
+  'file_contents'.
 
 		if( mv(argv[i],argv[i]+"~") )
 		{
   Try moving the file argv[i] to a backup file by adding a tilde to the end
   of the name. Then choose action depending on weather it worked or not.
 
-		  write_file(argv[i],file);
+		  write_file(argv[i],file_contents);
 
-  If it worked we re-create the file argv[i] by writing the string 'file' to
-  it.
+  If it worked we re-create the file argv[i] by writing the string
+  'file_contents' to it.
 
 		}else{
 		  write("Failed to create backup file.\n");
diff --git a/doc/manual/example3 b/doc/manual/example3
index 2323435af7..0d9552a40a 100644
--- a/doc/manual/example3
+++ b/doc/manual/example3
@@ -1,5 +1,15 @@
-  This example is a very simple www-server.
+3. This example is a very simple www-server.
 
+  For you who are not familiar with WWW (World Wide Web), it works by using
+  client program which will fetch files from remote servers when asked.
+  Usually by clicking a pitcure or text. This example is a program for the
+  server which will send files to any computer that requests them. The
+  protocol used to send the file is called HTTP. (HyperText Transfer Protocol)
+
+  Usually WWW involves HTML. HTML (HyperText Markup Language) is a way to
+  write documents with embedded pictures and links to other pages. These
+  links are normally displayed underlined and if you click them your WWW-
+  browser will load whatever document that link leads to.
 
 	#!/usr/local/bin/ulpc
 	
@@ -12,14 +22,18 @@
 	inherit "/precompiled/port";
 
   Inherit copies all the functionality of /precompiled/port into this program.
-  /precompiled/port makes it possible to bind a TCP socket to accept incoming
-  connections.
+  /precompiled/port makes it possible to bind a TCP (Transmission Control
+  Protocol, the internet stanard for computer communication) socket to accept
+  incoming connections. A socket is simply a number to separate communications
+  to and from different programs on the same computer.
 
   Next are some constants that will affect how uHTTPD will operate. This uses
-  the preprocessor directive #define. As an example, after the first define
-  below, BLOCK will be replaced with 16060.
+  the preprocessor directive #define. The preprocessor is the first stage in
+  the compiling process and can make textual processing of the code before
+  it is compiled. As an example, after the first define below, all occurances
+  of 'BLOCK' will be replaced with 16060.
 	
-	/* number of bytes to read for each write */
+	/* Amount of data moved in one operation */
 	#define BLOCK 16060
 	
 	/* Where do we have the html files ? */
@@ -31,6 +45,11 @@
 	/* Port to open */
 	#define PORT 1905
 
+  A port is a destination for a TCP connection. It is simply a number on the
+  local computer. 1905 is not the standard port for HTTP connections though,
+  which means that if you want to access this WWW server from a browser you
+  need to specify the port like this: http://my.host.my.domain:1905/
+
   Next we declare a global variable of the type program called output_class,
   and then we use the class construct to assign a program to it. class {}
   defines a clonable program. (or class for you C++ freaks)
@@ -48,23 +67,32 @@
   Then ther is a global variable called offset which is initalized to zero.
   (each instance of this class will have it's own instance of this variable,
    so it is not truly global, but..) 
-  Note that the initalization is done when the clas is cloned. (or instanciated
-  if you prefer C++ terminology)
-
-
-  Next we define the function write_callback(). 'void' means that it does not
-  return a value. Write callback will be used further down as a callback and
-  will be called whenever there is room in the socket output buffer.
+  Note that the initalization is done when the class is cloned. (or
+  instanciated if you prefer C++ terminology)
+
+
+  Next we define the function write_callback(). Later the program will go
+  into a 'waiting' state, until something is received to process, or until
+  there is buffer space available to write output to. When that happens a
+  callback will be called to do this. The write_callback() is called when
+  there is buffer space available. In the following lines 'void' means that
+  it does not return a value. Write callback will be used further down as a
+  callback and will be called whenever there is room in the socket output
+  buffer.
 	
 	  void write_callback()
 	  {
 	    int written;
 	    string data;
+
+  The following line means: call seek in the inherited program 'file'.
 	
 	    file::seek(offset);
 
   Move the file pointer to the where we want to the position we want to read
-  from.
+  from. The file pointer is simply a location in the file, usually it is where
+  the last read() ended and the next will begin. seek() can move this pointer
+  to where we want it though.
 
 	    data=file::read(BLOCK);
 
@@ -106,8 +134,9 @@
 	  string input="";
 
    And then we define the function that will be called when there is something
-   in the socket input buffer. Ignore the argument 'id' for now. The second
-   argument is the contents of the input buffer.
+   in the socket input buffer. The first argument 'id' is declared as mixed,
+   which means that it can contain any type of value. The second argument is
+   the contents of the input buffer.
 
 	  void read_callback(mixed id,string data)
 	  {
@@ -142,13 +171,18 @@
 	      input=combine_path(BASE,input);
 
   Combine the requested file with the base of the HTML tree, this gives
-  us a full filename beginning with a slash.
+  us a full filename beginning with a slash. The HTML tree is the
+  directory on the server in which the HTML files are located. Normally
+  all files in this directory can be accessed by anybody by using a WWW
+  browser. So if a user requests 'index.html' then that file name is first
+  added to BASE (/home/hubbe/www/html/ in this case) and if that file exists
+  it will be returned to the browser.
 	      
 	      if(!file::open(input,"r"))
 	      {
 
   Try opening the file in read-only mode. If this fails, try opening NOFILE
-  instead. 
+  instead. Opening the file will enable us to read it later.
 
 		if(!file::open(NOFILE,"r"))
 		{
@@ -199,7 +233,7 @@
 
 	    socket::set_nonblocking(read_callback,0,selfdestruct);
 
-  Then we set up the callback functions. (And sets the file nonblocking.)
+  Then we set up the callback functions and sets the file nonblocking.
   Nonblocking mode means that read() and write() will rather return that
   wait for I/O to finish. Then we sit back and wait for read_callback to
   be called.
@@ -218,9 +252,15 @@
 	void accept_callback()
 	{
 	  object tmp_output;
+
+  This creates a local variable of type 'object'. An object variable can
+  contain a clone of any program. uLPC does not consider clones of different
+  programs different types. This also means that function calls to objects
+  have to be resolved at run time.
+
 	  tmp_output=accept();
 
-  The function accept clones a /precompiled/file and makes this equal to the
+  The function accept  clones a /precompiled/file and makes this equal to the
   newly connected socket.
 
 	  if(!tmp_output) return;
@@ -230,7 +270,10 @@
 	  clone(output_class, tmp_output);
 
   Otherwise we clone an instanec of 'output_class' and let it take care of the
-  connection.
+  connection. Each clone of output_class will have it's own set of global
+  variables, which will enable many connections to be active at the same
+  time without data being mixed up. Note that the programs will not actually
+  run simulataneously though.
 
 	  destruct(tmp_output);
 
diff --git a/doc/simulated/write_file b/doc/simulated/write_file
index 174e7084ab..46d1b770bc 100644
--- a/doc/simulated/write_file
+++ b/doc/simulated/write_file
@@ -11,4 +11,4 @@ KEYWORDS
 	file
 
 SEE ALSO
-	read_file
+	read_bytes
diff --git a/doc/types/mixed b/doc/types/mixed
new file mode 100644
index 0000000000..6f620ced15
--- /dev/null
+++ b/doc/types/mixed
@@ -0,0 +1,15 @@
+NAME
+	mixed - any type
+
+DESCRIPTION
+	This is not really a type. But this keyword can be used to specify
+	that a variable, argument or return type can be of any type.
+
+EXAMPLES
+	mixed i=1;
+	mixed j="foo";
+	mixed foo() { return "bar"; }
+	mixed bar() { return ({}); }
+
+KEYWORDS
+	types
diff --git a/doc/types/program b/doc/types/program
index c653029056..cf34036ebd 100644
--- a/doc/types/program
+++ b/doc/types/program
@@ -8,6 +8,11 @@ DESCRIPTION
 	arguments to clone() and the only operators that applies to programs
 	are == and !=.
 
+NOTA BENE
+	In uLPC the term 'program' is somewhat confusing, becuase it is used
+	both to reference a complete runnable software package, and to a
+	structure in uLPC containing code.
+
 KEYWORDS
 	types
 
diff --git a/doc/types/string b/doc/types/string
index 0586b1e690..e15c543755 100644
--- a/doc/types/string
+++ b/doc/types/string
@@ -5,8 +5,10 @@ SYNTAX EXAMPLE
 	"foo"
 
 DESCRIPTION
-	This type can contain a string, or list of characters, strings can
-	contain any character, even null characters. Strings are a basic
+	This type can contan text. ie. a word, a sentence, or a book. Note
+	that this is not simply the letters A to Z, special characters,
+	null characters, newlines can all be stored in a string. Any 8-bit
+	character in fact. Strings are a basic
 	type in LPC, as opposed to C where strings are represented by an
 	array of char. This means that you cannot set individual characters
 	in a string with the index operator for instance. In fact, there are
@@ -14,6 +16,17 @@ DESCRIPTION
 	are 'shared', that means that if the same string is used in several
 	places, only one will be stored in memory.
 
+	When writing a string in a program, you enclose it in doublequotes.
+	To write special characters you need to use one of the following
+	syntaxes:
+
+	\n	newline
+	\r	charriage return
+	\t	tab
+	\b	backspace
+	\"	"
+	\\	\
+
 	A list of operators that applies to strings follow:
 	In this list a and b is used to represent a string expression:
 
-- 
GitLab


From 7d3623b23c30c6f210676c22dc2d0065e67a4ce1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 31 Mar 1996 06:15:21 +0200
Subject: [PATCH 091/351] make html_docs entry added

Rev: src/ChangeLog:1.25
---
 src/ChangeLog | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 8faef889d6..9e7a2c0399 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+Sun Mar 31 00:29:22 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
+
+	* make html_docs: new command to create a directory with
+	  html documentation for uLPC. This documentation can then
+	  be copied to a WWW directory.
+
 Sat Mar 23 19:02:40 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
 
 	* array.c: arrays are always initalized to zero to avoid
-- 
GitLab


From cce3a9b6f430b470bbd0cc8e84fbf6017977faf4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 31 Mar 1996 06:16:01 +0200
Subject: [PATCH 092/351] reports added

Rev: .cvsignore:1.4
---
 .cvsignore | 1 +
 .gitignore | 1 +
 2 files changed, 2 insertions(+)

diff --git a/.cvsignore b/.cvsignore
index 35e9d80097..d90b873748 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -5,3 +5,4 @@ uLPC_v1.0E-12.tar.gz
 uLPC_v1.0E-13.tar.gz
 uLPC_v1.1E-12.tar.gz
 uLPC_v1.7E-12.tar.gz
+reports
diff --git a/.gitignore b/.gitignore
index 5031a7f789..d2513525d1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,3 +37,4 @@ core
 /uLPC_v1.0E-13.tar.gz
 /uLPC_v1.1E-12.tar.gz
 /uLPC_v1.7E-12.tar.gz
+/reports
-- 
GitLab


From 18da782ca26f84e9d6c80c33128409e7d338a5c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 2 Apr 1996 16:25:46 +0200
Subject: [PATCH 093/351] links fixed

Rev: bin/htmlify_docs.lpc:1.8
Rev: doc/index.bmml:1.4
---
 bin/htmlify_docs.lpc | 16 +++++++++++++---
 doc/index.bmml       | 10 ++++++++++
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/bin/htmlify_docs.lpc b/bin/htmlify_docs.lpc
index ed754b5ef2..fce882ea30 100644
--- a/bin/htmlify_docs.lpc
+++ b/bin/htmlify_docs.lpc
@@ -433,9 +433,13 @@ string convert_page(string path, string fname)
 	  b=({});
 	  foreach(a,a)
 	  {
-	    // fixme!!
 	    keywords[a] = ( keywords[a] || ({}) ) | ({ name });
-	    b+=({ "<a href=index.html#"+a+">"+a+"</a>" });
+	    if(pages[a])
+	    {
+	      b+=({ "<a href="+pages[a]+">"+a+"</a>" });
+	    }else{
+	      b+=({ a });
+	    }
 	  }
 	  rest=implode_nicely(b);
 	  break;
@@ -558,7 +562,13 @@ string convert_page(string path, string fname)
 	case "LINK":
 	  sscanf(a,"%s %s",a,b);
 	  pages_done[(a/"/")[-1]]=1;
-	  tmp="<a href="+fippel_path(a)+".html>"+b+"</a>";
+	  tmp="<a href="+fippel_path(a)+">"+b+"</a>";
+	  break;
+
+	case "TAG":
+	  pages[a]=fippel_path(path)+"#"+a;
+	  pages_done[a]=1;
+	  tmp="<a name="+a+">";
 	  break;
 
 	default:
diff --git a/doc/index.bmml b/doc/index.bmml
index 53fdda3470..4b03625bf6 100644
--- a/doc/index.bmml
+++ b/doc/index.bmml
@@ -13,6 +13,8 @@ $version manual
 
 	KEYWORD_LIST examples
 
+	TAG control
+
  Control structures
 
   Control structures groups code into blocks and they control the order in
@@ -21,6 +23,8 @@ $version manual
 
 	KEYWORD_LIST control
 
+	TAG types
+
  Types
 
   Data is stored in different ways, integers (eg. 1, 2, 3, 4 etc.) are
@@ -31,6 +35,8 @@ $version manual
 
 	KEYWORD_LIST types
 
+	TAG lpc
+
  uLPC and object orientation
 
   This section is about the more fundamental workings of uLPC, such as
@@ -45,6 +51,8 @@ $version manual
 
 	LINK lpc/efuns Here's a list of all built-in functions.
 
+	TAG operators
+
  Operators
 
   uLPC operators behave much like the onces in C, but have many many additional
@@ -58,6 +66,8 @@ $version manual
   thought about order. Hopefully you should be able to use this section
   anyway once you've looked at the sections above.
 
+	TAG file
+
 	KEYWORD_INDEX file
 
 	KEYWORD_INDEX programs
-- 
GitLab


From 4534b7137daa9d7b74357c575143f5ae1618cb64 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 2 Apr 1996 19:19:15 +0200
Subject: [PATCH 094/351] entry added

Rev: src/ChangeLog:1.26
---
 src/ChangeLog | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 9e7a2c0399..27e5e491aa 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+Sun Mar 31 22:12:43 1996  Fredrik Hubinette  <hubbe@axel.signum.se>
+
+	* uLPC v1.0E-10 released.
+
 Sun Mar 31 00:29:22 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
 
 	* make html_docs: new command to create a directory with
-- 
GitLab


From 8b63787319c0d24e24a6108b8fbe3d48d850c2ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 11 Apr 1996 23:14:14 +0200
Subject: [PATCH 095/351] apply on void functions fixed

Rev: src/builtin_efuns.c:1.14
---
 src/builtin_efuns.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index 81cc0404a1..54bd074c07 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -285,10 +285,21 @@ void f_clone(INT32 args)
 
 void f_call_function(INT32 args)
 {
+  struct svalue *expected_sp=sp-args+2;
   strict_apply_svalue(sp-args, args - 1);
-  free_svalue(sp-2);
-  sp[-2]=sp[-1];
-  sp--;
+  if(sp < expected_sp)
+  {
+#ifdef DEBUG
+    if(sp+1 != expected_sp) fatal("Stack underflow!\n");
+#endif
+
+    pop_stack();
+    push_int(0);
+  }else{
+    free_svalue(sp-2);
+    sp[-2]=sp[-1];
+    sp--;
+  }
 }
 
 void f_backtrace(INT32 args)
@@ -1096,6 +1107,9 @@ void f_replace(INT32 args)
     push_string(s);
     break;
   }
+
+  default:
+    error("Bad argument 1 to replace().\n");
   }
 }
 
-- 
GitLab


From e26068d11b3ef56830c44fdf5520e4edfed28971 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 11 Apr 1996 23:14:28 +0200
Subject: [PATCH 096/351] case -1 fixed

Rev: src/las.c:1.7
---
 src/las.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/las.c b/src/las.c
index 81bbf3aa32..5bd79afa92 100644
--- a/src/las.c
+++ b/src/las.c
@@ -101,8 +101,8 @@ INT32 count_args(node *n)
   case '?':
   {
     int tmp1,tmp2;
-    tmp1=count_args(CDAR(n));
-    tmp2=count_args(CDAR(n));
+    tmp1=count_args(CADR(n));
+    tmp2=count_args(CDDR(n));
     if(tmp1==-1 || tmp2==-2) return -1;
     if(tmp1 < tmp2) return tmp1;
     return tmp2;
@@ -164,7 +164,14 @@ node *mknode(short token,node *a,node *b)
     break;
 
   case F_APPLY:
-    res->node_info |= OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND; /* for now */
+    if(a && a->token==F_CONSTANT &&
+       a->u.sval.type==T_FUNCTION &&
+       a->u.sval.subtype==-1)
+    {
+      res->node_info |= a->u.sval.u.efun->flags;
+    }else{
+      res->node_info |= OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND; /* for now */
+    }
     break;
 
   case F_RETURN:
-- 
GitLab


From 3e63556957bcdf12a2858863351d4321e2c42eb7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 11 Apr 1996 23:14:56 +0200
Subject: [PATCH 097/351] test for case -1 and apply on void functions fixed

Rev: src/test/create_testsuite:1.13
---
 src/test/create_testsuite | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 53ebd3d924..67aec404dc 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -59,6 +59,7 @@ define(TESTNO,0)
 
 test_compile_error_low(master()->add_precompiled_program(\"/test\",compile_string(\"int foo() { return 17; }\",\"62\")))
 
+test_any([[function f=random_seed; int t; foreach(allocate(1),t) f(t); return 1;]],1)
 test_compile([[while(0)if(0)continue;else;]])
 test_program([[int b=1,c; int a() { c=b+2; return c==3; }]])
 test_true([[ ("foobar"/"o") & ({ "foo" }) ]])
-- 
GitLab


From d72a876f801ceed0b9a20c12b4b7b2c08c6a146f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 03:47:21 +0200
Subject: [PATCH 098/351] peephole-related changes

Rev: src/program.c:1.9
---
 src/program.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/program.c b/src/program.c
index ec2f5f9442..2f33c4adcd 100644
--- a/src/program.c
+++ b/src/program.c
@@ -1079,11 +1079,11 @@ static void insert_small_number(int a,int area)
     ins_short(a,area);
   }else{
     ins_signed_byte(-128,area);
-    ins_long(a,area);
+    ins_int(a,area);
   }	
 }
 
-void store_linenumber(void)
+void store_linenumber(INT32 current_line, struct lpc_string *current_string)
 {
   if(last_line!=current_line || last_file != current_file)
   {
-- 
GitLab


From c91b86f4340f9d9944096607e5c122b49a8c2600 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 03:57:03 +0200
Subject: [PATCH 099/351] igonoring peep_engine.c

Rev: src/.cvsignore:1.2
---
 src/.cvsignore | 1 +
 src/.gitignore | 1 +
 2 files changed, 2 insertions(+)

diff --git a/src/.cvsignore b/src/.cvsignore
index e8c05a6b13..773fcbba07 100644
--- a/src/.cvsignore
+++ b/src/.cvsignore
@@ -1 +1,2 @@
 configure
+peep_engine.c
diff --git a/src/.gitignore b/src/.gitignore
index 55902085e8..17c607db6a 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1 +1,2 @@
 /configure
+/peep_engine.c
-- 
GitLab


From 4a60e31a8a41f62bc87771ed83ffc6f98df3f161 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 04:01:30 +0200
Subject: [PATCH 100/351] rusage fixed and new opcodes for peephole optimizer

Rev: src/language.y:1.13
---
 src/language.y | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/src/language.y b/src/language.y
index 0fde89d6f4..4a6a39f6a7 100644
--- a/src/language.y
+++ b/src/language.y
@@ -15,6 +15,9 @@
 %token F_POP_VALUE F_POP_N_ELEMS F_MARK F_CALL_LFUN
 
 %token F_BRANCH F_BRANCH_WHEN_ZERO F_BRANCH_WHEN_NON_ZERO
+%token F_BRANCH_WHEN_LT F_BRANCH_WHEN_GT
+%token F_BRANCH_WHEN_LE F_BRANCH_WHEN_GE
+%token F_BRANCH_WHEN_EQ F_BRANCH_WHEN_NE
 %token F_INC_LOOP F_DEC_LOOP
 %token F_INC_NEQ_LOOP F_DEC_NEQ_LOOP
 
@@ -28,14 +31,17 @@
  */
 %token F_LFUN F_GLOBAL F_LOCAL
 %token F_GLOBAL_LVALUE F_LOCAL_LVALUE
+%token F_CLEAR_LOCAL
 %token F_CONSTANT F_FLOAT F_STRING
-%token F_NUMBER F_NEG_NUMBER F_CONST_1 F_CONST0 F_CONST1 
+%token F_NUMBER F_NEG_NUMBER F_CONST_1 F_CONST0 F_CONST1 F_BIGNUM
 
 /*
  * These are the predefined functions that can be accessed from LPC.
  */
 
 %token F_INC F_DEC F_POST_INC F_POST_DEC F_INC_AND_POP F_DEC_AND_POP
+%token F_INC_LOCAL F_INC_LOCAL_AND_POP F_POST_INC_LOCAL
+%token F_DEC_LOCAL F_DEC_LOCAL_AND_POP F_POST_DEC_LOCAL
 %token F_RETURN F_DUMB_RETURN F_RETURN_0
 
 %token F_ASSIGN F_ASSIGN_AND_POP
@@ -120,6 +126,10 @@
 %token F_WHILE
 %token F_XOR_EQ
 
+%token F_ALIGN
+%token F_POINTER
+%token F_LABEL
+
 %token F_MAX_INSTR
 
 %right '='
@@ -1030,13 +1040,13 @@ comma_expr_or_maxint: /* empty */ { $$=mkintnode(0x7fffffff); }
 
 gauge: F_GAUGE '(' unused ')'
   {
-    $$=mknode(F_NEGATE,
-	      mknode(F_SUBTRACT,
-		     mknode(F_INDEX,mkefuncallnode("rusage",0),
-			    mkintnode(GAUGE_RUSAGE_INDEX)),
-		     mknode(F_ARG_LIST,$3,
-			    mknode(F_INDEX,mkefuncallnode("rusage",0),
-				   mkintnode(GAUGE_RUSAGE_INDEX)))),0);
+    $$=mkopernode("`-",
+		  mkopernode("`-",
+			     mknode(F_INDEX,mkefuncallnode("rusage",0),
+				    mkintnode(GAUGE_RUSAGE_INDEX)),
+			     mknode(F_ARG_LIST,$3,
+				    mknode(F_INDEX,mkefuncallnode("rusage",0),
+					   mkintnode(GAUGE_RUSAGE_INDEX)))),0);
   } ;
 
 typeof: F_TYPEOF '(' expr0 ')'
-- 
GitLab


From d334774209319aea39e1f1e187103be247d959d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 04:10:49 +0200
Subject: [PATCH 101/351] no real changes

Rev: src/las.c:1.8
---
 src/las.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/las.c b/src/las.c
index 5bd79afa92..e999b84833 100644
--- a/src/las.c
+++ b/src/las.c
@@ -164,9 +164,9 @@ node *mknode(short token,node *a,node *b)
     break;
 
   case F_APPLY:
-    if(a && a->token==F_CONSTANT &&
-       a->u.sval.type==T_FUNCTION &&
-       a->u.sval.subtype==-1)
+    if(a && a->token == F_CONSTANT &&
+       a->u.sval.type == T_FUNCTION &&
+       a->u.sval.subtype == -1)
     {
       res->node_info |= a->u.sval.u.efun->flags;
     }else{
@@ -1577,7 +1577,7 @@ void dooptcode(struct lpc_string *name,node *n, int args)
 {
 #ifdef DEBUG
   if(a_flag > 1)
-    fprintf(stderr,"Doing function: %s\n",name->str);
+    fprintf(stderr,"Doing function '%s' at %x\n",name->str,PC);
 #endif
   last_function_opt_info=OPT_SIDE_EFFECT;
   n=mknode(F_ARG_LIST,n,0);
-- 
GitLab


From 8beaf79684f76c61f1ee1dca26e0822ec9910aee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 04:22:09 +0200
Subject: [PATCH 102/351] crypt fixed for BSD

Rev: src/builtin_efuns.c:1.15
---
 src/builtin_efuns.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index 54bd074c07..1a94033b2e 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -701,7 +701,7 @@ void f_time(INT32 args)
 void f_crypt(INT32 args)
 {
   char salt[2];
-  char *ret;
+  char *ret, *saltp;
   char *choise =
     "cbhisjKlm4k65p7qrJfLMNQOPxwzyAaBDFgnoWXYCZ0123tvdHueEGISRTUV89./";
 
@@ -718,17 +718,17 @@ void f_crypt(INT32 args)
        sp[1-args].u.string->len < 2)
       error("Bad argument 2 to crypt()\n");
       
-    salt[0] = sp[1-args].u.string->str[0];
-    salt[1] = sp[1-args].u.string->str[1];
+    saltp=sp[1-args].u.string->str;
   } else {
     salt[0] = choise[my_rand()%strlen(choise)];
     salt[1] = choise[my_rand()%strlen(choise)];
+    saltp=salt;
   }
 #ifdef HAVE_CRYPT
-  ret = (char *)crypt(sp[-args].u.string->str, salt);
+  ret = (char *)crypt(sp[-args].u.string->str, saltp);
 #else
 #ifdef HAVE__CRYPT
-  ret = (char *)_crypt(sp[-args].u.string->str, salt);
+  ret = (char *)_crypt(sp[-args].u.string->str, saltp);
 #else
   ret = sp[-args].u.string->str;
 #endif
-- 
GitLab


From 6ff3e90cddf26e859687998122059c5d70789b45 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 04:25:30 +0200
Subject: [PATCH 103/351] some deebug added

Rev: src/dynamic_buffer.c:1.3
---
 src/dynamic_buffer.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/dynamic_buffer.c b/src/dynamic_buffer.c
index d4f71cdf91..4ac63519cf 100644
--- a/src/dynamic_buffer.c
+++ b/src/dynamic_buffer.c
@@ -14,6 +14,10 @@ static dynamic_buffer buff;
 char *low_make_buf_space(INT32 space,dynamic_buffer *buf)
 {
   char *ret;
+#ifdef DEBUG
+  if(!buf->s.str) fatal("ARRRRGH! Deadly Trap!\n");
+#endif
+
   if(buf->s.len+space>=buf->bufsize)
   {
     if(!buf->bufsize) buf->bufsize=1;
-- 
GitLab


From cf2a15c76b86f2233c0b260e6504df2d6d668152 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 04:31:43 +0200
Subject: [PATCH 104/351] alarm() added

Rev: src/lpc_signal.c:1.9
---
 src/lpc_signal.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/src/lpc_signal.c b/src/lpc_signal.c
index 1195d0388f..b149afe867 100644
--- a/src/lpc_signal.c
+++ b/src/lpc_signal.c
@@ -13,6 +13,10 @@
 #include <signal.h>
 #include <sys/wait.h>
 
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
 #ifdef NSIG
 #define MAX_SIGNALS NSIG
 #else
@@ -369,6 +373,22 @@ static void f_getpid(INT32 args)
   push_int(getpid());
 }
 
+static void f_alarm(INT32 args)
+{
+  long seconds;
+
+  if(args < 1)
+    error("Too few arguments to signame()\n");
+
+  if(sp[-args].type != T_INT)
+    error("Bad argument 1 to signame()\n");
+
+  seconds=sp[-args].u.integer;
+
+  pop_n_elems(args);
+  push_int(alarm(seconds));
+}
+
 void init_signals()
 {
   int e;
@@ -386,6 +406,7 @@ void init_signals()
   add_efun("signame",f_signame,"function(int:string)",0);
   add_efun("signum",f_signum,"function(string:int)",0);
   add_efun("getpid",f_getpid,"function(:int)",0);
+  add_efun("alarm",f_alarm,"function(int:int)",OPT_SIDE_EFFECT);
 }
 
 void exit_signals()
-- 
GitLab


From 7a82f9d8463e441c5517aa6e298f3b6daa538d4c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 05:01:06 +0200
Subject: [PATCH 105/351] now makes code through peephole optimizer

Rev: src/docode.c:1.5
---
 src/docode.c | 646 +++++++++++++++++----------------------------------
 1 file changed, 210 insertions(+), 436 deletions(-)

diff --git a/src/docode.c b/src/docode.c
index 5e1c52e3f8..a99b16402f 100644
--- a/src/docode.c
+++ b/src/docode.c
@@ -19,11 +19,11 @@
 #include "main.h"
 #include "lex.h"
 #include "builtin_efuns.h"
+#include "peep.h"
+#include "docode.h"
 
-int *break_stack=0;
-static int current_break,break_stack_size;
-int *continue_stack=0;
-static int current_continue,continue_stack_size;
+INT32 current_break=-1;
+INT32 current_continue=-1;
 
 static INT32 current_switch_case;
 static INT32 current_switch_default;
@@ -45,131 +45,35 @@ void ins_short(INT16 l,int area)
   add_to_mem_block(area, (char *)&l, sizeof(INT16));
 }
 
-static void upd_short(int offset, INT16 l)
-{
-#ifdef HANDLES_UNALIGNED_MEMORY_ACCESS
-  *((INT16 *)(areas[A_PROGRAM].s.str+offset))=l;
-#else
-  MEMCPY(areas[A_PROGRAM].s.str+offset, (char *)&l,sizeof(l));
-#endif
-}
-
-static void upd_int(int offset, INT32 tmp)
-{
-#ifdef HANDLES_UNALIGNED_MEMORY_ACCESS
-  *((int *)(areas[A_PROGRAM].s.str+offset))=tmp;
-#else
-  MEMCPY(areas[A_PROGRAM].s.str+offset, (char *)&tmp,sizeof(tmp));
-#endif
-}
-
 /*
  * Store an INT32.
  */
-void ins_long(INT32 l,int area)
+void ins_int(INT32 l,int area)
 {
   add_to_mem_block(area, (char *)&l+0, sizeof(INT32));
 }
 
-int store_linenumbers=1;
-
-static void low_ins_f_byte(unsigned int b)
+void upd_int(int offset, INT32 tmp)
 {
-  if(store_linenumbers) store_linenumber();
-
-#if defined(LASDEBUG)
-  if(lasdebug>1)
-    if(store_linenumbers)
-      fprintf(stderr,"Inserting f_byte %s (%d) at %ld\n",
-	      get_instruction_name(b), b,
-	      (long)PC);
-#endif
-  b-=F_OFFSET;
-#ifdef OPCPROF
-  if(store_linenumbers) add_compiled(b);
-#endif
-  if(b>255)
-  {
-    switch(b >> 8)
-    {
-    case 1: low_ins_f_byte(F_ADD_256); break;
-    case 2: low_ins_f_byte(F_ADD_512); break;
-    case 3: low_ins_f_byte(F_ADD_768); break;
-    case 4: low_ins_f_byte(F_ADD_1024); break;
-    default:
-      low_ins_f_byte(F_ADD_256X);
-      ins_byte(b/256,A_PROGRAM);
-    }
-    b&=255;
-  }
-  ins_byte((unsigned char)b,A_PROGRAM);
-}
-
-void ins_f_byte(unsigned int b)
-{
-#ifdef DEBUG
-  if(a_flag>2)
-    fprintf(stderr,">%6lx: %s\n",(long)PC,get_f_name(b));
+#ifdef HANDLES_UNALIGNED_MEMORY_ACCESS
+  *((int *)(areas[A_PROGRAM].s.str+offset))=tmp;
+#else
+  MEMCPY(areas[A_PROGRAM].s.str+offset, (char *)&tmp,sizeof(tmp));
 #endif
-  low_ins_f_byte(b);
 }
 
-static void ins_f_byte_with_numerical_arg(unsigned int a,unsigned int b)
+INT32 read_int(int offset)
 {
-  switch(b >> 8)
-  {
-  case 0 : break;
-  case 1 : low_ins_f_byte(F_PREFIX_256); break;
-  case 2 : low_ins_f_byte(F_PREFIX_512); break;
-  case 3 : low_ins_f_byte(F_PREFIX_768); break;
-  case 4 : low_ins_f_byte(F_PREFIX_1024); break;
-  default:
-    if( b < 256*256)
-    {
-      low_ins_f_byte(F_PREFIX_CHARX256);
-      ins_byte(b>>8, A_PROGRAM);
-    }else if(b < 256*256*256) {
-      low_ins_f_byte(F_PREFIX_WORDX256);
-      ins_byte(b >> 16, A_PROGRAM);
-      ins_byte(b >> 8, A_PROGRAM);
-    }else{
-      low_ins_f_byte(F_PREFIX_24BITX256);
-      ins_byte(b >> 24, A_PROGRAM);
-      ins_byte(b >> 16, A_PROGRAM);
-      ins_byte(b >> 8, A_PROGRAM);
-    }
-  }
-  ins_f_byte(a);
-#ifdef DEBUG
-  if(a_flag>2)
-    fprintf(stderr,">%6lx: argument = %u\n",(long)PC,b);
+  INT32 tmp;
+#ifdef HANDLES_UNALIGNED_MEMORY_ACCESS
+  tmp=*((int *)(areas[A_PROGRAM].s.str+offset));
+#else
+  MEMCPY((char *)&tmp, areas[A_PROGRAM].s.str+offset,sizeof(tmp));
 #endif
-  ins_byte(b, A_PROGRAM);
-}
-
-
-static void ins_int(int i)
-{
-  switch(i)
-  {
-  case 0: ins_f_byte(F_CONST0); break;
-  case 1: ins_f_byte(F_CONST1); break;
-  case -1: ins_f_byte(F_CONST_1); break;
-  default:
-    if(i<0)
-    {
-      ins_f_byte_with_numerical_arg(F_NEG_NUMBER,-i);
-    }else{
-      ins_f_byte_with_numerical_arg(F_NUMBER,i);
-    }
-  }
+  return tmp;
 }
 
-static void ins_float(FLOAT_TYPE f)
-{
-  ins_f_byte(F_FLOAT);
-  add_to_mem_block(A_PROGRAM,(char *)&f,sizeof(FLOAT_TYPE));
-}
+int store_linenumbers=1;
 
 /*
  * A mechanism to remember addresses on a stack. The size of the stack is
@@ -212,173 +116,16 @@ INT32 pop_address()
   return comp_stack[--comp_stackp];
 }
 
-static void do_pop(int nr)
-{
-  if(!nr) return;
-  if(nr==1)
-  {
-    ins_f_byte(F_POP_VALUE);
-  }else if(nr<256){
-    ins_f_byte(F_POP_N_ELEMS);
-    ins_byte(nr,A_PROGRAM);
-  }else{
-    ins_f_byte(F_POP_N_ELEMS);
-    ins_byte(255,A_PROGRAM);
-    do_pop(nr-255);
-  }
-}
-
-/* routines to optimize jumps */
-
-#define JUMP_CONDITIONAL 1
-#define JUMP_UNSET 2
-
-struct jump
-{
-  INT32 relative;
-  INT32 whereto;
-  INT32 wherefrom;
-  INT32 address;
-  unsigned char flags;
-  short token;
-};
-
-static int jump_ptr=0, max_jumps=0;
-static struct jump jumps[256];
-
-static void low_set_branch(INT32 address,INT32 whereto,INT32 relative)
-{
-  int j,e;
-
-  if(address<0) return;
-  j=jump_ptr;
-  e=max_jumps;
-  while(e>=0)
-  {
-    if(jumps[j].address==address && (jumps[j].flags & JUMP_UNSET))
-      break;
-    if(j) j--; else j=max_jumps;
-    e--;
-  }
-  if(e<0) j=-1; /* not found */
-    
-  for(e=0;e<=max_jumps;e++)
-  {
-    if(jumps[e].flags & JUMP_UNSET) continue;
-    if(jumps[e].flags & JUMP_CONDITIONAL) continue;
-    if(jumps[e].wherefrom!=whereto) continue;
-#if defined(LASDEBUG)
-    if(lasdebug>1) printf("Optimized Jump to a jump\n");
-#endif
-    whereto=jumps[e].whereto;
-    break;
-  }
-  
-  if(j>=0)
-  {
-    if(!(jumps[j].flags & JUMP_CONDITIONAL))
-    {
-      for(e=0;e<=max_jumps;e++)
-      {
-	if(jumps[e].flags & JUMP_UNSET) continue;
-	if(jumps[e].whereto==jumps[j].wherefrom)
-	{
-	  upd_int(jumps[e].address,whereto - jumps[e].relative);
-	  jumps[e].whereto=whereto;
-#if defined(LASDEBUG)
-	  if(lasdebug>1) printf("Optimized Jump to a jump\n");
-#endif
-	}
-      }
-    }
-    jumps[j].relative=relative;
-    jumps[j].whereto=whereto;
-    jumps[j].flags&=~JUMP_UNSET;
-  }
-  upd_int(address,whereto - relative);
-}
-
-static void set_branch(INT32 address,INT32 whereto)
-{
-  low_set_branch(address,whereto,address);
-}
 
-static INT32 do_jump(int token,INT32 whereto)
-{
-  jump_ptr=(jump_ptr+1)%NELEM(jumps);
-  if(jump_ptr>max_jumps) max_jumps=jump_ptr;
+static int label_no=0;
 
-  jumps[jump_ptr].flags=JUMP_UNSET;
-  jumps[jump_ptr].whereto=-1;
-  jumps[jump_ptr].token=token;
+static int alloc_label() { return ++label_no; }
 
-  if(token!=F_BRANCH)
-    jumps[jump_ptr].flags|=JUMP_CONDITIONAL;
-
-  if(token>=0)
-  {
-    jumps[jump_ptr].wherefrom=PC;
-    ins_f_byte(token);
-  }else{
-    jumps[jump_ptr].wherefrom=-1;
-  }
-  jumps[jump_ptr].relative=PC;
-  jumps[jump_ptr].address=PC;
-  ins_long(0, A_PROGRAM);
-  if(whereto!=-1) set_branch(jumps[jump_ptr].address, whereto);
-  return jumps[jump_ptr].address;
-}
-
-static void clean_jumptable() { max_jumps=jump_ptr=-1; }
-
-struct jump_list
+static int do_jump(int token,INT32 lbl)
 {
-  int *stack;
-  int current;
-  int size;
-};
-
-static void push_break_stack(struct jump_list *x)
-{
-  x->stack=break_stack;
-  x->current=current_break;
-  x->size=break_stack_size;
-  break_stack_size=10;
-  break_stack=(int *)xalloc(sizeof(int)*break_stack_size);
-  current_break=0;
-}
-
-static void pop_break_stack(struct jump_list *x,int jump)
-{
-  for(current_break--;current_break>=0;current_break--)
-    set_branch(break_stack[current_break],jump);
-
-  free((char *)break_stack);
-  
-  break_stack_size=x->size;
-  current_break=x->current;
-  break_stack=x->stack;
-}
-
-static void push_continue_stack(struct jump_list *x)
-{
-  x->stack=continue_stack;
-  x->current=current_continue;
-  x->size=continue_stack_size;
-  continue_stack_size=10;
-  continue_stack=(int *)xalloc(sizeof(int)*continue_stack_size);
-  current_continue=0;
-}
-
-static void pop_continue_stack(struct jump_list *x,int jump)
-{
-  for(current_continue--;current_continue>=0;current_continue--)
-    set_branch(continue_stack[current_continue],jump);
-
-  free((char *)continue_stack);
-  continue_stack_size=x->size;
-  current_continue=x->current;
-  continue_stack=x->stack;
+  if(lbl==-1) lbl=alloc_label();
+  emit(token, lbl);
+  return lbl;
 }
 
 static int do_docode2(node *n,int flags);
@@ -387,6 +134,17 @@ static int do_docode2(node *n,int flags);
 #define DO_NOT_COPY 2
 #define DO_POP 4
 
+#define ins_label(L) do_jump(F_LABEL, L)
+
+static void do_pop(int x)
+{
+  switch(x)
+  {
+  case 0: return;
+  case 1: emit2(F_POP_VALUE); break;
+  default: emit(F_POP_N_ELEMS,x); break;
+  }
+}
 #define DO_CODE_BLOCK(N) do_pop(do_docode(N,DO_NOT_COPY | DO_POP))
 
 int do_docode(node *n,INT16 flags)
@@ -402,12 +160,6 @@ int do_docode(node *n,INT16 flags)
 }
 
 
-int docode(node *n)
-{
-  clean_jumptable();
-  return do_docode(n,0);
-}
-
 static INT32 do_jump_when_zero(node *n,int j);
 
 static int do_jump_when_non_zero(node *n,int j)
@@ -488,7 +240,7 @@ static int do_docode2(node *n,int flags)
     {
     default:
       yyerror("Illegal lvalue.");
-      ins_int(0);
+      emit(F_NUMBER,0);
       return 1;
 
     case F_LVALUE_LIST:
@@ -509,7 +261,7 @@ static int do_docode2(node *n,int flags)
     {
       fatal("Internal compiler error, Yikes!\n");
     }
-    ins_f_byte(F_PUSH_ARRAY);
+    emit2(F_PUSH_ARRAY);
     return -0x7ffffff;
 
   case '?':
@@ -518,7 +270,7 @@ static int do_docode2(node *n,int flags)
     {
       tmp1=do_jump_when_zero(CAR(n), -1);
       DO_CODE_BLOCK(CADR(n));
-      set_branch(tmp1, PC);
+      emit(F_LABEL, tmp1);
       return 0;
     }
 
@@ -526,7 +278,7 @@ static int do_docode2(node *n,int flags)
     {
       tmp1=do_jump_when_non_zero(CAR(n), -1);
       DO_CODE_BLOCK(CDDR(n));
-      set_branch(tmp1, PC);
+      emit(F_LABEL,tmp1);
       return 0;
     }
 
@@ -545,12 +297,12 @@ static int do_docode2(node *n,int flags)
     do_pop(tmp3 - tmp1);
 
     tmp3=do_jump(F_BRANCH,-1);
-    set_branch(tmp2, PC);
+    emit(F_LABEL, tmp2);
 
     tmp2=do_docode(CDDR(n), flags);
     if(tmp2 < tmp1) fatal("Count arguments was wrong.\n");
     do_pop(tmp2 - tmp1);
-    set_branch(tmp3, PC);
+    emit(F_LABEL, tmp3);
     return tmp1;
   }
       
@@ -574,9 +326,9 @@ static int do_docode2(node *n,int flags)
     {
       if(do_docode(CDR(n), 0)!=1)
 	fatal("Internal compiler error, shit happens\n");
-      ins_f_byte(F_LTOSVAL2);
+      emit2(F_LTOSVAL2);
     }else{
-      ins_f_byte(F_LTOSVAL);
+      emit2(F_LTOSVAL);
       if(do_docode(CDR(n), 0)!=1)
 	fatal("Internal compiler error, shit happens (again)\n");
     }
@@ -584,24 +336,24 @@ static int do_docode2(node *n,int flags)
 
     switch(n->token)
     {
-    case F_ADD_EQ: ins_f_byte(F_ADD); break;
-    case F_AND_EQ: ins_f_byte(F_AND); break;
-    case F_OR_EQ:  ins_f_byte(F_OR);  break;
-    case F_XOR_EQ: ins_f_byte(F_XOR); break;
-    case F_LSH_EQ: ins_f_byte(F_LSH); break;
-    case F_RSH_EQ: ins_f_byte(F_RSH); break;
-    case F_SUB_EQ: ins_f_byte(F_SUBTRACT); break;
-    case F_MULT_EQ:ins_f_byte(F_MULTIPLY);break;
-    case F_MOD_EQ: ins_f_byte(F_MOD); break;
-    case F_DIV_EQ: ins_f_byte(F_DIVIDE); break;
+    case F_ADD_EQ: emit2(F_ADD); break;
+    case F_AND_EQ: emit2(F_AND); break;
+    case F_OR_EQ:  emit2(F_OR);  break;
+    case F_XOR_EQ: emit2(F_XOR); break;
+    case F_LSH_EQ: emit2(F_LSH); break;
+    case F_RSH_EQ: emit2(F_RSH); break;
+    case F_SUB_EQ: emit2(F_SUBTRACT); break;
+    case F_MULT_EQ:emit2(F_MULTIPLY);break;
+    case F_MOD_EQ: emit2(F_MOD); break;
+    case F_DIV_EQ: emit2(F_DIVIDE); break;
     }
 
     if(flags & DO_POP)
     {
-      ins_f_byte(F_ASSIGN_AND_POP);
+      emit2(F_ASSIGN_AND_POP);
       return 0;
     }else{
-      ins_f_byte(F_ASSIGN);
+      emit2(F_ASSIGN);
       return 1;
     }
 
@@ -625,16 +377,16 @@ static int do_docode2(node *n,int flags)
 	{
 	  if(do_docode(CDAR(n),DO_NOT_COPY)!=1)
 	    fatal("Infernal compiler error (dumpar core |ver hela mattan).\n");
-	  ins_f_byte(F_LTOSVAL2);
+	  emit2(F_LTOSVAL2);
 	}else{
-	  ins_f_byte(F_LTOSVAL);
+	  emit2(F_LTOSVAL);
 	  if(do_docode(CDAR(n),DO_NOT_COPY)!=1)
 	    fatal("Infernal compiler error (dumpar core).\n");
 	}
 
-	ins_f_byte(CAR(n)->token);
+	emit2(CAR(n)->token);
 
-	ins_f_byte(n->token);
+	emit2(n->token);
 	return n->token==F_ASSIGN;
       }
 
@@ -648,17 +400,17 @@ static int do_docode2(node *n,int flags)
       switch(CDR(n)->token)
       {
       case F_LOCAL:
-	ins_f_byte(flags & DO_POP ? F_ASSIGN_LOCAL_AND_POP:F_ASSIGN_LOCAL);
-	ins_byte(CDR(n)->u.number,A_PROGRAM);
+	emit(flags & DO_POP ? F_ASSIGN_LOCAL_AND_POP:F_ASSIGN_LOCAL,
+	     CDR(n)->u.number );
 	break;
 
       case F_GLOBAL:
-	ins_f_byte(flags & DO_POP ? F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL);
-	ins_byte(CDR(n)->u.number,A_PROGRAM);
+	emit(flags & DO_POP ? F_ASSIGN_GLOBAL_AND_POP:F_ASSIGN_GLOBAL,
+	     CDR(n)->u.number);
 	break;
 
       default:
-	ins_f_byte(flags & DO_POP ? F_ASSIGN_AND_POP:F_ASSIGN);
+	emit2(flags & DO_POP ? F_ASSIGN_AND_POP:F_ASSIGN);
 	break;
       }
       return flags & DO_POP ? 0 : 1;
@@ -671,7 +423,7 @@ static int do_docode2(node *n,int flags)
     tmp1=do_jump(n->token,-1);
     if(do_docode(CDR(n),0)!=1)
       fatal("Compiler internal error.\n");
-    set_branch(tmp1,PC);
+    emit(F_LABEL,tmp1);
     return 1;
 
   case F_EQ:
@@ -699,7 +451,7 @@ static int do_docode2(node *n,int flags)
     tmp1=do_docode(CAR(n),DO_NOT_COPY);
     if(do_docode(CDR(n),DO_NOT_COPY)!=2)
       fatal("Compiler internal error.\n");
-    ins_f_byte(n->token);
+    emit2(n->token);
     return tmp1;
 
   case F_INC:
@@ -712,10 +464,10 @@ static int do_docode2(node *n,int flags)
 
     if(flags & DO_POP)
     {
-      ins_f_byte(F_INC_AND_POP);
+      emit2(F_INC_AND_POP);
       return 0;
     }else{
-      ins_f_byte(n->token);
+      emit2(n->token);
       return 1;
     }
 
@@ -728,36 +480,40 @@ static int do_docode2(node *n,int flags)
 #endif
     if(flags & DO_POP)
     {
-      ins_f_byte(F_DEC_AND_POP);
+      emit2(F_DEC_AND_POP);
       return 0;
     }else{
-      ins_f_byte(n->token);
+      emit2(n->token);
       return 1;
     }
 
   case F_FOR:
   {
-    struct jump_list brk,cnt;
     INT32 *prev_switch_jumptable = current_switch_jumptable;
+    INT32 break_save = current_break;
+    INT32 continue_save = current_continue;
+    
     current_switch_jumptable=0;
+    current_break=alloc_label();
+    current_continue=alloc_label();
 
-    push_break_stack(&brk);
-    push_continue_stack(&cnt);
     if(CDR(n))
     {
       tmp1=do_jump(F_BRANCH,-1);
-      tmp2=PC;
+      tmp2=ins_label(-1);
       if(CDR(n)) DO_CODE_BLOCK(CADR(n));
-      pop_continue_stack(&cnt,PC);
+      ins_label(current_continue);
       if(CDR(n)) DO_CODE_BLOCK(CDDR(n));
-      set_branch(tmp1,PC);
+      emit(F_LABEL,tmp1);
     }else{
       tmp2=PC;
     }
     do_jump_when_non_zero(CAR(n),tmp2);
-    pop_break_stack(&brk,PC);
+    ins_label(current_break);
 
     current_switch_jumptable = prev_switch_jumptable;
+    current_break=break_save;
+    current_continue=continue_save;
     return 0;
   }
 
@@ -766,23 +522,27 @@ static int do_docode2(node *n,int flags)
 
   case F_FOREACH:
   {
-    struct jump_list cnt,brk;
     INT32 *prev_switch_jumptable = current_switch_jumptable;
+    INT32 break_save = current_break;
+    INT32 continue_save = current_continue;
+
     current_switch_jumptable=0;
+    current_break=alloc_label();
+    current_continue=alloc_label();
 
     tmp2=do_docode(CAR(n),DO_NOT_COPY);
-    ins_f_byte(F_CONST0);
+    emit2(F_CONST0);
     tmp3=do_jump(F_BRANCH,-1);
-    tmp1=PC;
-    push_break_stack(&brk);
-    push_continue_stack(&cnt);
+    tmp1=ins_label(-1);
     DO_CODE_BLOCK(CDR(n));
-    pop_continue_stack(&cnt,PC);
-    set_branch(tmp3,PC);
+    ins_label(current_continue);
+    emit(F_LABEL,tmp3);
     do_jump(n->token,tmp1);
-    pop_break_stack(&brk,PC);
+    ins_label(current_break);
 
     current_switch_jumptable = prev_switch_jumptable;
+    current_break=break_save;
+    current_continue=continue_save;
     return 0;
   }
 
@@ -791,40 +551,49 @@ static int do_docode2(node *n,int flags)
   case F_INC_LOOP:
   case F_DEC_LOOP:
   {
-    struct jump_list cnt,brk;
     INT32 *prev_switch_jumptable = current_switch_jumptable;
+    INT32 break_save = current_break;
+    INT32 continue_save = current_continue;
+
     current_switch_jumptable=0;
+    current_break=alloc_label();
+    current_continue=alloc_label();
 
     tmp2=do_docode(CAR(n),0);
     tmp3=do_jump(F_BRANCH,-1);
-    tmp1=PC;
-    push_break_stack(&brk);
-    push_continue_stack(&cnt);
+    tmp1=ins_label(-1);
+
     DO_CODE_BLOCK(CDR(n));
-    pop_continue_stack(&cnt,PC);
-    set_branch(tmp3,PC);
+    ins_label(current_continue);
+    emit(F_LABEL,tmp3);
     do_jump(n->token,tmp1);
-    pop_break_stack(&brk,PC);
+    ins_label(current_break);
 
     current_switch_jumptable = prev_switch_jumptable;
+    current_break=break_save;
+    current_continue=continue_save;
     return 0;
   }
 
   case F_DO:
   {
-    struct jump_list cnt,brk;
     INT32 *prev_switch_jumptable = current_switch_jumptable;
+    INT32 break_save = current_break;
+    INT32 continue_save = current_continue;
+
     current_switch_jumptable=0;
+    current_break=alloc_label();
+    current_continue=alloc_label();
 
-    tmp2=PC;
-    push_break_stack(&brk);
-    push_continue_stack(&cnt);
+    tmp2=ins_label(-1);
     DO_CODE_BLOCK(CAR(n));
-    pop_continue_stack(&cnt,PC);
+    ins_label(current_continue);
     do_jump_when_non_zero(CDR(n),tmp2);
-    pop_break_stack(&brk,PC);
+    ins_label(current_break);
 
     current_switch_jumptable = prev_switch_jumptable;
+    current_break=break_save;
+    current_continue=continue_save;
     return 0;
   }
 
@@ -836,12 +605,12 @@ static int do_docode2(node *n,int flags)
     }
 
     tmp1=do_docode(CAR(n),0);
-    if(!tmp1) { ins_f_byte(F_CONST0); tmp1=1; }
+    if(!tmp1) { emit2(F_CONST0); tmp1=1; }
     if(tmp1>1) do_pop(tmp1-1);
 
     tmp1=store_prog_string(n->type);
-    ins_f_byte_with_numerical_arg(F_STRING,tmp1);
-    ins_f_byte(F_CAST);
+    emit(F_STRING,tmp1);
+    emit2(F_CAST);
     return 1;
 
   case F_APPLY:
@@ -854,39 +623,39 @@ static int do_docode2(node *n,int flags)
 	  if(!CAR(n)->u.sval.u.efun->docode || 
 	     !CAR(n)->u.sval.u.efun->docode(n))
 	  {
-	    ins_f_byte(F_MARK);
+	    emit2(F_MARK);
 	    do_docode(CDR(n),0);
 	    tmp1=store_constant(& CAR(n)->u.sval,
 				!(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND));
-	    ins_f_byte(F_MAX_OPCODE + tmp1);
+	    emit(F_APPLY,tmp1);
 	  }
 	  if(n->type == void_type_string) return 0;
 	  return 1;
 	}else{
 	  if(CAR(n)->u.sval.u.object == &fake_object)
 	  {
-	    ins_f_byte(F_MARK);
+	    emit2(F_MARK);
 	    do_docode(CDR(n),0);
-	    ins_f_byte_with_numerical_arg(F_CALL_LFUN, CAR(n)->u.sval.subtype);
+	    emit(F_CALL_LFUN, CAR(n)->u.sval.subtype);
 	    return 1;
 	  }
        	}
       }
 
-      ins_f_byte(F_MARK);
+      emit2(F_MARK);
       do_docode(CDR(n),0);
       tmp1=store_constant(& CAR(n)->u.sval,
 			  !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND));
-      ins_f_byte(F_MAX_OPCODE + tmp1);
+      emit(F_APPLY,tmp1);
       
       return 1;
     }
     else if(CAR(n)->token == F_IDENTIFIER &&
 	    ID_FROM_INT(& fake_program, CAR(n)->u.number)->flags & IDENTIFIER_FUNCTION)
     {
-      ins_f_byte(F_MARK);
+      emit2(F_MARK);
       do_docode(CDR(n),0);
-      ins_f_byte_with_numerical_arg(F_CALL_LFUN, CAR(n)->u.number);
+      emit(F_CALL_LFUN, CAR(n)->u.number);
       return 1;
     }
     else
@@ -894,7 +663,7 @@ static int do_docode2(node *n,int flags)
       struct lpc_string *tmp;
       struct efun *fun;
 
-      ins_f_byte(F_MARK);
+      emit2(F_MARK);
       tmp=make_shared_string("call_function");
       if(!tmp) yyerror("No call_function efun.");
       fun=lookup_efun(tmp);
@@ -904,7 +673,7 @@ static int do_docode2(node *n,int flags)
       do_docode(CAR(n),0);
       do_docode(CDR(n),0);
       tmp1=store_constant(& fun->function, 1);
-      ins_f_byte(tmp1 + F_MAX_OPCODE);
+      emit(F_APPLY, tmp1);
       return 1;
     }
 
@@ -929,27 +698,24 @@ static int do_docode2(node *n,int flags)
 
   case F_SWITCH:
   {
-    struct jump_list brk;
     INT32 e,cases,*order;
     INT32 *jumptable;
     INT32 prev_switch_values_on_stack = current_switch_values_on_stack;
     INT32 prev_switch_case = current_switch_case;
     INT32 prev_switch_default = current_switch_default;
     INT32 *prev_switch_jumptable = current_switch_jumptable;
+    INT32 break_save = current_break;
 
     if(do_docode(CAR(n),0)!=1)
       fatal("Internal compiler error, time to panic\n");
 
-    push_break_stack(&brk);
+    current_break=alloc_label();
 
     cases=count_cases(CDR(n));
 
-    ins_f_byte(F_SWITCH);
-    tmp1=PC;
-    ins_short(0, A_PROGRAM);
-    while(PC != (unsigned INT32)MY_ALIGN(PC))
-      ins_byte(0, A_PROGRAM);
-    tmp2=PC;
+    tmp1=emit(F_SWITCH,0);
+    emit(F_ALIGN,sizeof(INT32));
+
     current_switch_values_on_stack=0;
     current_switch_case=0;
     current_switch_default=-1;
@@ -958,29 +724,30 @@ static int do_docode2(node *n,int flags)
 
     for(e=0; e<cases*2+1; e++)
     {
-      jumptable[e]=do_jump(-1,-1);
+      jumptable[e]=emit(F_POINTER, 0);
       current_switch_jumptable[e]=-1;
     }
 
     current_switch_jumptable[current_switch_case++]=-1;
 
     DO_CODE_BLOCK(CDR(n));
-
+    
     f_aggregate(cases);
-    sp[-1].u.array=compact_array(sp[-1].u.array);
     order=get_switch_order(sp[-1].u.array);
-    
+
+    /* Check for cases inside a range */
     for(e=0; e<cases-1; e++)
     {
-      if(current_switch_jumptable[order[e]*2+2] != -1)
+      if(current_switch_jumptable[ order[e]*2+2 ] != -1)
       {
-	if(current_switch_jumptable[order[e]*2+2] !=
-	   current_switch_jumptable[order[e+1]*2+1])
+	if(current_switch_jumptable[ order[e]*2+2 ] !=
+	   current_switch_jumptable[ order[e+1]*2+1 ])
 	  yyerror("Case inside range.");
       }
     }
 
-    if(current_switch_default < 0) current_switch_default = PC;
+    if(current_switch_default < 0)
+      current_switch_default = ins_label(-1);
 
     for(e=0;e<cases*2+1;e++)
       if(current_switch_jumptable[e]==-1)
@@ -992,10 +759,9 @@ static int do_docode2(node *n,int flags)
     free((char *)order);
 
     for(e=0; e<cases*2+1; e++)
-      low_set_branch(jumptable[e], current_switch_jumptable[e],tmp2);
+      update_arg(jumptable[e], current_switch_jumptable[e]);
 
-    e=store_constant(sp-1,1);
-    upd_short(tmp1,e);
+    update_arg(tmp1, store_constant(sp-1,1));
 
     pop_stack();
     free((char *)jumptable);
@@ -1006,8 +772,9 @@ static int do_docode2(node *n,int flags)
     current_switch_case = prev_switch_case;
     current_switch_values_on_stack = prev_switch_values_on_stack ;
 
-    pop_break_stack(&brk,PC);
+    emit(F_LABEL, current_break);
 
+    current_break=break_save;
     return 0;
   }
 
@@ -1032,11 +799,17 @@ static int do_docode2(node *n,int flags)
 	if(is_equal(sp-tmp1, sp-1))
 	  yyerror("Duplicate case.");
 
-      current_switch_jumptable[current_switch_case++]=PC;
+      current_switch_jumptable[current_switch_case++]=ins_label(-1);
 
       if(CDR(n))
       {
-	current_switch_jumptable[current_switch_case++]=PC;
+	if(!is_const(CDR(n)))
+	  yyerror("Case label isn't constant.");
+
+	current_switch_jumptable[current_switch_case+1]=
+	  current_switch_jumptable[current_switch_case]=
+	    current_switch_jumptable[current_switch_case-1];
+	current_switch_case+=2;
 	tmp1=eval_low(CDR(n));
 	if(tmp1<1)
 	{
@@ -1049,7 +822,6 @@ static int do_docode2(node *n,int flags)
 	for(tmp1=current_switch_values_on_stack; tmp1 > 1; tmp1--)
 	  if(is_equal(sp-tmp1, sp-1))
 	    yyerror("Duplicate case.");
-	current_switch_jumptable[current_switch_case++]=PC;
       }
       current_switch_jumptable[current_switch_case++]=-1;
     }
@@ -1063,74 +835,58 @@ static int do_docode2(node *n,int flags)
     }else if(current_switch_default!=-1){
       yyerror("Duplicate switch default.");
     }else{
-      current_switch_default = PC;
+      current_switch_default = ins_label(-1);
     }
     return 0;
 
   case F_BREAK:
-    if(!break_stack)
+    if(current_break == -1)
     {
       yyerror("Break outside loop or switch.");
     }else{
-      if(current_break>=break_stack_size)
-      {
-	break_stack_size*=2;
-	break_stack=(int *)realloc((char *)break_stack,
-				   sizeof(int)*break_stack_size);
-	if(!break_stack)
-	  fatal("Out of memory.\n");
-      }
-      break_stack[current_break++]=do_jump(F_BRANCH,-1);
+      do_jump(F_BRANCH, current_break);
     }
     return 0;
 
   case F_CONTINUE:
-    if(!continue_stack)
+    if(current_continue == -1)
     {
       yyerror("continue outside loop or switch.");
     }else{
-      if(current_continue>=continue_stack_size)
-      {
-	continue_stack_size*=2;
-	continue_stack=(int *)realloc((char *)continue_stack,
-				      sizeof(int)*continue_stack_size);
-      }
-      continue_stack[current_continue++]=do_jump(F_BRANCH,-1);
+      do_jump(F_BRANCH, current_continue);
     }
     return 0;
 
   case F_RETURN:
-    if(!CAR(n) ||
-       (CAR(n)->token == F_CONSTANT && IS_ZERO(&CAR(n)->u.sval)) ||
-       do_docode(CAR(n),0)<0)
-    {
-      ins_f_byte(F_RETURN_0);
-    }else{
-      ins_f_byte(F_RETURN);
-    }
+    do_docode(CAR(n),0);
+    emit2(F_RETURN);
     return 0;
 
   case F_SSCANF:
     tmp1=do_docode(CAR(n),DO_NOT_COPY);
     tmp2=do_docode(CDR(n),DO_NOT_COPY | DO_LVALUE);
-    ins_f_byte_with_numerical_arg(F_SSCANF,tmp1+tmp2);
+    emit(F_SSCANF,tmp1+tmp2);
     return 1;
 
   case F_CATCH:
   {
-    struct jump_list cnt,brk;
+    INT32 break_save = current_break;
+    INT32 continue_save = current_continue;
     INT32 *prev_switch_jumptable = current_switch_jumptable;
+
     current_switch_jumptable=0;
+    current_break=alloc_label();
+    current_continue=alloc_label();
 
     tmp1=do_jump(F_CATCH,-1);
-    push_break_stack(&brk);
-    push_continue_stack(&cnt);
     DO_CODE_BLOCK(CAR(n));
-    pop_continue_stack(&cnt,PC);
-    pop_break_stack(&brk,PC);
-    ins_f_byte(F_DUMB_RETURN);
-    set_branch(tmp1,PC);
+    ins_label(current_continue);
+    ins_label(current_break);
+    emit2(F_DUMB_RETURN);
+    emit(F_LABEL,tmp1);
 
+    current_break=break_save;
+    current_continue=continue_save;
     current_switch_jumptable = prev_switch_jumptable;
     return 1;
   }
@@ -1149,12 +905,12 @@ static int do_docode2(node *n,int flags)
       tmp1=do_docode(CAR(n), DO_NOT_COPY);
       if(do_docode(CDR(n),DO_NOT_COPY) != 1)
 	fatal("Internal compiler error, please report this (1).");
-      ins_f_byte(F_INDEX);
+      emit2(F_INDEX);
       if(!(flags & DO_NOT_COPY))
       {
 	while(n && n->token==F_INDEX) n=CAR(n);
 	if(n->token==F_CONSTANT && !(n->node_info & OPT_EXTERNAL_DEPEND))
-	  ins_f_byte(F_COPY_VALUE);
+	  emit2(F_COPY_VALUE);
       }
     }
     return tmp1;
@@ -1163,16 +919,12 @@ static int do_docode2(node *n,int flags)
     switch(n->u.sval.type)
     {
     case T_INT:
-      ins_int(n->u.sval.u.integer);
-      return 1;
-
-    case T_FLOAT:
-      ins_float(n->u.sval.u.float_number);
+      emit(F_NUMBER,n->u.sval.u.integer);
       return 1;
 
     case T_STRING:
       tmp1=store_prog_string(n->u.sval.u.string);
-      ins_f_byte_with_numerical_arg(F_STRING,tmp1);
+      emit(F_STRING,tmp1);
       return 1;
 
     case T_FUNCTION:
@@ -1180,25 +932,25 @@ static int do_docode2(node *n,int flags)
       {
 	if(n->u.sval.u.object == &fake_object)
 	{
-	  ins_f_byte_with_numerical_arg(F_LFUN,n->u.sval.subtype);
+	  emit(F_LFUN,n->u.sval.subtype);
 	  return 1;
 	}
       }
 
     default:
       tmp1=store_constant(&(n->u.sval),!(n->tree_info & OPT_EXTERNAL_DEPEND));
-      ins_f_byte_with_numerical_arg(F_CONSTANT,tmp1);
+      emit(F_CONSTANT,tmp1);
       return 1;
 
     case T_ARRAY:
     case T_MAPPING:
     case T_LIST:
       tmp1=store_constant(&(n->u.sval),!(n->tree_info & OPT_EXTERNAL_DEPEND));
-      ins_f_byte_with_numerical_arg(F_CONSTANT,tmp1);
+      emit(F_CONSTANT,tmp1);
       
       /* copy now or later ? */
       if(!(flags & DO_NOT_COPY) && !(n->tree_info & OPT_EXTERNAL_DEPEND))
-	ins_f_byte(F_COPY_VALUE);
+	emit2(F_COPY_VALUE);
       return 1;
 
     }
@@ -1206,10 +958,10 @@ static int do_docode2(node *n,int flags)
   case F_LOCAL:
     if(flags & DO_LVALUE)
     {
-      ins_f_byte_with_numerical_arg(F_LOCAL_LVALUE,n->u.number);
+      emit(F_LOCAL_LVALUE,n->u.number);
       return 2;
     }else{
-      ins_f_byte_with_numerical_arg(F_LOCAL,n->u.number);
+      emit(F_LOCAL,n->u.number);
       return 1;
     }
 
@@ -1220,21 +972,21 @@ static int do_docode2(node *n,int flags)
       {
 	yyerror("Cannot assign functions.\n");
       }else{
-	ins_f_byte_with_numerical_arg(F_LFUN,n->u.number);
+	emit(F_LFUN,n->u.number);
       }
     }else{
       if(flags & DO_LVALUE)
       {
-	ins_f_byte_with_numerical_arg(F_GLOBAL_LVALUE,n->u.number);
+	emit(F_GLOBAL_LVALUE,n->u.number);
 	return 2;
       }else{
-	ins_f_byte_with_numerical_arg(F_GLOBAL,n->u.number);
+	emit(F_GLOBAL,n->u.number);
       }
     }
     return 1;
 
   case F_EFUN:
-    ins_f_byte_with_numerical_arg(n->token,n->u.number);
+    emit(n->token,n->u.number);
     return 1;
 
   case F_VAL_LVAL:
@@ -1248,6 +1000,28 @@ static int do_docode2(node *n,int flags)
 
 void do_code_block(node *n)
 {
-  clean_jumptable();
+  init_bytecode();
+  label_no=0;
   DO_CODE_BLOCK(n);
+  asm_opt();
+  assemble();
+}
+
+int docode(node *n)
+{
+  int tmp;
+  int label_no_save = label_no;
+  dynamic_buffer instrbuf_save = instrbuf;
+
+  instrbuf.s.str=0;
+  label_no=0;
+  init_bytecode();
+
+  tmp=do_docode(n,0);
+  asm_opt();
+  assemble();
+
+  instrbuf=instrbuf_save;
+  label_no = label_no_save;
+  return tmp;
 }
-- 
GitLab


From 2199ede642e50d47025620c2bd9b167a5cb0a3ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 05:09:01 +0200
Subject: [PATCH 106/351] peephole optimizer added

Rev: src/peep.c:1.1
Rev: src/peep.h:1.1
Rev: src/peep.in:1.1
---
 src/peep.c  | 513 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/peep.h  |  22 +++
 src/peep.in |  86 +++++++++
 3 files changed, 621 insertions(+)
 create mode 100644 src/peep.c
 create mode 100644 src/peep.h
 create mode 100644 src/peep.in

diff --git a/src/peep.c b/src/peep.c
new file mode 100644
index 0000000000..8795c4336f
--- /dev/null
+++ b/src/peep.c
@@ -0,0 +1,513 @@
+#include "global.h"
+#include "types.h"
+#include "language.h"
+#include "stralloc.h"
+#include "dynamic_buffer.h"
+#include "program.h"
+#include "las.h"
+#include "docode.h"
+#include "main.h"
+#include "error.h"
+#include "lex.h"
+
+struct p_instr_s
+{
+  short opcode;
+  short line;
+  struct lpc_string *file;
+  INT32 arg;
+};
+
+typedef struct p_instr_s p_instr;
+
+dynamic_buffer instrbuf;
+
+static int hasarg(int opcode)
+{
+  switch(opcode)
+  {
+  case F_NUMBER:
+  case F_NEG_NUMBER:
+  case F_CALL_LFUN:
+  case F_SSCANF:
+  case F_POP_N_ELEMS:
+
+  case F_ASSIGN_GLOBAL:
+  case F_ASSIGN_GLOBAL_AND_POP:
+  case F_ASSIGN_LOCAL:
+  case F_ASSIGN_LOCAL_AND_POP:
+  case F_GLOBAL_LVALUE:
+  case F_LOCAL_LVALUE:
+  case F_CLEAR_LOCAL:
+  case F_LOCAL:
+  case F_GLOBAL:
+
+  case F_INC_LOCAL:
+  case F_DEC_LOCAL:
+  case F_POST_INC_LOCAL:
+  case F_POST_DEC_LOCAL:
+  case F_INC_LOCAL_AND_POP:
+  case F_DEC_LOCAL_AND_POP:
+
+  case F_LFUN:
+  case F_STRING:
+  case F_CONSTANT:
+  case F_SWITCH:
+  case F_APPLY:
+  case F_CATCH:
+
+  case F_BRANCH:
+  case F_BRANCH_WHEN_ZERO:
+  case F_BRANCH_WHEN_NON_ZERO:
+
+  case F_BRANCH_WHEN_EQ:
+  case F_BRANCH_WHEN_NE:
+  case F_BRANCH_WHEN_LT:
+  case F_BRANCH_WHEN_LE:
+  case F_BRANCH_WHEN_GT:
+  case F_BRANCH_WHEN_GE:
+
+  case F_FOREACH:
+  case F_INC_LOOP:
+  case F_DEC_LOOP:
+  case F_INC_NEQ_LOOP:
+  case F_DEC_NEQ_LOOP:
+
+  case F_LAND:
+  case F_LOR:
+
+  case F_ALIGN:
+  case F_POINTER:
+  case F_LABEL:
+    return 1;
+    
+  default:
+    return 0;
+  }
+}
+
+void init_bytecode()
+{
+  low_init_buf(&instrbuf);
+}
+
+void exit_bytecode()
+{
+  INT32 e,length;
+  p_instr *c;
+
+  c=(p_instr *)instrbuf.s.str;
+  length=instrbuf.s.len / sizeof(p_instr);
+
+  for(e=0;e<length;e++) free_string(c->file);
+  
+  toss_buffer(&instrbuf);
+}
+
+int insert_opcode(unsigned int f,
+		  INT32 b,
+		  INT32 current_line,
+		  struct lpc_string *current_file)
+{
+  p_instr *p;
+
+#ifdef DEBUG
+  if(!hasarg(f) && b)
+    fatal("hasarg() is wrong!\n");
+#endif
+
+  p=(p_instr *)low_make_buf_space(sizeof(p_instr), &instrbuf);
+
+
+#ifdef DEBUG
+  if(!instrbuf.s.len)
+    fatal("Low make buf space failed!!!!!!\n");
+#endif
+
+  p->opcode=f;
+  p->line=current_line;
+  copy_shared_string(p->file, current_file);
+  p->arg=b;
+
+  return p - (p_instr *)instrbuf.s.str;
+}
+
+int insert_opcode2(int f,int current_line, struct lpc_string *current_file)
+{
+#ifdef DEBUG
+  if(hasarg(f))
+    fatal("hasarg() is wrong!\n");
+#endif
+  return insert_opcode(f,0,current_line, current_file);
+}
+
+void update_arg(int instr,INT32 arg)
+{
+  p_instr *p;
+#ifdef DEBUG
+  if(instr > instrbuf.s.len / sizeof(p_instr) || instr < 0)
+    fatal("update_arg outside known space.\n");
+#endif  
+  p=(p_instr *)instrbuf.s.str;
+  p[instr].arg=arg;
+}
+
+
+/**** Bytecode Generator *****/
+
+void ins_f_byte(unsigned int b)
+{
+  b-=F_OFFSET;
+#ifdef OPCPROF
+  if(store_linenumbers) add_compiled(b);
+#endif
+  if(b>255)
+  {
+    switch(b >> 8)
+    {
+    case 1: ins_f_byte(F_ADD_256); break;
+    case 2: ins_f_byte(F_ADD_512); break;
+    case 3: ins_f_byte(F_ADD_768); break;
+    case 4: ins_f_byte(F_ADD_1024); break;
+    default:
+      ins_f_byte(F_ADD_256X);
+      ins_byte(b/256,A_PROGRAM);
+    }
+    b&=255;
+  }
+  ins_byte((unsigned char)b,A_PROGRAM);
+}
+
+static void ins_f_byte_with_arg(unsigned int a,unsigned INT32 b)
+{
+  switch(b >> 8)
+  {
+  case 0 : break;
+  case 1 : ins_f_byte(F_PREFIX_256); break;
+  case 2 : ins_f_byte(F_PREFIX_512); break;
+  case 3 : ins_f_byte(F_PREFIX_768); break;
+  case 4 : ins_f_byte(F_PREFIX_1024); break;
+  default:
+    if( b < 256*256)
+    {
+      ins_f_byte(F_PREFIX_CHARX256);
+      ins_byte(b>>8, A_PROGRAM);
+    }else if(b < 256*256*256) {
+      ins_f_byte(F_PREFIX_WORDX256);
+      ins_byte(b >> 16, A_PROGRAM);
+      ins_byte(b >> 8, A_PROGRAM);
+    }else{
+      ins_f_byte(F_PREFIX_24BITX256);
+      ins_byte(b >> 24, A_PROGRAM);
+      ins_byte(b >> 16, A_PROGRAM);
+      ins_byte(b >> 8, A_PROGRAM);
+    }
+  }
+  ins_f_byte(a);
+  ins_byte(b, A_PROGRAM);
+}
+
+void assemble()
+{
+  INT32 e,d,length,max_label,tmp;
+  INT32 *labels, *jumps, *point;
+  p_instr *c;
+
+  c=(p_instr *)instrbuf.s.str;
+  length=instrbuf.s.len / sizeof(p_instr);
+
+  max_label=0;
+  for(e=0;e<length;e++,c++)
+    if(c->opcode == F_LABEL)
+      if(c->arg > max_label)
+	max_label = c->arg;
+
+
+  labels=(INT32 *)xalloc(sizeof(INT32) * (max_label+1));
+  jumps=(INT32 *)xalloc(sizeof(INT32) * (max_label+1));
+  point=(INT32 *)xalloc(sizeof(INT32) * (max_label+1));
+
+  for(e=0;e<=max_label;e++) point[e]=labels[e]=jumps[e]=-1;
+
+  c=(p_instr *)instrbuf.s.str;
+  for(e=0;e<length;e++)
+  {
+#ifdef DEBUG
+    if(a_flag > 2 && store_linenumbers)
+    {
+      if(hasarg(c->opcode))
+	fprintf(stderr,"===%3d %4x %s(%d)\n",c->line,PC,get_token_name(c->opcode),c->arg);
+      else
+	fprintf(stderr,"===%3d %4x %s\n",c->line,PC,get_token_name(c->opcode));
+    }
+#endif
+
+    if(store_linenumbers)
+      store_linenumber(c->line, c->file);
+
+    switch(c->opcode)
+    {
+    case F_ALIGN:
+      while(PC % c->arg) ins_byte(0, A_PROGRAM);
+      break;
+
+    case F_LABEL:
+#ifdef DEBUG
+      if(c->arg > max_label || c->arg < 0)
+	fatal("max_label calculation failed!\n");
+
+      if(labels[c->arg] != -1)
+	fatal("Duplicate label!\n");
+#endif
+      labels[c->arg]=PC;
+
+      for(d=1;e+d<length;d++)
+      {
+	switch(c[d].opcode)
+	{
+	case F_LABEL: continue;
+	case F_BRANCH: point[c->arg]=c[d].arg;
+	}
+	break;
+      }
+      break;
+
+    case F_BRANCH_WHEN_EQ:
+    case F_BRANCH_WHEN_NE:
+    case F_BRANCH_WHEN_LT:
+    case F_BRANCH_WHEN_LE:
+    case F_BRANCH_WHEN_GT:
+    case F_BRANCH_WHEN_GE:
+    case F_BRANCH_WHEN_ZERO:
+    case F_BRANCH_WHEN_NON_ZERO:
+    case F_BRANCH:
+    case F_INC_LOOP:
+    case F_DEC_LOOP:
+    case F_INC_NEQ_LOOP:
+    case F_DEC_NEQ_LOOP:
+    case F_LAND:
+    case F_LOR:
+    case F_CATCH:
+    case F_FOREACH:
+      ins_f_byte(c->opcode);
+
+    case F_POINTER:
+#ifdef DEBUG
+      if(c->arg > max_label || c->arg < 0) fatal("Jump to unknown label?\n");
+#endif
+      tmp=PC;
+      ins_int(jumps[c->arg],A_PROGRAM);
+      jumps[c->arg]=tmp;
+      break;
+
+    case F_APPLY:
+      ins_f_byte(c->arg + F_MAX_OPCODE);
+      break;
+
+    default:
+      if(hasarg(c->opcode))
+	ins_f_byte_with_arg(c->opcode, c->arg);
+      else
+	ins_f_byte(c->opcode);
+      break;
+    }
+    
+    c++;
+  }
+
+  for(e=0;e<=max_label;e++)
+  {
+    int tmp2;
+    tmp2=e;
+    while(point[tmp2]!=-1) tmp2=point[tmp2];
+    tmp2=labels[tmp2];
+
+    while(jumps[e]!=-1)
+    {
+#ifdef DEBUG
+      if(labels[e]==-1)
+	fatal("Hyperspace error: unknown jump point.\n");
+#endif
+      tmp=read_int(jumps[e]);
+      upd_int(jumps[e], tmp2 - jumps[e]);
+      jumps[e]=tmp;
+    }
+  }
+
+  free((char *)labels);
+  free((char *)jumps);
+  free((char *)point);
+
+  exit_bytecode();
+}
+
+/**** Peephole optimizer ****/
+
+static int fifo_len, eye,len;
+static p_instr *instrs;
+
+#ifdef DEBUG
+static void debug()
+{
+  p_instr *p;
+
+  if(fifo_len > instrbuf.s.len / sizeof(p_instr))
+    fatal("Fifo too long.\n");
+
+  if(eye < 0)
+    fatal("Popped beyond start of code.\n");
+
+  if(instrbuf.s.len)
+  {
+    p=(p_instr *)low_make_buf_space(0, &instrbuf);
+    if(!p[-1].file)
+      fatal("No file name on last instruction!\n");
+  }
+}
+#else
+#define debug()
+#endif
+
+
+static p_instr *instr(int offset)
+{
+  p_instr *p;
+
+  debug();
+
+  if(offset >= 0)
+  {
+    if(offset < fifo_len)
+    {
+      p=(p_instr *)low_make_buf_space(0, &instrbuf);
+      p-=fifo_len;
+      p+=offset;
+      return p;
+    }else{
+      offset-=fifo_len;
+      offset+=eye;
+      if(offset >= len) return 0;
+      return instrs+offset;
+    }
+  }else{
+    fatal("Can't handle negative offsets in peephole optimizer!\n");
+  }
+}
+
+static int opcode(int offset)
+{
+  p_instr *a;
+  a=instr(offset);
+  if(a) return a->opcode;
+  return -1;
+}
+
+static int argument(int offset)
+{
+  p_instr *a;
+  a=instr(offset);
+  if(a) return a->arg;
+  return -1;
+}
+
+static void advance()
+{
+  if(fifo_len)
+  {
+    fifo_len--;
+  }else{
+    p_instr *p;
+    if(p=instr(0))
+      insert_opcode(p->opcode, p->arg, p->line, p->file);
+    eye++;
+  }
+  debug();
+}
+
+static void pop_n_opcodes(int n)
+{
+  while(n>0)
+  {
+    if(fifo_len)
+    {
+      p_instr *p;
+
+#ifdef DEBUG
+      if(instrbuf.s.len <= 0)
+	fatal("Popping out of opcodes.\n");
+#endif
+      low_make_buf_space(-sizeof(p_instr), &instrbuf);
+      p=(p_instr *)low_make_buf_space(0, &instrbuf);
+      
+      free_string(p->file);
+      fifo_len--;
+    }else{
+      eye++;
+    }
+    n--;
+  }
+}
+
+#define insert(X,Y) insert_opcode((X),(Y),current_line, current_file),dofix()
+#define insert2(X) insert_opcode2((X),current_line, current_file),dofix()
+
+static void dofix()
+{
+  p_instr *p,tmp;
+  int e;
+
+  if(fifo_len)
+  {
+    p=(p_instr *)low_make_buf_space(0, &instrbuf);
+    tmp=p[-1];
+    for(e=0;e<fifo_len;e++)
+      p[-1-e]=p[-2-e];
+    p[-1-e]=tmp;
+  }
+}
+
+
+void asm_opt()
+{
+#ifdef DEBUG
+  if(a_flag > 3)
+  {
+    p_instr *c;
+    INT32 e,length;
+    c=(p_instr *)instrbuf.s.str;
+    length=instrbuf.s.len / sizeof(p_instr);
+
+    fprintf(stderr,"Optimization begins: \n");
+    for(e=0;e<length;e++,c++)
+    {
+      if(hasarg(c->opcode))
+	fprintf(stderr,"---%3d: %s(%d)\n",c->line,get_token_name(c->opcode),c->arg);
+      else
+	fprintf(stderr,"---%3d: %s\n",c->line,get_token_name(c->opcode));
+    }
+  }
+#endif
+
+#include "peep_engine.c"
+
+
+#ifdef DEBUG
+  if(a_flag > 4)
+  {
+    p_instr *c;
+    INT32 e,length;
+    c=(p_instr *)instrbuf.s.str;
+    length=instrbuf.s.len / sizeof(p_instr);
+
+    fprintf(stderr,"Optimization begins: \n");
+    for(e=0;e<length;e++,c++)
+    {
+      if(hasarg(c->opcode))
+	fprintf(stderr,">>>%3d: %s(%d)\n",c->line,get_token_name(c->opcode),c->arg);
+      else
+	fprintf(stderr,">>>%3d: %s\n",c->line,get_token_name(c->opcode));
+    }
+  }
+#endif
+}
+
diff --git a/src/peep.h b/src/peep.h
new file mode 100644
index 0000000000..48268f65d2
--- /dev/null
+++ b/src/peep.h
@@ -0,0 +1,22 @@
+#ifndef PEEP_H
+#define PEEP_H
+
+#include "dynamic_buffer.h"
+extern dynamic_buffer instrbuf;
+
+/* Prototypes begin here */
+struct p_instr_s;
+void init_bytecode();
+void exit_bytecode();
+int insert_opcode(unsigned int f,
+		  INT32 b,
+		  INT32 current_line,
+		  struct lpc_string *current_file);
+int insert_opcode2(int f,int current_line, struct lpc_string *current_file);
+void update_arg(int instr,INT32 arg);
+void ins_f_byte(unsigned int b);
+void assemble();
+void asm_opt();
+/* Prototypes end here */
+
+#endif
diff --git a/src/peep.in b/src/peep.in
new file mode 100644
index 0000000000..53890f8872
--- /dev/null
+++ b/src/peep.in
@@ -0,0 +1,86 @@
+POP_N_ELEMS (0) : 
+POP_N_ELEMS POP_VALUE : POP_N_ELEMS ($1a + 1)
+POP_VALUE POP_VALUE : POP_N_ELEMS (2)
+POP_VALUE POP_N_ELEMS : POP_N_ELEMS ($2a + 1)
+POP_N_ELEMS POP_N_ELEMS : POP_N_ELEMS ($1a + $2a)
+POP_N_ELEMS(1) : POP_VALUE
+
+ASSIGN_GLOBAL POP_VALUE : ASSIGN_GLOBAL_AND_POP($1a)
+ASSIGN_LOCAL  POP_VALUE : ASSIGN_LOCAL_AND_POP($1a)
+NUMBER(0) : CONST0
+NUMBER(1) : CONST1
+NUMBER(-1) : CONST_1
+NUMBER (0x7fffffff) : BIGNUM
+CONST0 NEGATE : CONST0
+CONST1 NEGATE : CONST_1
+CONST_1 NEGATE : CONST1
+NUMBER NEGATE : NEG_NUMBER($1a)
+NUMBER [$1a < 0] : NEG_NUMBER (-$1a)
+NEG_NUMBER NEGATE : NUMBER ($1a)
+NEGATE CONST_1 ADD : COMPL
+NEGATE CONST1 SUBTRACT : COMPL
+CONST0 ASSIGN_LOCAL_AND_POP : CLEAR_LOCAL($2a)
+
+CONST_1 MULTIPLY : NEGATE
+#CONST0 MULTIPLY : POP_VALUE CONST0
+CONST1 MULTIPLY : 
+#NUMBER MULTIPLY [count_bits($1a)==1]: NUMBER(my_log2($1a)) LSH
+
+CONST_1 DIVIDE : NEGATE
+CONST1 DIVIDE : 
+#NUMBER DIVIDE [count_bits($1a)==1]: NUMBER(my_log2($1a)) RSH
+
+CONST0 SUBTRACT:
+CONST0 XOR:
+CONST_1 XOR: COMPL
+EQ CONST0: NOT
+CONST0 RETURN: RETURN_0
+INC POP_VALUE: INC_AND_POP
+POST_INC POP_VALUE: INC_AND_POP
+DEC POP_VALUE: DEC_AND_POP
+POST_DEC POP_VALUE: DEC_AND_POP
+NOT BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_ZERO($2a)
+NOT BRANCH_WHEN_ZERO: BRANCH_WHEN_NON_ZERO($2a)
+
+BRANCH !LABEL : BRANCH($1a)
+RETURN !LABEL : RETURN
+RETURN_0 !LABEL : RETURN_0
+BRANCH LABEL ($1a) :
+
+LOCAL_LVALUE INC : INC_LOCAL ($1a)
+LOCAL_LVALUE POST_INC : POST_INC_LOCAL ($1a)
+LOCAL_LVALUE INC_AND_POP : INC_LOCAL_AND_POP ($1a)
+INC_LOCAL POP_VALUE : INC_LOCAL_AND_POP ($1a)
+POST_INC_LOCAL POP_VALUE : INC_LOCAL_AND_POP ($1a)
+
+LOCAL_LVALUE DEC : DEC_LOCAL ($1a)
+LOCAL_LVALUE POST_DEC : POST_DEC_LOCAL ($1a)
+LOCAL_LVALUE DEC_AND_POP : DEC_LOCAL_AND_POP ($1a)
+DEC_LOCAL POP_VALUE : DEC_LOCAL_AND_POP ($1a)
+POST_DEC_LOCAL POP_VALUE : DEC_LOCAL_AND_POP ($1a)
+
+CONST1 BRANCH_WHEN_ZERO:
+CONST0 BRANCH_WHEN_ZERO: BRANCH($2a)
+CONST1 BRANCH_WHEN_NON_ZERO: BRANCH($2a)
+CONST0 BRANCH_WHEN_NON_ZERO: 
+
+EQ BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_EQ ($2a)
+NE BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_NE ($2a)
+LT BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_LT ($2a)
+GT BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_GT ($2a)
+LE BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_LE ($2a)
+GE BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_GE ($2a)
+
+EQ BRANCH_WHEN_ZERO: BRANCH_WHEN_NE ($2a)
+NE BRANCH_WHEN_ZERO: BRANCH_WHEN_EQ ($2a)
+LT BRANCH_WHEN_ZERO: BRANCH_WHEN_GE ($2a)
+GT BRANCH_WHEN_ZERO: BRANCH_WHEN_LE ($2a)
+LE BRANCH_WHEN_ZERO: BRANCH_WHEN_GT ($2a)
+GE BRANCH_WHEN_ZERO: BRANCH_WHEN_LT ($2a)
+
+EQ NOT: NE
+NE NOT: EQ
+LT NOT: GE
+GT NOT: LE
+LE NOT: GT
+GE NOT: LT
-- 
GitLab


From 8a630c813b4ffa5e6c46106d7efbea9206300cbf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 05:16:26 +0200
Subject: [PATCH 107/351] peephole stuff fixed, along with some other
 optimization stuff

Rev: src/operators.c:1.8
---
 src/operators.c | 123 +++++++++++++++++++++++++++---------------------
 1 file changed, 69 insertions(+), 54 deletions(-)

diff --git a/src/operators.c b/src/operators.c
index 60047105fb..9227d3b05a 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -18,6 +18,8 @@
 #include "error.h"
 #include "docode.h"
 #include "add_efun.h"
+#include "peep.h"
+#include "lex.h"
 
 #define COMPARISON(ID,NAME,EXPR) \
 void ID(INT32 args) \
@@ -71,28 +73,30 @@ void f_add(INT32 args)
     struct lpc_string *r;
     char *buf;
 
-    if(args==1) return;
-    size=0;
-
-    for(e=-args;e<0;e++) size+=sp[e].u.string->len;
-
-    if(args==2)
+    switch(args)
     {
-      r=add_shared_strings(sp[-2].u.string,sp[-1].u.string);
-    }else{
+    case 1: return;
+    default:
+      size=0;
+      for(e=-args;e<0;e++) size+=sp[e].u.string->len;
+
       r=begin_shared_string(size);
       buf=r->str;
       for(e=-args;e<0;e++)
       {
+#if 1
+	int q;
+	for(q=0;q<sp[e].u.string->len;q++)
+	  buf[q]=sp[e].u.string->str[q];
+#else
 	MEMCPY(buf,sp[e].u.string->str,sp[e].u.string->len);
+#endif
 	buf+=sp[e].u.string->len;
       }
       r=end_shared_string(r);
     }
-    for(e=-args;e<0;e++)
-    {
-      free_string(sp[e].u.string);
-    }
+
+    for(e=-args;e<0;e++) free_string(sp[e].u.string);
     sp-=args;
     push_string(r);
     break;
@@ -229,7 +233,7 @@ static int generate_sum(node *n)
 
   case 2:
     do_docode(CDR(n),DO_NOT_COPY);
-    ins_f_byte(F_ADD);
+    emit2(F_ADD);
     return 1;
 
   default:
@@ -297,17 +301,17 @@ static int generate_comparison(node *n)
     do_docode(CDR(n),DO_NOT_COPY);
 
     if(CAR(n)->u.sval.u.efun->function == f_eq)
-      ins_f_byte(F_EQ);
+      emit2(F_EQ);
     else if(CAR(n)->u.sval.u.efun->function == f_ne)
-      ins_f_byte(F_NE);
+      emit2(F_NE);
     else if(CAR(n)->u.sval.u.efun->function == f_lt)
-      ins_f_byte(F_LT);
+      emit2(F_LT);
     else if(CAR(n)->u.sval.u.efun->function == f_le)
-      ins_f_byte(F_LE);
+      emit2(F_LE);
     else if(CAR(n)->u.sval.u.efun->function == f_gt)
-      ins_f_byte(F_GT);
+      emit2(F_GT);
     else if(CAR(n)->u.sval.u.efun->function == f_ge)
-      ins_f_byte(F_GE);
+      emit2(F_GE);
     else
       fatal("Couldn't generate comparison!\n");
     return 1;
@@ -414,12 +418,12 @@ static int generate_minus(node *n)
   {
   case 1:
     do_docode(CDR(n),DO_NOT_COPY);
-    ins_f_byte(F_NEGATE);
+    emit2(F_NEGATE);
     return 1;
 
   case 2:
     do_docode(CDR(n),DO_NOT_COPY);
-    ins_f_byte(F_SUBTRACT);
+    emit2(F_SUBTRACT);
     return 1;
   }
   return 0;
@@ -489,7 +493,7 @@ static int generate_and(node *n)
 
   case 2:
     do_docode(CDR(n),0);
-    ins_f_byte(F_AND);
+    emit2(F_AND);
     return 1;
 
   default:
@@ -562,7 +566,7 @@ static int generate_or(node *n)
 
   case 2:
     do_docode(CDR(n),0);
-    ins_f_byte(F_OR);
+    emit2(F_OR);
     return 1;
 
   default:
@@ -635,7 +639,7 @@ static int generate_xor(node *n)
 
   case 2:
     do_docode(CDR(n),0);
-    ins_f_byte(F_XOR);
+    emit2(F_XOR);
     return 1;
 
   default:
@@ -648,7 +652,7 @@ void o_lsh()
   if(sp[-2].type != T_INT) error("Bad argument 1 to <<\n");
   if(sp[-1].type != T_INT) error("Bad argument 2 to <<\n");
   sp--;
-  sp[-1].u.integer <<= sp[0].u.integer;
+  sp[-1].u.integer = sp[-1].u.integer << sp->u.integer;
 }
 
 void f_lsh(INT32 args)
@@ -663,7 +667,7 @@ static int generate_lsh(node *n)
   if(count_args(CDR(n))==2)
   {
     do_docode(CDR(n),DO_NOT_COPY);
-    ins_f_byte(F_LSH);
+    emit2(F_LSH);
     return 1;
   }
   return 0;
@@ -671,10 +675,10 @@ static int generate_lsh(node *n)
 
 void o_rsh()
 {
-  if(sp[-2].type != T_INT) error("Bad argument 1 to >>\n"); 
+  if(sp[-2].type != T_INT) error("Bad argument 1 to >>\n");
   if(sp[-1].type != T_INT) error("Bad argument 2 to >>\n");
   sp--;
-  sp[-1].u.integer >>= sp[0].u.integer;
+  sp[-1].u.integer = sp[-1].u.integer >> sp->u.integer;
 }
 
 void f_rsh(INT32 args)
@@ -689,7 +693,7 @@ static int generate_rsh(node *n)
   if(count_args(CDR(n))==2)
   {
     do_docode(CDR(n),DO_NOT_COPY);
-    ins_f_byte(F_RSH);
+    emit2(F_RSH);
     return 1;
   }
   return 0;
@@ -761,7 +765,7 @@ static int generate_multiply(node *n)
 
   case 2:
     do_docode(CDR(n),0);
-    ins_f_byte(F_MULTIPLY);
+    emit2(F_MULTIPLY);
     return 1;
 
   default:
@@ -819,7 +823,7 @@ static int generate_divide(node *n)
   if(count_args(CDR(n))==2)
   {
     do_docode(CDR(n),DO_NOT_COPY);
-    ins_f_byte(F_DIVIDE);
+    emit2(F_DIVIDE);
     return 1;
   }
   return 0;
@@ -866,7 +870,7 @@ static int generate_mod(node *n)
   if(count_args(CDR(n))==2)
   {
     do_docode(CDR(n),DO_NOT_COPY);
-    ins_f_byte(F_MOD);
+    emit2(F_MOD);
     return 1;
   }
   return 0;
@@ -896,7 +900,7 @@ static int generate_not(node *n)
   if(count_args(CDR(n))==1)
   {
     do_docode(CDR(n),DO_NOT_COPY);
-    ins_f_byte(F_NOT);
+    emit2(F_NOT);
     return 1;
   }
   return 0;
@@ -904,8 +908,19 @@ static int generate_not(node *n)
 
 void o_compl()
 {
-  if (sp[-1].type != T_INT) error("Bad argument to ~\n");
-  sp[-1].u.integer = ~ sp[-1].u.integer;
+  switch(sp[-1].type)
+  {
+  case T_INT:
+    sp[-1].u.integer = ~ sp[-1].u.integer;
+    break;
+
+  case T_FLOAT:
+    sp[-1].u.float_number = -1.0 - sp[-1].u.float_number;
+    break;
+
+  default:
+    error("Bad argument to ~\n");
+  }
 }
 
 void f_compl(INT32 args)
@@ -919,7 +934,7 @@ static int generate_compl(node *n)
   if(count_args(CDR(n))==1)
   {
     do_docode(CDR(n),DO_NOT_COPY);
-    ins_f_byte(F_COMPL);
+    emit2(F_COMPL);
     return 1;
   }
   return 0;
@@ -999,32 +1014,32 @@ void o_range()
 
 void init_operators()
 {
-  add_efun2("`==",f_eq,"function(mixed,mixed:int)",0,0,generate_comparison);
-  add_efun2("`!=",f_ne,"function(mixed,mixed:int)",0,0,generate_comparison);
-  add_efun2("`<", f_lt,"function(int|float,int|float:int)|function(string,string:int)",0,0,generate_comparison);
-  add_efun2("`<=",f_le,"function(int|float,int|float:int)|function(string,string:int)",0,0,generate_comparison);
-  add_efun2("`>", f_gt,"function(int|float,int|float:int)|function(string,string:int)",0,0,generate_comparison);
-  add_efun2("`>=",f_ge,"function(int|float,int|float:int)|function(string,string:int)",0,0,generate_comparison);
+  add_efun2("`==",f_eq,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
+  add_efun2("`!=",f_ne,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
+  add_efun2("`<", f_lt,"function(int|float,int|float:int)|function(string,string:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
+  add_efun2("`<=",f_le,"function(int|float,int|float:int)|function(string,string:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
+  add_efun2("`>", f_gt,"function(int|float,int|float:int)|function(string,string:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
+  add_efun2("`>=",f_ge,"function(int|float,int|float:int)|function(string,string:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
 
-  add_efun2("`+",f_add,"function(int...:int)|!function(int...:mixed)&function(int|float...:float)|!function(int|float...:mixed)&function(string|int|float...:string)|function(array...:array)|function(mapping...:mapping)|function(list...:list)",0,optimize_binary,generate_sum);
+  add_efun2("`+",f_add,"function(int...:int)|!function(int...:mixed)&function(int|float...:float)|!function(int|float...:mixed)&function(string|int|float...:string)|function(array...:array)|function(mapping...:mapping)|function(list...:list)",OPT_TRY_OPTIMIZE,optimize_binary,generate_sum);
 
-  add_efun2("`-",f_minus,"function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(list,list:list)|function(float|int,float:float)|function(float,int:float)|function(int,int:int)|function(string,string:string)",0,0,generate_minus);
+  add_efun2("`-",f_minus,"function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(list,list:list)|function(float|int,float:float)|function(float,int:float)|function(int,int:int)|function(string,string:string)",OPT_TRY_OPTIMIZE,0,generate_minus);
 
-  add_efun2("`&",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_and);
+  add_efun2("`&",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",OPT_TRY_OPTIMIZE,optimize_binary,generate_and);
 
-  add_efun2("`|",f_or,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_or);
+  add_efun2("`|",f_or,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",OPT_TRY_OPTIMIZE,optimize_binary,generate_or);
 
-  add_efun2("`^",f_xor,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_xor);
+  add_efun2("`^",f_xor,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",OPT_TRY_OPTIMIZE,optimize_binary,generate_xor);
 
-  add_efun2("`<<",f_lsh,"function(int,int:int)",0,0,generate_lsh);
-  add_efun2("`>>",f_rsh,"function(int,int:int)",0,0,generate_rsh);
+  add_efun2("`<<",f_lsh,"function(int,int:int)",OPT_TRY_OPTIMIZE,0,generate_lsh);
+  add_efun2("`>>",f_rsh,"function(int,int:int)",OPT_TRY_OPTIMIZE,0,generate_rsh);
 
-  add_efun2("`*",f_multiply,"function(int...:int)|!function(int...:mixed)&function(float|int...:float)|function(string*,string:string)",0,optimize_binary,generate_multiply);
+  add_efun2("`*",f_multiply,"function(int...:int)|!function(int...:mixed)&function(float|int...:float)|function(string*,string:string)",OPT_TRY_OPTIMIZE,optimize_binary,generate_multiply);
 
-  add_efun2("`/",f_divide,"function(int,int:int)|function(float|int,float:float)|function(float,int:float)|function(string,string:string*)",0,0,generate_divide);
+  add_efun2("`/",f_divide,"function(int,int:int)|function(float|int,float:float)|function(float,int:float)|function(string,string:string*)",OPT_TRY_OPTIMIZE,0,generate_divide);
 
-  add_efun2("`%",f_mod,"function(int,int:int)|!function(int,int:mixed)&function(int|float,int|float:float)",0,0,generate_mod);
+  add_efun2("`%",f_mod,"function(int,int:int)|!function(int,int:mixed)&function(int|float,int|float:float)",OPT_TRY_OPTIMIZE,0,generate_mod);
 
-  add_efun2("`!",f_not,"function(mixed:int)",0,0,generate_not);
-  add_efun2("`~",f_compl,"function(int:int)",0,0,generate_compl);
+  add_efun2("`!",f_not,"function(mixed:int)",OPT_TRY_OPTIMIZE,0,generate_not);
+  add_efun2("`~",f_compl,"function(int:int)|function(float:float)",OPT_TRY_OPTIMIZE,0,generate_compl);
 }
-- 
GitLab


From c5016fbb25cc64d768909e18b1e27833daa058a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 05:52:47 +0200
Subject: [PATCH 108/351] new opcodes for peephole optimizer added

Rev: src/interpret.c:1.8
---
 src/interpret.c | 84 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 76 insertions(+), 8 deletions(-)

diff --git a/src/interpret.c b/src/interpret.c
index 117e643c83..f3a83ce04c 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -24,7 +24,7 @@
 #include "builtin_efuns.h"
 #include "lpc_signal.h"
 
-#define TRACE_LEN 256
+#define TRACE_LEN (100 + t_flag * 10)
 struct svalue evaluator_stack[EVALUATOR_STACK_SIZE];
 struct svalue *mark_stack[EVALUATOR_STACK_SIZE];
 struct frame *fp; /* frame pointer */
@@ -264,6 +264,18 @@ CASE(ID) \
   break; \
 }
 
+#define CJUMP(X,Y) \
+CASE(X); \
+if(Y(sp-2,sp-1)) { \
+  check_signals(); \
+  pc+=EXTRACT_INT(pc);\
+}else{ \
+  pc+=sizeof(INT32); \
+} \
+pop_n_elems(2); \
+break
+
+
 /*
  * reset the stack machine.
  */
@@ -418,6 +430,7 @@ static void eval_instruction(unsigned char *pc)
       CASE(F_CONST0); sp->type=T_INT; sp->u.integer=0;  sp++; break;
       CASE(F_CONST1); sp->type=T_INT; sp->u.integer=1;  sp++; break;
       CASE(F_CONST_1);sp->type=T_INT; sp->u.integer=-1; sp++; break;
+      CASE(F_BIGNUM); sp->type=T_INT; sp->u.integer=0x7fffffff; sp++; break;
       CASE(F_NUMBER); sp->type=T_INT; sp->u.integer=GET_ARG(); sp++; break;
       CASE(F_NEG_NUMBER);
       sp->type=T_INT;
@@ -493,6 +506,57 @@ static void eval_instruction(unsigned char *pc)
       sp+=2;
       break;
 
+      CASE(F_CLEAR_LOCAL);
+      instr=GET_ARG();
+      free_svalue(fp->locals + instr);
+      fp->locals[instr].type=T_INT;
+      fp->locals[instr].subtype=0;
+      fp->locals[instr].u.integer=0;
+      break;
+
+
+      CASE(F_INC_LOCAL);
+      instr=GET_ARG();
+      if(fp->locals[instr].type != T_INT) error("Bad argument to ++\n");
+      fp->locals[instr].u.integer++;
+      assign_svalue_no_free(sp++,fp->locals+instr);
+      break;
+
+      CASE(F_POST_INC_LOCAL);
+      instr=GET_ARG();
+      if(fp->locals[instr].type != T_INT) error("Bad argument to ++\n");
+      assign_svalue_no_free(sp++,fp->locals+instr);
+      fp->locals[instr].u.integer++;
+      break;
+
+      CASE(F_INC_LOCAL_AND_POP);
+      instr=GET_ARG();
+      if(fp->locals[instr].type != T_INT) error("Bad argument to ++\n");
+      fp->locals[instr].u.integer++;
+      break;
+
+
+      CASE(F_DEC_LOCAL);
+      instr=GET_ARG();
+      if(fp->locals[instr].type != T_INT) error("Bad argument to --\n");
+      fp->locals[instr].u.integer--;
+      assign_svalue_no_free(sp++,fp->locals+instr);
+      break;
+
+      CASE(F_POST_DEC_LOCAL);
+      instr=GET_ARG();
+      if(fp->locals[instr].type != T_INT) error("Bad argument to --\n");
+      assign_svalue_no_free(sp--,fp->locals+instr);
+      fp->locals[instr].u.integer++;
+      break;
+
+      CASE(F_DEC_LOCAL_AND_POP);
+      instr=GET_ARG();
+      if(fp->locals[instr].type != T_INT) error("Bad argument to --\n");
+      fp->locals[instr].u.integer--;
+      break;
+
+
       CASE(F_LTOSVAL);
       lvalue_to_svalue_no_free(sp,sp-2);
       sp++;
@@ -650,6 +714,13 @@ static void eval_instruction(unsigned char *pc)
       pop_stack();
       break;
 
+      CJUMP(F_BRANCH_WHEN_EQ, is_eq);
+      CJUMP(F_BRANCH_WHEN_NE,!is_eq);
+      CJUMP(F_BRANCH_WHEN_LT, is_lt);
+      CJUMP(F_BRANCH_WHEN_LE,!is_gt);
+      CJUMP(F_BRANCH_WHEN_GT, is_gt);
+      CJUMP(F_BRANCH_WHEN_GE,!is_lt);
+
       CASE(F_LAND);
       check_destructed(sp-1);
       if(!IS_ZERO(sp-1))
@@ -683,13 +754,10 @@ static void eval_instruction(unsigned char *pc)
       {
 	INT32 tmp;
 	tmp=switch_lookup(fp->context.prog->
-			  constants[EXTRACT_UWORD(pc)].u.array,sp-1);
-	pc+=sizeof(INT16);
+			  constants[GET_ARG()].u.array,sp-1);
 	pc=(unsigned char *)MY_ALIGN(pc);
-	if(tmp >= 0)
-	  pc+=((INT32 *)pc)[1+tmp*2];
-	else
-	  pc+=((INT32 *)pc)[2*~tmp];
+	pc+=(tmp>=0 ? 1+tmp*2 : 2*~tmp) * sizeof(INT32);
+	pc+=*(INT32*)pc;
 	pop_stack();
 	break;
       }
@@ -841,7 +909,7 @@ static void eval_instruction(unsigned char *pc)
 #ifdef DEBUG
       if(instr >= fp->context.prog->num_constants)
       {
-	instr += F_MAX_OPCODE;
+	instr += F_MAX_OPCODE - F_OFFSET;
 	fatal("Strange instruction %ld\n",(long)instr);
       }
 #endif      
-- 
GitLab


From da48828c2bd1ae7ca0b04a43217d20b1c5ec82cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 06:13:49 +0200
Subject: [PATCH 109/351] new opcode names added

Rev: src/lex.c:1.9
---
 src/lex.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/src/lex.c b/src/lex.c
index 9738a418ce..b272200d74 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -219,6 +219,7 @@ struct keyword instr_names[]=
 { "pop_n_elems",        F_POP_N_ELEMS },
 { "push 0",             F_CONST0 },
 { "push 1",             F_CONST1 },
+{ "push 0x7fffffff",    F_BIGNUM },
 { "range",              F_RANGE },
 { "return",		F_RETURN },
 { "return 0",		F_RETURN_0 },
@@ -235,6 +236,23 @@ struct keyword instr_names[]=
 { "|=",			F_OR_EQ },	
 { "||",			F_LOR },	
 { "~",			F_COMPL },
+{ "label",		F_LABEL },
+{ "data",		F_POINTER },
+{ "align",		F_ALIGN },
+{ "call",		F_APPLY },
+{ "clear local",	F_CLEAR_LOCAL },
+{ "++local",		F_INC_LOCAL },
+{ "++local and pop",	F_INC_LOCAL_AND_POP },
+{ "local++",		F_POST_INC_LOCAL },
+{ "--local",		F_DEC_LOCAL },
+{ "--local and pop",	F_DEC_LOCAL_AND_POP },
+{ "local--",		F_POST_DEC_LOCAL },
+{ "branch if <",	F_BRANCH_WHEN_LT },
+{ "branch if >",	F_BRANCH_WHEN_GT },
+{ "branch if <=",	F_BRANCH_WHEN_LE },
+{ "branch if >=",	F_BRANCH_WHEN_GE },
+{ "branch if ==",	F_BRANCH_WHEN_EQ },
+{ "branch if !=",	F_BRANCH_WHEN_NE },
 };
 
 struct instr instrs[F_MAX_INSTR - F_OFFSET];
-- 
GitLab


From 2c4cec01a48731b5ceff3e67fbcc9dcc9c60c571 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 06:15:49 +0200
Subject: [PATCH 110/351] peephole stuff added

Rev: src/Makefile.in:1.13
Rev: src/docode.h:1.3
Rev: src/program.h:1.5
---
 src/Makefile.in | 60 ++++++++++++++++++++++++++++++++-----------------
 src/docode.h    | 12 +++++-----
 src/program.h   |  2 +-
 3 files changed, 47 insertions(+), 27 deletions(-)

diff --git a/src/Makefile.in b/src/Makefile.in
index 60e69e1afd..b1f28d70dc 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -67,7 +67,7 @@ MAKE_FLAGS = "prefix=$(prefix)" "exex_prefix=$(exex_prefix)" "CC=$(CC)" "OTHERFL
 # Add alloca.o if you don't have alloca() on your machine.
 # Add ualarm.o if you don't have ualarm() on your machine.
 #
-OBJ=language.o add_efun.o array.o builtin_efuns.o backend.o \
+OBJ=language.o peep.o add_efun.o array.o builtin_efuns.o backend.o \
     call_out.o docode.o dynamic_buffer.o error.o fd_control.o \
     fsort.o hashtable.o interpret.o lex.o las.o list.o \
     lpc_types.o main.o mapping.o memory.o module.o object.o \
@@ -168,6 +168,10 @@ export: $(SRCDIR)/test/testsuite
 	chmod +x $(SRCDIR)/install-sh
 	$(RUNULPC) $(TMP_BINDIR)/export.lpc
 
+peep_engine.c: peep.in
+	echo "" >$(SRCDIR)/peep_engine.c
+	-$(RUNULPC) $(TMP_BINDIR)/mkpeep.lpc $(SRCDIR)/peep.in >$(SRCDIR)/peep_engine.c
+
 # make dependencies (requires compiled uLPC)
 depend: language.c
 	gcc -MM $(PREFLAGS) *.c $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)/Makefile.in
@@ -268,6 +272,22 @@ array.o: array.c \
   fsort.h \
   builtin_efuns.h \
   gc.h
+backend.o: backend.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  backend.h \
+  interpret.h \
+  program.h \
+  object.h \
+  svalue.h \
+  error.h \
+  call_out.h \
+  fd_control.h \
+  main.h \
+  callback.h \
+  array.h las.h \
+  dynamic_buffer.h
 builtin_efuns.o: builtin_efuns.c \
   global.h machine.h \
   config.h \
@@ -316,23 +336,6 @@ callback.o: callback.c \
   svalue.h \
   dynamic_buffer.h \
   program.h
-docode.o: docode.c \
-  global.h machine.h \
-  config.h \
-  port.h las.h \
-  svalue.h \
-  dynamic_buffer.h \
-  program.h language.h \
-  lpc_types.h \
-  stralloc.h \
-  interpret.h \
-  add_efun.h \
-  hashtable.h \
-  array.h \
-  macros.h \
-  error.h \
-  main.h lex.h \
-  builtin_efuns.h
 dynamic_buffer.o: dynamic_buffer.c \
   global.h machine.h \
   config.h \
@@ -368,7 +371,14 @@ fsort.o: fsort.c \
 gc.o: gc.c \
   global.h machine.h \
   config.h \
-  port.h gc.h \
+  port.h \
+  array.h las.h \
+  svalue.h \
+  dynamic_buffer.h \
+  program.h \
+  list.h \
+  mapping.h \
+  object.h gc.h \
   main.h
 hashtable.o: hashtable.c \
   global.h machine.h \
@@ -455,7 +465,8 @@ list.o: list.c \
   macros.h \
   error.h \
   interpret.h \
-  builtin_efuns.h
+  builtin_efuns.h \
+  gc.h
 lpc_signal.o: lpc_signal.c \
   global.h machine.h \
   config.h \
@@ -520,7 +531,8 @@ mapping.o: mapping.c \
   array.h \
   macros.h language.h \
   error.h \
-  interpret.h
+  interpret.h \
+  gc.h
 memory.o: memory.c \
   global.h machine.h \
   config.h \
@@ -583,6 +595,12 @@ operators.o: operators.c \
   docode.h \
   add_efun.h \
   hashtable.h
+peep.o: peep.c \
+  global.h machine.h \
+  config.h \
+  port.h \
+  peep_engine.c
+peep_engine.o: peep_engine.c
 port.o: port.c \
   global.h machine.h \
   config.h \
diff --git a/src/docode.h b/src/docode.h
index 8f87b05b8d..6e3d0de9e8 100644
--- a/src/docode.h
+++ b/src/docode.h
@@ -14,20 +14,22 @@ extern int store_linenumbers;
 extern int comp_stackp;
 extern INT32 comp_stack[COMPILER_STACK_SIZE];
 
+#define emit(X,Y) insert_opcode((X),(Y),current_line, current_file)
+#define emit2(X) insert_opcode2((X),current_line, current_file)
+
 /* Prototypes begin here */
 void ins_byte(unsigned char b,int area);
 void ins_signed_byte(char b,int area);
 void ins_short(INT16 l,int area);
-void ins_long(INT32 l,int area);
-void ins_f_byte(unsigned int b);
+void ins_int(INT32 l,int area);
+void upd_int(int offset, INT32 tmp);
+INT32 read_int(int offset);
 void push_address();
 void push_explicit(INT32 address);
 INT32 pop_address();
-struct jump;
-struct jump_list;
 int do_docode(node *n,INT16 flags);
-int docode(node *n);
 void do_code_block(node *n);
+int docode(node *n);
 /* Prototypes end here */
 
 #endif
diff --git a/src/program.h b/src/program.h
index b8a8fed9fd..07edbb8a3c 100644
--- a/src/program.h
+++ b/src/program.h
@@ -170,7 +170,7 @@ int find_identifier(char *name,struct program *prog);
 int store_prog_string(struct lpc_string *str);
 int store_constant(struct svalue *foo, int equal);
 void start_line_numbering(void);
-void store_linenumber(void);
+void store_linenumber(INT32 current_line, struct lpc_string *current_string);
 char *get_line(unsigned char *pc,struct program *prog,INT32 *linep);
 void my_yyerror(char *fmt,...);
 void compile();
-- 
GitLab


From 4d4a983dc035bf526c64d450c11b418ba20dd4e7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 06:20:25 +0200
Subject: [PATCH 111/351] nothing changed

Rev: src/modules/files/file.c:1.13
---
 src/modules/files/file.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index 4deb061b1c..40363df50a 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -237,6 +237,7 @@ static void file_read(INT32 args)
 	if(!bytes_read)
 	{
 	  free((char *)str);
+	  UNSET_ONERROR(ebuf);
 	  push_int(0);
 	  return;
 	}
@@ -294,6 +295,7 @@ static void file_read(INT32 args)
 	  if(!bytes_read)
 	  {
 	    free(b.s.str);
+	    UNSET_ONERROR(ebuf);
 	    push_int(0);
 	    return;
 	  }
-- 
GitLab


From c2a14b7f766f927c29c68ff1da7b62e7eb2e76b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 06:23:54 +0200
Subject: [PATCH 112/351] entries added

Rev: src/ChangeLog:1.27
---
 src/ChangeLog | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 27e5e491aa..0003022a83 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
+Sat Apr 13 04:00:45 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
+
+	* operators.c: optimization fixed for operators
+	* crypt() should now work with BSD crypt() I hope
+	* lots of files: added a peephole optimizer
+
+Tue Apr  2 17:01:10 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
+
+	* signal.c: alarm() added
+	* language.y: gauge() fixed
+
 Sun Mar 31 22:12:43 1996  Fredrik Hubinette  <hubbe@axel.signum.se>
 
 	* uLPC v1.0E-10 released.
-- 
GitLab


From ef1fa40562688b8cf2743dc1a9986adbc7003ca0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 06:24:50 +0200
Subject: [PATCH 113/351] more tests...

Rev: src/test/create_testsuite:1.14
---
 src/test/create_testsuite | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 67aec404dc..959f4183ed 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -550,6 +550,8 @@ test_any(int e;string t=""; e=0; while(++e<6) t+=e; return t,"12345";)
 test_any(int e=1;string t=""; while(e<20){t+=e;e*=2;} return t,"124816";)
 
 // Switch
+test_any(switch("") { case -1: case "gazonk": return 0; } return 1,1)
+test_any(switch("") { case -2: case "gazonk": return 0; } return 1,1)
 test_any(switch("") { case 0: case "gazonk": return 0; } return 1,1)
 test_any(switch("") { case "gazonk": case 0: return 0; } return 1,1)
 test_any(switch(0) { case 0: case "gazonk": return 0; } return 1,0)
-- 
GitLab


From 14d42ea40009c877ab59f8b7d1e4d93e8f504118 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 06:26:32 +0200
Subject: [PATCH 114/351] doc for new efun

Rev: doc/builtin/alarm:1.1
---
 doc/builtin/alarm | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 doc/builtin/alarm

diff --git a/doc/builtin/alarm b/doc/builtin/alarm
new file mode 100644
index 0000000000..233098d62e
--- /dev/null
+++ b/doc/builtin/alarm
@@ -0,0 +1,21 @@
+NAME
+	alarm - set an alarm clock for delivery of a signal
+
+SYNTAX
+	int alarm(int seconds);
+
+DESCRIPTION
+	alarm arranges for a SIGALRM signal to be delivered to the
+	process in seconds seconds.
+
+	If seconds is zero, no new alarm is scheduled.
+
+	In any event any previously set alarm is cancelled.
+
+RETURN VALUE
+	alarm returns the number of seconds  remaining  until  any
+	previously  scheduled  alarm  was  due to be delivered, or
+	zero if there was no previously scheduled alarm.
+
+SEE ALSO
+	signal
-- 
GitLab


From d17fa1eb974f6cddbab8e7a2da06c2d9d21f2f20 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 06:27:02 +0200
Subject: [PATCH 115/351] typos fixed

Rev: doc/builtin/replace:1.4
---
 doc/builtin/replace | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/builtin/replace b/doc/builtin/replace
index 32d2e1ed8a..14165f779e 100644
--- a/doc/builtin/replace
+++ b/doc/builtin/replace
@@ -17,7 +17,7 @@ DESCRIPTION
 	string replace(string s, string from, string to);
 
 	   When given strings as second and third argument, a copy of
-	   s with every occurance of 'from' return 'to'.
+	   s with every occurance of 'from' return 'to' is returned.
 
 	string replace(string s, string *from, string *to);
 
-- 
GitLab


From 3544b0bb721f34e8886fc5961658dda2ce1f5a2d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 06:27:47 +0200
Subject: [PATCH 116/351] peephole generator

Rev: bin/mkpeep.lpc:1.1
---
 bin/mkpeep.lpc | 378 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 378 insertions(+)
 create mode 100755 bin/mkpeep.lpc

diff --git a/bin/mkpeep.lpc b/bin/mkpeep.lpc
new file mode 100755
index 0000000000..4be16f6422
--- /dev/null
+++ b/bin/mkpeep.lpc
@@ -0,0 +1,378 @@
+#!/usr/local/bin/ulpc
+
+string skipwhite(string s)
+{
+#if DEBUG > 9
+  perror("skipwhite("+s+")\n");
+#endif
+
+  sscanf(s,"%*[ \t\n]%s",s);
+  return s;
+}
+
+/* Find the matching parenthesis */
+int find_end(string s)
+{
+  int e,parlvl=1;
+
+#if DEBUG > 8
+  perror("find_end("+s+")\n");
+#endif
+  
+  for(e=1;e<strlen(s);e++)
+  {
+    switch(s[e])
+    {
+    case '(': case '{': case '[':
+      parlvl++; break;
+    case ')': case '}': case ']':
+      parlvl--;
+      if(!parlvl) return e;
+      break;
+    }
+  }
+  perror("Syntax error.\n");
+  exit(1);
+}
+
+
+/* Splitline into components */
+mixed split(string s)
+{
+  string *a,*b,tmp;
+  int i,e,opcodes;
+  string line=s;
+  opcodes=0;
+
+#ifdef DEBUG
+  perror("split("+s+")\n");
+#endif
+
+  b=({});
+
+  s=skipwhite(s);
+  while(strlen(s))
+  {
+    switch(s[0])
+    {
+      /* Source / Target separator */
+    case ':':
+      b+=({":"});
+      s=s[1..];
+      break;
+
+    case '!':
+      b+=({"!"});
+      s=s[1..];
+      break;
+
+      /* Identifier */
+    case 'A'..'Z':
+    case 'a'..'z':
+    case '0'..'9':
+    case '_':
+      sscanf(s,"%[a-zA-Z0-9_]%s",tmp,s);
+      b+=({"F_"+tmp});
+      break;
+
+      /* argument */
+    case '(':
+      i=find_end(s);
+      b+=({ s[0..i] });
+      s=s[i+1..strlen(s)];
+      break;
+
+      /* condition */
+    case '[':
+      i=find_end(s);
+      b+=({ s[0..i] });
+      s=s[i+1..strlen(s)];
+      break;
+    }
+
+    s=skipwhite(s);
+  }
+
+  int i=search(b, ":");
+  if(i==-1)
+  {
+    perror("Syntax error.\n");
+    return 0;
+  }
+
+  a=b[..i-1];
+  b=b[i+1..];
+
+  for(e=0;e<sizeof(a);e++)
+    if(a[e][0]=='F')
+      opcodes++;
+
+  i=0;
+  for(e=0;e<sizeof(a);e++)
+  {
+    switch(a[e][0])
+    {
+    case '(':
+      a[e]=a[e]+"==$"+i+"a";
+      break;
+
+    case '[':
+      a[e]=a[e][1..strlen(a[e])-2];
+      break;
+
+    case 'F':
+      i++;
+      a[e]=a[e]+"==$"+i+"o";
+      break;
+    }
+  }
+
+
+  for(e=0;e<sizeof(a);e++)
+  {
+    if(a[e]=="!")
+    {
+      a[e+1]=replace(a[e+1],"==","!=");
+      a=a[..e-1]+a[e+1..];
+      e--;
+    }
+  }
+
+#ifdef DEBUG
+  perror(sprintf("%O\n",({a,b})));
+#endif
+
+  return ({a,b,opcodes, line});
+}
+
+/* Replace $[0-9]+(o|a) with something a C compiler can understand */
+string treat(string expr)
+{
+  int e;
+  string *tmp;
+  tmp=expr/"$";
+  for(e=1;e<sizeof(tmp);e++)
+  {
+    string num, type, rest;
+    if(sscanf(tmp[e],"%d%c%s",num,type,rest)!=3)
+    {
+      perror("Syntax error.\n");
+      exit(2);
+    }
+    num--;
+    switch(type)
+    {
+    case 'a': tmp[e]="argument("+num+")"+rest; break;
+    case 'o': tmp[e]="opcode("+num+")"+rest; break;
+    }
+  }
+  return implode(tmp,"");
+}
+
+/* Dump C co(d|r)e */
+void dump2(mixed *data,int ind)
+{
+  int e,i,max,maxe;
+  mixed a,b,d,tmp;
+  string test;
+  int wrote_switch;
+  mapping foo;
+  mixed cons, var;
+
+  foo=([]);
+
+  while(1)
+  {
+    foo=([]);
+
+    /* First we create a mapping:
+     * foo [ meta variable ] [ condition ] = ({ lines });
+     */
+    foreach(data,d)
+    {
+      a=d[0];
+      b=d[1];
+      for(e=0;e<sizeof(a);e++)
+      {
+	if(sscanf(a[e],"F_%[A-Z0-9_]==%s",cons,var)==2 ||
+	   sscanf(a[e],"(%d)==%s",cons,var)==2 ||
+	   sscanf(a[e],"%d==%s",cons,var)==2)
+	{
+	  if(!foo[var]) foo[var]=([]);
+	  if(!foo[var][a[e]]) foo[var][a[e]]=({});
+	  foo[var][a[e]]+=({d});
+	}
+      }
+    }
+
+    /* Check what variable has most values */
+    max=maxe=e=0; 
+    foreach(m_values(foo),d)
+    {
+      if(m_sizeof(d)>max)
+      {
+	max=m_sizeof(d);
+	maxe=e;
+      }
+      e++;
+    }
+
+    /* If zero, done */
+    if(max <= 1) break;
+
+    test=m_indices(foo)[maxe];
+    
+    wrote_switch++;
+    write(sprintf("%*nswitch(%s)\n",ind,treat(test)));
+    write(sprintf("%*n{\n",ind));
+
+    d=m_values(foo)[maxe];
+    a=m_indices(d);
+    b=m_values(d);
+
+
+    /* foo: variable
+     * a[x] : condition
+     * b[x] : line
+     */
+
+    for(e=0;e<sizeof(a);e++)
+    {
+      /* The lines b[e] are removed from data as they
+       * will be treated below
+       */
+      data-=b[e];
+
+      if(sscanf(a[e],"(%s)==%s",cons,var)!=2)
+	sscanf(a[e],"%s==%s",cons,var);
+      
+      write(sprintf("%*ncase %s:\n",ind,cons+""));
+
+      foreach(b[e],d) d[0]-=({a[e]});
+      dump2(b[e],ind+2);
+      write(sprintf("%*n  break;\n",ind));
+      write("\n");
+    }
+
+    if(sizeof(data))
+      write(sprintf("%*ndefault:\n",ind));
+    ind+=2;
+  }
+  
+  /* Take care of whatever is left */
+  if(sizeof(data))
+  {
+    foreach(data,d)
+    {
+      mixed q;
+
+      write(sprintf("%*n/* %s */\n",ind,d[3]));
+
+      
+      if(sizeof(d[0]))
+      {
+	string test;
+	test=treat(implode(d[0]," && "));
+	write(sprintf("%*nif(%s)\n",ind,test));
+      }
+      write(sprintf("%*n{\n",ind));
+      ind+=2;
+
+
+      for(i=0;i<sizeof(d[1]);i++)
+      {
+	if(i+1<sizeof(d[1]) && d[1][i+1][0]=='(')
+	{
+	  string tmp=d[1][i+1];
+	  tmp=treat(tmp[1..strlen(tmp)-2]);
+	  write(sprintf("%*nINT32 arg%d=%s;\n",ind,i,tmp));
+	  i++;
+	}
+      }
+
+      if(sizeof(d[1]))
+      {
+	write(sprintf("%*ncopy_shared_string(current_file,instr(0)->file);\n",ind));
+	write(sprintf("%*ncurrent_line=instr(0)->line;\n",ind));
+      }
+
+      write(sprintf("%*npop_n_opcodes(%d);\n",ind,d[2]));
+
+      int q;
+
+      for(i=0;i<sizeof(d[1]);i++)
+      {
+	if(i+1<sizeof(d[1]) && d[1][i+1][0]=='(')
+	{
+	  write(sprintf("%*ninsert(%s,arg%d);\n",ind,d[1][i],i));
+	  i++;
+	}else{
+	  write(sprintf("%*ninsert2(%s);\n",ind,d[1][i]));
+	}
+	q++;
+      }
+      if(sizeof(d[1]))
+      {
+	if(q)
+	  write(sprintf("%*nfifo_len+=%d;\n",ind,q));
+	write(sprintf("%*nfree_string(current_file);\n",ind));
+	write(sprintf("%*ndebug();\n",ind));
+      }
+      write(sprintf("%*ncontinue;\n",ind));
+
+      ind-=2;
+      write(sprintf("%*n}\n",ind,test));
+    }
+  }
+
+  while(wrote_switch--)
+  {
+    ind-=2;
+    write(sprintf("%*n}\n",ind));
+  }
+}
+  
+
+
+int main(int argc, string *argv)
+{
+  int e,max,maxe;
+  string f;
+  mapping foo=([]);
+  array(array(array(string))) data=({});
+
+  mapping tests=([]);
+
+  f=read_bytes(argv[1]);
+  foreach(explode(f,"\n"),f)
+  {
+    string *a,*b;
+    mapping tmp;
+
+    sscanf(f,"%s#",f);
+    if(!strlen(f)) continue;
+    data+=({split(f)});
+  }
+
+//  write(sprintf("%O\n",data));
+
+  write("  len=instrbuf.s.len/sizeof(p_instr);\n");
+  write("  instrs=(p_instr *)instrbuf.s.str;\n");
+  write("  instrbuf.s.str=0;\n");
+  write("  fifo_len=0;\n");
+  write("  init_bytecode();\n\n");
+  write("  for(eye=0;eye<len;)\n  {\n");
+  write("    INT32 current_line;\n");
+  write("    struct lpc_string *current_file;\n");
+  write("\n");
+
+  dump2(data,4);
+
+  write("    advance();\n");
+  write("  }\n");
+  write("  for(eye=0;eye<len;eye++) free_string(instrs[eye].file);\n");
+  write("  free((char *)instrs);\n");
+
+  return 0;
+}
+
-- 
GitLab


From e1d37a2fa0552ab1fbfe1081358a790d93d78423 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 07:29:25 +0200
Subject: [PATCH 117/351] faster sort_array

Rev: lib/simulate.lpc:1.11
---
 lib/simulate.lpc | 63 +++++++++++++++++++++++++++++++-----------------
 1 file changed, 41 insertions(+), 22 deletions(-)

diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index 82a26a8e0e..fc150db617 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -267,38 +267,57 @@ function this_function()
   return backtrace()[-2][2];
 }
 
-varargs mixed *sort_array(array foo,function cmp,mixed ... args)
+varargs mixed *sort_array2(array foo,function cmp, mixed ... args)
 {
-  int ap,bp,retp;
-  mixed *a,*b,*ret;
-
-  if(sizeof(foo)<2) return copy_value(foo);
-
+  array bar,tmp;
+  int len,start;
+  int length;
+  int foop, fooend, barp, barend;
+  
   if(!cmp) cmp=`>;
+  length=sizeof(foo);
 
-  a=sort_array(foo[0..sizeof(foo)/2-1],cmp,@args);
-  b=sort_array(foo[sizeof(foo)/2..sizeof(foo)],cmp,@args);
-  ret=allocate(sizeof(foo));
+  foo+=({});
+  bar=allocate(length);
 
-  while(1)
+  for(len=1;len<length;len*=2)
   {
-    if(cmp(a[ap],b[bp],@args) <= 0)
+    start=0;
+    while(start+len < length)
     {
-      ret[retp++]=a[ap++];
-      if(ap == sizeof(a))
+      foop=start;
+      barp=start+len;
+      fooend=barp;
+      barend=barp+len;
+      if(barend > length) barend=length;
+      
+      while(1)
       {
-	while(bp < sizeof(b)) ret[retp++]=b[bp++];
-	return ret;
-      }
-    }else{
-      ret[retp++]=b[bp++];
-      if(bp == sizeof(b))
-      {
-	while(ap < sizeof(a)) ret[retp++]=a[ap++];
-	return ret;
+	if(cmp(foo[foop],foo[barp],@args) <= 0)
+	{
+	  bar[start++]=foo[foop++];
+	  if(foop == fooend)
+	  {
+	    while(barp < barend) bar[start++]=foo[barp++];
+	    break;
+	  }
+	}else{
+	  bar[start++]=foo[barp++];
+	  if(barp == barend)
+	  {
+	    while(foop < fooend) bar[start++]=foo[foop++];
+	    break;
+	  }
+	}
       }
     }
+
+    tmp=foo;
+    foo=bar;
+    bar=tmp;
   }
+
+  return foo;
 }
 
 string capitalize(string s)
-- 
GitLab


From 31929c763f3c8ea5c114763ee62da356811fb41d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 13 Apr 1996 07:30:21 +0200
Subject: [PATCH 118/351] entry added

Rev: src/ChangeLog:1.28
---
 src/ChangeLog | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 0003022a83..0be821c184 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,6 @@
 Sat Apr 13 04:00:45 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
 
+	* simulate.lpc: replaced sort_array with a faster one
 	* operators.c: optimization fixed for operators
 	* crypt() should now work with BSD crypt() I hope
 	* lots of files: added a peephole optimizer
-- 
GitLab


From 5e5817ab4c9fb80ec26044892eeb90a184416b2d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 21 Apr 1996 20:22:33 +0200
Subject: [PATCH 119/351] nothing much changed

Rev: bin/hilfe.lpc:1.4
---
 bin/hilfe.lpc | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/bin/hilfe.lpc b/bin/hilfe.lpc
index 89470e7ea2..c9e823cd73 100755
--- a/bin/hilfe.lpc
+++ b/bin/hilfe.lpc
@@ -55,11 +55,7 @@ string input="";
 
 string skipwhite(string f)
 {
-//  perror("skipwhite '"+f+"'\n");
-//  trace(99);
   while(sscanf(f,"%*[ \r\n\t]%s",f) && sscanf(f,"/*%*s*/%s",f));
-//  trace(0);
-//  perror("returned  '"+f+"'\n");
   return f;
 }
 
-- 
GitLab


From 8a8ec4c255f5f42e4f2797e4a5cdc80bf21b8245 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 21 Apr 1996 20:23:00 +0200
Subject: [PATCH 120/351] minor fixes

Rev: lib/master.lpc:1.5
Rev: lib/simulate.lpc:1.12
---
 lib/master.lpc   | 12 +++++++++---
 lib/simulate.lpc |  2 +-
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/lib/master.lpc b/lib/master.lpc
index bf6d7b91e9..8d4d8f010a 100644
--- a/lib/master.lpc
+++ b/lib/master.lpc
@@ -167,11 +167,11 @@ void _main(string *argv, string *env)
   if(i >=0) exit(i);
 }
 
-int inhibit_compile_errors;
+mixed inhibit_compile_errors;
 
-void set_inhibit_compile_errors(int i)
+void set_inhibit_compile_errors(mixed f)
 {
-  inhibit_compile_errors=i;
+  inhibit_compile_errors=f;
 }
 
 /*
@@ -183,7 +183,13 @@ void set_inhibit_compile_errors(int i)
 void compile_error(string file,int line,string err)
 {
   if(!inhibit_compile_errors)
+  {
     perror(sprintf("%s:%d:%s\n",file,line,err));
+  }
+  else if(functionp(inhibit_compile_errors))
+  {
+    inhibit_compile_errors(file,line,err);
+  }
 }
 
 /* This function is called whenever an #include directive is encountered
diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index fc150db617..4270a479d2 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -267,7 +267,7 @@ function this_function()
   return backtrace()[-2][2];
 }
 
-varargs mixed *sort_array2(array foo,function cmp, mixed ... args)
+varargs mixed *sort_array(array foo,function cmp, mixed ... args)
 {
   array bar,tmp;
   int len,start;
-- 
GitLab


From 3e195b71fd3fc5c81db4c93c82839d46a480133d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 23 Apr 1996 21:01:35 +0200
Subject: [PATCH 121/351] conflict fixed

Rev: src/ChangeLog:1.29
---
 src/ChangeLog | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 0be821c184..2ea61c9d23 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -5,6 +5,11 @@ Sat Apr 13 04:00:45 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
 	* crypt() should now work with BSD crypt() I hope
 	* lots of files: added a peephole optimizer
 
+Thu Apr 11 23:13:24 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
+
+	* apply on void functions fixed
+	* case -1 fixed
+
 Tue Apr  2 17:01:10 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
 
 	* signal.c: alarm() added
-- 
GitLab


From 06ec86050a6103dbcc8c93919ad3dca0b17d9bfe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 23 Apr 1996 22:22:56 +0200
Subject: [PATCH 122/351] sort array fixed

Rev: lib/simulate.lpc:1.13
---
 lib/simulate.lpc | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index 4270a479d2..83758959b3 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -278,6 +278,7 @@ varargs mixed *sort_array(array foo,function cmp, mixed ... args)
   length=sizeof(foo);
 
   foo+=({});
+//  perror(sprintf("DEBUG: %O\n",foo));
   bar=allocate(length);
 
   for(len=1;len<length;len*=2)
@@ -290,6 +291,8 @@ varargs mixed *sort_array(array foo,function cmp, mixed ... args)
       fooend=barp;
       barend=barp+len;
       if(barend > length) barend=length;
+      if(barend <= barp) 
+	error("OOPS");
       
       while(1)
       {
@@ -311,6 +314,7 @@ varargs mixed *sort_array(array foo,function cmp, mixed ... args)
 	}
       }
     }
+    while(start < length) bar[start]=foo[start++];
 
     tmp=foo;
     foo=bar;
@@ -375,7 +379,7 @@ void create()
   add_efun("sum_arrays",sum_arrays);
   add_efun("system",system);
   add_efun("this_function",this_function);
-  add_efun("version",lambda() { return "uLPC v1.0E-10"; });
+  add_efun("version",lambda() { return "uLPC v1.0E-9"; });
   add_efun("write_file",write_file);
 }
 
-- 
GitLab


From 576b41f85ec77f52f9a32f8fd6fe2870b1c4a40f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 23 Apr 1996 22:24:49 +0200
Subject: [PATCH 123/351] ignoring language.y language.h

Rev: src/.cvsignore:1.3
---
 src/.cvsignore | 2 ++
 src/.gitignore | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/src/.cvsignore b/src/.cvsignore
index 773fcbba07..d731bc07dd 100644
--- a/src/.cvsignore
+++ b/src/.cvsignore
@@ -1,2 +1,4 @@
 configure
+language.c
+language.h
 peep_engine.c
diff --git a/src/.gitignore b/src/.gitignore
index 17c607db6a..73ff5defb0 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1,2 +1,4 @@
 /configure
+/language.c
+/language.h
 /peep_engine.c
-- 
GitLab


From 645e26c6dfa8170b2e047f4e121aca9af1762007 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 23 Apr 1996 22:25:24 +0200
Subject: [PATCH 124/351] debug fixed

Rev: src/peep.c:1.2
---
 src/peep.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/peep.c b/src/peep.c
index 8795c4336f..a066b94d94 100644
--- a/src/peep.c
+++ b/src/peep.c
@@ -145,7 +145,7 @@ void update_arg(int instr,INT32 arg)
 {
   p_instr *p;
 #ifdef DEBUG
-  if(instr > instrbuf.s.len / sizeof(p_instr) || instr < 0)
+  if(instr > (long)instrbuf.s.len / (long)sizeof(p_instr) || instr < 0)
     fatal("update_arg outside known space.\n");
 #endif  
   p=(p_instr *)instrbuf.s.str;
@@ -351,7 +351,7 @@ static void debug()
 {
   p_instr *p;
 
-  if(fifo_len > instrbuf.s.len / sizeof(p_instr))
+  if(fifo_len > (long)instrbuf.s.len / (long)sizeof(p_instr))
     fatal("Fifo too long.\n");
 
   if(eye < 0)
-- 
GitLab


From dfea369bbad331ee02cfbcfd126fe6f99ac5f1ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 23 Apr 1996 22:30:12 +0200
Subject: [PATCH 125/351] minor fix

Rev: src/program.c:1.10
---
 src/program.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/program.c b/src/program.c
index 2f33c4adcd..65759de03a 100644
--- a/src/program.c
+++ b/src/program.c
@@ -1083,7 +1083,7 @@ static void insert_small_number(int a,int area)
   }	
 }
 
-void store_linenumber(INT32 current_line, struct lpc_string *current_string)
+void store_linenumber(INT32 current_line, struct lpc_string *current_file)
 {
   if(last_line!=current_line || last_file != current_file)
   {
-- 
GitLab


From defd42a4d5b395e598aedb1b569a2a66238a38f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 23 Apr 1996 22:30:54 +0200
Subject: [PATCH 126/351] fixed to distrubute language.c

Rev: src/Makefile.in:1.14
---
 src/Makefile.in | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/src/Makefile.in b/src/Makefile.in
index b1f28d70dc..32907d1d8d 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -123,7 +123,7 @@ tidy:
 clean: tidy
 	-for a in $(MODULES) ; do ( cd $$a ; ${MAKE} $(MAKE_FLAGS) clean ) ; done
 	-for a in $(MODULES) ; do rm -f $$a/*.o ; done
-	-rm -f language.h language.c TAGS tags
+	-rm -f TAGS tags
 	-rm -f yacc.acts yacc.debug yacc.tmp *.debug.log a.out
 
 # make _really_ clean
@@ -164,10 +164,15 @@ run_hilfe:
 
 # make export archive (requires compiled uLPC)
 # Do not compile in source tree if you want to use this!
-export: $(SRCDIR)/test/testsuite
+# Beware that export archive this includes bison/yacc/byacc source
+# and thus has to follow the rules stated in that code.
+export: $(SRCDIR)/test/testsuite new_peep_engine $(SRCDIR)/language.c $(SRCDIR)/language.h
 	chmod +x $(SRCDIR)/install-sh
 	$(RUNULPC) $(TMP_BINDIR)/export.lpc
 
+new_peep_engine:
+	$(RUNULPC) $(TMP_BINDIR)/mkpeep.lpc $(SRCDIR)/peep.in >$(SRCDIR)/peep_engine.c
+
 peep_engine.c: peep.in
 	echo "" >$(SRCDIR)/peep_engine.c
 	-$(RUNULPC) $(TMP_BINDIR)/mkpeep.lpc $(SRCDIR)/peep.in >$(SRCDIR)/peep_engine.c
@@ -191,14 +196,14 @@ module_objects:
 
 lang.o: lang.c config.h object.h interpret.h program.h
 
-language.h: language.y
+$(SRCDIR)/language.h: language.y
 	@echo "Expect 1 shift/reduce conflict."
 	$(YACC) $(YFLAGS) $(SRCDIR)/language.y
-	mv y.tab.c language.c
-	mv y.tab.h language.h
+	mv y.tab.c $(SRCDIR)/language.c
+	mv y.tab.h $(SRCDIR)/language.h
 
-language.c: language.h
-	touch language.c
+$(SRCDIR)/language.c: language.h
+	touch $(SRCDIR)/language.c
 
 module.c: modlist.h
 
-- 
GitLab


From 26e7e7cddda6947525e5fc0d2bf514e09c68cd3c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 23 Apr 1996 22:31:49 +0200
Subject: [PATCH 127/351] now really tests for %pure_parser

Rev: src/configure.in:1.10
---
 src/configure.in | 98 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 77 insertions(+), 21 deletions(-)

diff --git a/src/configure.in b/src/configure.in
index 8070285c90..b632c48c3a 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1,5 +1,6 @@
 AC_INIT(interpret.c)
 AC_PROG_CC
+AC_C_CROSS
 
 # We need some special hacks when running slowaris
 AC_PATH_PROG(uname_prog,uname,no)
@@ -100,33 +101,87 @@ fi
 
 AC_CONFIG_HEADER(machine.h)
 AC_PROG_INSTALL
-AC_PROG_YACC
 AC_PROG_CPP
 AC_PROG_RANLIB
 AC_SET_MAKE
-AC_CHECK_PROG(has_strings, strings, yes, no)
 
-if test "$has_strings" = "yes"; then
-  yacc_prog=`echo $YACC | sed 's/^\([^ ]*\) .*$/\1/'`
-  AC_PATH_PROG(yacc_prog,$yacc_prog,/bin/true)
-
-  AC_MSG_CHECKING(if $YACC handles pure_parser)
-  AC_CACHE_VAL(lpc_cv_yacc_pure_parser,
-  [
-    lpc_cv_yacc_pure_parser=no
-    strings $yacc_prog >conftest.bar
-    if egrep pure_parser conftest.bar >/dev/null; then
-      lpc_cv_yacc_pure_parser=yes
+AC_MSG_CHECKING(for yacc clone that handles %pure_parser)
+AC_CACHE_VAL(lpc_cv_prog_working_yacc,
+[
+for YACC in byacc "bison -y" yacc "echo Get bison if you want to make export" ; do
+  set dummy $YACC; ac_word=$2
+  has_it=no
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      has_it="yes"
+      break
     fi
-  ])
+  done
+  IFS="$ac_save_ifs"
+  
+  if test "$has_it" = "yes"; then
+cat >conftest.y<<\EOF
+%pure_parser
+%{
+void parse();
+void yyerror(char *);
+%}
+%%
+all: foo bar
+foo: 'f' 'o' 'o' { parse(); } ;
+bar: 'b' 'a' 'r' ;
+%%
+int context;
 
-  if test "$lpc_cv_yacc_pure_parser" = "yes"; then
-    AC_MSG_RESULT(yes)
-  else
-    AC_MSG_RESULT([[no, get bison and retry... (giving up)]])
-    exit 1
+int yylex(YYSTYPE *yylval)
+{
+  switch(context++)
+  {
+    case 0: return 'f';
+    case 1: return 'o';
+    case 2: return 'o';
+    case 3: return 'b';
+    case 4: return 'a';
+    case 5: return 'r';
+    default: return 0;
+  }
+}
+
+int depth=0;
+void parse()
+{
+  int tmp;
+  if(depth++>5) return;
+  tmp=context;
+  context=0;
+  yyparse();
+  context=tmp;
+}
+int errors=0;
+void yyerror(char *fel) { errors++; }
+int main()
+{
+  parse();
+  exit(errors);
+}
+EOF
+    if $YACC -d conftest.y 1>&5 2>&5; then
+      AC_TRY_RUN([
+#include "y.tab.c"
+],pure_parser_works=yes,pure_parser_works=no)
+      if test "$pure_parser_works" = "yes"; then
+        break
+      fi
+    fi
   fi
-fi
+done
+lpc_cv_prog_working_yacc="$YACC"
+])
+
+YACC="$lpc_cv_prog_working_yacc"
+AC_MSG_RESULT($YACC)
 
 AC_MSG_CHECKING(first yacc define)
 AC_CACHE_VAL(lpc_cv_yacc_first,
@@ -138,7 +193,7 @@ all: GURKA
 %%
 EOF
 lpc_cv_yacc_first=257;
-if $YACC -d conftest.y ; then
+if $YACC -d conftest.y 1>&5 2>&5; then
   if test -f y.tab.h; then
     lpc_cv_yacc_first=`egrep GURKA y.tab.h | sed 's/^#[^0-9]*\([0-9]*\)[^0-9]*$/\1/'`
     echo $lpc_cv_yacc_first >conftest.out
@@ -762,6 +817,7 @@ BUILDDIR=`pwd`
 
 AC_CONFIG_SUBDIRS($dirs)
 
+AC_SUBST(YACC)
 AC_SUBST(MODULE_OBJS)
 AC_SUBST(INSTALL)
 AC_SUBST(WARN)
-- 
GitLab


From 1617a8b42ce033bc86878d97333a8118b6b75b3f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 23 Apr 1996 22:39:25 +0200
Subject: [PATCH 128/351] new tar file ignored

Rev: .cvsignore:1.5
---
 .cvsignore | 3 ++-
 .gitignore | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/.cvsignore b/.cvsignore
index d90b873748..fe66920fc0 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -1,8 +1,9 @@
+reports
 test
 test.lpc
 uLPC_v1.0E-10.tar.gz
 uLPC_v1.0E-12.tar.gz
 uLPC_v1.0E-13.tar.gz
+uLPC_v1.0E-9.tar.gz
 uLPC_v1.1E-12.tar.gz
 uLPC_v1.7E-12.tar.gz
-reports
diff --git a/.gitignore b/.gitignore
index d2513525d1..173fd526a8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,11 +30,12 @@ _$*
 *.elc
 *.ln
 core
+/reports
 /test
 /test.lpc
 /uLPC_v1.0E-10.tar.gz
 /uLPC_v1.0E-12.tar.gz
 /uLPC_v1.0E-13.tar.gz
+/uLPC_v1.0E-9.tar.gz
 /uLPC_v1.1E-12.tar.gz
 /uLPC_v1.7E-12.tar.gz
-/reports
-- 
GitLab


From 787fa2126fc541a2be492e1328cebe430164ae66 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 23 Apr 1996 22:48:12 +0200
Subject: [PATCH 129/351] entry added

Rev: src/ChangeLog:1.30
---
 src/ChangeLog | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 2ea61c9d23..40b997c3d7 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+Tue Apr 23 22:32:04 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
+
+	* Makefile.in: Now language.c and language.h is a part of the
+	  distribution so you won't need bison to compile.
+
 Sat Apr 13 04:00:45 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
 
 	* simulate.lpc: replaced sort_array with a faster one
-- 
GitLab


From 8cea355c3bfcf3686e67f5ded4ee9b8a4039e665 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 26 Apr 1996 18:37:25 +0200
Subject: [PATCH 130/351] better error messages

Rev: src/modules/regexp/regexp.c:1.3
---
 src/modules/regexp/regexp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/modules/regexp/regexp.c b/src/modules/regexp/regexp.c
index 962dd8233c..6c496acdff 100644
--- a/src/modules/regexp/regexp.c
+++ b/src/modules/regexp/regexp.c
@@ -168,7 +168,7 @@
  * Utility definitions.
  */
 
-#define regerror(X) error(X);
+#define regerror(X) error("Regexp: %s\n",X);
 #define SPECIAL 0x100
 #define LBRAC	('('|SPECIAL)
 #define RBRAC	(')'|SPECIAL)
-- 
GitLab


From 4f20efdd2397b6e37a5d2b25fa03e2efef5add87 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 27 Apr 1996 21:38:58 +0200
Subject: [PATCH 131/351] stuff added

Rev: src/todo:1.5
---
 src/todo | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/todo b/src/todo
index 878868b834..260fc1f7da 100644
--- a/src/todo
+++ b/src/todo
@@ -177,11 +177,10 @@ add garbage collect
 
 addera generisk callback
 
-set_socket_nonblocking adderar ingen referens till objektet...
-
 assert (kolla typer explicit)
 generalisera foreach()
 constant
 'type wish'
 rewrite sort_array
 
+document file::set_nonblocking better (prototype callbacks etc.)
-- 
GitLab


From c99706dac15a6de88e0fae5b174b3756eab73c97 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 27 Apr 1996 21:43:38 +0200
Subject: [PATCH 132/351] make depend done

Rev: src/Makefile.in:1.15
Rev: src/modules/files/Makefile.in:1.3
Rev: src/modules/math/Makefile.in:1.2
Rev: src/modules/regexp/Makefile.in:1.3
Rev: src/modules/sprintf/Makefile.in:1.3
---
 src/Makefile.in                 | 670 ++++++++++++--------------------
 src/modules/files/Makefile.in   |  94 +++--
 src/modules/math/Makefile.in    |  18 +-
 src/modules/regexp/Makefile.in  |  38 +-
 src/modules/sprintf/Makefile.in |  29 +-
 5 files changed, 338 insertions(+), 511 deletions(-)

diff --git a/src/Makefile.in b/src/Makefile.in
index 32907d1d8d..ecbeed9977 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -166,7 +166,7 @@ run_hilfe:
 # Do not compile in source tree if you want to use this!
 # Beware that export archive this includes bison/yacc/byacc source
 # and thus has to follow the rules stated in that code.
-export: $(SRCDIR)/test/testsuite new_peep_engine $(SRCDIR)/language.c $(SRCDIR)/language.h
+export: $(SRCDIR)/test/testsuite new_peep_engine $(SRCDIR)/language.c $(SRCDIR)/language.h depend
 	chmod +x $(SRCDIR)/install-sh
 	$(RUNULPC) $(TMP_BINDIR)/export.lpc
 
@@ -179,7 +179,7 @@ peep_engine.c: peep.in
 
 # make dependencies (requires compiled uLPC)
 depend: language.c
-	gcc -MM $(PREFLAGS) *.c $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)/Makefile.in
+	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)/Makefile.in
 	for a in $(MODULES) ; do ( cd $$a ; ${MAKE} $(MAKE_FLAGS) depend ) ; done
 
 docs:
@@ -229,438 +229,272 @@ $(SRCDIR)/test/testsuite: $(SRCDIR)/test/create_testsuite
 
 
 #Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
-language.o: language.c global.h machine.h \
-  config.h \
-  port.h \
-  interpret.h \
-  program.h \
-  array.h las.h \
-  svalue.h \
-  dynamic_buffer.h \
-  object.h \
-  stralloc.h \
-  lex.h \
-  lpc_types.h \
-  add_efun.h \
-  hashtable.h \
-  macros.h \
-  error.h \
-  docode.h
 add_efun.o: add_efun.c \
-  add_efun.h \
-  svalue.h \
-  types.h machine.h \
-  hashtable.h \
-  las.h \
-  config.h \
-  dynamic_buffer.h \
-  program.h \
-  macros.h \
-  memory.h \
-  lpc_types.h \
-  stralloc.h \
-  interpret.h
+ add_efun.h svalue.h \
+ types.h machine.h \
+ hashtable.h las.h \
+ config.h dynamic_buffer.h \
+ program.h macros.h \
+ memory.h lpc_types.h \
+ stralloc.h interpret.h
 alloca.o: alloca.c
-array.o: array.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  svalue.h \
-  array.h las.h \
-  dynamic_buffer.h \
-  program.h \
-  object.h \
-  stralloc.h \
-  interpret.h language.h \
-  error.h \
-  lpc_types.h \
-  fsort.h \
-  builtin_efuns.h \
-  gc.h
+array.o: array.c global.h \
+ machine.h config.h port.h \
+ svalue.h array.h \
+ las.h dynamic_buffer.h \
+ program.h object.h \
+ stralloc.h interpret.h \
+ language.h error.h \
+ lpc_types.h fsort.h \
+ builtin_efuns.h gc.h
 backend.o: backend.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  backend.h \
-  interpret.h \
-  program.h \
-  object.h \
-  svalue.h \
-  error.h \
-  call_out.h \
-  fd_control.h \
-  main.h \
-  callback.h \
-  array.h las.h \
-  dynamic_buffer.h
+ global.h machine.h config.h \
+ port.h backend.h \
+ interpret.h program.h \
+ object.h svalue.h \
+ error.h call_out.h \
+ fd_control.h main.h \
+ callback.h array.h \
+ las.h dynamic_buffer.h
 builtin_efuns.o: builtin_efuns.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  interpret.h \
-  program.h \
-  svalue.h \
-  macros.h \
-  object.h \
-  array.h las.h \
-  dynamic_buffer.h \
-  error.h \
-  add_efun.h \
-  hashtable.h \
-  mapping.h \
-  stralloc.h \
-  lex.h list.h \
-  lpc_types.h \
-  rusage.h \
-  operators.h \
-  fsort.h \
-  call_out.h \
-  callback.h \
-  gc.h
+ global.h machine.h config.h \
+ port.h interpret.h \
+ program.h svalue.h \
+ macros.h object.h \
+ array.h las.h \
+ dynamic_buffer.h error.h \
+ add_efun.h hashtable.h \
+ mapping.h stralloc.h \
+ lex.h list.h \
+ lpc_types.h rusage.h \
+ operators.h fsort.h \
+ call_out.h callback.h \
+ gc.h
 call_out.o: call_out.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  array.h las.h \
-  svalue.h \
-  dynamic_buffer.h \
-  program.h \
-  call_out.h \
-  object.h \
-  interpret.h \
-  error.h \
-  builtin_efuns.h \
-  main.h
+ global.h machine.h config.h \
+ port.h array.h \
+ las.h svalue.h \
+ dynamic_buffer.h program.h \
+ call_out.h object.h \
+ interpret.h error.h \
+ builtin_efuns.h main.h
 callback.o: callback.c \
-  macros.h \
-  memory.h \
-  types.h machine.h \
-  callback.h \
-  array.h las.h \
-  config.h \
-  svalue.h \
-  dynamic_buffer.h \
-  program.h
+ macros.h memory.h \
+ types.h machine.h \
+ callback.h array.h \
+ las.h config.h \
+ svalue.h dynamic_buffer.h \
+ program.h
+docode.o: docode.c global.h \
+ machine.h config.h port.h \
+ las.h svalue.h \
+ dynamic_buffer.h program.h \
+ language.h lpc_types.h \
+ stralloc.h interpret.h \
+ add_efun.h hashtable.h \
+ array.h macros.h \
+ error.h main.h \
+ lex.h builtin_efuns.h \
+ peep.h docode.h
 dynamic_buffer.o: dynamic_buffer.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  dynamic_buffer.h \
-  stralloc.h \
-  error.h \
-  svalue.h
-error.o: error.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  macros.h \
-  error.h \
-  svalue.h \
-  interpret.h \
-  program.h \
-  stralloc.h \
-  builtin_efuns.h \
-  array.h las.h \
-  dynamic_buffer.h \
-  object.h
+ global.h machine.h config.h \
+ port.h dynamic_buffer.h \
+ stralloc.h error.h \
+ svalue.h
+error.o: error.c global.h \
+ machine.h config.h port.h \
+ macros.h error.h \
+ svalue.h interpret.h \
+ program.h stralloc.h \
+ builtin_efuns.h array.h \
+ las.h dynamic_buffer.h \
+ object.h
 fd_control.o: fd_control.c \
-  fd_control.h \
-  global.h machine.h \
-  config.h \
-  port.h
-fsort.o: fsort.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  fsort.h
-gc.o: gc.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  array.h las.h \
-  svalue.h \
-  dynamic_buffer.h \
-  program.h \
-  list.h \
-  mapping.h \
-  object.h gc.h \
-  main.h
+ fd_control.h global.h \
+ machine.h config.h port.h
+fsort.o: fsort.c global.h \
+ machine.h config.h port.h \
+ fsort.h
+gc.o: gc.c global.h \
+ machine.h config.h port.h \
+ array.h las.h \
+ svalue.h dynamic_buffer.h \
+ program.h list.h \
+ mapping.h object.h \
+ gc.h main.h
 hashtable.o: hashtable.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  hashtable.h \
-  stralloc.h \
-  stuff.h \
-  error.h \
-  svalue.h
+ global.h machine.h config.h \
+ port.h hashtable.h \
+ stralloc.h stuff.h \
+ error.h svalue.h
 interpret.o: interpret.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  interpret.h \
-  program.h \
-  object.h \
-  svalue.h \
-  array.h las.h \
-  dynamic_buffer.h \
-  mapping.h \
-  error.h language.h \
-  stralloc.h \
-  add_efun.h \
-  hashtable.h \
-  macros.h \
-  list.h \
-  backend.h \
-  operators.h \
-  opcodes.h \
-  main.h lex.h \
-  builtin_efuns.h \
-  lpc_signal.h
-las.o: las.c \
-  global.h machine.h \
-  config.h \
-  port.h language.h \
-  interpret.h \
-  program.h \
-  las.h \
-  svalue.h \
-  dynamic_buffer.h \
-  array.h \
-  object.h \
-  stralloc.h \
-  lex.h \
-  lpc_types.h \
-  add_efun.h \
-  hashtable.h \
-  mapping.h \
-  list.h \
-  error.h \
-  docode.h \
-  main.h
-lex.o: lex.c \
-  global.h machine.h \
-  config.h \
-  port.h language.h \
-  array.h las.h \
-  svalue.h \
-  dynamic_buffer.h \
-  program.h \
-  lex.h \
-  stralloc.h \
-  add_efun.h \
-  hashtable.h \
-  stuff.h \
-  interpret.h \
-  error.h \
-  object.h \
-  operators.h \
-  opcodes.h \
-  builtin_efuns.h \
-  macros.h
-list.o: list.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  array.h las.h \
-  svalue.h \
-  dynamic_buffer.h \
-  program.h \
-  list.h \
-  macros.h \
-  error.h \
-  interpret.h \
-  builtin_efuns.h \
-  gc.h
+ global.h machine.h config.h \
+ port.h interpret.h \
+ program.h object.h \
+ svalue.h array.h \
+ las.h dynamic_buffer.h \
+ mapping.h error.h \
+ language.h stralloc.h \
+ add_efun.h hashtable.h \
+ macros.h list.h \
+ backend.h operators.h \
+ opcodes.h main.h \
+ lex.h builtin_efuns.h \
+ lpc_signal.h
+language.o: language.c \
+ global.h machine.h config.h \
+ port.h interpret.h \
+ program.h array.h \
+ las.h svalue.h \
+ dynamic_buffer.h object.h \
+ stralloc.h lex.h \
+ lpc_types.h add_efun.h \
+ hashtable.h macros.h \
+ error.h docode.h
+las.o: las.c global.h \
+ machine.h config.h port.h \
+ language.h interpret.h \
+ program.h las.h \
+ svalue.h dynamic_buffer.h \
+ array.h object.h \
+ stralloc.h lex.h \
+ lpc_types.h add_efun.h \
+ hashtable.h mapping.h \
+ list.h error.h \
+ docode.h main.h
+lex.o: lex.c global.h \
+ machine.h config.h port.h \
+ language.h array.h \
+ las.h svalue.h \
+ dynamic_buffer.h program.h \
+ lex.h stralloc.h \
+ add_efun.h hashtable.h \
+ stuff.h interpret.h \
+ error.h object.h \
+ operators.h opcodes.h \
+ builtin_efuns.h macros.h
+list.o: list.c global.h \
+ machine.h config.h port.h \
+ array.h las.h \
+ svalue.h dynamic_buffer.h \
+ program.h list.h \
+ macros.h error.h \
+ interpret.h builtin_efuns.h \
+ gc.h
 lpc_signal.o: lpc_signal.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  svalue.h \
-  interpret.h \
-  program.h \
-  stralloc.h \
-  add_efun.h \
-  hashtable.h \
-  las.h \
-  dynamic_buffer.h \
-  macros.h \
-  backend.h
+ global.h machine.h config.h \
+ port.h svalue.h \
+ interpret.h program.h \
+ stralloc.h add_efun.h \
+ hashtable.h las.h \
+ dynamic_buffer.h macros.h \
+ backend.h
 lpc_types.o: lpc_types.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  svalue.h \
-  lpc_types.h \
-  stralloc.h \
-  stuff.h \
-  array.h las.h \
-  dynamic_buffer.h \
-  program.h \
-  add_efun.h \
-  hashtable.h \
-  object.h \
-  list.h \
-  mapping.h \
-  macros.h \
-  error.h
-main.o: main.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  backend.h \
-  module.h \
-  object.h \
-  svalue.h \
-  lex.h \
-  lpc_types.h \
-  builtin_efuns.h \
-  array.h las.h \
-  dynamic_buffer.h \
-  program.h \
-  stralloc.h \
-  interpret.h \
-  error.h \
-  macros.h \
-  callback.h \
-  lpc_signal.h
+ global.h machine.h config.h \
+ port.h svalue.h \
+ lpc_types.h stralloc.h \
+ stuff.h array.h \
+ las.h dynamic_buffer.h \
+ program.h add_efun.h \
+ hashtable.h object.h \
+ list.h mapping.h \
+ macros.h error.h
+main.o: main.c global.h \
+ machine.h config.h port.h \
+ backend.h module.h \
+ object.h svalue.h \
+ lex.h lpc_types.h \
+ builtin_efuns.h array.h \
+ las.h dynamic_buffer.h \
+ program.h stralloc.h \
+ interpret.h error.h \
+ macros.h callback.h \
+ lpc_signal.h
 mapping.o: mapping.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  mapping.h \
-  las.h \
-  svalue.h \
-  dynamic_buffer.h \
-  program.h \
-  array.h \
-  macros.h language.h \
-  error.h \
-  interpret.h \
-  gc.h
-memory.o: memory.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  error.h \
-  svalue.h
-module.o: module.c \
-  module.h \
-  types.h machine.h \
-  macros.h \
-  memory.h \
-  error.h \
-  svalue.h modlist.h
-object.o: object.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  object.h \
-  svalue.h \
-  dynamic_buffer.h \
-  interpret.h \
-  program.h \
-  stralloc.h \
-  macros.h \
-  error.h \
-  main.h \
-  array.h las.h \
-  gc.h
+ global.h machine.h config.h \
+ port.h mapping.h \
+ las.h svalue.h \
+ dynamic_buffer.h program.h \
+ array.h macros.h \
+ language.h error.h \
+ interpret.h gc.h
+memory.o: memory.c global.h \
+ machine.h config.h port.h \
+ error.h svalue.h
+module.o: module.c module.h \
+ types.h machine.h macros.h \
+ memory.h error.h \
+ svalue.h modlist.h
+object.o: object.c global.h \
+ machine.h config.h port.h \
+ object.h svalue.h \
+ dynamic_buffer.h \
+ interpret.h program.h \
+ stralloc.h macros.h \
+ error.h main.h \
+ array.h las.h \
+ gc.h
 opcodes.o: opcodes.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  interpret.h \
-  program.h \
-  svalue.h \
-  array.h las.h \
-  dynamic_buffer.h \
-  stralloc.h \
-  mapping.h \
-  list.h \
-  opcodes.h \
-  object.h \
-  error.h \
-  lpc_types.h
+ global.h machine.h config.h \
+ port.h interpret.h \
+ program.h svalue.h \
+ array.h las.h \
+ dynamic_buffer.h stralloc.h \
+ mapping.h list.h \
+ opcodes.h object.h \
+ error.h lpc_types.h
 operators.o: operators.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  interpret.h \
-  program.h \
-  svalue.h \
-  list.h las.h \
-  dynamic_buffer.h \
-  mapping.h \
-  array.h \
-  stralloc.h \
-  opcodes.h \
-  operators.h language.h \
-  error.h \
-  docode.h \
-  add_efun.h \
-  hashtable.h
-peep.o: peep.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  peep_engine.c
+ global.h machine.h config.h \
+ port.h interpret.h \
+ program.h svalue.h \
+ list.h las.h \
+ dynamic_buffer.h mapping.h \
+ array.h stralloc.h \
+ opcodes.h operators.h \
+ language.h error.h \
+ docode.h add_efun.h \
+ hashtable.h peep.h \
+ lex.h
+peep.o: peep.c global.h \
+ machine.h config.h port.h \
+ language.h stralloc.h \
+ dynamic_buffer.h program.h \
+ las.h svalue.h \
+ docode.h main.h \
+ error.h lex.h \
+ peep_engine.c
 peep_engine.o: peep_engine.c
-port.o: port.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  macros.h
+port.o: port.c global.h \
+ machine.h config.h port.h \
+ macros.h
 program.o: program.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  program.h \
-  object.h \
-  svalue.h \
-  dynamic_buffer.h \
-  lpc_types.h \
-  stralloc.h \
-  las.h language.h \
-  lex.h \
-  macros.h \
-  fsort.h \
-  error.h \
-  docode.h \
-  interpret.h \
-  hashtable.h \
-  main.h gc.h \
-  compilation.h
-rusage.o: rusage.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  rusage.h
+ global.h machine.h config.h \
+ port.h program.h \
+ object.h svalue.h \
+ dynamic_buffer.h \
+ lpc_types.h stralloc.h \
+ las.h language.h \
+ lex.h macros.h \
+ fsort.h error.h \
+ docode.h interpret.h \
+ hashtable.h main.h \
+ gc.h compilation.h
+rusage.o: rusage.c global.h \
+ machine.h config.h port.h \
+ rusage.h
 stralloc.o: stralloc.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  stralloc.h \
-  macros.h \
-  dynamic_buffer.h \
-  error.h \
-  svalue.h
-stuff.o: stuff.c \
-  stuff.h \
-  types.h machine.h
-svalue.o: svalue.c \
-  global.h machine.h \
-  config.h \
-  port.h \
-  svalue.h \
-  stralloc.h \
-  array.h las.h \
-  dynamic_buffer.h \
-  program.h \
-  mapping.h \
-  list.h \
-  object.h \
-  add_efun.h \
-  hashtable.h \
-  error.h
+ global.h machine.h config.h \
+ port.h stralloc.h \
+ macros.h dynamic_buffer.h \
+ error.h svalue.h
+stuff.o: stuff.c stuff.h \
+ types.h machine.h
+svalue.o: svalue.c global.h \
+ machine.h config.h port.h \
+ svalue.h stralloc.h \
+ array.h las.h \
+ dynamic_buffer.h program.h \
+ mapping.h list.h \
+ object.h add_efun.h \
+ hashtable.h error.h
 ualarm.o: ualarm.c
diff --git a/src/modules/files/Makefile.in b/src/modules/files/Makefile.in
index 9df921c43f..08a46f581d 100644
--- a/src/modules/files/Makefile.in
+++ b/src/modules/files/Makefile.in
@@ -21,54 +21,50 @@ depend:
 #Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
 datagram.o: datagram.c
 efuns.o: efuns.c \
-  global.h \
-  machine.h \
-  config.h \
-  port.h \
-  interpret.h \
-  program.h \
-  svalue.h \
-  stralloc.h \
-  array.h \
-  las.h \
-  dynamic_buffer.h \
-  mapping.h \
-  macros.h \
-  fd_control.h \
-  file_machine.h
+ global.h machine.h \
+ config.h \
+ port.h \
+ interpret.h \
+ program.h \
+ svalue.h \
+ stralloc.h \
+ array.h \
+ las.h \
+ dynamic_buffer.h \
+ mapping.h \
+ macros.h \
+ fd_control.h file_machine.h
 file.o: file.c \
-  global.h \
-  machine.h \
-  config.h \
-  port.h \
-  interpret.h \
-  program.h \
-  svalue.h \
-  stralloc.h \
-  array.h \
-  las.h \
-  dynamic_buffer.h \
-  object.h \
-  macros.h \
-  backend.h \
-  fd_control.h \
-  file_machine.h file.h \
-  error.h \
-  lpc_signal.h
+ global.h machine.h \
+ config.h \
+ port.h \
+ interpret.h \
+ program.h \
+ svalue.h \
+ stralloc.h \
+ array.h \
+ las.h \
+ dynamic_buffer.h \
+ object.h \
+ macros.h \
+ backend.h \
+ fd_control.h file_machine.h \
+ file.h \
+ error.h \
+ lpc_signal.h
 socket.o: socket.c \
-  global.h \
-  machine.h \
-  config.h \
-  port.h \
-  interpret.h \
-  program.h \
-  svalue.h \
-  stralloc.h \
-  array.h \
-  las.h \
-  dynamic_buffer.h \
-  object.h \
-  macros.h \
-  backend.h \
-  fd_control.h \
-  file_machine.h file.h
+ global.h machine.h \
+ config.h \
+ port.h \
+ interpret.h \
+ program.h \
+ svalue.h \
+ stralloc.h \
+ array.h \
+ las.h \
+ dynamic_buffer.h \
+ object.h \
+ macros.h \
+ backend.h \
+ fd_control.h file_machine.h \
+ file.h
diff --git a/src/modules/math/Makefile.in b/src/modules/math/Makefile.in
index 6dfea15813..23d8ad254b 100644
--- a/src/modules/math/Makefile.in
+++ b/src/modules/math/Makefile.in
@@ -19,12 +19,12 @@ depend:
 
 #Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
 math.o: math.c \
-  interpret.h \
-  program.h \
-  config.h machine.h \
-  types.h \
-  add_efun.h \
-  svalue.h \
-  hashtable.h \
-  las.h \
-  dynamic_buffer.h
+ interpret.h \
+ program.h \
+ config.h machine.h \
+ types.h \
+ add_efun.h \
+ svalue.h \
+ hashtable.h \
+ las.h \
+ dynamic_buffer.h
diff --git a/src/modules/regexp/Makefile.in b/src/modules/regexp/Makefile.in
index f3a73a2b6c..43cee96b2a 100644
--- a/src/modules/regexp/Makefile.in
+++ b/src/modules/regexp/Makefile.in
@@ -19,24 +19,22 @@ depend:
 
 #Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
 glue.o: glue.c \
-  global.h \
-  machine.h \
-  config.h \
-  port.h \
-  interpret.h \
-  program.h \
-  svalue.h \
-  stralloc.h \
-  array.h \
-  las.h \
-  dynamic_buffer.h \
-  object.h \
-  macros.h
+ global.h machine.h \
+ config.h \
+ port.h \
+ interpret.h \
+ program.h \
+ svalue.h \
+ stralloc.h \
+ array.h \
+ las.h \
+ dynamic_buffer.h \
+ object.h \
+ macros.h
 regexp.o: regexp.c \
-  global.h \
-  machine.h \
-  config.h \
-  port.h \
-  regexp.h \
-  error.h \
-  svalue.h
+ global.h machine.h \
+ config.h \
+ port.h \
+ regexp.h \
+ error.h \
+ svalue.h
diff --git a/src/modules/sprintf/Makefile.in b/src/modules/sprintf/Makefile.in
index 56de303c76..b30322242b 100644
--- a/src/modules/sprintf/Makefile.in
+++ b/src/modules/sprintf/Makefile.in
@@ -19,18 +19,17 @@ depend:
 
 #Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
 sprintf.o: sprintf.c \
-  global.h \
-  machine.h \
-  config.h \
-  port.h \
-  error.h \
-  svalue.h \
-  array.h \
-  las.h \
-  dynamic_buffer.h \
-  program.h \
-  stralloc.h \
-  lpc_types.h \
-  add_efun.h \
-  hashtable.h \
-  interpret.h
+ global.h machine.h \
+ config.h \
+ port.h \
+ error.h \
+ svalue.h \
+ array.h \
+ las.h \
+ dynamic_buffer.h \
+ program.h \
+ stralloc.h \
+ lpc_types.h \
+ add_efun.h \
+ hashtable.h \
+ interpret.h
-- 
GitLab


From c2926bf46f02923dfd1ad54e602fc9b98368e629 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 29 Apr 1996 20:53:53 +0200
Subject: [PATCH 133/351] Now in Makefile.src

Rev: src/Makefile.in:1.16(DEAD)
Rev: src/modules/files/Makefile.in:1.4(DEAD)
Rev: src/modules/math/Makefile.in:1.3(DEAD)
Rev: src/modules/regexp/Makefile.in:1.4(DEAD)
Rev: src/modules/sprintf/Makefile.in:1.4(DEAD)
---
 src/Makefile.in                 | 500 --------------------------------
 src/modules/files/Makefile.in   |  70 -----
 src/modules/math/Makefile.in    |  30 --
 src/modules/regexp/Makefile.in  |  40 ---
 src/modules/sprintf/Makefile.in |  35 ---
 5 files changed, 675 deletions(-)
 delete mode 100644 src/Makefile.in
 delete mode 100644 src/modules/files/Makefile.in
 delete mode 100644 src/modules/math/Makefile.in
 delete mode 100644 src/modules/regexp/Makefile.in
 delete mode 100644 src/modules/sprintf/Makefile.in

diff --git a/src/Makefile.in b/src/Makefile.in
deleted file mode 100644
index ecbeed9977..0000000000
--- a/src/Makefile.in
+++ /dev/null
@@ -1,500 +0,0 @@
-# This line is needed on some machines.
-@SET_MAKE@
-
-# Don't change this line.  Define EXTRALIBS before this line if you
-# wish to add any libraries.
-LIBS=@LIBS@ $(EXTRALIBS)
-
-# not used yet
-INSTALL=@INSTALL@
-
-SRCDIR=@srcdir@
-VPATH=@srcdir@
-
-# These are used while compiling
-TMP_LIBDIR = @LIBDIR@
-TMP_BINDIR = @BINDIR@
-TMP_BUILDDIR = @BUILDDIR@
-TMP_DOCDIR = @DOCDIR@
-
-prefix = @prefix@
-exec_prefix = $(prefix)/bin
-lib_prefix = $(prefix)/lib/ulpc
-
-#
-# use bison please, yacc doesn't always work good enough.
-#
-YACC=@YACC@
-YFLAGS=-d -v
-
-# If you don't have 'strchr', then add next flag to CFLAGS.
-# -Dstrchr=index -Dstrrchr=rindex
-#
-PROFIL=
-#PROFIL=-pg
-
-#
-#Enable warnings from the compiler, if wanted.
-#
-WARN=@WARN@
-#WARN=-W -Wunused -Wformat
-#WARN -Wunused -Wformat -Wuninitialized
-#WARN= -Wall -Wshadow -Dlint
-
-#add extra defines here
-# Be sure to use -g and -DDEBUG when looking for bugs
-DEFINES=-DDEBUG -DDEFAULT_MASTER=\"$(lib_prefix)/master.lpc\"
-
-# -O should work with all compilers
-OPTIMIZE=@OPTIMIZE@
-
-# Preprocessor flags.
-PREFLAGS=-I. -I$(SRCDIR) $(DEFINES)
-OTHERFLAGS=$(OSFLAGS) $(OPTIMIZE) $(WARN) $(PROFIL)
-CFLAGS=$(PREFLAGS) $(OTHERFLAGS)
-
-CC=@CC@
-CPP=@CPP@
-
-LD=$(CC)
-LDFLAGS=$(CFLAGS)
-
-RUNULPC=$(TMP_BUILDDIR)/ulpc -m $(TMP_LIBDIR)/master.lpc
-FIXDEP=$(RUNULPC) $(TMP_BINDIR)/fixdepends.lpc
-
-MAKE_FLAGS = "prefix=$(prefix)" "exex_prefix=$(exex_prefix)" "CC=$(CC)" "OTHERFLAGS=$(OTHERFLAGS)" "FIXDEP=$(FIXDEP)"
-
-# Add alloca.o if you don't have alloca() on your machine.
-# Add ualarm.o if you don't have ualarm() on your machine.
-#
-OBJ=language.o peep.o add_efun.o array.o builtin_efuns.o backend.o \
-    call_out.o docode.o dynamic_buffer.o error.o fd_control.o \
-    fsort.o hashtable.o interpret.o lex.o las.o list.o \
-    lpc_types.o main.o mapping.o memory.o module.o object.o \
-    opcodes.o operators.o port.o program.o rusage.o stralloc.o \
-    stuff.o svalue.o gc.o callback.o lpc_signal.o @EXTRA_OBJS@
-
-#
-MODULES=@subdirs@
-MODULE_OBJS=@MODULE_OBJS@
-
-#
-# User callable targets
-#
-
-all: ulpc
-
-ulpc: $(OBJ) module_objects
-	-mv ulpc ulpc.old
-	$(LD) $(LDFLAGS) $(OBJ) $(MODULE_OBJS) -o ulpc $(LIBS)
-
-
-# purify
-pure: $(OBJ) module_objects
-	-mv ulpc ulpc.old
-	purify -free-queue-length=500 -inuse-at-exit=yes -chain-length=12 $(LD) $(LDFLAGS) $(OBJ) $(MODULE_OBJS) -o ulpc $(LIBS)
-
-# purecov
-cover: $(OBJ) module_objects
-	-mv ulpc ulpc.old
-	purecov purify -free-queue-length=500 -inuse-at-exit=yes -chain-length=12 $(LD) $(LDFLAGS) $(OBJ) $(MODULE_OBJS) -o ulpc $(LIBS)
-
-# quantify
-quant: $(OBJ) module_objects
-	-mv ulpc ulpc.old
-	quantify $(LD) $(LDFLAGS) $(OBJ) $(MODULE_OBJS) -o ulpc $(LIBS)
-
-# install
-install:
-	if [ ! -d "$(prefix)" ]; then mkdir "$(prefix)" ; chmod 755 "$(prefix)" ; fi
-	if [ ! -d "$(exec_prefix)" ]; then mkdir "$(exec_prefix)" ; chmod 755 "$(exec_prefix)" ; fi
-	$(INSTALL) ./ulpc $(exec_prefix)
-	if [ ! -d "$(prefix)/lib" ]; then mkdir "$(prefix)/lib" ; chmod 755 "$(prefix)/lib" ; fi
-	if [ ! -d "$(lib_prefix)" ]; then mkdir "$(lib_prefix)" ; chmod 755 "$(lib_prefix)" ; fi
-	$(INSTALL) $(TMP_LIBDIR)/master.lpc $(lib_prefix)
-	$(INSTALL) $(TMP_LIBDIR)/simulate.lpc $(lib_prefix)
-
-# tidy up a bit
-tidy:
-	-rm -f *.o core $(MUD_LIB)/core y.output y.tab.c y.tab.h
-	-rm -f $(TMP_BINDIR)/core *.o *.i *.i~
-
-# make clean
-clean: tidy
-	-for a in $(MODULES) ; do ( cd $$a ; ${MAKE} $(MAKE_FLAGS) clean ) ; done
-	-for a in $(MODULES) ; do rm -f $$a/*.o ; done
-	-rm -f TAGS tags
-	-rm -f yacc.acts yacc.debug yacc.tmp *.debug.log a.out
-
-# make _really_ clean
-spotless: clean
-	rm -f Makefile machine.h
-	find . -type f '(' -name '*~' -o -name '.*~' -o -name core -o -name '.nfs*' -name '#*#' ')' -print | xargs rm -f
-	-rm -f lexical.c mon.out *.ln config.status
-	-rm -f $(TMP_BINDIR)/driver $(TMP_BINDIR)/*~ $(TMP_BINDIR)/#*#
-	-rm -f .pure driver* l.outa*
-
-# create tags
-tags:
-	ctags *.c
-
-TAGS:
-	etags -t *.h *.c
-
-# verify / debug
-verify_manual:
-	$(RUNULPC) $(SRCDIR)/test/verifymanual.lpc $(TMP_DOCDIR)
-
-verify: $(SRCDIR)/test/testsuite
-	$(RUNULPC) $(SRCDIR)/test/test_lpc.lpc $(SRCDIR)/test/testsuite
-
-# verify / debug verbose
-verbose_verify: $(SRCDIR)/test/testsuite
-	$(RUNULPC) $(SRCDIR)/test/test_lpc.lpc $(SRCDIR)/test/testsuite --verbose
-
-# verify & debug VERBOSE
-gdb_verify: $(SRCDIR)/test/testsuite
-	echo >.gdbinit handle SIGUSR1 nostop noprint pass
-	echo >>.gdbinit run -m $(TMP_LIBDIR)/master.lpc $(SRCDIR)/test/test_lpc.lpc $(SRCDIR)/test/testsuite -v -v -f
-	gdb ./ulpc
-
-# run hilfe, for interactive testing
-run_hilfe:
-	$(RUNULPC) $(TMP_BINDIR)/hilfe
-
-# make export archive (requires compiled uLPC)
-# Do not compile in source tree if you want to use this!
-# Beware that export archive this includes bison/yacc/byacc source
-# and thus has to follow the rules stated in that code.
-export: $(SRCDIR)/test/testsuite new_peep_engine $(SRCDIR)/language.c $(SRCDIR)/language.h depend
-	chmod +x $(SRCDIR)/install-sh
-	$(RUNULPC) $(TMP_BINDIR)/export.lpc
-
-new_peep_engine:
-	$(RUNULPC) $(TMP_BINDIR)/mkpeep.lpc $(SRCDIR)/peep.in >$(SRCDIR)/peep_engine.c
-
-peep_engine.c: peep.in
-	echo "" >$(SRCDIR)/peep_engine.c
-	-$(RUNULPC) $(TMP_BINDIR)/mkpeep.lpc $(SRCDIR)/peep.in >$(SRCDIR)/peep_engine.c
-
-# make dependencies (requires compiled uLPC)
-depend: language.c
-	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)/Makefile.in
-	for a in $(MODULES) ; do ( cd $$a ; ${MAKE} $(MAKE_FLAGS) depend ) ; done
-
-docs:
-	mkdir docs
-
-html_docs: docs
-	$(RUNULPC) $(TMP_BINDIR)/htmlify_docs $(TMP_DOCDIR) docs
-
-#
-# uLPC internal targets
-#
-module_objects:
-	for a in $(MODULES) ; do ( cd $$a ; ${MAKE} $(MAKE_FLAGS) ) ; done
-
-lang.o: lang.c config.h object.h interpret.h program.h
-
-$(SRCDIR)/language.h: language.y
-	@echo "Expect 1 shift/reduce conflict."
-	$(YACC) $(YFLAGS) $(SRCDIR)/language.y
-	mv y.tab.c $(SRCDIR)/language.c
-	mv y.tab.h $(SRCDIR)/language.h
-
-$(SRCDIR)/language.c: language.h
-	touch $(SRCDIR)/language.c
-
-module.c: modlist.h
-
-configure: configure.in
-	cd $(SRCDIR) && autoconf
-
-config.status: configure
-	./config.status --recheck
-
-Makefile: Makefile.in config.status
-	./config.status
-
-machine.h: stamp-h
-
-stamp-h: machine.h.in config.status
-	./config.status
-
-modlist.h:
-	./config.status
-
-$(SRCDIR)/test/testsuite: $(SRCDIR)/test/create_testsuite
-	m4 <$(SRCDIR)/test/create_testsuite >$(SRCDIR)/test/testsuite
-
-
-#Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
-add_efun.o: add_efun.c \
- add_efun.h svalue.h \
- types.h machine.h \
- hashtable.h las.h \
- config.h dynamic_buffer.h \
- program.h macros.h \
- memory.h lpc_types.h \
- stralloc.h interpret.h
-alloca.o: alloca.c
-array.o: array.c global.h \
- machine.h config.h port.h \
- svalue.h array.h \
- las.h dynamic_buffer.h \
- program.h object.h \
- stralloc.h interpret.h \
- language.h error.h \
- lpc_types.h fsort.h \
- builtin_efuns.h gc.h
-backend.o: backend.c \
- global.h machine.h config.h \
- port.h backend.h \
- interpret.h program.h \
- object.h svalue.h \
- error.h call_out.h \
- fd_control.h main.h \
- callback.h array.h \
- las.h dynamic_buffer.h
-builtin_efuns.o: builtin_efuns.c \
- global.h machine.h config.h \
- port.h interpret.h \
- program.h svalue.h \
- macros.h object.h \
- array.h las.h \
- dynamic_buffer.h error.h \
- add_efun.h hashtable.h \
- mapping.h stralloc.h \
- lex.h list.h \
- lpc_types.h rusage.h \
- operators.h fsort.h \
- call_out.h callback.h \
- gc.h
-call_out.o: call_out.c \
- global.h machine.h config.h \
- port.h array.h \
- las.h svalue.h \
- dynamic_buffer.h program.h \
- call_out.h object.h \
- interpret.h error.h \
- builtin_efuns.h main.h
-callback.o: callback.c \
- macros.h memory.h \
- types.h machine.h \
- callback.h array.h \
- las.h config.h \
- svalue.h dynamic_buffer.h \
- program.h
-docode.o: docode.c global.h \
- machine.h config.h port.h \
- las.h svalue.h \
- dynamic_buffer.h program.h \
- language.h lpc_types.h \
- stralloc.h interpret.h \
- add_efun.h hashtable.h \
- array.h macros.h \
- error.h main.h \
- lex.h builtin_efuns.h \
- peep.h docode.h
-dynamic_buffer.o: dynamic_buffer.c \
- global.h machine.h config.h \
- port.h dynamic_buffer.h \
- stralloc.h error.h \
- svalue.h
-error.o: error.c global.h \
- machine.h config.h port.h \
- macros.h error.h \
- svalue.h interpret.h \
- program.h stralloc.h \
- builtin_efuns.h array.h \
- las.h dynamic_buffer.h \
- object.h
-fd_control.o: fd_control.c \
- fd_control.h global.h \
- machine.h config.h port.h
-fsort.o: fsort.c global.h \
- machine.h config.h port.h \
- fsort.h
-gc.o: gc.c global.h \
- machine.h config.h port.h \
- array.h las.h \
- svalue.h dynamic_buffer.h \
- program.h list.h \
- mapping.h object.h \
- gc.h main.h
-hashtable.o: hashtable.c \
- global.h machine.h config.h \
- port.h hashtable.h \
- stralloc.h stuff.h \
- error.h svalue.h
-interpret.o: interpret.c \
- global.h machine.h config.h \
- port.h interpret.h \
- program.h object.h \
- svalue.h array.h \
- las.h dynamic_buffer.h \
- mapping.h error.h \
- language.h stralloc.h \
- add_efun.h hashtable.h \
- macros.h list.h \
- backend.h operators.h \
- opcodes.h main.h \
- lex.h builtin_efuns.h \
- lpc_signal.h
-language.o: language.c \
- global.h machine.h config.h \
- port.h interpret.h \
- program.h array.h \
- las.h svalue.h \
- dynamic_buffer.h object.h \
- stralloc.h lex.h \
- lpc_types.h add_efun.h \
- hashtable.h macros.h \
- error.h docode.h
-las.o: las.c global.h \
- machine.h config.h port.h \
- language.h interpret.h \
- program.h las.h \
- svalue.h dynamic_buffer.h \
- array.h object.h \
- stralloc.h lex.h \
- lpc_types.h add_efun.h \
- hashtable.h mapping.h \
- list.h error.h \
- docode.h main.h
-lex.o: lex.c global.h \
- machine.h config.h port.h \
- language.h array.h \
- las.h svalue.h \
- dynamic_buffer.h program.h \
- lex.h stralloc.h \
- add_efun.h hashtable.h \
- stuff.h interpret.h \
- error.h object.h \
- operators.h opcodes.h \
- builtin_efuns.h macros.h
-list.o: list.c global.h \
- machine.h config.h port.h \
- array.h las.h \
- svalue.h dynamic_buffer.h \
- program.h list.h \
- macros.h error.h \
- interpret.h builtin_efuns.h \
- gc.h
-lpc_signal.o: lpc_signal.c \
- global.h machine.h config.h \
- port.h svalue.h \
- interpret.h program.h \
- stralloc.h add_efun.h \
- hashtable.h las.h \
- dynamic_buffer.h macros.h \
- backend.h
-lpc_types.o: lpc_types.c \
- global.h machine.h config.h \
- port.h svalue.h \
- lpc_types.h stralloc.h \
- stuff.h array.h \
- las.h dynamic_buffer.h \
- program.h add_efun.h \
- hashtable.h object.h \
- list.h mapping.h \
- macros.h error.h
-main.o: main.c global.h \
- machine.h config.h port.h \
- backend.h module.h \
- object.h svalue.h \
- lex.h lpc_types.h \
- builtin_efuns.h array.h \
- las.h dynamic_buffer.h \
- program.h stralloc.h \
- interpret.h error.h \
- macros.h callback.h \
- lpc_signal.h
-mapping.o: mapping.c \
- global.h machine.h config.h \
- port.h mapping.h \
- las.h svalue.h \
- dynamic_buffer.h program.h \
- array.h macros.h \
- language.h error.h \
- interpret.h gc.h
-memory.o: memory.c global.h \
- machine.h config.h port.h \
- error.h svalue.h
-module.o: module.c module.h \
- types.h machine.h macros.h \
- memory.h error.h \
- svalue.h modlist.h
-object.o: object.c global.h \
- machine.h config.h port.h \
- object.h svalue.h \
- dynamic_buffer.h \
- interpret.h program.h \
- stralloc.h macros.h \
- error.h main.h \
- array.h las.h \
- gc.h
-opcodes.o: opcodes.c \
- global.h machine.h config.h \
- port.h interpret.h \
- program.h svalue.h \
- array.h las.h \
- dynamic_buffer.h stralloc.h \
- mapping.h list.h \
- opcodes.h object.h \
- error.h lpc_types.h
-operators.o: operators.c \
- global.h machine.h config.h \
- port.h interpret.h \
- program.h svalue.h \
- list.h las.h \
- dynamic_buffer.h mapping.h \
- array.h stralloc.h \
- opcodes.h operators.h \
- language.h error.h \
- docode.h add_efun.h \
- hashtable.h peep.h \
- lex.h
-peep.o: peep.c global.h \
- machine.h config.h port.h \
- language.h stralloc.h \
- dynamic_buffer.h program.h \
- las.h svalue.h \
- docode.h main.h \
- error.h lex.h \
- peep_engine.c
-peep_engine.o: peep_engine.c
-port.o: port.c global.h \
- machine.h config.h port.h \
- macros.h
-program.o: program.c \
- global.h machine.h config.h \
- port.h program.h \
- object.h svalue.h \
- dynamic_buffer.h \
- lpc_types.h stralloc.h \
- las.h language.h \
- lex.h macros.h \
- fsort.h error.h \
- docode.h interpret.h \
- hashtable.h main.h \
- gc.h compilation.h
-rusage.o: rusage.c global.h \
- machine.h config.h port.h \
- rusage.h
-stralloc.o: stralloc.c \
- global.h machine.h config.h \
- port.h stralloc.h \
- macros.h dynamic_buffer.h \
- error.h svalue.h
-stuff.o: stuff.c stuff.h \
- types.h machine.h
-svalue.o: svalue.c global.h \
- machine.h config.h port.h \
- svalue.h stralloc.h \
- array.h las.h \
- dynamic_buffer.h program.h \
- mapping.h list.h \
- object.h add_efun.h \
- hashtable.h error.h
-ualarm.o: ualarm.c
diff --git a/src/modules/files/Makefile.in b/src/modules/files/Makefile.in
deleted file mode 100644
index 08a46f581d..0000000000
--- a/src/modules/files/Makefile.in
+++ /dev/null
@@ -1,70 +0,0 @@
-SRCDIR=@srcdir@
-VPATH=@srcdir@:@srcdir@/../..:../..
-PREFLAGS=-I. -I$(SRCDIR) -I$(SRCDIR)/../.. -I../..
-CFLAGS=$(PREFLAGS) $(OTHERFLAGS)
-
-FILES=file.o efuns.o socket.o
-
-files.a: $(FILES)
-	-rm -f files.a
-	ar cq files.a $(FILES)
-	-@RANLIB@ files.a
-
-clean:
-	-rm -f *.o *.a
-
-depend:
-	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)/Makefile.in
-
-
-
-#Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
-datagram.o: datagram.c
-efuns.o: efuns.c \
- global.h machine.h \
- config.h \
- port.h \
- interpret.h \
- program.h \
- svalue.h \
- stralloc.h \
- array.h \
- las.h \
- dynamic_buffer.h \
- mapping.h \
- macros.h \
- fd_control.h file_machine.h
-file.o: file.c \
- global.h machine.h \
- config.h \
- port.h \
- interpret.h \
- program.h \
- svalue.h \
- stralloc.h \
- array.h \
- las.h \
- dynamic_buffer.h \
- object.h \
- macros.h \
- backend.h \
- fd_control.h file_machine.h \
- file.h \
- error.h \
- lpc_signal.h
-socket.o: socket.c \
- global.h machine.h \
- config.h \
- port.h \
- interpret.h \
- program.h \
- svalue.h \
- stralloc.h \
- array.h \
- las.h \
- dynamic_buffer.h \
- object.h \
- macros.h \
- backend.h \
- fd_control.h file_machine.h \
- file.h
diff --git a/src/modules/math/Makefile.in b/src/modules/math/Makefile.in
deleted file mode 100644
index 23d8ad254b..0000000000
--- a/src/modules/math/Makefile.in
+++ /dev/null
@@ -1,30 +0,0 @@
-SRCDIR=@srcdir@
-VPATH=@srcdir@:@srcdir@/../..:../..
-PREFLAGS=-I$(SRCDIR) -I$(SRCDIR)/../.. -I../..
-CFLAGS=$(PREFLAGS) $(OTHERFLAGS)
-
-FILES=math.o
-
-math.a: $(FILES)
-	-rm -f math.a
-	ar cq math.a $(FILES)
-	-@RANLIB@ math.a
-
-clean:
-	-rm -f *.o
-
-depend:
-	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)/Makefile.in
-
-
-#Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
-math.o: math.c \
- interpret.h \
- program.h \
- config.h machine.h \
- types.h \
- add_efun.h \
- svalue.h \
- hashtable.h \
- las.h \
- dynamic_buffer.h
diff --git a/src/modules/regexp/Makefile.in b/src/modules/regexp/Makefile.in
deleted file mode 100644
index 43cee96b2a..0000000000
--- a/src/modules/regexp/Makefile.in
+++ /dev/null
@@ -1,40 +0,0 @@
-SRCDIR=@srcdir@
-VPATH=@srcdir@:@srcdir@/../..:../..
-PREFLAGS=-I$(SRCDIR) -I$(SRCDIR)/../.. -I../..
-CFLAGS=$(PREFLAGS) $(OTHERFLAGS)
-
-FILES=regexp.o glue.o
-
-regexp.a: $(FILES)
-	-rm -f regexp.a
-	ar cq regexp.a $(FILES)
-	-@RANLIB@ regexp.a
-
-clean:
-	-rm -f *.o *.a
-
-depend:
-	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)/Makefile.in
-
-
-#Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
-glue.o: glue.c \
- global.h machine.h \
- config.h \
- port.h \
- interpret.h \
- program.h \
- svalue.h \
- stralloc.h \
- array.h \
- las.h \
- dynamic_buffer.h \
- object.h \
- macros.h
-regexp.o: regexp.c \
- global.h machine.h \
- config.h \
- port.h \
- regexp.h \
- error.h \
- svalue.h
diff --git a/src/modules/sprintf/Makefile.in b/src/modules/sprintf/Makefile.in
deleted file mode 100644
index b30322242b..0000000000
--- a/src/modules/sprintf/Makefile.in
+++ /dev/null
@@ -1,35 +0,0 @@
-SRCDIR=@srcdir@
-VPATH=@srcdir@:@srcdir@/../..:../..
-PREFLAGS=-I$(SRCDIR) -I$(SRCDIR)/../.. -I../..
-CFLAGS=$(PREFLAGS) $(OTHERFLAGS)
-
-FILES=sprintf.o
-
-sprintf.a: $(FILES)
-	-rm -f sprintf.a
-	ar cq sprintf.a $(FILES)
-	-@RANLIB@ sprintf.a
-
-clean:
-	-rm -f *.o *.a
-
-depend:
-	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)/Makefile.in
-
-
-#Dependencies begin here, DO NOT REMOVE THIS LINE!!!!
-sprintf.o: sprintf.c \
- global.h machine.h \
- config.h \
- port.h \
- error.h \
- svalue.h \
- array.h \
- las.h \
- dynamic_buffer.h \
- program.h \
- stralloc.h \
- lpc_types.h \
- add_efun.h \
- hashtable.h \
- interpret.h
-- 
GitLab


From 104566423b87a3b745fe31430ee4ee839ae5985d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 29 Apr 1996 20:54:35 +0200
Subject: [PATCH 134/351] Now ignores Makefile.in

Rev: src/.cvsignore:1.4
Rev: src/modules/files/.cvsignore:1.2
Rev: src/modules/math/.cvsignore:1.2
Rev: src/modules/regexp/.cvsignore:1.2
Rev: src/modules/sprintf/.cvsignore:1.2
---
 src/.cvsignore                 | 1 +
 src/.gitignore                 | 1 +
 src/modules/files/.cvsignore   | 1 +
 src/modules/files/.gitignore   | 1 +
 src/modules/math/.cvsignore    | 1 +
 src/modules/math/.gitignore    | 1 +
 src/modules/regexp/.cvsignore  | 1 +
 src/modules/regexp/.gitignore  | 1 +
 src/modules/sprintf/.cvsignore | 1 +
 src/modules/sprintf/.gitignore | 1 +
 10 files changed, 10 insertions(+)

diff --git a/src/.cvsignore b/src/.cvsignore
index d731bc07dd..d978d3ea85 100644
--- a/src/.cvsignore
+++ b/src/.cvsignore
@@ -2,3 +2,4 @@ configure
 language.c
 language.h
 peep_engine.c
+Makefile.in
diff --git a/src/.gitignore b/src/.gitignore
index 73ff5defb0..c96df2a4ca 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -2,3 +2,4 @@
 /language.c
 /language.h
 /peep_engine.c
+/Makefile.in
diff --git a/src/modules/files/.cvsignore b/src/modules/files/.cvsignore
index e8c05a6b13..76e8a85506 100644
--- a/src/modules/files/.cvsignore
+++ b/src/modules/files/.cvsignore
@@ -1 +1,2 @@
 configure
+Makefile.in
diff --git a/src/modules/files/.gitignore b/src/modules/files/.gitignore
index 55902085e8..1f3e111bcb 100644
--- a/src/modules/files/.gitignore
+++ b/src/modules/files/.gitignore
@@ -1 +1,2 @@
 /configure
+/Makefile.in
diff --git a/src/modules/math/.cvsignore b/src/modules/math/.cvsignore
index e8c05a6b13..76e8a85506 100644
--- a/src/modules/math/.cvsignore
+++ b/src/modules/math/.cvsignore
@@ -1 +1,2 @@
 configure
+Makefile.in
diff --git a/src/modules/math/.gitignore b/src/modules/math/.gitignore
index 55902085e8..1f3e111bcb 100644
--- a/src/modules/math/.gitignore
+++ b/src/modules/math/.gitignore
@@ -1 +1,2 @@
 /configure
+/Makefile.in
diff --git a/src/modules/regexp/.cvsignore b/src/modules/regexp/.cvsignore
index e8c05a6b13..76e8a85506 100644
--- a/src/modules/regexp/.cvsignore
+++ b/src/modules/regexp/.cvsignore
@@ -1 +1,2 @@
 configure
+Makefile.in
diff --git a/src/modules/regexp/.gitignore b/src/modules/regexp/.gitignore
index 55902085e8..1f3e111bcb 100644
--- a/src/modules/regexp/.gitignore
+++ b/src/modules/regexp/.gitignore
@@ -1 +1,2 @@
 /configure
+/Makefile.in
diff --git a/src/modules/sprintf/.cvsignore b/src/modules/sprintf/.cvsignore
index e8c05a6b13..76e8a85506 100644
--- a/src/modules/sprintf/.cvsignore
+++ b/src/modules/sprintf/.cvsignore
@@ -1 +1,2 @@
 configure
+Makefile.in
diff --git a/src/modules/sprintf/.gitignore b/src/modules/sprintf/.gitignore
index 55902085e8..1f3e111bcb 100644
--- a/src/modules/sprintf/.gitignore
+++ b/src/modules/sprintf/.gitignore
@@ -1 +1,2 @@
 /configure
+/Makefile.in
-- 
GitLab


From a64add56c2ac57e52f419c0e06001b3d76eb5be1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 29 Apr 1996 20:54:56 +0200
Subject: [PATCH 135/351] Now generates Makefile.in if needed

Rev: src/run_autoconfig:1.2
---
 src/run_autoconfig | 31 ++++++++++++++++++++-----------
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/src/run_autoconfig b/src/run_autoconfig
index 52966349fe..cbe3af9d3d 100755
--- a/src/run_autoconfig
+++ b/src/run_autoconfig
@@ -1,16 +1,25 @@
 #!/bin/sh
 
-autoconf
-cd modules
-for a in *
+# Bootstrap script
+
+fix()
+{
+  if [ -d $1 ]; then
+    ( cd $1 ; autoconf )
+  fi
+
+  if [ ! -f $1/Makefile.in ]; then
+    cp $1/Makefile.src $1/Makefile.in
+  fi
+}
+
+
+fix .
+for a in modules/*
 do
   case $a in
-    CVS) ;;
-    RCS) ;;
-    *)
-      if [ -d $a ]; then
-        ( cd $a ; autoconf )
-      fi
-   ;;
+    modules/CVS) ;;
+    modules/RCS) ;;
+    *) fix $a ;;
   esac
-done
\ No newline at end of file
+done
-- 
GitLab


From 44552a20803f9eda17f93049c95c638ff11f6aa6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 29 Apr 1996 20:57:21 +0200
Subject: [PATCH 136/351] Entry added

Rev: src/ChangeLog:1.31
---
 src/ChangeLog | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 40b997c3d7..196fbc41cd 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+Mon Apr 29 20:47:31 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
+
+	* Makefile.in: All makefiles are now generated from Makefile.src ->
+	  Makefile.in -> Makefile. This is so I don't have to save
+	  dependencies in my CVS repository :)
+
 Tue Apr 23 22:32:04 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
 
 	* Makefile.in: Now language.c and language.h is a part of the
-- 
GitLab


From 933d365a7323b12fb23469d32a8b3516a3e674c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 29 Apr 1996 20:58:50 +0200
Subject: [PATCH 137/351] New file

Rev: src/Makefile.src:1.1
Rev: src/modules/files/Makefile.src:1.1
Rev: src/modules/math/Makefile.src:1.1
Rev: src/modules/regexp/Makefile.src:1.1
Rev: src/modules/sprintf/Makefile.src:1.1
---
 src/Makefile.src                 | 230 +++++++++++++++++++++++++++++++
 src/modules/files/Makefile.src   |  18 +++
 src/modules/math/Makefile.src    |  17 +++
 src/modules/regexp/Makefile.src  |  17 +++
 src/modules/sprintf/Makefile.src |  17 +++
 5 files changed, 299 insertions(+)
 create mode 100644 src/Makefile.src
 create mode 100644 src/modules/files/Makefile.src
 create mode 100644 src/modules/math/Makefile.src
 create mode 100644 src/modules/regexp/Makefile.src
 create mode 100644 src/modules/sprintf/Makefile.src

diff --git a/src/Makefile.src b/src/Makefile.src
new file mode 100644
index 0000000000..d5cf8c8ace
--- /dev/null
+++ b/src/Makefile.src
@@ -0,0 +1,230 @@
+# This line is needed on some machines.
+@SET_MAKE@
+
+# Don't change this line.  Define EXTRALIBS before this line if you
+# wish to add any libraries.
+LIBS=@LIBS@ $(EXTRALIBS)
+
+# not used yet
+INSTALL=@INSTALL@
+
+SRCDIR=@srcdir@
+VPATH=@srcdir@
+
+# These are used while compiling
+TMP_LIBDIR = @LIBDIR@
+TMP_BINDIR = @BINDIR@
+TMP_BUILDDIR = @BUILDDIR@
+TMP_DOCDIR = @DOCDIR@
+
+prefix = @prefix@
+exec_prefix = $(prefix)/bin
+lib_prefix = $(prefix)/lib/ulpc
+
+#
+# use bison please, yacc doesn't always work good enough.
+#
+YACC=@YACC@
+YFLAGS=-d -v
+
+# If you don't have 'strchr', then add next flag to CFLAGS.
+# -Dstrchr=index -Dstrrchr=rindex
+#
+PROFIL=
+#PROFIL=-pg
+
+#
+#Enable warnings from the compiler, if wanted.
+#
+WARN=@WARN@
+#WARN=-W -Wunused -Wformat
+#WARN -Wunused -Wformat -Wuninitialized
+#WARN= -Wall -Wshadow -Dlint
+
+#add extra defines here
+# Be sure to use -g and -DDEBUG when looking for bugs
+DEFINES=-DDEBUG -DDEFAULT_MASTER=\"$(lib_prefix)/master.lpc\"
+
+# -O should work with all compilers
+OPTIMIZE=@OPTIMIZE@
+
+# Preprocessor flags.
+PREFLAGS=-I. -I$(SRCDIR) $(DEFINES)
+OTHERFLAGS=$(OSFLAGS) $(OPTIMIZE) $(WARN) $(PROFIL)
+CFLAGS=$(PREFLAGS) $(OTHERFLAGS)
+
+CC=@CC@
+CPP=@CPP@
+
+LD=$(CC)
+LDFLAGS=$(CFLAGS)
+
+RUNULPC=$(TMP_BUILDDIR)/ulpc -m $(TMP_LIBDIR)/master.lpc
+FIXDEP=$(TMP_BINDIR)/fixdepends.sh
+
+MAKE_FLAGS = "prefix=$(prefix)" "exex_prefix=$(exex_prefix)" "CC=$(CC)" "OTHERFLAGS=$(OTHERFLAGS)" "FIXDEP=$(FIXDEP)"
+
+# Add alloca.o if you don't have alloca() on your machine.
+# Add ualarm.o if you don't have ualarm() on your machine.
+#
+OBJ=language.o peep.o add_efun.o array.o builtin_efuns.o backend.o \
+    call_out.o docode.o dynamic_buffer.o error.o fd_control.o \
+    fsort.o hashtable.o interpret.o lex.o las.o list.o \
+    lpc_types.o main.o mapping.o memory.o module.o object.o \
+    opcodes.o operators.o port.o program.o rusage.o stralloc.o \
+    stuff.o svalue.o gc.o callback.o lpc_signal.o @EXTRA_OBJS@
+
+#
+MODULES=@subdirs@
+MODULE_OBJS=@MODULE_OBJS@
+
+#
+# User callable targets
+#
+
+all: ulpc
+
+ulpc: $(OBJ) module_objects
+	-mv ulpc ulpc.old
+	$(LD) $(LDFLAGS) $(OBJ) $(MODULE_OBJS) -o ulpc $(LIBS)
+
+
+# purify
+pure: $(OBJ) module_objects
+	-mv ulpc ulpc.old
+	purify -free-queue-length=500 -inuse-at-exit=yes -chain-length=12 $(LD) $(LDFLAGS) $(OBJ) $(MODULE_OBJS) -o ulpc $(LIBS)
+
+# purecov
+cover: $(OBJ) module_objects
+	-mv ulpc ulpc.old
+	purecov purify -free-queue-length=500 -inuse-at-exit=yes -chain-length=12 $(LD) $(LDFLAGS) $(OBJ) $(MODULE_OBJS) -o ulpc $(LIBS)
+
+# quantify
+quant: $(OBJ) module_objects
+	-mv ulpc ulpc.old
+	quantify $(LD) $(LDFLAGS) $(OBJ) $(MODULE_OBJS) -o ulpc $(LIBS)
+
+# install
+install:
+	if [ ! -d "$(prefix)" ]; then mkdir "$(prefix)" ; chmod 755 "$(prefix)" ; fi
+	if [ ! -d "$(exec_prefix)" ]; then mkdir "$(exec_prefix)" ; chmod 755 "$(exec_prefix)" ; fi
+	$(INSTALL) ./ulpc $(exec_prefix)
+	if [ ! -d "$(prefix)/lib" ]; then mkdir "$(prefix)/lib" ; chmod 755 "$(prefix)/lib" ; fi
+	if [ ! -d "$(lib_prefix)" ]; then mkdir "$(lib_prefix)" ; chmod 755 "$(lib_prefix)" ; fi
+	$(INSTALL) $(TMP_LIBDIR)/master.lpc $(lib_prefix)
+	$(INSTALL) $(TMP_LIBDIR)/simulate.lpc $(lib_prefix)
+
+# tidy up a bit
+tidy:
+	-rm -f *.o core $(MUD_LIB)/core y.output y.tab.c y.tab.h
+	-rm -f $(TMP_BINDIR)/core *.o *.i *.i~
+
+# make clean
+clean: tidy
+	-for a in $(MODULES) ; do ( cd $$a ; ${MAKE} $(MAKE_FLAGS) clean ) ; done
+	-for a in $(MODULES) ; do rm -f $$a/*.o ; done
+	-rm -f TAGS tags
+	-rm -f yacc.acts yacc.debug yacc.tmp *.debug.log a.out
+
+# make _really_ clean
+spotless: clean
+	rm -f Makefile machine.h
+	find . -type f '(' -name '*~' -o -name '.*~' -o -name core -o -name '.nfs*' -name '#*#' ')' -print | xargs rm -f
+	-rm -f lexical.c mon.out *.ln config.status
+	-rm -f $(TMP_BINDIR)/driver $(TMP_BINDIR)/*~ $(TMP_BINDIR)/#*#
+	-rm -f .pure driver* l.outa*
+
+# create tags
+tags:
+	ctags *.c
+
+TAGS:
+	etags -t *.h *.c
+
+# verify / debug
+verify_manual:
+	$(RUNULPC) $(SRCDIR)/test/verifymanual.lpc $(TMP_DOCDIR)
+
+verify: $(SRCDIR)/test/testsuite
+	$(RUNULPC) $(SRCDIR)/test/test_lpc.lpc $(SRCDIR)/test/testsuite
+
+# verify / debug verbose
+verbose_verify: $(SRCDIR)/test/testsuite
+	$(RUNULPC) $(SRCDIR)/test/test_lpc.lpc $(SRCDIR)/test/testsuite --verbose
+
+# verify & debug VERBOSE
+gdb_verify: $(SRCDIR)/test/testsuite
+	echo >.gdbinit handle SIGUSR1 nostop noprint pass
+	echo >>.gdbinit run -m $(TMP_LIBDIR)/master.lpc $(SRCDIR)/test/test_lpc.lpc $(SRCDIR)/test/testsuite -v -v -f
+	gdb ./ulpc
+
+# run hilfe, for interactive testing
+run_hilfe:
+	$(RUNULPC) $(TMP_BINDIR)/hilfe
+
+# make export archive (requires compiled uLPC)
+# Do not compile in source tree if you want to use this!
+# Beware that export archive this includes bison/yacc/byacc source
+# and thus has to follow the rules stated in that code.
+export: $(SRCDIR)/test/testsuite new_peep_engine $(SRCDIR)/language.c $(SRCDIR)/language.h depend
+	chmod +x $(SRCDIR)/install-sh
+	$(RUNULPC) $(TMP_BINDIR)/export.lpc
+
+new_peep_engine:
+	$(RUNULPC) $(TMP_BINDIR)/mkpeep.lpc $(SRCDIR)/peep.in >$(SRCDIR)/peep_engine.c
+
+peep_engine.c: peep.in
+	echo "" >$(SRCDIR)/peep_engine.c
+	-$(RUNULPC) $(TMP_BINDIR)/mkpeep.lpc $(SRCDIR)/peep.in >$(SRCDIR)/peep_engine.c
+
+# make dependencies (requires compiled uLPC)
+depend: language.c
+	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)
+	for a in $(MODULES) ; do ( cd $$a ; ${MAKE} $(MAKE_FLAGS) depend ) ; done
+
+docs:
+	mkdir docs
+
+html_docs: docs
+	$(RUNULPC) $(TMP_BINDIR)/htmlify_docs $(TMP_DOCDIR) docs
+
+#
+# uLPC internal targets
+#
+module_objects:
+	for a in $(MODULES) ; do ( cd $$a ; ${MAKE} $(MAKE_FLAGS) ) ; done
+
+lang.o: lang.c config.h object.h interpret.h program.h
+
+$(SRCDIR)/language.h: language.y
+	@echo "Expect 1 shift/reduce conflict."
+	$(YACC) $(YFLAGS) $(SRCDIR)/language.y
+	mv y.tab.c $(SRCDIR)/language.c
+	mv y.tab.h $(SRCDIR)/language.h
+
+$(SRCDIR)/language.c: language.h
+	touch $(SRCDIR)/language.c
+
+module.c: modlist.h
+
+configure: configure.in
+	cd $(SRCDIR) && autoconf
+
+config.status: configure
+	./config.status --recheck
+
+Makefile: Makefile.in config.status
+	./config.status
+
+machine.h: stamp-h
+
+stamp-h: machine.h.in config.status
+	./config.status
+
+modlist.h:
+	./config.status
+
+$(SRCDIR)/test/testsuite: $(SRCDIR)/test/create_testsuite
+	m4 <$(SRCDIR)/test/create_testsuite >$(SRCDIR)/test/testsuite
+
+
diff --git a/src/modules/files/Makefile.src b/src/modules/files/Makefile.src
new file mode 100644
index 0000000000..2366499c36
--- /dev/null
+++ b/src/modules/files/Makefile.src
@@ -0,0 +1,18 @@
+SRCDIR=@srcdir@
+VPATH=@srcdir@:@srcdir@/../..:../..
+PREFLAGS=-I. -I$(SRCDIR) -I$(SRCDIR)/../.. -I../..
+CFLAGS=$(PREFLAGS) $(OTHERFLAGS)
+
+FILES=file.o efuns.o socket.o
+
+files.a: $(FILES)
+	-rm -f files.a
+	ar cq files.a $(FILES)
+	-@RANLIB@ files.a
+
+clean:
+	-rm -f *.o *.a
+
+depend:
+	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)
+
diff --git a/src/modules/math/Makefile.src b/src/modules/math/Makefile.src
new file mode 100644
index 0000000000..919399491d
--- /dev/null
+++ b/src/modules/math/Makefile.src
@@ -0,0 +1,17 @@
+SRCDIR=@srcdir@
+VPATH=@srcdir@:@srcdir@/../..:../..
+PREFLAGS=-I$(SRCDIR) -I$(SRCDIR)/../.. -I../..
+CFLAGS=$(PREFLAGS) $(OTHERFLAGS)
+
+FILES=math.o
+
+math.a: $(FILES)
+	-rm -f math.a
+	ar cq math.a $(FILES)
+	-@RANLIB@ math.a
+
+clean:
+	-rm -f *.o
+
+depend:
+	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)
diff --git a/src/modules/regexp/Makefile.src b/src/modules/regexp/Makefile.src
new file mode 100644
index 0000000000..0ca33fdcc4
--- /dev/null
+++ b/src/modules/regexp/Makefile.src
@@ -0,0 +1,17 @@
+SRCDIR=@srcdir@
+VPATH=@srcdir@:@srcdir@/../..:../..
+PREFLAGS=-I$(SRCDIR) -I$(SRCDIR)/../.. -I../..
+CFLAGS=$(PREFLAGS) $(OTHERFLAGS)
+
+FILES=regexp.o glue.o
+
+regexp.a: $(FILES)
+	-rm -f regexp.a
+	ar cq regexp.a $(FILES)
+	-@RANLIB@ regexp.a
+
+clean:
+	-rm -f *.o *.a
+
+depend:
+	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)
diff --git a/src/modules/sprintf/Makefile.src b/src/modules/sprintf/Makefile.src
new file mode 100644
index 0000000000..a6a33e7322
--- /dev/null
+++ b/src/modules/sprintf/Makefile.src
@@ -0,0 +1,17 @@
+SRCDIR=@srcdir@
+VPATH=@srcdir@:@srcdir@/../..:../..
+PREFLAGS=-I$(SRCDIR) -I$(SRCDIR)/../.. -I../..
+CFLAGS=$(PREFLAGS) $(OTHERFLAGS)
+
+FILES=sprintf.o
+
+sprintf.a: $(FILES)
+	-rm -f sprintf.a
+	ar cq sprintf.a $(FILES)
+	-@RANLIB@ sprintf.a
+
+clean:
+	-rm -f *.o *.a
+
+depend:
+	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)
-- 
GitLab


From ff2ffc383864f8fd174b7cd16eee143a62121565 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 29 Apr 1996 21:00:21 +0200
Subject: [PATCH 138/351] Fixdepends re-implemented

Rev: bin/fixdepends.lpc:1.2(DEAD)
Rev: bin/fixdepends.sh:1.1
---
 bin/fixdepends.lpc | 35 -----------------------------------
 bin/fixdepends.sh  | 10 ++++++++++
 2 files changed, 10 insertions(+), 35 deletions(-)
 delete mode 100755 bin/fixdepends.lpc
 create mode 100755 bin/fixdepends.sh

diff --git a/bin/fixdepends.lpc b/bin/fixdepends.lpc
deleted file mode 100755
index 5790241800..0000000000
--- a/bin/fixdepends.lpc
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/local/bin/ulpc
-
-#define FILESET "a-zA-Z0-9./,_-"
-#define DEPENDLINE "\n#Dependencies begin here, DO NOT REMOVE THIS LINE!!!!\n"
-
-int main(int argc, string *argv)
-{
-  string f,makefile,pre,file;
-  
-  if(argc<2)
-  {
-    perror("Usage: fixdepends <makefile>\n");
-    exit(1);
-  }
-
-  if(!file_stat(argv[1]))
-  {
-    perror("Makefile not found.\n");
-    exit(1);
-  }
-
-  // Read depends from stdin
-  f=clone((program)"/precompiled/file","stdin")->read(0x7fffffff);
-  makefile=read_bytes(argv[1]);
-  sscanf(makefile,"%s" DEPENDLINE,makefile);
-  mv(argv[1],argv[1]+"~");
-  makefile+=DEPENDLINE;
-  while(strlen(f) && sscanf(f,"%[^" FILESET "]%s",pre,f)==2)
-  {
-    sscanf(f,"%[" FILESET "]%s",file,f);
-    makefile+=pre+(explode(file,"/")[-1]);  // Basename
-  }
-  makefile+=f;
-  write_file(argv[1],makefile);
-}
diff --git a/bin/fixdepends.sh b/bin/fixdepends.sh
new file mode 100755
index 0000000000..26306e0da5
--- /dev/null
+++ b/bin/fixdepends.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+cd $1
+
+(
+  cat Makefile.src
+  echo "# Depencies begin here"
+  sed 's@[-/a-zA-Z0-9.,_]*/\([-a-zA-Z0-9.,_]*\)@\1@g'
+) > Makefile.in
+
-- 
GitLab


From f16bd38a8435f9060f58fcd38b40f507c57499df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Wed, 1 May 1996 01:48:36 +0200
Subject: [PATCH 139/351] bugfix

Rev: bin/htmlify_docs.lpc:1.9
Rev: src/peep.in:1.2
---
 bin/htmlify_docs.lpc | 2 ++
 src/peep.in          | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/bin/htmlify_docs.lpc b/bin/htmlify_docs.lpc
index fce882ea30..0ba0dadbd1 100644
--- a/bin/htmlify_docs.lpc
+++ b/bin/htmlify_docs.lpc
@@ -417,6 +417,8 @@ string convert_page(string path, string fname)
 	    subpages[fname+"-&gt;"+part_name]=path+"#"+part_name;
 	  }
 
+	case "RETURN VALUE":
+	case "RETURN VALUES":
 	case "DESCRIPTION":
 	case "NOTA BENE":
 	case "BUGS":
diff --git a/src/peep.in b/src/peep.in
index 53890f8872..838c5cd822 100644
--- a/src/peep.in
+++ b/src/peep.in
@@ -45,7 +45,7 @@ NOT BRANCH_WHEN_ZERO: BRANCH_WHEN_NON_ZERO($2a)
 BRANCH !LABEL : BRANCH($1a)
 RETURN !LABEL : RETURN
 RETURN_0 !LABEL : RETURN_0
-BRANCH LABEL ($1a) :
+BRANCH LABEL ($1a) : LABEL ($1a)
 
 LOCAL_LVALUE INC : INC_LOCAL ($1a)
 LOCAL_LVALUE POST_INC : POST_INC_LOCAL ($1a)
-- 
GitLab


From 5fe3c86b5fd408b2331d4fceac6d9cb9b9a6ebbf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Wed, 1 May 1996 23:39:22 +0200
Subject: [PATCH 140/351] never used

Rev: src/get_linker_options:1.2(DEAD)
---
 src/get_linker_options | 29 -----------------------------
 1 file changed, 29 deletions(-)
 delete mode 100644 src/get_linker_options

diff --git a/src/get_linker_options b/src/get_linker_options
deleted file mode 100644
index 29960312c6..0000000000
--- a/src/get_linker_options
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/sh
-#
-# Build a list of things to link from module subdirs
-# Modules that need extra libraries should create a file
-# 'linker_opts' in the build tree containing the required
-# linker options
-#
-
-fullnames=`cat $1`
-
-dirs=
-for dir in $fullnames
-do
-  dir="`echo $dir|sed 's,^.*/\([^/]*\)$,\1,'`"  # Portable (?) basename
-  dirs="$dirs $dir"
-done
-
-for dir in $fullnames
-do
-  echo modules/$modname/$modname.a
-done
-
-for dir in $fullnames
-do
-  if [ -f modules/$modname/linker_opts ]; then
-    cat modules/$modname/linker_opts
-  fi
-done
-
-- 
GitLab


From b487c4e9806679ca27b7024b53376c13c7c70681 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Wed, 1 May 1996 23:44:08 +0200
Subject: [PATCH 141/351] logical operators added

Rev: doc/operators/and:1.3
Rev: doc/operators/logical_and:1.1
Rev: doc/operators/logical_or:1.1
Rev: doc/operators/or:1.3
---
 doc/operators/and         |  2 +-
 doc/operators/logical_and | 18 ++++++++++++++++++
 doc/operators/logical_or  | 17 +++++++++++++++++
 doc/operators/or          |  2 +-
 4 files changed, 37 insertions(+), 2 deletions(-)
 create mode 100644 doc/operators/logical_and
 create mode 100644 doc/operators/logical_or

diff --git a/doc/operators/and b/doc/operators/and
index 849eeae0ce..80c4b40c7d 100644
--- a/doc/operators/and
+++ b/doc/operators/and
@@ -21,4 +21,4 @@ KEYWORDS
 	operators
 
 SEE ALSO
-	`|, `^
+	`|, `^, &&
diff --git a/doc/operators/logical_and b/doc/operators/logical_and
new file mode 100644
index 0000000000..9232678f5b
--- /dev/null
+++ b/doc/operators/logical_and
@@ -0,0 +1,18 @@
+NAME
+	&& - logical and
+
+SYNTAX
+	a && b
+
+
+DESCRIPTION
+	This operator does logical 'and' between expressions. It first
+	evaluates a and returns zero if a is zero. Otherwise it returns
+	b. Note that b is not evaluated at all if a returns zero.
+
+
+KEYWORDS
+	operators
+
+SEE ALSO
+	`&, ||
diff --git a/doc/operators/logical_or b/doc/operators/logical_or
new file mode 100644
index 0000000000..b7ade5bb1c
--- /dev/null
+++ b/doc/operators/logical_or
@@ -0,0 +1,17 @@
+NAME
+	|| - logical or
+
+SYNTAX
+	a || b
+
+
+DESCRIPTION
+	This operator does logical 'or' between expressions. It first
+	evaluates a and returns that if a is non-zero. Otherwise it
+	returns b. Note that b is not evaluated at all if a is non-zero.
+
+KEYWORDS
+	operators
+
+SEE ALSO
+	`|, &&
diff --git a/doc/operators/or b/doc/operators/or
index 0388fa1318..d04e9c44af 100644
--- a/doc/operators/or
+++ b/doc/operators/or
@@ -21,4 +21,4 @@ KEYWORDS
 	operators
 
 SEE ALSO
-	`&, `^
+	`&, `^, ||
-- 
GitLab


From d4f85438bd5397631adccb6cf971fcdb597d7b6f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Wed, 1 May 1996 23:47:21 +0200
Subject: [PATCH 142/351] module documentation moved

Rev: doc/builtin/zero_type:1.3
Rev: doc/manual/example1:1.4
Rev: doc/types/mapping:1.5
---
 doc/builtin/zero_type | 2 +-
 doc/manual/example1   | 4 ++--
 doc/types/mapping     | 5 +++--
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/doc/builtin/zero_type b/doc/builtin/zero_type
index 6edca1ab16..36c31442a2 100644
--- a/doc/builtin/zero_type
+++ b/doc/builtin/zero_type
@@ -14,7 +14,7 @@ DESCRIPTION
 	no such call_out could be found. Otherwize zero_type will return zero.
 
 KEYWORDS
-	int
+	int, mapping
 
 SEE ALSO
 	find_call_out
diff --git a/doc/manual/example1 b/doc/manual/example1
index 5600124036..f86b5bfcf9 100644
--- a/doc/manual/example1
+++ b/doc/manual/example1
@@ -82,7 +82,7 @@
 
 	int main(int argc, string *argv)
 	{
-	  if(argc > 2 && argv[1]=="--traditional")
+	  if(argc > 1 && argv[1]=="--traditional")
 	  {
 	    write("hello world\n"); // old stype
 	  }else{
@@ -114,7 +114,7 @@
   the command line (including the command itself) and argv is an array formed
   by these words.
 
-	  if(argc > 2 && argv[1] == "--traditional")
+	  if(argc > 1 && argv[1] == "--traditional")
 	  {
 	    write("hello world\n"); // old stype
 	  }else{
diff --git a/doc/types/mapping b/doc/types/mapping
index 0077a6ce05..6ff371b7a3 100644
--- a/doc/types/mapping
+++ b/doc/types/mapping
@@ -35,7 +35,7 @@ DESCRIPTION
 	! a	boolean not, returns 0
 	a[c]	indexing, returns the value associated with the value c
 		in the mapping a. If there is no index c in the mapping
-		zero will be returned. (With zero type = 1)
+		zero will be returned. (With zero_type = 1)
 	a[c]=d	setting, this associates d with c in the mapping, the index
 		c will be added to the mapping automatically if it isn't
 		already there.
@@ -44,4 +44,5 @@ KEYWORDS
 	types
 
 SEE ALSO
-	array, list, builtin/sizeof, builtin/indices, builtin/values
+	array, list, builtin/sizeof, builtin/indices, builtin/values,
+	builtin/zero_type
-- 
GitLab


From 9aa704348b2a7fe1605e48ef51f4615fbeaaf325 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 2 May 1996 00:05:26 +0200
Subject: [PATCH 143/351] linker_options implemented and doc files moved

Rev: doc/files/cd:1.2(DEAD)
Rev: doc/files/exece:1.2(DEAD)
Rev: doc/files/file:1.2(DEAD)
Rev: doc/files/file_stat:1.2(DEAD)
Rev: doc/files/fork:1.2(DEAD)
Rev: doc/files/get_dir:1.2(DEAD)
Rev: doc/files/getcwd:1.2(DEAD)
Rev: doc/files/mkdir:1.2(DEAD)
Rev: doc/files/mv:1.2(DEAD)
Rev: doc/files/perror:1.2(DEAD)
Rev: doc/files/port:1.2(DEAD)
Rev: doc/files/rm:1.2(DEAD)
Rev: doc/math/acos:1.2(DEAD)
Rev: doc/math/asin:1.2(DEAD)
Rev: doc/math/atan:1.2(DEAD)
Rev: doc/math/ceil:1.2(DEAD)
Rev: doc/math/cos:1.2(DEAD)
Rev: doc/math/exp:1.2(DEAD)
Rev: doc/math/floor:1.2(DEAD)
Rev: doc/math/log:1.2(DEAD)
Rev: doc/math/pow:1.2(DEAD)
Rev: doc/math/sin:1.2(DEAD)
Rev: doc/math/sqrt:1.2(DEAD)
Rev: doc/math/tan:1.2(DEAD)
Rev: doc/regexp/regexp:1.2(DEAD)
Rev: doc/sprintf/sprintf:1.2(DEAD)
Rev: src/modules/files/Makefile.src:1.2
Rev: src/modules/files/doc/cd:1.1
Rev: src/modules/files/doc/exece:1.1
Rev: src/modules/files/doc/file:1.1
Rev: src/modules/files/doc/file_stat:1.1
Rev: src/modules/files/doc/fork:1.1
Rev: src/modules/files/doc/get_dir:1.1
Rev: src/modules/files/doc/getcwd:1.1
Rev: src/modules/files/doc/mkdir:1.1
Rev: src/modules/files/doc/mv:1.1
Rev: src/modules/files/doc/perror:1.1
Rev: src/modules/files/doc/port:1.1
Rev: src/modules/files/doc/rm:1.1
Rev: src/modules/math/Makefile.src:1.2
Rev: src/modules/math/configure.in:1.2
Rev: src/modules/math/doc/acos:1.1
Rev: src/modules/math/doc/asin:1.1
Rev: src/modules/math/doc/atan:1.1
Rev: src/modules/math/doc/ceil:1.1
Rev: src/modules/math/doc/cos:1.1
Rev: src/modules/math/doc/exp:1.1
Rev: src/modules/math/doc/floor:1.1
Rev: src/modules/math/doc/log:1.1
Rev: src/modules/math/doc/pow:1.1
Rev: src/modules/math/doc/sin:1.1
Rev: src/modules/math/doc/sqrt:1.1
Rev: src/modules/math/doc/tan:1.1
Rev: src/modules/regexp/doc/regexp:1.1
Rev: src/modules/sprintf/doc/sprintf:1.1
---
 src/modules/files/Makefile.src                   | 1 +
 {doc/files => src/modules/files/doc}/cd          | 0
 {doc/files => src/modules/files/doc}/exece       | 0
 {doc/files => src/modules/files/doc}/file        | 0
 {doc/files => src/modules/files/doc}/file_stat   | 0
 {doc/files => src/modules/files/doc}/fork        | 0
 {doc/files => src/modules/files/doc}/get_dir     | 0
 {doc/files => src/modules/files/doc}/getcwd      | 0
 {doc/files => src/modules/files/doc}/mkdir       | 0
 {doc/files => src/modules/files/doc}/mv          | 0
 {doc/files => src/modules/files/doc}/perror      | 0
 {doc/files => src/modules/files/doc}/port        | 0
 {doc/files => src/modules/files/doc}/rm          | 0
 src/modules/math/Makefile.src                    | 1 +
 src/modules/math/configure.in                    | 6 ++++++
 {doc/math => src/modules/math/doc}/acos          | 0
 {doc/math => src/modules/math/doc}/asin          | 0
 {doc/math => src/modules/math/doc}/atan          | 0
 {doc/math => src/modules/math/doc}/ceil          | 0
 {doc/math => src/modules/math/doc}/cos           | 0
 {doc/math => src/modules/math/doc}/exp           | 0
 {doc/math => src/modules/math/doc}/floor         | 0
 {doc/math => src/modules/math/doc}/log           | 0
 {doc/math => src/modules/math/doc}/pow           | 0
 {doc/math => src/modules/math/doc}/sin           | 0
 {doc/math => src/modules/math/doc}/sqrt          | 0
 {doc/math => src/modules/math/doc}/tan           | 0
 {doc/regexp => src/modules/regexp/doc}/regexp    | 0
 {doc/sprintf => src/modules/sprintf/doc}/sprintf | 0
 29 files changed, 8 insertions(+)
 rename {doc/files => src/modules/files/doc}/cd (100%)
 rename {doc/files => src/modules/files/doc}/exece (100%)
 rename {doc/files => src/modules/files/doc}/file (100%)
 rename {doc/files => src/modules/files/doc}/file_stat (100%)
 rename {doc/files => src/modules/files/doc}/fork (100%)
 rename {doc/files => src/modules/files/doc}/get_dir (100%)
 rename {doc/files => src/modules/files/doc}/getcwd (100%)
 rename {doc/files => src/modules/files/doc}/mkdir (100%)
 rename {doc/files => src/modules/files/doc}/mv (100%)
 rename {doc/files => src/modules/files/doc}/perror (100%)
 rename {doc/files => src/modules/files/doc}/port (100%)
 rename {doc/files => src/modules/files/doc}/rm (100%)
 rename {doc/math => src/modules/math/doc}/acos (100%)
 rename {doc/math => src/modules/math/doc}/asin (100%)
 rename {doc/math => src/modules/math/doc}/atan (100%)
 rename {doc/math => src/modules/math/doc}/ceil (100%)
 rename {doc/math => src/modules/math/doc}/cos (100%)
 rename {doc/math => src/modules/math/doc}/exp (100%)
 rename {doc/math => src/modules/math/doc}/floor (100%)
 rename {doc/math => src/modules/math/doc}/log (100%)
 rename {doc/math => src/modules/math/doc}/pow (100%)
 rename {doc/math => src/modules/math/doc}/sin (100%)
 rename {doc/math => src/modules/math/doc}/sqrt (100%)
 rename {doc/math => src/modules/math/doc}/tan (100%)
 rename {doc/regexp => src/modules/regexp/doc}/regexp (100%)
 rename {doc/sprintf => src/modules/sprintf/doc}/sprintf (100%)

diff --git a/src/modules/files/Makefile.src b/src/modules/files/Makefile.src
index 2366499c36..7cfca629e9 100644
--- a/src/modules/files/Makefile.src
+++ b/src/modules/files/Makefile.src
@@ -9,6 +9,7 @@ files.a: $(FILES)
 	-rm -f files.a
 	ar cq files.a $(FILES)
 	-@RANLIB@ files.a
+	echo >linker_options @LIBS@
 
 clean:
 	-rm -f *.o *.a
diff --git a/doc/files/cd b/src/modules/files/doc/cd
similarity index 100%
rename from doc/files/cd
rename to src/modules/files/doc/cd
diff --git a/doc/files/exece b/src/modules/files/doc/exece
similarity index 100%
rename from doc/files/exece
rename to src/modules/files/doc/exece
diff --git a/doc/files/file b/src/modules/files/doc/file
similarity index 100%
rename from doc/files/file
rename to src/modules/files/doc/file
diff --git a/doc/files/file_stat b/src/modules/files/doc/file_stat
similarity index 100%
rename from doc/files/file_stat
rename to src/modules/files/doc/file_stat
diff --git a/doc/files/fork b/src/modules/files/doc/fork
similarity index 100%
rename from doc/files/fork
rename to src/modules/files/doc/fork
diff --git a/doc/files/get_dir b/src/modules/files/doc/get_dir
similarity index 100%
rename from doc/files/get_dir
rename to src/modules/files/doc/get_dir
diff --git a/doc/files/getcwd b/src/modules/files/doc/getcwd
similarity index 100%
rename from doc/files/getcwd
rename to src/modules/files/doc/getcwd
diff --git a/doc/files/mkdir b/src/modules/files/doc/mkdir
similarity index 100%
rename from doc/files/mkdir
rename to src/modules/files/doc/mkdir
diff --git a/doc/files/mv b/src/modules/files/doc/mv
similarity index 100%
rename from doc/files/mv
rename to src/modules/files/doc/mv
diff --git a/doc/files/perror b/src/modules/files/doc/perror
similarity index 100%
rename from doc/files/perror
rename to src/modules/files/doc/perror
diff --git a/doc/files/port b/src/modules/files/doc/port
similarity index 100%
rename from doc/files/port
rename to src/modules/files/doc/port
diff --git a/doc/files/rm b/src/modules/files/doc/rm
similarity index 100%
rename from doc/files/rm
rename to src/modules/files/doc/rm
diff --git a/src/modules/math/Makefile.src b/src/modules/math/Makefile.src
index 919399491d..44f0678005 100644
--- a/src/modules/math/Makefile.src
+++ b/src/modules/math/Makefile.src
@@ -9,6 +9,7 @@ math.a: $(FILES)
 	-rm -f math.a
 	ar cq math.a $(FILES)
 	-@RANLIB@ math.a
+	echo >linker_options @LIBS@
 
 clean:
 	-rm -f *.o
diff --git a/src/modules/math/configure.in b/src/modules/math/configure.in
index 1a03a6eafd..7e6871bcdd 100644
--- a/src/modules/math/configure.in
+++ b/src/modules/math/configure.in
@@ -3,6 +3,12 @@ AC_INIT(math.c)
 AC_PROG_CC
 AC_PROG_RANLIB
 
+AC_CHECK_LIB(m, floor)
+if test "${ac_cv_lib_m}" = "no" -a "${lpc_cv_sys_os}" = "Linux"; then
+  AC_MSG_WARN(I will compensate for this by adding -lc -lm)
+  LIBS="${LIBS} -lc -lm"
+fi
+
 AC_SUBST(RANLIB)
 
 AC_OUTPUT(Makefile,echo FOO >stamp-h )
diff --git a/doc/math/acos b/src/modules/math/doc/acos
similarity index 100%
rename from doc/math/acos
rename to src/modules/math/doc/acos
diff --git a/doc/math/asin b/src/modules/math/doc/asin
similarity index 100%
rename from doc/math/asin
rename to src/modules/math/doc/asin
diff --git a/doc/math/atan b/src/modules/math/doc/atan
similarity index 100%
rename from doc/math/atan
rename to src/modules/math/doc/atan
diff --git a/doc/math/ceil b/src/modules/math/doc/ceil
similarity index 100%
rename from doc/math/ceil
rename to src/modules/math/doc/ceil
diff --git a/doc/math/cos b/src/modules/math/doc/cos
similarity index 100%
rename from doc/math/cos
rename to src/modules/math/doc/cos
diff --git a/doc/math/exp b/src/modules/math/doc/exp
similarity index 100%
rename from doc/math/exp
rename to src/modules/math/doc/exp
diff --git a/doc/math/floor b/src/modules/math/doc/floor
similarity index 100%
rename from doc/math/floor
rename to src/modules/math/doc/floor
diff --git a/doc/math/log b/src/modules/math/doc/log
similarity index 100%
rename from doc/math/log
rename to src/modules/math/doc/log
diff --git a/doc/math/pow b/src/modules/math/doc/pow
similarity index 100%
rename from doc/math/pow
rename to src/modules/math/doc/pow
diff --git a/doc/math/sin b/src/modules/math/doc/sin
similarity index 100%
rename from doc/math/sin
rename to src/modules/math/doc/sin
diff --git a/doc/math/sqrt b/src/modules/math/doc/sqrt
similarity index 100%
rename from doc/math/sqrt
rename to src/modules/math/doc/sqrt
diff --git a/doc/math/tan b/src/modules/math/doc/tan
similarity index 100%
rename from doc/math/tan
rename to src/modules/math/doc/tan
diff --git a/doc/regexp/regexp b/src/modules/regexp/doc/regexp
similarity index 100%
rename from doc/regexp/regexp
rename to src/modules/regexp/doc/regexp
diff --git a/doc/sprintf/sprintf b/src/modules/sprintf/doc/sprintf
similarity index 100%
rename from doc/sprintf/sprintf
rename to src/modules/sprintf/doc/sprintf
-- 
GitLab


From 549f8bd63b725df06f1edbc05541ba4d1edcb3bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 2 May 1996 09:23:40 +0200
Subject: [PATCH 144/351] module docs moved

Rev: bin/htmlify_docs.lpc:1.10
Rev: src/Makefile.src:1.2
Rev: src/configure.in:1.11
Rev: src/modules/files/configure.in:1.5
---
 bin/htmlify_docs.lpc           | 42 +++++++++++++++++++++++++++-------
 src/Makefile.src               | 30 +++++++++++++-----------
 src/configure.in               |  8 ++-----
 src/modules/files/configure.in |  4 ++++
 4 files changed, 57 insertions(+), 27 deletions(-)

diff --git a/bin/htmlify_docs.lpc b/bin/htmlify_docs.lpc
index 0ba0dadbd1..736f46f071 100644
--- a/bin/htmlify_docs.lpc
+++ b/bin/htmlify_docs.lpc
@@ -11,6 +11,7 @@ mapping subpages = ([]);
 
 string new_path;
 int writepages;
+string docdir;
 
 
 /*
@@ -51,7 +52,7 @@ string fippel_path(string path)
   if(path[strlen(path)-5..]==".bmml") path=path[..strlen(path)-6];
   if(path[strlen(path)-5..]!=".html") path+=".html";
 
-  return path;
+  return docdir+path;
 }
 
 /*
@@ -693,7 +694,7 @@ void scanfiles(string path, string fname)
 }
 
 /** Traverse directory **/
-void traversedir(string path,function fun)
+void traversedir(string path)
 {
   string file;
   foreach(get_dir(path) - ({"CVS","RCS",".cvsignore"}),file)
@@ -709,14 +710,39 @@ void traversedir(string path,function fun)
     {
       traversedir(tmp,fun);
     }else{
-      fun(tmp,file);
+      scanfiles(tmp,file);
     }
   }
 }
 
+void dodocs(string path, int module)
+{
+  cd(path);
+  if(!module)
+  {
+    docdir="";
+  }else{
+    docdir="module"+module;
+    if(sscanf(reverse(path),"cod/%s",docdir))
+    {
+      sscanf(docdir,"%s/",docdir);
+      docdir=reverse(docdir);
+    }
+    docdir+="_";
+  }
+  traversedir(".");
+}
+
 int main(int argc, string *argv)
 {
   string np;
+  int e;
+
+  if(argc < 3)
+  {
+    perror("Usage: html_docs.lpc to_path from_path [module_doc_path ...]\n");
+    exit(0);
+  }
 
   megamagic::create("^(.*)&lt;([a-z_0-9]+)&gt;(.*)$");
   lastident::create("^(.*[^<>a-z_0-9])([a-z_0-9]+)([^<>a-z_0-9]*)$");
@@ -729,17 +755,17 @@ int main(int argc, string *argv)
 
   is_example::create("^(" LINE ")+$");
 
-  new_path=combine_path(getcwd(),argv[2]);
-  cd(argv[1]);
+  for(e=1;e<sizeof(argv);e++)
+    argv[e]=combine_path(getcwd(),argv[e]);
 
   write("Scanning pages for links and keywords.\n");
   writepages=0;
-  traversedir(".",scanfiles);
+  for(e=2;e<sizeof(argv);e++) dodocs(argv[e],e-2);
 
   write("Writing html files.\n");
   writepages=1;
-  traversedir(".",scanfiles);
-
+  for(e=2;e<sizeof(argv);e++) dodocs(argv[e],e-2);
+    
   foreach(indices(keywords) - indices(indexes_done),np)
   {
     perror("Keywords never indexed: "+np+"\n");
diff --git a/src/Makefile.src b/src/Makefile.src
index d5cf8c8ace..45301f10cc 100644
--- a/src/Makefile.src
+++ b/src/Makefile.src
@@ -3,7 +3,7 @@
 
 # Don't change this line.  Define EXTRALIBS before this line if you
 # wish to add any libraries.
-LIBS=@LIBS@ $(EXTRALIBS)
+LIBS=@LIBS@ $(EXTRALIBS) `for a in $(MODULES) ; do if [ -f $$a/linker_options ]; then cat $$a/linker_options ; fi ; done`
 
 # not used yet
 INSTALL=@INSTALL@
@@ -82,13 +82,13 @@ MODULE_OBJS=@MODULE_OBJS@
 # User callable targets
 #
 
-all: ulpc
+all: $(OBJ) module_objects
+	$(MAKE) $(MAKE_FLAGS) ulpc
 
-ulpc: $(OBJ) module_objects
+ulpc: $(OBJ) $(MODULE_OBJS)
 	-mv ulpc ulpc.old
 	$(LD) $(LDFLAGS) $(OBJ) $(MODULE_OBJS) -o ulpc $(LIBS)
 
-
 # purify
 pure: $(OBJ) module_objects
 	-mv ulpc ulpc.old
@@ -102,7 +102,7 @@ cover: $(OBJ) module_objects
 # quantify
 quant: $(OBJ) module_objects
 	-mv ulpc ulpc.old
-	quantify $(LD) $(LDFLAGS) $(OBJ) $(MODULE_OBJS) -o ulpc $(LIBS)
+	quantify $(LD) $(LDFLAGS) $(OBJ) $(MODULE_OBJS) -o ulpc $(LIBS) 
 
 # install
 install:
@@ -186,7 +186,7 @@ docs:
 	mkdir docs
 
 html_docs: docs
-	$(RUNULPC) $(TMP_BINDIR)/htmlify_docs $(TMP_DOCDIR) docs
+	$(RUNULPC) $(TMP_BINDIR)/htmlify_docs docs $(TMP_DOCDIR) `for a in $MODULES); do echo $(SRCDIR)/$$a ; done`
 
 #
 # uLPC internal targets
@@ -207,22 +207,26 @@ $(SRCDIR)/language.c: language.h
 
 module.c: modlist.h
 
-configure: configure.in
+$(SRCDIR)/configure: configure.in
 	cd $(SRCDIR) && autoconf
 
-config.status: configure
+config.status: $(SRCDIR)/configure
 	./config.status --recheck
 
-Makefile: Makefile.in config.status
-	./config.status
+$(SRCDIR)/Makefile.in: $(SRCDIR)/Makefile.src
+	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)
+
+Makefile: $(SRCDIR)/Makefile.in config.status
+	CONFIG_FILES=Makefile CONFIG_HEADERS= ./config.status
+	@echo "Run make again"
+	@exit 1
 
 machine.h: stamp-h
-
 stamp-h: machine.h.in config.status
-	./config.status
+	CONFIG_FILES= CONFIG_HEADERS=machine.h ./config.status
 
 modlist.h:
-	./config.status
+	CONFIG_FILES=modlist.h CONFIG_HEADERS= ./config.status
 
 $(SRCDIR)/test/testsuite: $(SRCDIR)/test/create_testsuite
 	m4 <$(SRCDIR)/test/create_testsuite >$(SRCDIR)/test/testsuite
diff --git a/src/configure.in b/src/configure.in
index b632c48c3a..6e0b5ab994 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -235,12 +235,8 @@ if test "${ac_cv_lib_m}" = "no" -a "${lpc_cv_sys_os}" = "Linux"; then
   AC_MSG_WARN(I will compensate for this by adding -lc -lm)
   LIBS="${LIBS} -lc -lm"
 fi
-AC_CHECK_LIB(socket, socket)
-AC_CHECK_LIB(crypt, crypt)
-if test "$ac_cv_lib_socket" = yes -o "${ac_cv_lib_ucb}" = yes; then
- AC_CHECK_LIB(nsl, main)
-fi
 
+AC_CHECK_LIB(crypt, crypt)
 
 OLD_LIBOBJS="${LIBOBJS}"
 
@@ -836,7 +832,7 @@ if test ! -d ./modules ; then
   mkdir modules
 fi
 
-AC_MSG_RESULT(creating modlist.h)
+echo creating modlist.h
 echo "void init_main_efuns(void);" >modlist.h
 echo "void init_main_programs(void);" >>modlist.h
 echo "void exit_main(void);" >>modlist.h
diff --git a/src/modules/files/configure.in b/src/modules/files/configure.in
index 0fbedbdda8..c026599a54 100644
--- a/src/modules/files/configure.in
+++ b/src/modules/files/configure.in
@@ -9,6 +9,10 @@ AC_HAVE_HEADERS(arpa/inet.h sys/socketvar.h netinet/in.h \
  sys/stream.h sys/protosw.h)
 AC_HEADER_DIRENT
 AC_CHECK_LIB(socket, socket)
+AC_CHECK_LIB(crypt, crypt)
+if test "$ac_cv_lib_socket" = yes -o "${ac_cv_lib_ucb}" = yes; then
+ AC_CHECK_LIB(nsl, main)
+fi
 
 AC_HAVE_FUNCS(socketpair getwd)
 
-- 
GitLab


From 5a0c951499bdb4ec03a3a645c85cc831df990b39 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 2 May 1996 22:08:29 +0200
Subject: [PATCH 145/351] bugfix

Rev: doc/operators/range:1.2
---
 doc/operators/range | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/doc/operators/range b/doc/operators/range
index 97e6922cfb..9159afaefb 100644
--- a/doc/operators/range
+++ b/doc/operators/range
@@ -17,10 +17,10 @@ DESCRIPTION
 	the result will include everything from (and including) b to the end.
 
 EXAMPLES
-	"foobar"[0..3]	returns "foo"
-	"foobar"[4..6]	returns "bar"
-	({1,2,3})[..2]	returns ({1,2})
-	({1,2,3})[2..]	returns ({2,3})
+	"foobar"[0..2]	returns "foo"
+	"foobar"[3..5]	returns "bar"
+	({1,2,3})[..1]	returns ({1,2})
+	({1,2,3})[1..]	returns ({2,3})
 	({1,2,3})[..]	returns ({1,2,3})
 
 KEYWORDS
-- 
GitLab


From da55f9b79ec0de31f1ae723db155cc089412bc92 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 3 May 1996 13:49:48 +0200
Subject: [PATCH 146/351] better typechecking

Rev: src/las.c:1.9
---
 src/las.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/las.c b/src/las.c
index e999b84833..9a0912e000 100644
--- a/src/las.c
+++ b/src/las.c
@@ -961,6 +961,12 @@ void fix_type_field(node *n)
     }
     break;
 
+  case F_ASSIGN:
+    if(CAR(n) && CDR(n) && 
+       !match_types(CDR(n)->type,CAR(n)->type))
+      my_yyerror("Bad type in assignment.\n");
+    break;
+
   case F_INDEX:
     type_a=CAR(n)->type;
     type_b=CDR(n)->type;
-- 
GitLab


From a6ee1d9d40d15a37f66a73cfc93d886dc2190cc5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 3 May 1996 13:50:48 +0200
Subject: [PATCH 147/351] entry added

Rev: src/ChangeLog:1.32
---
 src/ChangeLog | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 196fbc41cd..e0f85b6e72 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
+Fri May  3 13:50:05 1996  Fredrik Hubinette  <hubbe@freeone.signum.se>
+
+	* las.c: type-checking improved
+
+Wed May  1 00:49:36 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
+
+	* uLPC_v1.0E-9 released.
+
 Mon Apr 29 20:47:31 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
 
 	* Makefile.in: All makefiles are now generated from Makefile.src ->
-- 
GitLab


From 3b2560092c205194a7d135df79596586774be822 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 3 May 1996 13:51:08 +0200
Subject: [PATCH 148/351] minor bugfix

Rev: doc/types/float:1.4
---
 doc/types/float | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/types/float b/doc/types/float
index 454fe71cb4..3ce15fac72 100644
--- a/doc/types/float
+++ b/doc/types/float
@@ -16,7 +16,7 @@ DESCRIPTION
 	a + b	summation
 	a - b	subtraction
 	a * b	multiplication
-	a / b	integer division
+	a / b	division
 	a % b	modulo ( same thing as  a - floor( a / b ) * b )
 	- a	negation
 	a == b	return 1 if a is equal to b, 0 otherwise
-- 
GitLab


From eeb387ccd8c448188f6364c49233e56dc5db7176 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 4 May 1996 13:03:26 +0200
Subject: [PATCH 149/351] version changed

Rev: lib/simulate.lpc:1.14
---
 lib/simulate.lpc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index 83758959b3..8da82da8f8 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -379,7 +379,7 @@ void create()
   add_efun("sum_arrays",sum_arrays);
   add_efun("system",system);
   add_efun("this_function",this_function);
-  add_efun("version",lambda() { return "uLPC v1.0E-9"; });
+  add_efun("version",lambda() { return "uLPC v1.0E-8"; });
   add_efun("write_file",write_file);
 }
 
-- 
GitLab


From 9035a18b6c1032a3f975eaeaf08694f95ee82152 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 4 May 1996 13:03:44 +0200
Subject: [PATCH 150/351] better typechecking

Rev: src/las.c:1.10
---
 src/las.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/las.c b/src/las.c
index 9a0912e000..e1bf83770c 100644
--- a/src/las.c
+++ b/src/las.c
@@ -965,6 +965,7 @@ void fix_type_field(node *n)
     if(CAR(n) && CDR(n) && 
        !match_types(CDR(n)->type,CAR(n)->type))
       my_yyerror("Bad type in assignment.\n");
+    copy_shared_string(b->type, CDR(n)->type);
     break;
 
   case F_INDEX:
-- 
GitLab


From d02759dcd50573d0bb3abae91556a0599e75bb88 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 4 May 1996 13:43:15 +0200
Subject: [PATCH 151/351] entry added

Rev: src/ChangeLog:1.33
---
 src/ChangeLog | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index e0f85b6e72..cd89b849a4 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -2,6 +2,11 @@ Fri May  3 13:50:05 1996  Fredrik Hubinette  <hubbe@freeone.signum.se>
 
 	* las.c: type-checking improved
 
+Sat May  4 13:40:48 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
+
+	* uLPC_v1.1E-9 released.
+	* lpc_types.c (internal_parse_typeA): fixed a minor bug
+
 Wed May  1 00:49:36 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
 
 	* uLPC_v1.0E-9 released.
-- 
GitLab


From 4d0653219efc86472adc7bd698385e49b888c24e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 4 May 1996 13:43:30 +0200
Subject: [PATCH 152/351] bugfix in mapping types

Rev: src/lpc_types.c:1.4
---
 src/lpc_types.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/lpc_types.c b/src/lpc_types.c
index e2186c7974..9686feccc8 100644
--- a/src/lpc_types.c
+++ b/src/lpc_types.c
@@ -186,13 +186,19 @@ static void internal_parse_typeA(char **s)
     while(isspace(**s)) ++*s;
     if(**s == '(')
     {
+      type_stack_mark();
       ++*s;
+      type_stack_mark();
       internal_parse_type(s);
+      type_stack_reverse();
       if(**s != ':') error("Expecting ':'.\n");
       ++*s;
+      type_stack_mark();
       internal_parse_type(s);
+      type_stack_reverse();
       if(**s != ')') error("Expecting ')'.\n");
       ++*s;
+      type_stack_reverse();
     }else{
       push_type(T_MIXED);
       push_type(T_MIXED);
-- 
GitLab


From eb76f1b529c57eb82d8607191a811970caeec657 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 4 May 1996 13:44:01 +0200
Subject: [PATCH 153/351] added tests for typeof()

Rev: src/test/create_testsuite:1.15
---
 src/test/create_testsuite | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 959f4183ed..7542de3d61 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -93,6 +93,13 @@ test_eq(AFJLLAF,17)
 test_do(add_efun("AFJLLAF"))
 test_do(signal(signum("SIGUSR1")))
 
+// typeof
+test_eq(typeof(1),"int")
+test_eq(typeof(""),"string")
+test_eq(typeof(""[0]),"int")
+test_eq(typeof(0.0),"float")
+test_eq(typeof(all_efuns()["all_efuns"]),"mixed")
+
 // class
 test_true(programp(class {}))
 test_true(functionp(clone(class { int foo() { return 1; }})->foo))
-- 
GitLab


From d8632c77cbf387b8957265b68e32c7fdf3bb92e5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 4 May 1996 17:11:25 +0200
Subject: [PATCH 154/351] minor fixes

Rev: lib/master.lpc:1.6
Rev: src/Makefile.src:1.3
Rev: src/builtin_efuns.c:1.16
Rev: src/las.c:1.11
---
 lib/master.lpc      | 2 +-
 src/Makefile.src    | 2 ++
 src/builtin_efuns.c | 2 +-
 src/las.c           | 2 +-
 4 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/lib/master.lpc b/lib/master.lpc
index 8d4d8f010a..0be461015c 100644
--- a/lib/master.lpc
+++ b/lib/master.lpc
@@ -242,7 +242,7 @@ string describe_backtrace(mixed *trace)
   }else{
     for(e=0;e<sizeof(trace);e++)
     {
-      mixed *tmp;
+      mixed tmp;
       string row;
 
       tmp=trace[e];
diff --git a/src/Makefile.src b/src/Makefile.src
index 45301f10cc..58499830a9 100644
--- a/src/Makefile.src
+++ b/src/Makefile.src
@@ -177,6 +177,8 @@ peep_engine.c: peep.in
 	echo "" >$(SRCDIR)/peep_engine.c
 	-$(RUNULPC) $(TMP_BINDIR)/mkpeep.lpc $(SRCDIR)/peep.in >$(SRCDIR)/peep_engine.c
 
+peep.o: peep_engine.c
+
 # make dependencies (requires compiled uLPC)
 depend: language.c
 	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)
diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index 1a94033b2e..64ea863c98 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -1244,7 +1244,7 @@ void init_builtin_efuns()
   add_efun("all_efuns",f_all_efuns,"function(:mapping(string:mixed))",OPT_EXTERNAL_DEPEND);
   add_efun("allocate", f_allocate, "function(int, string|void:mixed *)", 0);
   add_efun("arrayp",  f_arrayp,  "function(mixed:int)",0);
-  add_efun("backtrace",f_backtrace,"function(:array(array(function|int)))",OPT_EXTERNAL_DEPEND);
+  add_efun("backtrace",f_backtrace,"function(:array(array(function|int|string)))",OPT_EXTERNAL_DEPEND);
   add_efun("call_function",f_call_function,"function(mixed,mixed ...:mixed)",OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND);
   add_efun("call_out",f_call_out,"function(function,int,mixed...:void)",OPT_SIDE_EFFECT);
   add_efun("call_out_info",f_call_out_info,"function(:array*)",OPT_EXTERNAL_DEPEND);
diff --git a/src/las.c b/src/las.c
index e1bf83770c..58df15ca01 100644
--- a/src/las.c
+++ b/src/las.c
@@ -965,7 +965,7 @@ void fix_type_field(node *n)
     if(CAR(n) && CDR(n) && 
        !match_types(CDR(n)->type,CAR(n)->type))
       my_yyerror("Bad type in assignment.\n");
-    copy_shared_string(b->type, CDR(n)->type);
+    copy_shared_string(n->type, CDR(n)->type);
     break;
 
   case F_INDEX:
-- 
GitLab


From 7cfda73074e99835e67fcded5a5a324b5b4ebd5a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 13 May 1996 22:24:26 +0200
Subject: [PATCH 155/351] removed -Wunused

Rev: src/configure.in:1.12
---
 src/configure.in | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/configure.in b/src/configure.in
index 6e0b5ab994..1b30a57638 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -53,7 +53,7 @@ fi
 CFLAGS="$OLD_CFLAGS"
 
 if test "$GCC" = "yes"; then
-  WARN="-g -W -Wunused -Wformat"
+  WARN="-g -W -Wformat"
 
   AC_MSG_CHECKING(-pipe)
   AC_CACHE_VAL(lpc_cv_option_pipe,
@@ -230,6 +230,7 @@ AC_TYPE_SIGNAL
 AC_CHECK_TYPE(time_t,INT32)
 
 AC_CHECK_LIB(PW, alloca)
+AC_CHECK_LIB(crypt, crypt)
 AC_CHECK_LIB(m, floor)
 if test "${ac_cv_lib_m}" = "no" -a "${lpc_cv_sys_os}" = "Linux"; then
   AC_MSG_WARN(I will compensate for this by adding -lc -lm)
-- 
GitLab


From db077db35e79b083c18d85ac7697aae4922714d3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 13 May 1996 22:35:59 +0200
Subject: [PATCH 156/351] minor fix

Rev: src/modules/files/configure.in:1.6
---
 src/modules/files/configure.in | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/modules/files/configure.in b/src/modules/files/configure.in
index c026599a54..deb96b9132 100644
--- a/src/modules/files/configure.in
+++ b/src/modules/files/configure.in
@@ -9,7 +9,6 @@ AC_HAVE_HEADERS(arpa/inet.h sys/socketvar.h netinet/in.h \
  sys/stream.h sys/protosw.h)
 AC_HEADER_DIRENT
 AC_CHECK_LIB(socket, socket)
-AC_CHECK_LIB(crypt, crypt)
 if test "$ac_cv_lib_socket" = yes -o "${ac_cv_lib_ucb}" = yes; then
  AC_CHECK_LIB(nsl, main)
 fi
-- 
GitLab


From 96f750f59511d6132b8540000976905d4b27929c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 13 May 1996 22:37:23 +0200
Subject: [PATCH 157/351] new module

Rev: src/modules/gdbmmod/.cvsignore:1.1
Rev: src/modules/gdbmmod/Makefile.src:1.1
Rev: src/modules/gdbmmod/configure.in:1.1
Rev: src/modules/gdbmmod/doc/gdbm:1.1
Rev: src/modules/gdbmmod/gdbm_machine.h.in:1.1
Rev: src/modules/gdbmmod/gdbmmod.c:1.1
---
 src/modules/gdbmmod/.cvsignore        |   4 +
 src/modules/gdbmmod/.gitignore        |   4 +
 src/modules/gdbmmod/Makefile.src      |  19 ++
 src/modules/gdbmmod/configure.in      |  13 ++
 src/modules/gdbmmod/doc/gdbm          | 149 +++++++++++++
 src/modules/gdbmmod/gdbm_machine.h.in |   7 +
 src/modules/gdbmmod/gdbmmod.c         | 290 ++++++++++++++++++++++++++
 7 files changed, 486 insertions(+)
 create mode 100644 src/modules/gdbmmod/.cvsignore
 create mode 100644 src/modules/gdbmmod/.gitignore
 create mode 100644 src/modules/gdbmmod/Makefile.src
 create mode 100644 src/modules/gdbmmod/configure.in
 create mode 100644 src/modules/gdbmmod/doc/gdbm
 create mode 100644 src/modules/gdbmmod/gdbm_machine.h.in
 create mode 100644 src/modules/gdbmmod/gdbmmod.c

diff --git a/src/modules/gdbmmod/.cvsignore b/src/modules/gdbmmod/.cvsignore
new file mode 100644
index 0000000000..95cf939d53
--- /dev/null
+++ b/src/modules/gdbmmod/.cvsignore
@@ -0,0 +1,4 @@
+configure
+Makefile.in
+configure
+Makefile.in
diff --git a/src/modules/gdbmmod/.gitignore b/src/modules/gdbmmod/.gitignore
new file mode 100644
index 0000000000..3e601eb607
--- /dev/null
+++ b/src/modules/gdbmmod/.gitignore
@@ -0,0 +1,4 @@
+/configure
+/Makefile.in
+/configure
+/Makefile.in
diff --git a/src/modules/gdbmmod/Makefile.src b/src/modules/gdbmmod/Makefile.src
new file mode 100644
index 0000000000..8918ad4889
--- /dev/null
+++ b/src/modules/gdbmmod/Makefile.src
@@ -0,0 +1,19 @@
+SRCDIR=@srcdir@
+VPATH=@srcdir@:@srcdir@/../..:../..
+PREFLAGS=-I. -I$(SRCDIR) -I$(SRCDIR)/../.. -I../..
+CFLAGS=$(PREFLAGS) $(OTHERFLAGS)
+
+FILES=gdbmmod.o
+LIB=gdbmmod.a
+
+$(LIB): $(FILES)
+	-rm -f $(LIB)
+	ar cq $(LIB) $(FILES)
+	-@RANLIB@ $(LIB)
+	echo >linker_options @LIBS@
+
+clean:
+	-rm -f *.o *.a
+
+depend:
+	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)
diff --git a/src/modules/gdbmmod/configure.in b/src/modules/gdbmmod/configure.in
new file mode 100644
index 0000000000..95e44af3ea
--- /dev/null
+++ b/src/modules/gdbmmod/configure.in
@@ -0,0 +1,13 @@
+AC_INIT(gdbmmod.c)
+AC_CONFIG_HEADER(gdbm_machine.h)
+
+AC_PROG_CC
+AC_PROG_RANLIB
+AC_SUBST(RANLIB)
+
+AC_CHECK_HEADERS(gdbm.h)
+AC_CHECK_LIB(gdbm, gdbm_open)
+
+AC_OUTPUT(Makefile,echo FOO >stamp-h )
+
+
diff --git a/src/modules/gdbmmod/doc/gdbm b/src/modules/gdbmmod/doc/gdbm
new file mode 100644
index 0000000000..1811ac0486
--- /dev/null
+++ b/src/modules/gdbmmod/doc/gdbm
@@ -0,0 +1,149 @@
+NAME
+	/precompiled/gdbm - database interface
+
+DESCRIPTION
+	This is the an interface to the gdbm library. This module might or
+	might not be available in your uLPC depending on weather gdbm was
+	available when uLPC was compiled.
+
+	A gdbm database has essentially the same functionality as a mapping,
+	except the syntax is different, and it is located on disk, not in
+	memory. Each gdbm database is one file which contains a set of
+	key-value pairs. Both keys and values are strings and all keys are
+	unique.
+
+============================================================================
+NAME
+	create - open database
+
+SYNTAX
+	int gdbm->create();
+	or
+	int gdbm->create(string file);
+	or
+	int gdbm->create(string file, string mode);
+
+DESCRIPTION
+	Without arguments, this function does nothing. With one argument it
+	opens the given file as a gdbm database, if this fails for some
+	reason, an error will be generated. If a second argument is present,
+	it specifies how to open the database using one or more of the follow
+	flags in a string:
+
+	r	open database for reading
+	w	open database for writing
+	c	create database if it does not exist
+	t	overwrite existing database
+	f	fast mode
+
+	The fast mode prevents the database from syncronizing each change
+	in the database immediately. This is dangerous because the database
+	can be left in an unusable state if uLPC is terminated abnormally.
+
+	The default mode is "rwc".
+
+NOTA BENE
+	The gdbm manual states that it is important that the database is
+	closed properly. Unfortunately this will not be the case if uLPC
+	calls exit() or returns from main(). You should therefore make sure
+	you call close or destruct your gdbm objects when exiting your
+	program. This will probably be done automatically in the future.
+
+============================================================================
+NAME
+	close - close database
+
+SYNTAX
+	void gdbm->close();
+
+DESCRIPTION
+	This closes the database.
+
+============================================================================
+NAME
+	store - store a value in the database
+
+SYNTAX
+	int gdbm->store(string key, string data);
+
+DESCRIPTION
+	Associate the contents of 'data' with the key 'key'. If the key 'key'
+	already exists in the database the data for that key will be replaced.
+	If it does not exist it will be added. An error will be generated if
+	the database was not open for writing.
+
+============================================================================
+NAME
+	fetch - fetch a value from the databse
+
+SYNTAX
+	string gdbm->fetch(string key);
+
+DESCRIPTION
+	Return the data associated with the key 'key' in the database.
+	If there was no such key in the database, zero is returned.
+
+============================================================================
+NAME
+	delete - delete a value from the database
+
+SYNTAX
+	int gdbm->delete(string key);
+
+DESCRIPTION
+	Remove a key from the database. Note that no error will be generated
+	if the key does not exist.
+
+============================================================================
+NAME
+	firstkey - get first key in database
+
+SYNTAX
+	string gdbm->firstkey();
+
+DESCRIPTION
+	Return the first key in the database, this can be any key in the
+	database.
+
+============================================================================
+NAME
+	nextkey - get next key in database
+
+SYNTAX
+	string gdbm->nextkey(string key);
+
+DESCRIPTION
+	This returns the key in database that follows the key 'key' key.
+	This is of course used to iterate over all keys in the database.
+
+EXAMPLE
+	/* Write the contents of the database */
+	for(key=gdbm->firstkey(); k; k=gdbm->nextkey(k))
+	  write(k+":"+gdbm->fetch(k)+"\n");
+
+============================================================================
+NAME
+	reorganize - reorganize database
+
+SYNTAX
+	int gdbm->reorganize();
+
+DESCRIPTION
+	Deletions and insertions into the database can cause fragmentation
+	which will make the database bigger. This routine reorganizes the
+	contents to get rid of fragmentation. Note however that this function
+	can take a LOT of time to run.
+
+============================================================================
+NAME
+	sync - synchronize database
+
+SYNTAX
+	void gdbm->sync();
+
+DESCRIPTION
+	When opening the database with the 'f' flag writings to the database
+	can be cached in memory for a long time. Calling sync will write
+	all such caches to disk and not return until 
+
+============================================================================
diff --git a/src/modules/gdbmmod/gdbm_machine.h.in b/src/modules/gdbmmod/gdbm_machine.h.in
new file mode 100644
index 0000000000..eb025a8fc0
--- /dev/null
+++ b/src/modules/gdbmmod/gdbm_machine.h.in
@@ -0,0 +1,7 @@
+#ifndef GDBM_MACHINE_H
+#define GDBM_MACHINE_H
+
+/* Define this if you have <gdbm.h> */
+#undef HAVE_GDBM_H
+
+#endif
diff --git a/src/modules/gdbmmod/gdbmmod.c b/src/modules/gdbmmod/gdbmmod.c
new file mode 100644
index 0000000000..0510cb8d3a
--- /dev/null
+++ b/src/modules/gdbmmod/gdbmmod.c
@@ -0,0 +1,290 @@
+/*\
+||| This file a part of uLPC, and is copyright by Fredrik Hubinette
+||| uLPC is distributed as GPL (General Public License)
+||| See the files COPYING and DISCLAIMER for more information.
+\*/
+#include "global.h"
+#include "gdbm_machine.h"
+#include "types.h"
+
+#ifdef HAVE_GDBM_H
+
+#include "interpret.h"
+#include "svalue.h"
+#include "stralloc.h"
+#include "array.h"
+#include "object.h"
+#include "macros.h"
+
+#include <gdbm.h>
+
+struct gdbm_glue
+{
+  GDBM_FILE dbf;
+};
+
+#define THIS ((struct gdbm_glue *)(fp->current_storage))
+
+static void do_free()
+{
+  if(THIS->dbf)
+  {
+    gdbm_close(THIS->dbf);
+    THIS->dbf=0;
+  }
+}
+
+static int fixmods(char *mods)
+{
+  int mode;
+  mode=0;
+  while(1)
+  {
+    switch(*(mods++))
+    {
+    case 0:
+      switch(mode & 15)
+      {
+      default: error("No mode given for gdbm->open()\n"); 
+      case 1|16:
+      case 1: mode=GDBM_READER; break;
+      case 3: mode=GDBM_WRITER; break;
+      case 3|16: mode=GDBM_WRITER | GDBM_FAST; break;
+      case 7: mode=GDBM_WRCREAT; break;
+      case 7|16: mode=GDBM_WRCREAT | GDBM_FAST; break;
+      case 15: mode=GDBM_NEWDB; break;
+      case 15|16: mode=GDBM_NEWDB | GDBM_FAST; break;
+      }
+      return mode;
+
+    case 'r': case 'R': mode|=1;  break;
+    case 'w': case 'W': mode|=3;  break;
+    case 'c': case 'C': mode|=7;  break;
+    case 't': case 'T': mode|=15; break;
+    case 'f': case 'F': mode|=16; break;
+
+    default:
+      error("Bad mode flag in gdbm->open.\n");
+    }
+  }
+}
+
+void gdbmmod_fatal(char *err)
+{
+  error("GDBM: %s\n",err);
+}
+
+static void gdbmmod_create(INT32 args)
+{
+  do_free();
+  if(args)
+  {
+    int rwmode = GDBM_WRCREAT;
+    if(sp[-args].type != T_STRING)
+      error("Bad argument 1 to gdbm->create()\n");
+
+    if(args>1)
+    {
+      if(sp[1-args].type != T_STRING)
+	error("Bad argument 2 to gdbm->create()\n");
+
+      rwmode=fixmods(sp[1-args].u.string->str);
+    }
+
+    THIS->dbf=gdbm_open(sp[-args].u.string->str, 512, rwmode, 00666, gdbmmod_fatal);
+    pop_n_elems(args);
+    if(!THIS->dbf)
+      error("Failed to open GDBM database.\n");
+  }
+}
+
+#define STRING_TO_DATUM(dat, st) dat.dptr=st->str,dat.dsize=st->len;
+#define DATUM_TO_STRING(dat) make_shared_binary_string(dat.dptr, dat.dsize)
+
+static void gdbmmod_fetch(INT32 args)
+{
+  datum key,ret;
+  if(!args)
+    error("Too few arguments to gdbm->fetch()\n");
+
+  if(sp[-args].type != T_STRING)
+    error("Bad argument 1 to gdbm->fetch()\n");
+
+  if(!THIS->dbf)
+    error("GDBM database not open.\n");
+
+  STRING_TO_DATUM(key, sp[-args].u.string);
+
+  ret=gdbm_fetch(THIS->dbf, key);
+  pop_n_elems(args);
+  if(ret.dptr)
+  {
+    push_string(DATUM_TO_STRING(ret));
+    free(ret.dptr);
+  }else{
+    push_int(0);
+  }
+}
+
+static void gdbmmod_delete(INT32 args)
+{
+  datum key;
+  int ret;
+  if(!args)
+    error("Too few arguments to gdbm->delete()\n");
+
+  if(sp[-args].type != T_STRING)
+    error("Bad argument 1 to gdbm->delete()\n");
+
+  if(!THIS->dbf)
+    error("GDBM database not open.\n");
+
+  STRING_TO_DATUM(key, sp[-args].u.string);
+
+  ret=gdbm_delete(THIS->dbf, key);
+  pop_n_elems(args);
+  push_int(0);
+}
+
+static void gdbmmod_firstkey(INT32 args)
+{
+  datum ret;
+  pop_n_elems(args);
+
+  if(!THIS->dbf) error("GDBM database not open.\n");
+
+  ret=gdbm_firstkey(THIS->dbf);
+  if(ret.dptr)
+  {
+    push_string(DATUM_TO_STRING(ret));
+    free(ret.dptr);
+  }else{
+    push_int(0);
+  }
+}
+
+static void gdbmmod_nextkey(INT32 args)
+{
+  datum key,ret;
+  if(!args)
+    error("Too few arguments to gdbm->nextkey()\n");
+
+  if(sp[-args].type != T_STRING)
+    error("Bad argument 1 to gdbm->nextkey()\n");
+
+  if(!THIS->dbf)
+    error("GDBM database not open.\n");
+
+  STRING_TO_DATUM(key, sp[-args].u.string);
+
+  ret=gdbm_nextkey(THIS->dbf, key);
+  pop_n_elems(args);
+  if(ret.dptr)
+  {
+    push_string(DATUM_TO_STRING(ret));
+    free(ret.dptr);
+  }else{
+    push_int(0);
+  }
+}
+
+static void gdbmmod_store(INT32 args)
+{
+  datum key,data;
+  int ret;
+  if(args<2)
+    error("Too few arguments to gdbm->store()\n");
+
+  if(sp[-args].type != T_STRING)
+    error("Bad argument 1 to gdbm->store()\n");
+
+  if(sp[1-args].type != T_STRING)
+    error("Bad argument 2 to gdbm->store()\n");
+
+  if(!THIS->dbf)
+    error("GDBM database not open.\n");
+
+  STRING_TO_DATUM(key, sp[-args].u.string);
+  STRING_TO_DATUM(data, sp[-args].u.string);
+
+  ret=gdbm_store(THIS->dbf, key, data, GDBM_REPLACE);
+  if(ret == -1)
+    error("GDBM database not open for writing.\n");
+
+  pop_n_elems(args);
+  push_int(ret == 0);
+}
+
+static void gdbmmod_reorganize(INT32 args)
+{
+  datum ret;
+  pop_n_elems(args);
+
+  if(!THIS->dbf) error("GDBM database not open.\n");
+  ret=gdbm_firstkey(THIS->dbf);
+  pop_n_elems(args);
+  if(ret.dptr)
+  {
+    push_string(DATUM_TO_STRING(ret));
+    free(ret.dptr);
+  }else{
+    push_int(0);
+  }
+}
+
+static void gdbmmod_sync(INT32 args)
+{
+  pop_n_elems(args);
+
+  if(!THIS->dbf) error("GDBM database not open.\n");
+  gdbm_sync(THIS->dbf);
+  push_int(0);
+}
+
+static void gdbmmod_close(INT32 args)
+{
+  pop_n_elems(args);
+
+  do_free(THIS->dbf);
+  push_int(0);
+}
+
+static void init_gdbm_glue(char *foo, struct object *o)
+{
+  THIS->dbf=0;
+}
+
+static void exit_gdbm_glue(char *foo, struct object *o)
+{
+  do_free();
+}
+
+#endif
+
+void init_gdbmmod_efuns(void) {}
+void exit_gdbmmod(void) {}
+
+void init_gdbmmod_programs(void)
+{
+#ifdef HAVE_GDBM_H
+  start_new_program();
+  add_storage(sizeof(struct gdbm_glue));
+  
+  add_function("create",gdbmmod_create,"function(void|string:void)",0);
+
+  add_function("close",gdbmmod_close,"function(:void)",0);
+  add_function("store",gdbmmod_store,"function(string,string:int)",0);
+  add_function("fetch",gdbmmod_fetch,"function(string:string)",0);
+  add_function("delete",gdbmmod_delete,"function(string:int)",0);
+  add_function("firstkey",gdbmmod_firstkey,"function(:string)",0);
+  add_function("nextkey",gdbmmod_nextkey,"function(string:string)",0);
+  add_function("reorganize",gdbmmod_reorganize,"function(:int)",0);
+  add_function("sync",gdbmmod_sync,"function(:void)",0);
+
+  set_init_callback(init_gdbm_glue);
+  set_exit_callback(exit_gdbm_glue);
+
+  end_c_program("/precompiled/gdbm");
+#endif
+}
+
-- 
GitLab


From 8db8da90ddaa285754c57f33883bc82f37957cdc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 13 May 1996 22:45:37 +0200
Subject: [PATCH 158/351] bugfix

Rev: src/svalue.c:1.10
---
 src/svalue.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/svalue.c b/src/svalue.c
index 3c75166201..0cc24edc8c 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -654,6 +654,8 @@ TYPE_FIELD gc_check_svalues(struct svalue *s, int num)
 	gc_check(s->u.object);
       }else{
 	free_svalue(s);
+	s->type=T_INT;
+	s->u.integer=0;
       }
       break;
 
@@ -680,6 +682,7 @@ void gc_check_short_svalue(union anything *u, TYPE_T type)
       gc_check(u->object);
     }else{
       free_short_svalue(u,T_OBJECT);
+      u->object=0;
     }
     break;
 
@@ -713,6 +716,8 @@ void gc_mark_svalues(struct svalue *s, int num)
 	gc_mark_object_as_referenced(s->u.object);
       }else{
 	free_svalue(s);
+	s->type=T_INT;
+	s->u.integer=0;
       }
       break;
     }
@@ -735,6 +740,7 @@ void gc_mark_short_svalue(union anything *u, TYPE_T type)
       gc_mark_object_as_referenced(u->object);
     }else{
       free_short_svalue(u,T_OBJECT);
+      u->object=0;
     }
     break;
   }
-- 
GitLab


From a781d3eaded973b86e944990cfbdf781e5a4450c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 13 May 1996 22:47:53 +0200
Subject: [PATCH 159/351] More entries

Rev: src/ChangeLog:1.34
---
 src/ChangeLog | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index cd89b849a4..b3c3954b0a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+Mon May 13 22:20:24 1996  Fredrik Hubinette  <hubbe@axel.signum.se>
+
+	* -Wunused removed
+	* new module: gdbmmod
+	* svalue.c: bug in garbage collect fixed
+
 Fri May  3 13:50:05 1996  Fredrik Hubinette  <hubbe@freeone.signum.se>
 
 	* las.c: type-checking improved
-- 
GitLab


From a746024ee35bf724808d7cc871039d80eb58a6a0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 16 May 1996 00:54:23 +0200
Subject: [PATCH 160/351] script to test EVERYTHING

Rev: bin/metatest:1.1
---
 bin/metatest | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100755 bin/metatest

diff --git a/bin/metatest b/bin/metatest
new file mode 100755
index 0000000000..5daa5c9df3
--- /dev/null
+++ b/bin/metatest
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+SRCPATH=`dirname $0`
+SRCPATH=`dirname $SRCPATH`
+
+case $SRCPATH in
+  /*) ;;
+  *) SRCPATH=`pwd`/$SRCPATH ;;
+esac
+
+set -e
+set -x
+
+docompile() {
+  mkdir test1
+  cd test1
+  $SRCPATH/src/configure --cache-file ../testcache
+  make "$1"
+  make verify "$1"
+  make verify LPCOPTS=-d2 "$1"
+  cd ..
+  rm -rf test1
+}
+
+docompile2() {
+  docompile DEBUGDEF="$1 -DDEBUG"
+  docompile DEBUGDEF="$1"
+}
+
+docompile3() {
+  docompile2 "$1 -DALWAYS_GC"
+  docompile2 "$1 -DNO_GC"
+  docompile2 "$1"
+}
+
+docompile3
+rm testcache
-- 
GitLab


From 1d09a17e54e7882311214e2027303dd6f1c38250 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 16 May 1996 00:52:50 +0200
Subject: [PATCH 161/351] typo fixed

Rev: doc/manual/example1:1.5
Rev: doc/manual/example2:1.3
Rev: doc/manual/example3:1.3
Rev: doc/operators/logical_and:1.2
---
 doc/manual/example1       | 4 ++--
 doc/manual/example2       | 2 +-
 doc/manual/example3       | 2 +-
 doc/operators/logical_and | 1 -
 4 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/doc/manual/example1 b/doc/manual/example1
index f86b5bfcf9..fac03d5f11 100644
--- a/doc/manual/example1
+++ b/doc/manual/example1
@@ -126,9 +126,9 @@
   other than zero. Otherwise what's between the second set of brackets will
   be executed. Let's look at that expression:
 
-	argc > 2 && argv[1] == "--traditional"
+	argc > 1 && argv[1] == "--traditional"
 
-  Loosely translated, this means: argc is greater than two and the second
+  Loosely translated, this means: argc is greater than one and the second
   element in the array argv is equal to the string "--traditional".
 
   Also note the comments:
diff --git a/doc/manual/example2 b/doc/manual/example2
index 11fffb14b1..121572f8fc 100644
--- a/doc/manual/example2
+++ b/doc/manual/example2
@@ -114,7 +114,7 @@
 
 		file_contents=replace(file_contents,argv[1],argv[2]);
 
-  Call the builtin function replace and replace oall occurances of the 'from'
+  Call the builtin function replace and replace all occurances of the 'from'
   string with the 'to' string and assign the new result to the variable
   'file_contents'.
 
diff --git a/doc/manual/example3 b/doc/manual/example3
index 0d9552a40a..1ec71ccf09 100644
--- a/doc/manual/example3
+++ b/doc/manual/example3
@@ -64,7 +64,7 @@
 
 	  int offset=0;
 
-  Then ther is a global variable called offset which is initalized to zero.
+  Then there is a global variable called offset which is initalized to zero.
   (each instance of this class will have it's own instance of this variable,
    so it is not truly global, but..) 
   Note that the initalization is done when the class is cloned. (or
diff --git a/doc/operators/logical_and b/doc/operators/logical_and
index 9232678f5b..fcd4f4d037 100644
--- a/doc/operators/logical_and
+++ b/doc/operators/logical_and
@@ -10,7 +10,6 @@ DESCRIPTION
 	evaluates a and returns zero if a is zero. Otherwise it returns
 	b. Note that b is not evaluated at all if a returns zero.
 
-
 KEYWORDS
 	operators
 
-- 
GitLab


From ca2437d26ff989bbe376586c363e9f5648363491 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 16 May 1996 00:54:09 +0200
Subject: [PATCH 162/351] module docs moved to module dirs

Rev: bin/htmlify_docs.lpc:1.11
---
 bin/htmlify_docs.lpc | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/bin/htmlify_docs.lpc b/bin/htmlify_docs.lpc
index 736f46f071..cfe1b84f57 100644
--- a/bin/htmlify_docs.lpc
+++ b/bin/htmlify_docs.lpc
@@ -708,7 +708,7 @@ void traversedir(string path)
 
     if(file_size(tmp)==-2)
     {
-      traversedir(tmp,fun);
+      traversedir(tmp);
     }else{
       scanfiles(tmp,file);
     }
@@ -718,6 +718,7 @@ void traversedir(string path)
 void dodocs(string path, int module)
 {
   cd(path);
+  perror("Doing "+path+"\n");
   if(!module)
   {
     docdir="";
@@ -744,6 +745,8 @@ int main(int argc, string *argv)
     exit(0);
   }
 
+//  perror(sprintf("argv = %O\n",argv));
+
   megamagic::create("^(.*)&lt;([a-z_0-9]+)&gt;(.*)$");
   lastident::create("^(.*[^<>a-z_0-9])([a-z_0-9]+)([^<>a-z_0-9]*)$");
 
@@ -758,6 +761,8 @@ int main(int argc, string *argv)
   for(e=1;e<sizeof(argv);e++)
     argv[e]=combine_path(getcwd(),argv[e]);
 
+  new_path=argv[1];
+
   write("Scanning pages for links and keywords.\n");
   writepages=0;
   for(e=2;e<sizeof(argv);e++) dodocs(argv[e],e-2);
-- 
GitLab


From 8ce9ada0336d380a3a5f2f33467a3fce7e2c75a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 16 May 1996 00:54:52 +0200
Subject: [PATCH 163/351] updated

Rev: src/README:1.3
---
 src/README | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/README b/src/README
index 5a1d0864b4..6463e7e4ec 100644
--- a/src/README
+++ b/src/README
@@ -19,6 +19,10 @@ This is what you need to do to install uLPC:
 
 5) If you want to install ulpc, write 'make install'
 
+6) Optionally do 'make html_docs' to create a directory called docs which
+   will contain the uLPC documentation in html. This directory can then
+   be copied to anywhere you want.
+
 What to do when it doesn't work:
 1) Try again.
 
-- 
GitLab


From a67f2f25b7ef43647e8116fce8ec490c9e767e2c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 16 May 1996 00:55:29 +0200
Subject: [PATCH 164/351] added conditinal tests

Rev: src/test/test_lpc.lpc:1.2
---
 src/test/test_lpc.lpc | 39 ++++++++++++++++++++++++++++++---------
 1 file changed, 30 insertions(+), 9 deletions(-)

diff --git a/src/test/test_lpc.lpc b/src/test/test_lpc.lpc
index 5a8419f099..58b63477e5 100755
--- a/src/test/test_lpc.lpc
+++ b/src/test/test_lpc.lpc
@@ -9,7 +9,17 @@ int main(int argc, string *argv)
 
   for(e=1;e<argc;e++)
   {
-    switch(argv[e])
+    string opt;
+    int arg;
+    arg=1;
+    if(sscanf(argv[e],"--%s=%d",opt,arg)==2)
+      opt="--"+opt;
+    else if(sscanf(argv[e],"-%s%d",opt,arg)==2)
+      opt="-"+opt;
+    else
+      opt=argv[e];
+    
+    switch(opt)
     {
       case "-h":
       case "--help":
@@ -18,30 +28,29 @@ int main(int argc, string *argv)
 
       case "-v":
       case "--verbose":
-        verbose++;
+        verbose+=arg;
         break;
 
       case "-s":
       case "--start-test":
-	sscanf(argv[++e],"%d",start);
+	start=arg;
 	start--;
 	break;
 
       case "-f":
       case "--fail":
-	fail++;
+	fail+=arg;
 	break;
 
-
       case "-t":
       case "--trace":
-	t++;
+	t+=arg;
 	break;
 
       default:
 	if(tests)
 	{
-	  perror("Uknown argument: "+argv[e]+".\n");
+	  perror("Uknown argument: "+opt+".\n");
 	  exit(1);
 	}
 	tests=(read_bytes(argv[e])||"")/"\n....\n";
@@ -56,12 +65,24 @@ int main(int argc, string *argv)
 
   for(e=start;e<sizeof(tests);e++)
   {
-    string test;
+    string test,condition;
     int type;
     object o;
     mixed a,b;
 
-    sscanf(tests[e],"%s\n%s",type,test);
+    test=tests[e];	
+    if(sscanf(test,"COND %s\n%s",condition,test)==2)
+    {
+      if(!clone(compile_string("mixed c() { return "+condition+"; }","Cond "+(e+1)))->c())
+      {
+	if(verbose)
+	  perror("Not doing test "+(e+1)+"\n");
+	successes++;
+	continue;
+      }
+    }
+ 
+    sscanf(test,"%s\n%s",type,test);
     sscanf(type,"%*s expected result: %s",type);
 
     if(verbose)
-- 
GitLab


From 920d68bedc2e11ad430b0777c294fb4740c76854 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 16 May 1996 00:56:12 +0200
Subject: [PATCH 165/351] added tests for gdbm module

Rev: src/test/create_testsuite:1.16
---
 src/test/create_testsuite | 71 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 68 insertions(+), 3 deletions(-)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 7542de3d61..60210691d6 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -8,11 +8,12 @@ changequote([[,]])
 changecom
 
 define(SEPARATOR,[[....]])
+define(CONDITION,[[]])
 
 define(DOTEST,[[dnl
 divert(0)dnl
 define([[TESTNO]],incr(TESTNO))dnl
-test TESTNO, expected result: [[$1]]
+CONDITION()test TESTNO, expected result: [[$1]]
 [[$2]]
 SEPARATOR
 divert(-1)dnl]])
@@ -55,6 +56,14 @@ void a() { master()->add_precompiled_program("[[$1]]",class {
 define(test_program, [[DOTEST(TRUE,dnl
 [[$1]])]])
 
+define(cond,[[
+define([[CONDITION]],[[COND $1
+]])
+$2
+define([[CONDITION]],[[]])
+]])
+define(ifefun,[[cond([[all_efuns()->$1]],[[$2]])]])
+
 define(TESTNO,0)
 
 test_compile_error_low(master()->add_precompiled_program(\"/test\",compile_string(\"int foo() { return 17; }\",\"62\")))
@@ -64,8 +73,64 @@ test_compile([[while(0)if(0)continue;else;]])
 test_program([[int b=1,c; int a() { c=b+2; return c==3; }]])
 test_true([[ ("foobar"/"o") & ({ "foo" }) ]])
 test_any([[ array a="foo bar"/" "; return sizeof(a & ({"foo"}))]],1)
-test_true(intp(gc()));
-test_any([[ gc(); array a=({0}); a[0]=a; a=0; return gc() > 0; ]],1);
+
+// gc
+ifefun(gc,
+[[
+  test_true(intp(gc()));
+  test_any([[ gc(); array a=({0}); a[0]=a; a=0; return gc() > 0; ]],1);
+]])
+
+// gdbm
+cond( [[ master()->programs["/precompiled/gdbm"] ]],
+[[
+  define([[GDBM]],[[ (program)"/precompiled/gdbm" ]])
+  test_true(programp(GDBM))
+  test_do(destruct(clone(GDBM)))
+
+  define([[GDBMTESTS]],
+  [[
+    test_do(rm("test.gdbm"))
+    test_do(add_efun("GDBMBASE",clone(GDBM,"test.gdbm")))
+    test_true(file_stat("test.gdbm"))
+
+    GDBMNULLTEST
+    test_true(GDBMBASE->store("foo","bar"))
+    GDBMNULLTEST
+    test_equal(GDBMBASE->fetch("foo"),"bar")
+    test_do([[int e; for(e=0;e<1000;e++) GDBMBASE->store("x"+e,"y"+e)]])
+    GDBMNULLTEST
+    test_any(int e; for(e=0;e<1000;e++) if(GDBMBASE->fetch("x"+e)!="y"+e) return e; return -1,-1)
+    GDBMNULLTEST
+    test_true(GDBMBASE->store(sprintf("%'23'100000s",""),sprintf("%'32'100000s","")))
+    test_true(GDBMBASE->fetch(sprintf("%'23'100000s",""))==sprintf("%'32'100000s",""))
+    GDBMNULLTEST
+    test_equal(GDBMBASE->fetch("foo"),"bar")
+    test_any(int e; for(e=0;e<1000;e++) if(GDBMBASE->fetch("x"+e)!="y"+e) return e; return -1,-1)
+    test_true(GDBMBASE->fetch(sprintf("%'23'100000s",""))==sprintf("%'32'100000s",""))
+    test_any(int e; string k; for(k=GDBMBASE->firstkey();k;k=GDBMBASE->nextkey(k)) e++; return e,1002)
+
+    test_do(GDBMBASE->sync())
+    test_do(GDBMBASE->reorganize())
+    test_do(GDBMBASE->close())
+  ]])
+
+  define([[GDBMNULLTEST]],[[
+    test_false(GDBMBASE->fetch("slakjdfasdf"))
+  ]])
+
+  GDBMTESTS
+
+  define([[GDBMNULLTEST]],[[
+    test_false(GDBMBASE->fetch("slakjdfasdf"))
+    test_do(GDBMBASE->reorganize())
+    test_do(GDBMBASE->sync())
+    test_do(GDBMBASE->close())
+    test_do(GDBMBASE->create("test.gdbm"))
+  ]])
+
+  GDBMTESTS
+]])
 
 test_eq("\377"[0],255)
 test_do(add_efun("foo",clone(class {int i;})))
-- 
GitLab


From bb2fc1270a4182d0bdb602067ab93c238f7cae7f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 16 May 1996 00:57:09 +0200
Subject: [PATCH 166/351] lots of small changes

Rev: src/Makefile.src:1.4
---
 src/Makefile.src | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/Makefile.src b/src/Makefile.src
index 58499830a9..931e4e12b7 100644
--- a/src/Makefile.src
+++ b/src/Makefile.src
@@ -43,7 +43,8 @@ WARN=@WARN@
 
 #add extra defines here
 # Be sure to use -g and -DDEBUG when looking for bugs
-DEFINES=-DDEBUG -DDEFAULT_MASTER=\"$(lib_prefix)/master.lpc\"
+DEBUGDEF=-DDEBUG
+DEFINES=$(DEBUGDEF) -DDEFAULT_MASTER=\"$(lib_prefix)/master.lpc\"
 
 # -O should work with all compilers
 OPTIMIZE=@OPTIMIZE@
@@ -59,7 +60,7 @@ CPP=@CPP@
 LD=$(CC)
 LDFLAGS=$(CFLAGS)
 
-RUNULPC=$(TMP_BUILDDIR)/ulpc -m $(TMP_LIBDIR)/master.lpc
+RUNULPC=$(TMP_BUILDDIR)/ulpc -m $(TMP_LIBDIR)/master.lpc $(LPCOPTS)
 FIXDEP=$(TMP_BINDIR)/fixdepends.sh
 
 MAKE_FLAGS = "prefix=$(prefix)" "exex_prefix=$(exex_prefix)" "CC=$(CC)" "OTHERFLAGS=$(OTHERFLAGS)" "FIXDEP=$(FIXDEP)"
@@ -188,7 +189,7 @@ docs:
 	mkdir docs
 
 html_docs: docs
-	$(RUNULPC) $(TMP_BINDIR)/htmlify_docs docs $(TMP_DOCDIR) `for a in $MODULES); do echo $(SRCDIR)/$$a ; done`
+	$(RUNULPC) $(TMP_BINDIR)/htmlify_docs docs $(TMP_DOCDIR) `for a in $(MODULES); do echo $(SRCDIR)/$$a/doc ; done`
 
 #
 # uLPC internal targets
-- 
GitLab


From c5d981cb0cd587084ace73ab42ec74d2fa987755 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 16 May 1996 00:58:58 +0200
Subject: [PATCH 167/351] minor changes

Rev: src/builtin_efuns.c:1.17
Rev: src/config.h:1.4
---
 src/builtin_efuns.c | 6 ++++++
 src/config.h        | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index 64ea863c98..c0229c9cc0 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -351,11 +351,13 @@ void f_backtrace(INT32 args)
 	ITEM(i)[0].subtype=NUMBER_NUMBER;
 	ITEM(i)[0].type=T_INT;
       }
+      i->type_field = BIT_FUNCTION | BIT_INT | BIT_STRING;
     }else{
       ITEM(a)[frames].type=T_INT;
       ITEM(a)[frames].u.integer=0;
     }
   }
+  a->type_field = BIT_ARRAY | BIT_INT;
 }
 
 void f_add_efun(INT32 args)
@@ -1202,6 +1204,7 @@ void f_sleep(INT32 args)
   }
 }
 
+#ifdef GC2
 void f_gc(INT32 args)
 {
   INT32 tmp;
@@ -1210,6 +1213,7 @@ void f_gc(INT32 args)
   do_gc();
   push_int(tmp - num_objects);
 }
+#endif
 
 #ifdef TYPEP
 #undef TYPEP
@@ -1295,7 +1299,9 @@ void init_builtin_efuns()
   add_efun("upper_case",f_upper_case,"function(string:string)",0);
   add_efun("values",f_values,"function(string|list:int*)|function(array|mapping|object:mixed*)",0);
   add_efun("zero_type",f_zero_type,"function(int:int)",0);
+#ifdef GC2
   add_efun("gc",f_gc,"function(:int)",OPT_SIDE_EFFECT);
+#endif
 }
 
 
diff --git a/src/config.h b/src/config.h
index d905a755de..6fccd9fecb 100644
--- a/src/config.h
+++ b/src/config.h
@@ -36,7 +36,9 @@
 /*
  * Undefine this to disable garabge collection
  */
+#ifndef NO_GC
 #define GC2
+#endif
    
 
 /*
-- 
GitLab


From 6b92163835463553ed9740dfd7798a667978c07b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 16 May 1996 00:59:27 +0200
Subject: [PATCH 168/351] removed a warning

Rev: src/error.c:1.5
Rev: src/gc.c:1.4
---
 src/error.c | 2 +-
 src/gc.c    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/error.c b/src/error.c
index b027f8d6c8..c99d9a9243 100644
--- a/src/error.c
+++ b/src/error.c
@@ -91,7 +91,7 @@ void va_error(char *fmt, va_list args)
     abort();
   }
 
-  if(strlen(buf) >= sizeof(buf))
+  if((long)strlen(buf) >= (long)sizeof(buf))
     fatal("Buffer overflow in error()\n");
   
   push_string(make_shared_string(buf));
diff --git a/src/gc.c b/src/gc.c
index e2ca81baa8..8fa6e26bd5 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -167,7 +167,7 @@ static INT32 hashprimes[] =
   2147483647,/* ~ 2^31 = 2147483648 */
 };
 
-void do_gc()
+void do_gc(void)
 {
   double tmp;
   INT32 tmp2;
-- 
GitLab


From e3c6e1dd57c4a6f1cff2d003208ca81eb696ebf9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 16 May 1996 00:59:39 +0200
Subject: [PATCH 169/351] more debug added

Rev: src/array.c:1.11
Rev: src/array.h:1.7
Rev: src/gc.h:1.3
---
 src/array.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 src/array.h |  1 +
 src/gc.h    | 21 ++++++------
 3 files changed, 98 insertions(+), 17 deletions(-)

diff --git a/src/array.c b/src/array.c
index 512914eb68..39fb8928e3 100644
--- a/src/array.c
+++ b/src/array.c
@@ -17,6 +17,7 @@
 #include "builtin_efuns.h"
 #include "memory.h"
 #include "gc.h"
+#include "main.h"
 
 struct array empty_array=
 {
@@ -26,7 +27,6 @@ struct array empty_array=
   0,                     /* Size = 0 */
   0,                     /* malloced Size = 0 */
   0,                     /* no types */
-  T_MIXED,                 /* mixed array */
 };
 
 
@@ -56,7 +56,7 @@ struct array *low_allocate_array(INT32 size,INT32 extra_space)
   
 
   /* for now, we don't know what will go in here */
-  v->type_field=BIT_MIXED;
+  v->type_field=BIT_MIXED | BIT_UNFINISHED;
 
   v->malloced_size=size+extra_space;
   v->size=size;
@@ -185,7 +185,7 @@ void array_set_index(struct array *v,INT32 index, struct svalue *s)
   v->refs++;
   check_destructed(s);
 
-  v->type_field |= 1 << s->type;
+  v->type_field = (v->type_field & ~BIT_UNFINISHED) | 1 << s->type;
   assign_svalue( ITEM(v) + index, s);
   free_array(v);
 }
@@ -264,11 +264,13 @@ static struct array *resize_array(struct array *a, INT32 size)
 	ITEM(a)[a->size].subtype=NUMBER_NUMBER;
 	ITEM(a)[a->size].u.integer=0;
       }
+      a->type_field |= BIT_INT;
       return a;
     }else{
       struct array *ret;
       ret=allocate_array_no_init(size, (size>>3)+1);
       MEMCPY(ITEM(ret),ITEM(a),sizeof(struct svalue)*a->size);
+      ret->type_field = a->type_field | BIT_INT;
       a->size=0;
       free_array(a);
       return ret;
@@ -371,6 +373,10 @@ INT32 array_search(struct array *v, struct svalue *s,INT32 start)
   check_destructed(s);
 
   /* Why search for something that is not there? */
+#ifdef DEBUG
+    if(d_flag > 1)  array_check_type_field(v);
+#endif
+
   if(v->type_field & (1 << s->type))
   {
     TYPE_FIELD t=0;
@@ -437,6 +443,9 @@ void check_array_for_destruct(struct array *v)
   INT16 types;
 
   types = 0;
+#ifdef DEBUG
+  if(d_flag > 1)  array_check_type_field(v);
+#endif
   if(v->type_field & (BIT_OBJECT | BIT_FUNCTION))
   {
     for(e=0; e<v->size; e++)
@@ -468,6 +477,9 @@ INT32 array_find_destructed_object(struct array *v)
 {
   INT32 e;
   TYPE_FIELD types;
+#ifdef DEBUG
+  if(d_flag > 1)  array_check_type_field(v);
+#endif
   if(v->type_field & (BIT_OBJECT | BIT_FUNCTION))
   {
     types=0;
@@ -604,6 +616,9 @@ static INT32 low_lookup(struct array *v,
 
 INT32 set_lookup(struct array *a, struct svalue *s)
 {
+#ifdef DEBUG
+  if(d_flag > 1)  array_check_type_field(a);
+#endif
   /* face it, it's not there */
   if( (((2 << s->type) -1) & a->type_field) == 0)
     return -1;
@@ -618,6 +633,9 @@ INT32 set_lookup(struct array *a, struct svalue *s)
 INT32 switch_lookup(struct array *a, struct svalue *s)
 {
   /* face it, it's not there */
+#ifdef DEBUG
+  if(d_flag > 1)  array_check_type_field(a);
+#endif
   if( (((2 << s->type) -1) & a->type_field) == 0)
     return -1;
 
@@ -672,6 +690,22 @@ void array_fix_type_field(struct array *v)
   v->type_field = t;
 }
 
+#ifdef DEBUG
+/* Maybe I should have a 'clean' flag for this computation */
+void array_check_type_field(struct array *v)
+{
+  int e;
+  TYPE_FIELD t;
+
+  t=0;
+
+  for(e=0; e<v->size; e++) t |= 1 << ITEM(v)[e].type;
+
+  if(t & ~(v->type_field))
+    fatal("Type field out of order!\n");
+}
+#endif
+
 struct array *compact_array(struct array *v) { return v; }
 
 /*
@@ -717,6 +751,13 @@ INT32 * merge(struct array *a,struct array *b,INT32 opcode)
   INT32 ap,bp,i,*ret,*ptr;
   
   ap=bp=0;
+#ifdef DEBUG
+  if(d_flag > 1)
+  {
+    array_check_type_field(a);
+    array_check_type_field(b);
+  }
+#endif
   if(!(a->type_field & b->type_field))
   {
     /* do smart optimizations */
@@ -829,6 +870,14 @@ int array_equal_p(struct array *a, struct array *b, struct processing *p)
   if(a->size != b->size) return 0;
   if(!a->size) return 1;
 
+#ifdef DEBUG
+  if(d_flag > 1)
+  {
+    array_check_type_field(a);
+    array_check_type_field(b);
+  }
+#endif
+
   /* This could be done much better if I KNEW that
    * the type fields didn't contain types that
    * really aren't in the array
@@ -942,6 +991,14 @@ struct array *merge_array_without_order(struct array *a,
 /* subtract an array from another */
 struct array *subtract_arrays(struct array *a, struct array *b)
 {
+#ifdef DEBUG
+  if(d_flag > 1)
+  {
+    array_check_type_field(a);
+    array_check_type_field(b);
+  }
+#endif
+
   if(a->type_field & b->type_field)
   {
     return merge_array_with_order(a, b, OP_SUB);
@@ -958,6 +1015,14 @@ struct array *subtract_arrays(struct array *a, struct array *b)
 /* and two arrays */
 struct array *and_arrays(struct array *a, struct array *b)
 {
+#ifdef DEBUG
+  if(d_flag > 1)
+  {
+    array_check_type_field(a);
+    array_check_type_field(b);
+  }
+#endif
+
   if(a->type_field & b->type_field)
   {
     return merge_array_without_order(a, b, OP_AND);
@@ -969,7 +1034,7 @@ struct array *and_arrays(struct array *a, struct array *b)
 int check_that_array_is_constant(struct array *a)
 {
   array_fix_type_field(a);
-  if(a->type_field & ((1 << T_FUNCTION) | (1 << T_OBJECT)))
+  if(a->type_field & (BIT_FUNCTION | BIT_OBJECT))
     return 0;
   return 1;
 }
@@ -980,7 +1045,7 @@ node *make_node_from_array(struct array *a)
   INT32 e;
 
   array_fix_type_field(a);
-  if(a->type_field == (1 << T_INT))
+  if(a->type_field == BIT_INT)
   {
     for(e=0; e<a->size; e++)
       if(ITEM(a)[e].u.integer != 0)
@@ -1111,7 +1176,7 @@ struct array *explode(struct lpc_string *str,
   if(!del->len)
   {
     ret=allocate_array_no_init(str->len,0);
-    ret->type_field |= 1<<T_STRING;
+    ret->type_field |= BIT_STRING;
     for(e=0;e<str->len;e++)
     {
       ITEM(ret)[e].type=T_STRING;
@@ -1130,7 +1195,7 @@ struct array *explode(struct lpc_string *str,
     }
 
     ret=allocate_array_no_init(e+1,0);
-    ret->type_field |= 1<<T_STRING;
+    ret->type_field |= BIT_STRING;
 
     s=str->str;
     for(d=0;d<e;d++)
@@ -1297,8 +1362,20 @@ void gc_check_all_arrays()
   a=&empty_array;
   do
   {
+#ifdef DEBUG
+    if(d_flag > 1)  array_check_type_field(a);
+#endif
     if(a->type_field & BIT_COMPLEX)
-      a->type_field = gc_check_svalues(ITEM(a), a->size);
+    {
+      TYPE_FIELD t;
+      t=gc_check_svalues(ITEM(a), a->size);
+
+      /* Ugly, but we are not allowed to change type_field
+       * at the same time as the array is being built...
+       */
+      if(!(a->type_field & BIT_UNFINISHED) || a->refs!=1)
+	a->type_field = t;
+    }
 
     a=a->next;
   } while (a != & empty_array);
diff --git a/src/array.h b/src/array.h
index 526120e763..bbc7837646 100644
--- a/src/array.h
+++ b/src/array.h
@@ -82,6 +82,7 @@ INT32 switch_lookup(struct array *a, struct svalue *s);
 struct array *order_array(struct array *v, INT32 *order);
 struct array *reorder_and_copy_array(struct array *v, INT32 *order);
 void array_fix_type_field(struct array *v);
+void array_check_type_field(struct array *v);
 struct array *compact_array(struct array *v);
 union anything *low_array_get_item_ptr(struct array *a,
 				       INT32 ind,
diff --git a/src/gc.h b/src/gc.h
index cffbd118c2..4b20f92605 100644
--- a/src/gc.h
+++ b/src/gc.h
@@ -9,16 +9,12 @@ extern INT32 num_objects;
 extern INT32 num_allocs;
 extern INT32 alloc_threshold;
 
-#define GC_ALLOC() do{ num_objects++; if(++num_allocs > alloc_threshold) do_gc(); } while(0);
-#define GC_FREE() num_objects--
-
+#ifdef ALWAYS_GC
+#define GC_ALLOC() do{ num_objects++; ++num_allocs; do_gc(); } while(0)
 #else
-
-#define GC_ALLOC()
-#define GC_FREE()
-#define do_gc()
-
+#define GC_ALLOC() do{ num_objects++; if(++num_allocs > alloc_threshold) do_gc(); } while(0)
 #endif
+#define GC_FREE() num_objects--
 
 /* Prototypes begin here */
 struct marker;
@@ -27,7 +23,14 @@ void gc_check(void *a);
 int gc_is_referenced(void *a);
 int gc_mark(void *a);
 int gc_do_free(void *a);
-void do_gc();
+void do_gc(void);
 /* Prototypes end here */
 
+#else
+
+#define GC_ALLOC()
+#define GC_FREE()
+#define do_gc()
+
+#endif
 #endif
-- 
GitLab


From 5aa04ac1626019049a9837eed1e808991f8efa21 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 16 May 1996 00:59:51 +0200
Subject: [PATCH 170/351] minor change

Rev: src/add_efun.c:1.3
Rev: src/main.c:1.4
---
 src/add_efun.c | 3 ++-
 src/main.c     | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/add_efun.c b/src/add_efun.c
index 7c35fa8cf2..4ecc6d4e3d 100644
--- a/src/add_efun.c
+++ b/src/add_efun.c
@@ -109,7 +109,8 @@ static void push_efun_entry(struct hash_entry *h)
   f=BASEOF(h, efun, link);
   push_string(f->link.s);
   f->link.s->refs++;
-  copy_svalues_recursively_no_free(sp++,& f->function,1,0);
+  copy_svalues_recursively_no_free(sp,& f->function,1,0);
+  sp++;
 }
 
 void push_all_efuns_on_stack()
diff --git a/src/main.c b/src/main.c
index c2cb32d47a..cf2a0a9271 100644
--- a/src/main.c
+++ b/src/main.c
@@ -190,7 +190,8 @@ void main(int argc, char **argv, char **env)
   if(SETJMP(back))
   {
     automatic_fatal="Error in handle_error, previous error (in _main): ";
-    assign_svalue_no_free(sp++, & throw_value);
+    assign_svalue_no_free(sp, & throw_value);
+    sp++;
     APPLY_MASTER("handle_error", 1);
     pop_stack();
     exit(10);
-- 
GitLab


From 6a1f6de3793d3c051e0ee23abdfccf05766b42f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 16 May 1996 01:00:05 +0200
Subject: [PATCH 171/351] minor bugfix

Rev: src/mapping.c:1.5
Rev: src/modules/gdbmmod/gdbmmod.c:1.2
---
 src/mapping.c                 | 2 ++
 src/modules/gdbmmod/gdbmmod.c | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/mapping.c b/src/mapping.c
index 5f566a0cc8..1325d2e58f 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -348,6 +348,8 @@ void f_aggregate_mapping(INT32 args)
     ITEM(val)[e]=*(s++);
   }
   sp-=args;
+  ind->type_field=BIT_MIXED;
+  val->type_field=BIT_MIXED;
   m=allocate_mapping(ind,val);
   order_mapping(m);
   sp->u.mapping=m;
diff --git a/src/modules/gdbmmod/gdbmmod.c b/src/modules/gdbmmod/gdbmmod.c
index 0510cb8d3a..908e7119e9 100644
--- a/src/modules/gdbmmod/gdbmmod.c
+++ b/src/modules/gdbmmod/gdbmmod.c
@@ -205,7 +205,7 @@ static void gdbmmod_store(INT32 args)
     error("GDBM database not open.\n");
 
   STRING_TO_DATUM(key, sp[-args].u.string);
-  STRING_TO_DATUM(data, sp[-args].u.string);
+  STRING_TO_DATUM(data, sp[1-args].u.string);
 
   ret=gdbm_store(THIS->dbf, key, data, GDBM_REPLACE);
   if(ret == -1)
-- 
GitLab


From 197d17a61a2a4245f0dc6c84ad8b279bcc246ee6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 16 May 1996 01:00:26 +0200
Subject: [PATCH 172/351] warning removed

Rev: src/program.c:1.11
---
 src/program.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/program.c b/src/program.c
index 65759de03a..6ebc01c23f 100644
--- a/src/program.c
+++ b/src/program.c
@@ -1154,7 +1154,7 @@ void my_yyerror(char *fmt,...)
   va_start(args,fmt);
   VSPRINTF(buf,fmt,args);
 
-  if(strlen(buf) >= sizeof(buf))
+  if((long)strlen(buf) >= (long)sizeof(buf))
     fatal("Buffer overflow in my_yyerror.");
 
   yyerror(buf);
-- 
GitLab


From 4eb50ab1c7a58b514e6221bc91f4b5c6e990988f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 16 May 1996 01:00:49 +0200
Subject: [PATCH 173/351] added BIT_UNUSED

Rev: src/svalue.h:1.7
---
 src/svalue.h | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/svalue.h b/src/svalue.h
index 0609503933..fa505ccd8f 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -75,8 +75,12 @@ struct svalue
 #define BIT_INT (1<<T_INT)
 #define BIT_FLOAT (1<<T_FLOAT)
 
+/* Used to signifiy that this array might not be finished yet */
+/* garbage collect uses this */
+#define BIT_UNFINISHED (1<<15)
+
 #define BIT_NOTHING 0
-#define BIT_MIXED 0xffff
+#define BIT_MIXED 0x7fff
 #define BIT_BASIC (BIT_INT|BIT_FLOAT|BIT_STRING)
 #define BIT_COMPLEX (BIT_ARRAY|BIT_LIST|BIT_OBJECT|BIT_PROGRAM|BIT_MAPPING)
 
-- 
GitLab


From a008f340cb6fd74f81b9f77ac66227e33c040a19 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 16 May 1996 01:01:40 +0200
Subject: [PATCH 174/351] entries added

Rev: src/ChangeLog:1.35
---
 src/ChangeLog | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index b3c3954b0a..cd6468b8d1 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
+Thu May 16 00:53:16 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
+
+	* fixed some major bugs in gc()
+	* undefing GC2 now works
+	* create_testsuite: tests for gdbmmod added
+	* test_lpc.lpc: added conditional tests
+	* module doc dirs moved to the module dirs.
+
 Mon May 13 22:20:24 1996  Fredrik Hubinette  <hubbe@axel.signum.se>
 
 	* -Wunused removed
-- 
GitLab


From c09314fa309d8b6f880cf7fe82ea7e17057437ac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 27 May 1996 01:41:45 +0200
Subject: [PATCH 175/351] fixed a typo

Rev: doc/types/string:1.5
---
 doc/types/string | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/types/string b/doc/types/string
index e15c543755..91550e40a1 100644
--- a/doc/types/string
+++ b/doc/types/string
@@ -21,7 +21,7 @@ DESCRIPTION
 	syntaxes:
 
 	\n	newline
-	\r	charriage return
+	\r	carriage return
 	\t	tab
 	\b	backspace
 	\"	"
-- 
GitLab


From 051983f55781f0a8a1efa7217d2d6e0f2b97137d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 27 May 1996 01:44:28 +0200
Subject: [PATCH 176/351] added latest version

Rev: .cvsignore:1.6
---
 .cvsignore | 1 +
 .gitignore | 1 +
 2 files changed, 2 insertions(+)

diff --git a/.cvsignore b/.cvsignore
index fe66920fc0..00bbbf0d2e 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -4,6 +4,7 @@ test.lpc
 uLPC_v1.0E-10.tar.gz
 uLPC_v1.0E-12.tar.gz
 uLPC_v1.0E-13.tar.gz
+uLPC_v1.0E-8.tar.gz
 uLPC_v1.0E-9.tar.gz
 uLPC_v1.1E-12.tar.gz
 uLPC_v1.7E-12.tar.gz
diff --git a/.gitignore b/.gitignore
index 173fd526a8..ada9bcc0fa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,6 +36,7 @@ core
 /uLPC_v1.0E-10.tar.gz
 /uLPC_v1.0E-12.tar.gz
 /uLPC_v1.0E-13.tar.gz
+/uLPC_v1.0E-8.tar.gz
 /uLPC_v1.0E-9.tar.gz
 /uLPC_v1.1E-12.tar.gz
 /uLPC_v1.7E-12.tar.gz
-- 
GitLab


From b5790500c71a19a19156739a76db2fe4c6dd67eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 28 May 1996 14:32:47 +0200
Subject: [PATCH 177/351] entry added

Rev: src/ChangeLog:1.36
---
 src/ChangeLog | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index cd6468b8d1..006811a3c7 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+Mon May 27 03:39:20 1996  Fredrik Hubinette  <hubbe@axel.signum.se>
+
+	* uLPC v1.0E-8 released
+
 Thu May 16 00:53:16 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
 
 	* fixed some major bugs in gc()
-- 
GitLab


From 9ef305c6b3e9ff4a28d076406117f94f01336503 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 16:28:30 +0200
Subject: [PATCH 178/351] nothing changed

Rev: bin/hilfe.lpc:1.5
---
 bin/hilfe.lpc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/bin/hilfe.lpc b/bin/hilfe.lpc
index c9e823cd73..54c6a8b963 100755
--- a/bin/hilfe.lpc
+++ b/bin/hilfe.lpc
@@ -322,6 +322,7 @@ mixed parse_function(string fun)
   case "int":
   case "void":
   case "object":
+  case "array":
   case "mapping":
   case "string":
   case "list":
@@ -391,6 +392,7 @@ mixed parse_statement(string ex)
   case "int":
   case "void":
   case "object":
+  case "array":
   case "mapping":
   case "string":
   case "list":
-- 
GitLab


From 663b2040a6129f3d35a9d4c3ae64be06c2cae878 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 16:29:12 +0200
Subject: [PATCH 179/351] now even longer

Rev: bin/metatest:1.2
---
 bin/metatest | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/bin/metatest b/bin/metatest
index 5daa5c9df3..75bb951a09 100755
--- a/bin/metatest
+++ b/bin/metatest
@@ -11,27 +11,36 @@ esac
 set -e
 set -x
 
-docompile() {
+docompile4() {
   mkdir test1
   cd test1
   $SRCPATH/src/configure --cache-file ../testcache
-  make "$1"
-  make verify "$1"
-  make verify LPCOPTS=-d2 "$1"
+  d="DEBUGDEF=$1"
+  make "$d"
+  make verify "$d"
+  make verify LPCOPTS=-d2 "$d"
+#  make verify LPCOPTS=-d99 "$d"
   cd ..
   rm -rf test1
 }
 
+docompile3() {
+  docompile4 "$1"
+  docompile4 "$1 -DFLAT_MAPPINGS"
+  docompile4 "$1 -DOLD_MAPPINGS"
+}
+
 docompile2() {
-  docompile DEBUGDEF="$1 -DDEBUG"
-  docompile DEBUGDEF="$1"
+  docompile3 "$1 -DDEBUG"
+  docompile3 "$1"
 }
 
-docompile3() {
+docompile1() {
   docompile2 "$1 -DALWAYS_GC"
   docompile2 "$1 -DNO_GC"
   docompile2 "$1"
 }
 
-docompile3
+
+docompile1
 rm testcache
-- 
GitLab


From b43f5f513334126b2e82159ff02ef4bad1055891 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 16:31:04 +0200
Subject: [PATCH 180/351] new files

Rev: doc/builtin/column:1.1
Rev: doc/builtin/rows:1.1
Rev: doc/builtin/sort:1.1
---
 doc/builtin/column | 20 ++++++++++++++++++++
 doc/builtin/rows   | 20 ++++++++++++++++++++
 doc/builtin/sort   | 25 +++++++++++++++++++++++++
 3 files changed, 65 insertions(+)
 create mode 100644 doc/builtin/column
 create mode 100644 doc/builtin/rows
 create mode 100644 doc/builtin/sort

diff --git a/doc/builtin/column b/doc/builtin/column
new file mode 100644
index 0000000000..5beb87cc98
--- /dev/null
+++ b/doc/builtin/column
@@ -0,0 +1,20 @@
+NAME
+	column - extract a column
+
+SYNTAX
+	array column(mixed *data,mixed index)
+
+DESCRIPTION
+	This function is exactly equivialent to:
+
+	map_array(index,lambda(mixed x,mixed y) { return x[y]; },data)
+
+	Except of course it is a lot shorter and faster.
+	That is, it indexes every index in the array data on the value of
+	the argument index and returns an array with the results.
+
+KEYWORDS
+	array
+
+SEE ALSO
+	rows
diff --git a/doc/builtin/rows b/doc/builtin/rows
new file mode 100644
index 0000000000..4e6dfb6aea
--- /dev/null
+++ b/doc/builtin/rows
@@ -0,0 +1,20 @@
+NAME
+	rows - select a set of rows from an array
+
+SYNTAX
+	array rows(mixed data, mixed *index)
+
+DESCRIPTION
+	This function is exactly equivialent to:
+
+	map_array(index,lambda(mixed x,mixed y) { return y[x]; },data)
+
+	Except of course it is a lot shorter and faster.
+	That is, it indexes data on every index in the array index and
+	returns an array with the results.
+
+KEYWORDS
+	array
+
+SEE ALSO
+	column
diff --git a/doc/builtin/sort b/doc/builtin/sort
new file mode 100644
index 0000000000..c19e557d9f
--- /dev/null
+++ b/doc/builtin/sort
@@ -0,0 +1,25 @@
+NAME
+	sort - sort an array destructively
+
+SYNTAX
+	mixed *sort(array(mixed) index, array(mixed) ... data);
+
+DESCRIPTION
+	This function sorts the array 'index' destructively. That means
+	that the array itself is changed and returned, no copy is created.
+	If extra arguments are given, they are supposed to be arrays of the
+	same size. Each of these arrays will be modified in the same way as
+	'index'. Ie. if index 3 is moved to position 0 in 'index' index 3
+	will be moved to position 0 in all the other arrays as well.
+
+	Sort can sort strings, integers and floats in ascending order.
+	Arrays will be sorted first on size and then on the first element
+	of each array.
+
+	Sort returns it's first argument.
+
+KEYWORDS
+	array
+
+SEE ALSO
+	reverse
-- 
GitLab


From 283eea2de427603e2c347ff9991f4955589a2a3f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 16:33:20 +0200
Subject: [PATCH 181/351] sort array now uses sort()

Rev: lib/simulate.lpc:1.15
---
 lib/simulate.lpc | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index 8da82da8f8..0eead87e02 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -274,7 +274,13 @@ varargs mixed *sort_array(array foo,function cmp, mixed ... args)
   int length;
   int foop, fooend, barp, barend;
   
-  if(!cmp) cmp=`>;
+  if(!cmp || cmp==`>)
+  {
+    foo+=({});
+    sort(foo);
+    return foo;
+  }
+
   length=sizeof(foo);
 
   foo+=({});
@@ -379,7 +385,7 @@ void create()
   add_efun("sum_arrays",sum_arrays);
   add_efun("system",system);
   add_efun("this_function",this_function);
-  add_efun("version",lambda() { return "uLPC v1.0E-8"; });
+  add_efun("version",lambda() { return "uLPC v1.0E-7"; });
   add_efun("write_file",write_file);
 }
 
-- 
GitLab


From 71b72b11a44250a6b3676f0d380e098c469f6de4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 16:39:19 +0200
Subject: [PATCH 182/351] added functions for sorting alphabetically

Rev: src/array.c:1.12
Rev: src/array.h:1.8
---
 src/array.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
 src/array.h |  1 +
 2 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/src/array.c b/src/array.c
index 39fb8928e3..a820f36adb 100644
--- a/src/array.c
+++ b/src/array.c
@@ -542,7 +542,9 @@ static int set_svalue_cmpfun(struct svalue *a, struct svalue *b)
     return a->subtype - b->subtype;
 
   case T_INT:
-    return a->u.integer - b->u.integer;
+    if(a->u.integer < b->u.integer) return -1;
+    if(a->u.integer > b->u.integer) return 1;
+    return 0;
 
   default:
     if(a->u.refs < b->u.refs) return -1;
@@ -557,7 +559,9 @@ static int switch_svalue_cmpfun(struct svalue *a, struct svalue *b)
   switch(a->type)
   {
   case T_INT:
-    return a->u.integer - b->u.integer;
+    if(a->u.integer < b->u.integer) return -1;
+    if(a->u.integer > b->u.integer) return 1;
+    return 0;
 
   case T_FLOAT:
     if(a->u.float_number < b->u.float_number) return -1;
@@ -572,6 +576,35 @@ static int switch_svalue_cmpfun(struct svalue *a, struct svalue *b)
   }
 }
 
+static int alpha_svalue_cmpfun(struct svalue *a, struct svalue *b)
+{
+  if(a->type != b->type) return a->type - b->type;
+  switch(a->type)
+  {
+  case T_INT:
+    if(a->u.integer < b->u.integer) return -1;
+    if(a->u.integer > b->u.integer) return  1;
+    return 0;
+
+  case T_FLOAT:
+    if(a->u.float_number < b->u.float_number) return -1;
+    if(a->u.float_number > b->u.float_number) return  1;
+    return 0;
+
+  case T_STRING:
+    return my_strcmp(a->u.string, b->u.string);
+
+  case T_ARRAY:
+    if(a==b) return 0;
+    if(!a->u.array->size) return -1;
+    if(!b->u.array->size) return  1;
+    return alpha_svalue_cmpfun(ITEM(a->u.array), ITEM(b->u.array));
+    
+  default:
+    return set_svalue_cmpfun(a,b);
+  }
+}
+
 /*
  * return an 'order' suitable for making mappings, lists other sets
  */
@@ -589,6 +622,15 @@ INT32 *get_switch_order(struct array *a)
 }
 
 
+/*
+ * return an 'order' suitable for sorting.
+ */
+INT32 *get_alpha_order(struct array *a)
+{
+  return get_order(a, alpha_svalue_cmpfun);
+}
+
+
 static INT32 low_lookup(struct array *v,
 			struct svalue *s,
 			cmpfun fun)
diff --git a/src/array.h b/src/array.h
index bbc7837646..12c5e9ff49 100644
--- a/src/array.h
+++ b/src/array.h
@@ -77,6 +77,7 @@ INT32 array_find_destructed_object(struct array *v);
 INT32 *get_order(struct array *v, cmpfun fun);
 INT32 *get_set_order(struct array *a);
 INT32 *get_switch_order(struct array *a);
+INT32 *get_alpha_order(struct array *a);
 INT32 set_lookup(struct array *a, struct svalue *s);
 INT32 switch_lookup(struct array *a, struct svalue *s);
 struct array *order_array(struct array *v, INT32 *order);
-- 
GitLab


From a9d78b2210b1fdf6fdc7c0eea24dc4a528e2949d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 16:40:06 +0200
Subject: [PATCH 183/351] minor fix

Rev: doc/builtin/sort:1.2
---
 doc/builtin/sort | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/doc/builtin/sort b/doc/builtin/sort
index c19e557d9f..c13208ada7 100644
--- a/doc/builtin/sort
+++ b/doc/builtin/sort
@@ -13,8 +13,7 @@ DESCRIPTION
 	will be moved to position 0 in all the other arrays as well.
 
 	Sort can sort strings, integers and floats in ascending order.
-	Arrays will be sorted first on size and then on the first element
-	of each array.
+	Arrays will be sorted first on the first element of each array.
 
 	Sort returns it's first argument.
 
-- 
GitLab


From 433204655bdeeb9ee44518c1dcf311d8b1e4953a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 16:42:42 +0200
Subject: [PATCH 184/351] nothing changed

Rev: src/main.c:1.5
---
 src/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main.c b/src/main.c
index cf2a0a9271..e1fc8a391d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -230,9 +230,9 @@ void exit_main()
   void cleanup_program();
 
   automatic_fatal="uLPC is exiting: ";
+  cleanup_objects();
   exit_signals();
   exit_lex();
-  cleanup_objects();
   cleanup_interpret();
   cleanup_added_efuns();
   free_all_call_outs();
-- 
GitLab


From 94ed5f97cbb7205454524791cdcb51c4cce7e99c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 16:43:30 +0200
Subject: [PATCH 185/351] pop_n_elems fixed

Rev: src/interpret.c:1.9
---
 src/interpret.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/interpret.c b/src/interpret.c
index f3a83ce04c..b8c13ee2b0 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -196,8 +196,8 @@ void pop_n_elems(INT32 x)
 
   if(x < 0) fatal("Popping negative number of args....\n");
 #endif
-  free_svalues(sp-x,x,BIT_MIXED);
   sp-=x;
+  free_svalues(sp,x,BIT_MIXED);
 }
 
 #ifdef DEBUG
-- 
GitLab


From 1407c9c8fb86c10b14f8aa7a20c641a9ba912f53 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 16:44:09 +0200
Subject: [PATCH 186/351] unneeded function remvoved

Rev: src/object.c:1.9
---
 src/object.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/object.c b/src/object.c
index e61c203dcd..41af09bbb0 100644
--- a/src/object.c
+++ b/src/object.c
@@ -16,6 +16,7 @@
 #include "main.h"
 #include "array.h"
 #include "gc.h"
+#include "backend.h"
 
 struct object *master_object = 0;
 struct object *first_object;
@@ -154,6 +155,10 @@ void destruct(struct object *o)
   struct frame frame;
   struct program *p;
 
+#ifdef DEBUG
+  if(d_flag > 20) do_debug();
+#endif
+
   if(!o || !(p=o->prog)) return; /* Object already destructed */
 
   o->refs++;
@@ -642,9 +647,6 @@ struct array *object_values(struct object *o)
 
 #ifdef GC2
 
-void gc_check_object(struct object *o)
-{
-}
 
 void gc_mark_object_as_referenced(struct object *o)
 {
-- 
GitLab


From 28119b1d894ee1529af352272cf63a95c7c61df9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 16:46:27 +0200
Subject: [PATCH 187/351] recursive signal calling now fixed

Rev: src/lpc_signal.c:1.10
---
 src/lpc_signal.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/src/lpc_signal.c b/src/lpc_signal.c
index b149afe867..cc9108068a 100644
--- a/src/lpc_signal.c
+++ b/src/lpc_signal.c
@@ -230,14 +230,16 @@ static RETSIGTYPE receive_signal(int signum)
 
 void check_signals()
 {
+  static int signalling=0;
 #ifdef DEBUG
   extern int d_flag;
   if(d_flag>5) do_debug(0);
 #endif
 
-  if(firstsig != lastsig)
+  if(firstsig != lastsig && !signalling)
   {
     int tmp=firstsig;
+    signalling=1;
 
     while(lastsig != tmp)
     {
@@ -247,6 +249,8 @@ void check_signals()
       apply_svalue(signal_callbacks + sigbuf[lastsig], 1);
       pop_stack();
     }
+
+    signalling=0;
   }
 }
 
@@ -389,6 +393,24 @@ static void f_alarm(INT32 args)
   push_int(alarm(seconds));
 }
 
+#ifdef HAVE_UALARM
+static void f_ualarm(INT32 args)
+{
+  long seconds;
+
+  if(args < 1)
+    error("Too few arguments to signame()\n");
+
+  if(sp[-args].type != T_INT)
+    error("Bad argument 1 to signame()\n");
+
+  seconds=sp[-args].u.integer;
+
+  pop_n_elems(args);
+  push_int(ualarm(seconds));
+}
+#endif
+
 void init_signals()
 {
   int e;
@@ -407,6 +429,9 @@ void init_signals()
   add_efun("signum",f_signum,"function(string:int)",0);
   add_efun("getpid",f_getpid,"function(:int)",0);
   add_efun("alarm",f_alarm,"function(int:int)",OPT_SIDE_EFFECT);
+#ifdef HAVE_UALARM
+  add_efun("ualarm",f_ualarm,"function(int:int)",OPT_SIDE_EFFECT);
+#endif
 }
 
 void exit_signals()
-- 
GitLab


From 0cea4230e9530c931072cda2ed1ca4e271e46109 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 16:50:54 +0200
Subject: [PATCH 188/351] recursive signal calling now fixed

Rev: src/lpc_signal.c:1.11
---
 src/lpc_signal.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/lpc_signal.c b/src/lpc_signal.c
index cc9108068a..97d7234a37 100644
--- a/src/lpc_signal.c
+++ b/src/lpc_signal.c
@@ -10,6 +10,7 @@
 #include "add_efun.h"
 #include "macros.h"
 #include "backend.h"
+#include "error.h"
 #include <signal.h>
 #include <sys/wait.h>
 
@@ -228,9 +229,13 @@ static RETSIGTYPE receive_signal(int signum)
 #endif
 }
 
+static int signalling=0;
+
+static void unset_signalling(void *notused) { signalling=0; }
+
 void check_signals()
 {
-  static int signalling=0;
+  ONERROR ebuf;
 #ifdef DEBUG
   extern int d_flag;
   if(d_flag>5) do_debug(0);
@@ -241,6 +246,8 @@ void check_signals()
     int tmp=firstsig;
     signalling=1;
 
+    SET_ONERROR(ebuf,unset_signalling,0);
+
     while(lastsig != tmp)
     {
       if(++lastsig == SIGNAL_BUFFER) lastsig=0;
@@ -250,6 +257,8 @@ void check_signals()
       pop_stack();
     }
 
+    UNSET_ONERROR(ebuf);
+
     signalling=0;
   }
 }
-- 
GitLab


From 515b6c7c67c453c432265d62b9e15607562e0487 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 16:53:51 +0200
Subject: [PATCH 189/351] two new implementations

Rev: src/mapping.c:1.6
Rev: src/mapping.h:1.4
---
 src/mapping.c | 1204 ++++++++++++++++++++++++++++++++++++++++++++++++-
 src/mapping.h |   70 ++-
 2 files changed, 1251 insertions(+), 23 deletions(-)

diff --git a/src/mapping.c b/src/mapping.c
index 1325d2e58f..9ed17cd250 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -4,7 +4,9 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
+#include "main.h"
 #include "types.h"
+#include "object.h"
 #include "mapping.h"
 #include "svalue.h"
 #include "array.h"
@@ -14,8 +16,1187 @@
 #include "memory.h"
 #include "dynamic_buffer.h"
 #include "interpret.h"
+#include "las.h"
 #include "gc.h"
 
+#ifndef OLD_MAPPINGS
+
+#ifndef FLAT_MAPPINGS
+#  define AVG_LINK_LENGTH 4
+#  define MIN_LINK_LENGTH 1
+#  define MAP_SLOTS(X) ((X)+((X)>>4)+8)
+#define LOOP(m) for(e=0;e<m->hashsize;e++) for(k=m->hash[e];k;k=k->next)
+#else
+#  define MAX_FILL 80
+#  define AVG_FILL 60
+#  define MIN_FILL 30
+#  define MAP_SLOTS(X) ((X)*100/AVG_FILL+1)
+#define LOOP(m) for(e=0;e<m->hashsize;e++) if((k=m->hash+e)->ind.type <= MAX_TYPE)
+#endif
+
+struct keypair
+{
+#ifndef FLAT_MAPPINGS
+  struct keypair *next;
+#endif
+  struct svalue ind, val;
+};
+
+struct mapping *first_mapping;
+
+static void init_mapping(struct mapping *m, INT32 size)
+{
+#ifndef FLAT_MAPPINGS
+  char *tmp;
+  INT32 e;
+  INT32 hashsize,hashspace;
+
+#ifdef DEBUG
+  if(size < 0) fatal("init_mapping with negative value.\n");
+#endif
+
+  hashsize=size / AVG_LINK_LENGTH + 1;
+  if(!(hashsize & 1)) hashsize++;
+  hashspace=hashsize+1;
+  e=sizeof(struct keypair)*size+ sizeof(struct keypair *)*hashspace;
+  tmp=(char *)xalloc(e);
+
+  m->hash=(struct keypair **) tmp;
+  m->hashsize=hashsize;
+
+  tmp+=sizeof(struct keypair *)*hashspace;
+  m->free_list=(struct keypair *) tmp;
+  
+  MEMSET((char *)m->hash, 0, sizeof(struct keypair *) * m->hashsize);
+
+  for(e=1;e<size;e++)
+    m->free_list[e-1].next = m->free_list + e;
+  m->free_list[e-1].next=0;
+
+#else
+  INT32 e;
+  INT32 hashsize;
+  hashsize=size*100/MAX_FILL+1;
+  m->hash=(struct keypair *)xalloc(sizeof(struct keypair)*hashsize);
+  m->hashsize=hashsize;
+  for(e=0;e<hashsize;e++) m->hash[e].ind.type=T_VOID;
+#endif  
+  m->ind_types = 0;
+  m->val_types = 0;
+  m->size = 0;
+}
+
+
+static struct mapping *allocate_mapping(int size)
+{
+  struct mapping *m;
+
+  GC_ALLOC();
+
+  m=ALLOC_STRUCT(mapping);
+
+  init_mapping(m,size);
+
+  m->next = first_mapping;
+  m->prev = 0;
+  m->refs = 1;
+
+  if(first_mapping) first_mapping->prev = m;
+  first_mapping=m;
+
+  return m;
+}
+
+unsigned INT32 hash_svalue(struct svalue *s)
+{
+  unsigned INT32 q;
+  switch(s->type)
+  {
+  case T_INT:   q=s->u.integer; break;
+  case T_FLOAT: q=(unsigned INT32)(s->u.float_number * 16843009.0); break;
+  default:      q=(unsigned INT32)s->u.refs >> 2;
+  }
+  q+=q % 997;
+  q+=((q + s->type) * 9248339);
+  
+  return q;
+}
+
+void really_free_mapping(struct mapping *m)
+{
+  INT32 e;
+  struct keypair *k;
+#ifdef DEBUG
+  if(m->refs)
+    fatal("really free mapping on mapping with nonzero refs.\n");
+#endif
+
+  LOOP(m)
+  {
+    free_svalue(& k->val);
+    free_svalue(& k->ind);
+  }
+
+  if(m->prev)
+    m->prev->next = m->next;
+  else
+    first_mapping = m->next;
+
+  if(m->next) m->next->prev = m->prev;
+
+  free((char *)m->hash);
+  free((char *)m);
+
+  GC_FREE();
+}
+
+#ifndef FLAT_MAPPINGS
+static void mapping_rehash_backwards(struct mapping *m, struct keypair *p)
+{
+  unsigned INT32 h;
+  struct keypair *tmp;
+
+  if(!p) return;
+  mapping_rehash_backwards(m,p->next);
+  h=hash_svalue(& p->ind) % m->hashsize;
+  tmp=m->free_list;
+  m->free_list=tmp->next;
+  tmp->next=m->hash[h];
+  m->hash[h]=tmp;
+  tmp->ind=p->ind;
+  tmp->val=p->val;
+  m->size++;
+  m->ind_types |= 1 << p->ind.type;
+  m->val_types |= 1 << p->val.type;
+}
+#endif
+
+static struct mapping *rehash(struct mapping *m, int new_size)
+{
+#ifdef DEBUG
+  INT32 tmp=m->size;
+#endif
+#ifndef FLAT_MAPPINGS
+  INT32 e,hashsize;
+  struct keypair *k,**hash;
+
+  hashsize=m->hashsize;
+  hash=m->hash;
+
+  init_mapping(m, new_size);
+
+  for(e=0;e<hashsize;e++)
+    mapping_rehash_backwards(m, hash[e]);
+#else
+  struct keypair *hash;
+  INT32 e,hashsize;
+
+  hashsize=m->hashsize;
+  hash=m->hash;
+
+  init_mapping(m, new_size);
+
+  for(e=0;e<hashsize;e++)
+    if(hash[e].ind.type <= MAX_TYPE)
+      mapping_insert(m, & hash[e].ind, & hash[e].val);
+#endif
+
+#ifdef DEBUG
+  if(m->size != tmp)
+    fatal("Rehash failed, size not same any more.\n");
+#endif
+
+  free((char *)hash);
+  return m;
+}
+
+void mapping_fix_type_field(struct mapping *m)
+{
+  INT32 e;
+  struct keypair *k;
+  TYPE_FIELD ind_types, val_types;
+
+  val_types = ind_types = 0;
+#ifndef FLAT_MAPPINGS
+  for(e=0;e<m->hashsize;e++)
+  {
+    for(k=m->hash[e];k;k=k->next)
+    {
+      val_types |= 1 << k->val.type;
+      ind_types |= 1 << k->ind.type;
+    }
+  }
+#else
+  for(e=0;e<m->hashsize;e++)
+  {
+    if(m->hash[e].ind.type <= MAX_TYPE)
+    {
+      val_types |= 1 << m->hash[e].val.type;
+      ind_types |= 1 << m->hash[e].ind.type;
+    }
+  }
+#endif
+
+#ifdef DEBUG
+  if(val_types & ~(m->val_types))
+    fatal("Mapping value types out of order!\n");
+
+  if(ind_types & ~(m->ind_types))
+    fatal("Mapping indices types out of order!\n");
+#endif
+  m->val_types = val_types;
+  m->ind_types = ind_types;
+}
+
+#ifdef DEBUG
+static void check_mapping_type_fields(struct mapping *m)
+{
+  INT32 e;
+  struct keypair *k,**prev;
+  TYPE_FIELD ind_types, val_types;
+
+  ind_types=val_types=0;
+
+#ifndef FLAT_MAPPINGS
+  for(e=0;e<m->hashsize;e++)
+  {
+    for(k=m->hash[e];k;k=k->next)
+    {
+      val_types |= 1 << k->val.type;
+      ind_types |= 1 << k->ind.type;
+    }
+  }
+#else
+  for(e=0;e<m->hashsize;e++)
+  {
+    if(m->hash[e].ind.type <= MAX_TYPE)
+    {
+      val_types |= 1 << m->hash[e].val.type;
+      ind_types |= 1 << m->hash[e].ind.type;
+    }
+  }
+#endif
+
+  if(val_types & ~(m->val_types))
+    fatal("Mapping value types out of order!\n");
+
+  if(ind_types & ~(m->ind_types))
+    fatal("Mapping indices types out of order!\n");
+}
+#endif
+
+
+void mapping_insert(struct mapping *m,
+		    struct svalue *key,
+		    struct svalue *val)
+{
+#ifndef FLAT_MAPPINGS
+  unsigned INT32 h;
+  struct keypair *k, **prev;
+
+  if(val->type==T_INT)
+    val->subtype=NUMBER_NUMBER;
+
+  h=hash_svalue(key) % m->hashsize;
+  
+#ifdef DEBUG
+  if(d_flag > 1) check_mapping_type_fields(m);
+#endif
+  if(m->ind_types & (1 << key->type))
+  {
+    for(prev= m->hash + h;k=*prev;prev=&k->next)
+    {
+      if(is_eq(& k->ind, key))
+      {
+	*prev=k->next;
+	k->next=m->hash[h];
+	m->hash[h]=k;
+	
+	m->val_types |= 1 << val->type;
+	assign_svalue(& k->val, val);
+	return;
+      }
+    }
+  }
+
+  if(!(k=m->free_list))
+  {
+    rehash(m, m->size * 2 + 1);
+    h=hash_svalue(key) % m->hashsize;
+    k=m->free_list;
+  }
+
+  m->free_list=k->next;
+  k->next=m->hash[h];
+  m->hash[h]=k;
+  m->ind_types |= 1 << key->type;
+  m->val_types |= 1 << val->type;
+  assign_svalue_no_free(& k->ind, key);
+  assign_svalue_no_free(& k->val, val);
+  m->size++;
+#else
+  unsigned INT32 h;
+  if(val->type==T_INT)
+    val->subtype=NUMBER_NUMBER;
+
+  h=hash_svalue(key) % m->hashsize;
+
+  while(m->hash[h].ind.type != T_VOID)
+  {
+    if(is_eq(& m->hash[h].ind, key))
+    {
+      assign_svalue(& m->hash[h].val, val);
+      m->val_types |= 1 << val->type;
+      return;
+    }
+    if(++h == m->hashsize) h=0;
+  }
+
+  if((m->size+1) * 100 > m->hashsize * MAX_FILL)
+  {
+    rehash(m, m->size * 2 + 1);
+    h=hash_svalue(key) % m->hashsize;
+
+    while(m->hash[h].ind.type != T_VOID)
+      if(++h == m->hashsize) h=0;
+  }
+
+  m->size++;
+
+  assign_svalue_no_free(& m->hash[h].ind, key);
+  assign_svalue_no_free(& m->hash[h].val, val);
+  m->ind_types |= 1 << key->type;
+  m->val_types |= 1 << val->type;
+#endif
+}
+
+union anything *mapping_get_item_ptr(struct mapping *m,
+				     struct svalue *key,
+				     TYPE_T t)
+{
+#ifndef FLAT_MAPPINGS
+  unsigned INT32 h;
+  struct keypair *k, **prev;
+
+  h=hash_svalue(key) % m->hashsize;
+  
+  for(prev= m->hash + h;k=*prev;prev=&k->next)
+  {
+    if(is_eq(& k->ind, key))
+    {
+      *prev=k->next;
+      k->next=m->hash[h];
+      m->hash[h]=k;
+
+      if(k->val.type == t) return & ( k->val.u );
+      return 0;
+    }
+  }
+
+  if(!(k=m->free_list))
+  {
+    rehash(m, m->size * 2 + 1);
+    h=hash_svalue(key) % m->hashsize;
+    k=m->free_list;
+  }
+
+  m->free_list=k->next;
+  k->next=m->hash[h];
+  m->hash[h]=k;
+  assign_svalue_no_free(& k->ind, key);
+  k->val.type=T_INT;
+  k->val.subtype=NUMBER_NUMBER;
+  k->val.u.integer=0;
+  m->ind_types |= 1 << key->type;
+  m->val_types |= BIT_INT;
+  m->size++;
+
+  if(t != T_INT) return 0;
+  return & ( k->val.u );
+#else
+  unsigned INT32 h;
+
+  h=hash_svalue(key) % m->hashsize;
+
+  while(m->hash[h].ind.type != T_VOID)
+  {
+    if(is_eq(& m->hash[h].ind, key))
+    {
+      if(m->hash[h].ind.type == t) return &(m->hash[h].val.u);
+      return 0;
+    }
+    if(++h == m->hashsize) h=0;
+  }
+
+  if((m->size+1) * 100 > m->hashsize * MAX_FILL)
+  {
+    rehash(m, m->size * 2 + 1);
+    h=hash_svalue(key) % m->hashsize;
+  }
+
+  m->size++;
+
+  assign_svalue_no_free(& m->hash[h].ind, key);
+  m->hash[h].val.type=T_INT;
+  m->hash[h].val.subtype=NUMBER_NUMBER;
+  m->hash[h].val.u.integer=0;
+  m->ind_types |= 1 << key->type;
+  m->val_types |= BIT_INT;
+  return &(m->hash[h].val.u);
+#endif
+}
+
+void map_delete(struct mapping *m,
+		struct svalue *key)
+{
+#ifndef FLAT_MAPPINGS
+  unsigned INT32 h;
+  struct keypair *k, **prev;
+
+  h=hash_svalue(key) % m->hashsize;
+  
+  for(prev= m->hash + h;k=*prev;prev=&k->next)
+  {
+    if(is_eq(& k->ind, key))
+    {
+      *prev=k->next;
+      free_svalue(& k->ind);
+      free_svalue(& k->val);
+      k->next=m->free_list;
+      m->free_list=k;
+      m->size--;
+
+      if(m->size < (m->hashsize + 1) * MIN_LINK_LENGTH)
+	rehash(m, MAP_SLOTS(m->size));
+
+      return;
+    }
+  }
+#else
+  unsigned INT32 h;
+
+  h=hash_svalue(key) % m->hashsize;
+
+  while(m->hash[h].ind.type != T_VOID)
+  {
+    if(is_eq(& m->hash[h].ind, key))
+    {
+      free_svalue(&(m->hash[h].ind));
+      free_svalue(&(m->hash[h].val));
+      m->hash[h].ind.type=T_DELETED;
+      m->size--;
+
+      if(m->size * 100 < m->hashsize * MIN_FILL)
+	rehash(m, m->hashsize / 2 + 1);
+
+      return;
+    }
+    if(++h == m->hashsize) h=0;
+  }
+#endif
+}
+
+void check_mapping_for_destruct(struct mapping *m)
+{
+#ifndef FLAT_MAPPINGS
+  INT32 e;
+  struct keypair *k, **prev;
+  TYPE_FIELD ind_types, val_types;
+
+#ifdef DEBUG
+  if(d_flag > 1) check_mapping_type_fields(m);
+#endif
+
+  if((m->ind_types | m->val_types) & BIT_OBJECT)
+  {
+    val_types = ind_types = 0;
+    for(e=0;e<m->hashsize;e++)
+    {
+      for(prev= m->hash + e;k=*prev;prev=&k->next)
+      {
+	check_destructed(& k->val);
+	
+	if(k->ind.type == T_OBJECT && !k->ind.u.object->prog)
+	{
+	  *prev=k->next;
+	  free_svalue(& k->ind);
+	  free_svalue(& k->val);
+	  k->next=m->free_list;
+	  m->free_list=k;
+	  m->size--;
+	}else{
+	  val_types |= 1 << k->val.type;
+	  ind_types |= 1 << k->ind.type;
+	}
+      }
+    }
+    if(MAP_SLOTS(m->size) < m->hashsize * MIN_LINK_LENGTH)
+      rehash(m, MAP_SLOTS(m->size));
+
+    m->val_types = val_types;
+    m->ind_types = ind_types;
+  }
+#else
+  INT32 e;
+  TYPE_FIELD ind_types, val_types;
+
+#ifdef DEBUG
+  if(d_flag > 1) check_mapping_type_fields(m);
+#endif
+
+  if((m->ind_types | m->val_types) & BIT_OBJECT)
+  {
+    val_types = ind_types = 0;
+    for(e=0;e<m->hashsize;e++)
+    {
+      if(m->hash[e].ind.type > MAX_TYPE) continue;
+
+      check_destructed(& m->hash[e].val);
+
+      if(m->hash[e].ind.type == T_OBJECT &&
+	 !m->hash[e].ind.u.object->prog)
+      {
+	free_svalue(& m->hash[e].ind);
+	free_svalue(& m->hash[e].val);
+	m->hash[e].ind.type=T_VOID;
+	m->size--;
+      }
+    }
+
+    if(m->size * 100 + 1 < m->hashsize * MIN_FILL)
+      rehash(m, m->size / 2+1);
+
+    m->val_types = val_types;
+    m->ind_types = ind_types;
+  }
+#endif
+}
+
+static struct svalue *low_mapping_lookup(struct mapping *m,
+					 struct svalue *key)
+{
+#ifndef FLAT_MAPPINGS
+  unsigned INT32 h;
+  struct keypair *k, **prev;
+
+#ifdef DEBUG
+  if(d_flag > 1) check_mapping_type_fields(m);
+#endif
+
+  if((1 << key->type) & m->ind_types)
+  {
+    h=hash_svalue(key) % m->hashsize;
+  
+    for(prev= m->hash + h;k=*prev;prev=&k->next)
+    {
+      if(is_eq(& k->ind, key))
+      {
+	*prev=k->next;
+	k->next=m->hash[h];
+	m->hash[h]=k;
+	
+	return &k->val;
+      }
+    }
+  }
+
+#else
+  unsigned INT32 h;
+
+#ifdef DEBUG
+  if(d_flag > 1) check_mapping_type_fields(m);
+#endif
+
+  if((1 << key->type) & m->ind_types)
+  {
+    h=hash_svalue(key) % m->hashsize;
+    while(m->hash[h].ind.type != T_VOID)
+    {
+      if(is_eq(& m->hash[h].ind, key))
+	return & m->hash[h].val;
+
+      if(++h == m->hashsize) h=0;
+    }
+  }
+#endif
+  return 0;
+}
+
+void mapping_index_no_free(struct svalue *dest,
+			   struct mapping *m,
+			   struct svalue *key)
+{
+  struct svalue *p;
+
+  if(p=low_mapping_lookup(m,key))
+  {
+    assign_svalue_no_free(dest, p);
+  }else{
+    dest->type=T_INT;
+    dest->u.integer=0;
+    dest->subtype=NUMBER_UNDEFINED;
+  }
+}
+
+struct array *mapping_indices(struct mapping *m)
+{
+  INT32 e;
+  struct array *a;
+  struct svalue *s;
+  struct keypair *k;
+
+  a=allocate_array(m->size);
+  s=ITEM(a);
+
+  LOOP(m) assign_svalue(s++, & k->ind);
+
+  a->type_field = m->ind_types;
+  
+  return a;
+}
+
+struct array *mapping_values(struct mapping *m)
+{
+  INT32 e;
+  struct keypair *k;
+  struct array *a;
+  struct svalue *s;
+
+  a=allocate_array(m->size);
+  s=ITEM(a);
+
+  LOOP(m)
+  {
+    check_destructed(& k->val);
+    assign_svalue(s++, & k->val);
+  }
+
+  a->type_field = m->val_types;
+  
+  return a;
+}
+
+void mapping_replace(struct mapping *m,struct svalue *from, struct svalue *to)
+{
+  INT32 e;
+  struct keypair *k;
+
+  LOOP(m)
+    if(is_eq(& k->val, from))
+      assign_svalue(& k->val, to);
+
+  m->val_types |= 1 << to->type;
+}
+
+struct mapping *mkmapping(struct array *ind, struct array *val)
+{
+  struct mapping *m;
+  struct svalue *i,*v;
+  INT32 e;
+
+#ifdef DEBUG
+  if(ind->size != val->size)
+    fatal("mkmapping on different sized arrays.\n");
+#endif
+
+  m=allocate_mapping(MAP_SLOTS(ind->size));
+  i=ITEM(ind);
+  v=ITEM(val);
+  for(e=0;e<ind->size;e++) mapping_insert(m, i++, v++);
+
+  return m;
+}
+
+struct mapping *copy_mapping(struct mapping *m)
+{
+  INT32 e;
+  struct mapping *n;
+  struct keypair *k;
+
+  n=allocate_mapping(MAP_SLOTS(m->size));
+
+  LOOP(m)
+  {
+    /* check_destructed(& k->ind); */
+    check_destructed(& k->val);
+
+    mapping_insert(n, &k->ind, &k->val);
+  }
+  
+  return m;
+}
+
+struct mapping *merge_mappings(struct mapping *a, struct mapping *b, INT32 op)
+{
+  struct array *ai, *av;
+  struct array *bi, *bv;
+  struct array *ci, *cv;
+  INT32 *zipper;
+  struct mapping *m;
+
+  ai=mapping_indices(a);
+  av=mapping_values(a);
+  zipper=get_set_order(ai);
+  order_array(ai, zipper);
+  order_array(av, zipper);
+  free((char *)zipper);
+
+  bi=mapping_indices(b);
+  bv=mapping_values(b);
+  zipper=get_set_order(bi);
+  order_array(bi, zipper);
+  order_array(bv, zipper);
+  free((char *)zipper);
+
+  zipper=merge(ai,bi,op);
+
+  ci=array_zip(ai,bi,zipper);
+  free_array(ai);
+  free_array(bi);
+
+  cv=array_zip(av,bv,zipper);
+  free_array(av);
+  free_array(bv);
+  
+  free((char *)zipper);
+
+  m=mkmapping(ci, cv);
+  free_array(ci);
+  free_array(cv);
+
+  return m;
+}
+
+struct mapping *add_mappings(struct svalue *argp, INT32 args)
+{
+  struct mapping *ret,*a,*b;
+  switch(args)
+  {
+  case 0: return allocate_mapping(0);
+  case 1: return copy_mapping(argp->u.mapping);
+  case 2: return merge_mappings(argp[0].u.mapping, argp[1].u.mapping, OP_ADD);
+  case 3:
+    a=merge_mappings(argp[0].u.mapping,argp[1].u.mapping,OP_ADD);
+    ret=merge_mappings(a,argp[2].u.mapping,OP_ADD);
+    free_mapping(a);
+    return ret;
+  default:
+    a=add_mappings(argp,args/2);
+    b=add_mappings(argp+args/2,args-args/2);
+    ret=merge_mappings(a,b,OP_ADD);
+    free_mapping(a);
+    free_mapping(b);
+    return ret;
+  }
+}
+
+int mapping_equal_p(struct mapping *a, struct mapping *b, struct processing *p)
+{
+  struct processing curr;
+  struct keypair *k;
+  INT32 e;
+
+  if(a==b) return 1;
+  if(a->size != b->size) return 0;
+
+  curr.pointer_a = a;
+  curr.pointer_b = b;
+  curr.next = p;
+
+  for( ;p ;p=p->next)
+    if(p->pointer_a == (void *)a && p->pointer_b == (void *)b)
+      return 1;
+
+  check_mapping_for_destruct(a);
+  check_mapping_for_destruct(b);
+  
+  LOOP(a)
+  {
+    struct svalue *s;
+    if(s=low_mapping_lookup(b, & k->ind))
+    {
+      if(!low_is_equal(s, &k->val, &curr)) return 0;
+    }else{
+      return 0;
+    }
+  }
+  return 1;
+}
+
+void describe_mapping(struct mapping *m,struct processing *p,int indent)
+{
+  struct processing doing;
+  INT32 e,d;
+  struct keypair *k;
+  char buf[40];
+
+  if(! m->size)
+  {
+    my_strcat("([ ])");
+    return;
+  }
+
+  doing.next=p;
+  doing.pointer_a=(void *)m;
+  for(e=0;p;e++,p=p->next)
+  {
+    if(p->pointer_a == (void *)m)
+    {
+      sprintf(buf,"@%ld",(long)e);
+      my_strcat(buf);
+      return;
+    }
+  }
+  
+  sprintf(buf,"([ /* %ld elements */\n",(long) m->size);
+  my_strcat(buf);
+
+  d=0;
+
+  LOOP(m)
+  {
+    if(!d)
+    {
+      my_strcat(",\n");
+      d=1;
+    }
+    for(d=0; d<indent; d++) my_putchar(' ');
+    describe_svalue(& k->ind, indent+2, p);
+    my_putchar(':');
+    describe_svalue(& k->val, indent+2, p);
+  }
+
+  my_putchar('\n');
+  for(e=2; e<indent; e++) my_putchar(' ');
+  my_strcat("])");
+}
+
+node * make_node_from_mapping(struct mapping *m)
+{
+  struct keypair *k;
+  INT32 e;
+
+  mapping_fix_type_field(m);
+
+  if((m->ind_types | m->val_types) & (BIT_FUNCTION | BIT_OBJECT))
+  {
+    struct array *ind, *val;
+    node *n;
+    ind=mapping_indices(m);
+    val=mapping_indices(m);
+    n=mkefuncallnode("mkmapping",mknode(F_ARG_LIST,make_node_from_array(ind),make_node_from_array(val)));
+    free_array(ind);
+    free_array(val);
+    return n;
+  }else{
+    struct svalue s;
+    s.type=T_MAPPING;
+    s.subtype=0;
+    s.u.mapping=m;
+    return mkconstantsvaluenode(&s);
+  }
+}
+
+void f_m_delete(INT32 args)
+{
+  if(args < 2)
+    error("Too few arguments to m_delete.\n");
+  if(sp[-args].type != T_MAPPING)
+    error("Bad argument to to m_delete.\n");
+
+  map_delete(sp[-args].u.mapping,sp+1-args);
+  pop_n_elems(args-1);
+}
+
+void f_aggregate_mapping(INT32 args)
+{
+  INT32 e;
+  struct keypair *k;
+  struct mapping *m;
+
+  if(args & 1)
+    error("Uneven number of arguments to aggregage_mapping.\n");
+
+  m=allocate_mapping(MAP_SLOTS(args / 2));
+
+  for(e=-args;e<0;e+=2) mapping_insert(m, sp+e, sp+e+1);
+  pop_n_elems(args);
+  push_mapping(m);
+}
+
+struct mapping *copy_mapping_recursively(struct mapping *m,
+					 struct processing *p)
+{
+  struct processing doing;
+  struct mapping *ret;
+  INT32 e;
+  struct keypair *k;
+
+  doing.next=p;
+  doing.pointer_a=(void *)m;
+  for(;p;p=p->next)
+  {
+    if(p->pointer_a == (void *)m)
+    {
+      ret=(struct mapping *)p->pointer_b;
+      ret->refs++;
+      return ret;
+    }
+  }
+
+  ret=allocate_mapping(MAP_SLOTS(m->size));
+  doing.pointer_b=ret;
+
+  LOOP(m)
+  {
+    /* check_destructed(& k->ind); */
+    check_destructed(& k->val);
+    
+    copy_svalues_recursively_no_free(sp,&k->ind, 1, p);
+    sp++;
+    copy_svalues_recursively_no_free(sp,&k->val, 1, p);
+    sp++;
+    
+    mapping_insert(ret, sp-2, sp-1);
+    pop_n_elems(2);
+  }
+
+  return ret;
+}
+
+
+void mapping_search_no_free(struct svalue *to,
+			    struct mapping *m,
+			    struct svalue *look_for,
+			    struct svalue *start)
+{
+#ifndef FLAT_MAPPINGS
+  unsigned INT32 h;
+  struct keypair *k;
+
+  h=0;
+  k=m->hash[h];
+  if(start)
+  {
+    h=hash_svalue(start) % m->hashsize;
+    for(k=m->hash[h];k;k=k->next)
+      if(is_eq(&k->ind, start))
+	break;
+
+    if(!k)
+    {
+      to->type=T_INT;
+      to->subtype=NUMBER_UNDEFINED;
+      to->u.integer=0;
+      return;
+    }
+    k=k->next;
+  }
+
+  while(h < m->hashsize)
+  {
+    while(k)
+    {
+      if(is_eq(look_for, &k->val))
+      {
+	assign_svalue_no_free(to,&k->ind);
+	return;
+      }
+      k=k->next;
+    }
+    k=m->hash[++h];
+  }
+#else
+  unsigned INT32 h;
+
+  h=0;
+  if(start)
+  {
+    h=hash_svalue(start) % m->hashsize;
+    
+    while(1)
+    {
+      if(m->hash[h].ind.type != T_VOID)
+      {
+	to->type=T_INT;
+	to->subtype=NUMBER_UNDEFINED;
+	to->u.integer=0;
+	return;
+      }
+      
+      if(is_eq(& m->hash[h].ind, start))
+	break;
+      if(++h == m->hashsize) h=0;
+    }
+    if(++h == m->hashsize) h=0;
+  }
+
+  for(h=0;h<m->hashsize;h++)
+  {
+    if(m->hash[h].ind.type <= MAX_TYPE)
+    {
+      if(is_eq(& m->hash[h].val, look_for))
+      {
+	assign_svalue_no_free(to, & m->hash[h].ind);
+	return;
+      }
+    }
+  }
+	
+#endif
+
+  to->type=T_INT;
+  to->subtype=NUMBER_UNDEFINED;
+  to->u.integer=0;
+}
+
+
+#ifdef DEBUG
+
+void check_mapping(struct mapping *m)
+{
+  if(m->refs <=0)
+    fatal("Mapping has zero refs.\n");
+
+  if(m->next && m->next->prev != m)
+    fatal("Mapping ->next->prev != mapping.\n");
+
+  if(m->prev)
+  {
+    if(m->prev->next != m)
+      fatal("Mapping ->prev->next != mapping.\n");
+  }else{
+    if(first_mapping != m)
+      fatal("Mapping ->prev == 0 but first_mapping != mapping.\n");
+  }
+
+  if(m->hashsize < 0)
+    fatal("Assert: I don't think he's going to make it Jim.\n");
+
+  if(m->size < 0)
+    fatal("Core breach, evacuate ship!\n");
+
+#ifndef FLAT_MAPPINGS
+  if(m->size > (m->hashsize + 3) * AVG_LINK_LENGTH)
+    fatal("Pretty mean hashtable there buster!.\n");
+  
+  if(m->size < (m->hashsize - 3) * MIN_LINK_LENGTH)
+    fatal("Hashsize is too small for mapping.\n");
+#endif
+  
+  if(m->size > 0 && (!m->ind_types || !m->val_types))
+    fatal("Mapping type fields are... wrong.\n");
+
+  if(!m->hash)
+    fatal("Hey! where did my hashtable go??\n");
+  
+}
+
+void check_all_mappings()
+{
+  struct mapping *m;
+  for(m=first_mapping;m;m=m->next)
+    check_mapping(m);
+}
+#endif
+
+
+#ifdef GC2
+
+void gc_mark_mapping_as_referenced(struct mapping *m)
+{
+  INT32 e;
+  struct keypair *k;
+
+  if(gc_mark(m))
+  {
+    if((m->ind_types | m->val_types) & BIT_COMPLEX)
+    {
+      LOOP(m)
+      {
+	gc_mark_svalues(&k->ind, 1);
+	gc_mark_svalues(&k->val, 1);
+      }
+    }
+  }
+}
+
+void gc_check_all_mappings()
+{
+  INT32 e;
+  struct keypair *k;
+  struct mapping *m;
+
+  for(m=first_mapping;m;m=m->next)
+  {
+    if((m->ind_types | m->val_types) & BIT_COMPLEX)
+    {
+      LOOP(m)
+      {
+	gc_check_svalues(&k->ind, 1);
+	gc_check_svalues(&k->val, 1);
+      }
+    }
+  }
+}
+
+void gc_mark_all_mappings()
+{
+  struct mapping *m;
+  for(m=first_mapping;m;m=m->next)
+    if(gc_is_referenced(m))
+      gc_mark_mapping_as_referenced(m);
+}
+
+void gc_free_all_unreferenced_mappings()
+{
+  INT32 e;
+  struct keypair *k;
+  struct mapping *m,*next;
+
+  for(m=first_mapping;m;m=next)
+  {
+    if(gc_do_free(m))
+    {
+      m->refs++;
+
+#ifndef FLAT_MAPPINGS
+      for(e=0;e<m->hashsize;e++)
+      {
+	for(k=m->hash[e];k;k=k->next)
+	{
+	  free_svalue(&k->ind);
+	  free_svalue(&k->val);
+	}
+	k->next=m->free_list;
+	m->hash[e]=0;
+      }
+#else
+      for(e=0;e<m->hashsize;m++)
+      {
+	if((k=m->hash+e)->ind.type <= MAX_TYPE)
+	{
+	  free_svalue(&k->ind);
+	  free_svalue(&k->val);
+	}
+	k->ind.type=T_VOID;
+      }
+#endif
+      m->size=0;
+
+      next=m->next;
+
+      free_mapping(m);
+    }else{
+      next=m->next;
+    }
+  }
+}
+
+#endif /* GC2 */
+
+
+#else /* OLD_MAPPINGS */
 struct mapping *first_mapping;
 
 /*
@@ -103,6 +1284,13 @@ void really_free_mapping(struct mapping *m)
   GC_FREE();
 }
 
+
+void mapping_fix_type_field(struct mapping *m)
+{
+  array_fix_type_field(m->ind);
+  array_fix_type_field(m->val);
+}
+
 static void order_mapping(struct mapping *m)
 {
   INT32 *order;
@@ -139,17 +1327,21 @@ void mapping_insert(struct mapping *m,
   }
 }
 
-#if 0
 struct array *mapping_indices(struct mapping *m)
 {
-  return m->ind;
+  return copy_array(m->ind);
 }
 
 struct array *mapping_values(struct mapping *m)
 {
-  return m->val;
+  return copy_array(m->val);
 }
-#endif
+
+void mapping_replace(struct mapping *m,struct svalue *from, struct svalue *to)
+{
+  array_replace(m->val, from, to);
+}
+
 
 void map_delete(struct mapping *m,struct svalue *ind)
 {
@@ -377,9 +1569,12 @@ struct mapping *copy_mapping_recursively(struct mapping *m,
 
   ret=allocate_mapping(&empty_array, &empty_array);
   doing.pointer_b=(void *)ret;
+  empty_array.refs+=2;
 
   ret->ind=copy_array_recursively(m->ind,&doing);
+  empty_array.refs--;
   ret->val=copy_array_recursively(m->val,&doing);
+  empty_array.refs--;
 
   order_mapping(ret);
 
@@ -496,3 +1691,4 @@ void gc_free_all_unreferenced_mappings()
 }
 
 #endif /* GC2 */
+#endif /* OLD_MAPPINGS */
diff --git a/src/mapping.h b/src/mapping.h
index 8132d4cae5..8666d8256c 100644
--- a/src/mapping.h
+++ b/src/mapping.h
@@ -8,6 +8,32 @@
 
 #include "las.h"
 
+#ifndef OLD_MAPPINGS
+#ifndef FLAT_MAPPINGS
+struct mapping
+{
+  INT32 refs, size, hashsize;
+  TYPE_FIELD ind_types, val_types;
+  struct mapping *next, *prev;
+  struct keypair **hash;
+  struct keypair *free_list;
+};
+
+#else
+struct mapping
+{
+  INT32 refs, size, hashsize;
+  TYPE_FIELD ind_types, val_types;
+  struct mapping *next, *prev;
+  struct keypair *hash;
+};
+#endif
+
+#define m_sizeof(m) ((m)->size)
+#define m_ind_types(m) ((m)->ind_types)
+#define m_val_types(m) ((m)->val_types)
+#else
+
 struct mapping
 {
   INT32 refs;
@@ -16,32 +42,38 @@ struct mapping
   struct array *val;
 };
 
+#define m_sizeof(m) (m->ind->size)
+#define m_ind_types(m) ((m)->ind->type_field)
+#define m_val_types(m) ((m)->val->type_field)
+
+#endif
+
 #define free_mapping(M) do{ struct mapping *m_=(M); if(!--m_->refs) really_free_mapping(m_); }while(0)
 
 /* Prototypes begin here */
-void mapping_index_no_free(struct svalue *dest,
-			   struct mapping *m,
-			   struct svalue *ind);
-void mapping_index(struct svalue *dest,
-		   struct mapping *m,
-		   struct svalue *ind);
+struct keypair;
+unsigned INT32 hash_svalue(struct svalue *s);
 void really_free_mapping(struct mapping *m);
-struct mapping *mkmapping(struct array *ind, struct array *val);
+void mapping_fix_type_field(struct mapping *m);
 void mapping_insert(struct mapping *m,
-		    struct svalue *ind,
-		    struct svalue *from);
-struct array *mapping_indices(struct mapping *m);
-struct array *mapping_values(struct mapping *m);
-void map_delete(struct mapping *m,struct svalue *ind);
-void check_mapping_for_destruct(struct mapping *m);
+		    struct svalue *key,
+		    struct svalue *val);
 union anything *mapping_get_item_ptr(struct mapping *m,
-				     struct svalue *ind,
+				     struct svalue *key,
 				     TYPE_T t);
-struct mapping *copy_mapping(struct mapping *tmp);
-struct mapping *merge_mappings(struct mapping *a,
-			       struct mapping *b,
-			       INT32 operator);
-struct mapping *add_mappings(struct svalue *argp,INT32 args);
+void map_delete(struct mapping *m,
+		struct svalue *key);
+void check_mapping_for_destruct(struct mapping *m);
+void mapping_index_no_free(struct svalue *dest,
+			   struct mapping *m,
+			   struct svalue *key);
+struct array *mapping_indices(struct mapping *m);
+struct array *mapping_values(struct mapping *m);
+void mapping_replace(struct mapping *m,struct svalue *from, struct svalue *to);
+struct mapping *mkmapping(struct array *ind, struct array *val);
+struct mapping *copy_mapping(struct mapping *m);
+struct mapping *merge_mappings(struct mapping *a, struct mapping *b, INT32 op);
+struct mapping *add_mappings(struct svalue *argp, INT32 args);
 int mapping_equal_p(struct mapping *a, struct mapping *b, struct processing *p);
 void describe_mapping(struct mapping *m,struct processing *p,int indent);
 node * make_node_from_mapping(struct mapping *m);
-- 
GitLab


From 39e0bd912dceb1922d1d1a4d43223e241daa87eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 16:54:31 +0200
Subject: [PATCH 190/351] more debug added

Rev: src/svalue.c:1.11
Rev: src/svalue.h:1.8
---
 src/svalue.c | 20 ++++++++++++++++++++
 src/svalue.h |  5 +++--
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/src/svalue.c b/src/svalue.c
index 0cc24edc8c..300745e4c9 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -4,6 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
+#include "main.h"
 #include "svalue.h"
 #include "stralloc.h"
 #include "array.h"
@@ -613,6 +614,8 @@ void copy_svalues_recursively_no_free(struct svalue *to,
 #ifdef DEBUG
 void check_short_svalue(union anything *u,TYPE_T type)
 {
+  static inside=0;
+
   check_type(type);
   check_refs2(u,type);
   if(!u->refs) return;
@@ -623,6 +626,23 @@ void check_short_svalue(union anything *u,TYPE_T type)
     if(!debug_findstring(u->string))
       fatal("Shared string not shared!\n");
     break;
+
+  default:
+    if(d_flag > 50)
+    {
+      if(inside) return;
+      inside=1;
+
+      switch(type)
+      {
+      case T_MAPPING: check_mapping(u->mapping); break;
+      case T_ARRAY: check_array(u->array); break;
+      case T_PROGRAM: check_program(u->program); break;
+/*      case T_OBJECT: check_object(u->object); break; */
+/*      case T_LIST: check_list(u->list); break; */
+      }
+      inside=0;
+    }
   }
 }
 
diff --git a/src/svalue.h b/src/svalue.h
index fa505ccd8f..29c3e9b7ef 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -40,7 +40,7 @@ union anything
 
 struct svalue
 {
-  INT16 type;
+  unsigned INT16 type;
   INT16 subtype;
   union anything u;
 };
@@ -55,6 +55,7 @@ struct svalue
 #define T_FLOAT 7
 #define T_INT 8
 
+#define T_DELETED 246
 #define T_NOT 247
 #define T_AND 248
 #define T_UNKNOWN 249
@@ -118,7 +119,7 @@ do{ \
 }while(0)
 
 #ifdef DEBUG
-#define check_type(T) if(T > MAX_TYPE && T!=T_LVALUE && T!=T_SHORT_LVALUE && T!=T_VOID) fatal("Type error\n")
+#define check_type(T) if(T > MAX_TYPE && T!=T_LVALUE && T!=T_SHORT_LVALUE && T!=T_VOID && T!=T_DELETED) fatal("Type error\n")
 #define check_refs(S) if((S)->type < MAX_REF_TYPE && (!(S)->u.refs || (S)->u.refs[0] < 0)) fatal("Svalue to object without references.\n")
 #define check_refs2(S,T) if((T) < MAX_REF_TYPE && (S)->refs && (S)->refs[0] <= 0) fatal("Svalue to object without references.\n")
 
-- 
GitLab


From 6557ff0e85b05c6c187c4d999c744f6e6281d624 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 16:58:17 +0200
Subject: [PATCH 191/351] small fix for mappings

Rev: src/lpc_types.c:1.5
---
 src/lpc_types.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/lpc_types.c b/src/lpc_types.c
index 9686feccc8..ffbb8b274b 100644
--- a/src/lpc_types.c
+++ b/src/lpc_types.c
@@ -928,8 +928,8 @@ struct lpc_string *get_type_of_svalue(struct svalue *s)
     return pop_type();
 
   case T_MAPPING:
-    check_array_type(s->u.mapping->ind);
-    check_array_type(s->u.mapping->val);
+    push_type(T_MIXED);
+    push_type(T_MIXED);
     push_type(T_MAPPING);
     return pop_type();
 
-- 
GitLab


From ed70b7ef5028cd5bfc60e5ccb68283bb7714d26b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 17:01:42 +0200
Subject: [PATCH 192/351] new efuns

Rev: src/builtin_efuns.c:1.18
---
 src/builtin_efuns.c | 254 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 249 insertions(+), 5 deletions(-)

diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index c0229c9cc0..d43e8809fd 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -23,6 +23,8 @@
 #include "call_out.h"
 #include "callback.h"
 #include "gc.h"
+#include "backend.h"
+#include "main.h"
 
 #if TIME_WITH_SYS_TIME
 # include <sys/time.h>
@@ -584,7 +586,7 @@ void f_sizeof(INT32 args)
     break;
 
   case T_MAPPING:
-    tmp=sp[-1].u.mapping->ind->size;
+    tmp=m_sizeof(sp[-1].u.mapping);
     free_mapping(sp[-1].u.mapping);
     break;
 
@@ -794,7 +796,7 @@ void f_indices(INT32 args)
     break;
 
   case T_MAPPING:
-    a=copy_array(sp[-args].u.mapping->ind);
+    a=mapping_indices(sp[-args].u.mapping);
     break;
 
   case T_LIST:
@@ -818,7 +820,7 @@ void f_values(INT32 args)
   INT32 size;
   struct array *a;
   if(args < 1)
-    error("Too few arguments to indices()\n");
+    error("Too few arguments to values()\n");
 
   switch(sp[-args].type)
   {
@@ -838,7 +840,7 @@ void f_values(INT32 args)
     break;
 
   case T_MAPPING:
-    a=copy_array(sp[-args].u.mapping->val);
+    a=mapping_values(sp[-args].u.mapping);
     break;
 
   case T_LIST:
@@ -1074,7 +1076,7 @@ void f_replace(INT32 args)
 
   case T_MAPPING:
   {
-    array_replace(sp[-args].u.mapping->val,sp+1-args,sp+2-args);
+    mapping_replace(sp[-args].u.mapping,sp+1-args,sp+2-args);
     pop_n_elems(args-1);
     break;
   }
@@ -1237,10 +1239,93 @@ TYPEP(f_listp, "listp", T_LIST)
 TYPEP(f_stringp, "stringp", T_STRING)
 TYPEP(f_floatp, "floatp", T_FLOAT)
 
+void f_sort(INT32 args)
+{
+  INT32 e,*order;
+
+  if(args < 0)
+    fatal("Too few arguments to sort().\n");
+
+  for(e=0;e<args;e++)
+  {
+    if(sp[e-args].type != T_ARRAY)
+      error("Bad argument %ld to sort().\n",(long)(e+1));
+
+    if(sp[e-args].u.array->size != sp[-args].u.array->size)
+      error("Argument %ld to sort() has wrong size.\n",(long)(e+1));
+  }
+
+  order=get_alpha_order(sp[-args].u.array);
+  for(e=0;e<args;e++) order_array(sp[e-args].u.array,order);
+  free((char *)order);
+  pop_n_elems(args-1);
+}
+
+void f_rows(INT32 args)
+{
+  INT32 e;
+  struct array *a,*tmp;
+
+  if(args < 2)
+    error("Too few arguments to rows().\n");
+
+  if(sp[1-args].type!=T_ARRAY)
+    error("Bad argument 1 to rows().\n");
+
+  tmp=sp[1-args].u.array;
+  push_array(a=allocate_array(tmp->size));
+
+  for(e=0;e<a->size;e++)
+    index_no_free(ITEM(a)+e, sp-args-1, ITEM(tmp)+e);
+
+  a->refs++;
+  pop_n_elems(args+1);
+  push_array(a);
+}
+
+void f_column(INT32 args)
+{
+  INT32 e;
+  struct array *a,*tmp;
+
+  if(args < 2)
+    error("Too few arguments to column().\n");
+
+  if(sp[-args].type!=T_ARRAY)
+    error("Bad argument 1 to column().\n");
+
+  tmp=sp[-args].u.array;
+  push_array(a=allocate_array(tmp->size));
+
+  for(e=0;e<a->size;e++)
+    index_no_free(ITEM(a)+e, ITEM(tmp)+e, sp-args);
+
+  a->refs++;
+  pop_n_elems(args+1);
+  push_array(a);
+}
+
+#ifdef DEBUG
+void f__verify_internals(INT32 args)
+{
+  INT32 tmp;
+  tmp=d_flag;
+  d_flag=0x7fffffff;
+  do_debug();
+  d_flag=tmp;
+  pop_n_elems(args);
+}
+
+#endif
+
 void init_builtin_efuns()
 {
   init_operators();
 
+#ifdef DEBUG
+  add_efun("_verify_internals",f__verify_internals,"function(:void)",OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND);
+#endif
+
   add_efun("add_efun",f_add_efun,"function(string,void|mixed:void)",OPT_SIDE_EFFECT);
   add_efun("aggregate",f_aggregate,"function(mixed ...:mixed *)",OPT_TRY_OPTIMIZE);
   add_efun("aggregate_list",f_aggregate_list,"function(mixed ...:list)",OPT_TRY_OPTIMIZE);
@@ -1299,9 +1384,168 @@ void init_builtin_efuns()
   add_efun("upper_case",f_upper_case,"function(string:string)",0);
   add_efun("values",f_values,"function(string|list:int*)|function(array|mapping|object:mixed*)",0);
   add_efun("zero_type",f_zero_type,"function(int:int)",0);
+  add_efun("sort",f_sort,"function(array(mixed),array(mixed)...:array(mixed))",OPT_SIDE_EFFECT);
+  add_efun("column",f_column,"function(array,mixed:array)",0);
+  add_efun("rows",f_rows,"function(mixed,array:array)",0);
 #ifdef GC2
   add_efun("gc",f_gc,"function(:int)",OPT_SIDE_EFFECT);
 #endif
 }
 
 
+#if 0
+/* Check if the glob s[0..len[ matches the string m[0..mlen[ */
+static int does_match(char *s, int len, char *m, int mlen)
+{
+  int i,j;
+  for (i=j=0; i<mlen && j<len; i++,j++)
+  {
+    switch (m[i])
+    {
+     case '?': break;
+
+     case '*': 
+      i++;
+      if (i==mlen) return 1;	/* slut */
+
+      for (;j<len;j++)
+	if (does_match(s+j,len-j,m+i,mlen-i))
+	  return 1;
+
+      return 0;
+
+     default: 
+      if (m[i]!=s[j]) return 0;
+    }
+  }
+  if (i==mlen && j==len) return 1;
+  return 0;
+}
+
+void f_glob(INT32 args)
+{
+  INT32 i,matches;
+  struct array *a;
+  struct svalue *sval, *tmp;
+  struct lpc_string *glob;
+
+  if(args < 2)
+    error("Too few arguments to glob().\n");
+
+  if(args > 2) pop_n_elems(args-2);
+
+  if (sp[1-args].type!=T_STRING)
+    error("Bad argument 2 to glob().\n");
+
+  glob=sp[-args].u.string;
+
+  switch(sp[-args].type)
+  {
+  case T_STRING:
+    i=do_match(sp[1-args].u.string,
+	       sp[1-args].u.string->length,
+	       glob,
+	       glob->length);
+    pop_n_elems(2);
+    push_int(i);
+    break;
+    
+  case T_ARRAY:
+    a=sp[-args].u.array;
+    for(i=0;i<a->size;i++)
+    {
+      if(do_match(ITEM(a)[i].u.string,
+		  ITEM(a)[i].u.string->length,
+		  glob,
+		  glob->length))
+      {
+	ITEM(a)[i].u.string->refs++;
+	push_string(ITEM(a)[i].u.string);
+	matches++;
+      }
+    }
+    f_aggregate(matches);
+    tmp=sp[-1];
+    sp--;
+    pop_n_elems(2);
+    sp[0]=tmp;
+    sp++;
+    break;
+
+  default:
+    error("Bad argument 2 to glob().\n");
+  }
+}
+
+
+/*
+ * add_efun("glob",f_glob,"function(string,string:string)|function(string,array(string):array(string))",0);
+ * add_efun("localtime",f_localtime,
+ * "function(int:mapping(string:int))",OPT_EXTERNAL_DEPEND);
+ */
+
+#if !HAVE_INT_TIMEZONE
+int _tz;
+#else
+extern long int timezone;
+#endif
+
+
+
+void f_localtime(INT32 args)
+{
+  struct tm *tm;
+  time_t t;
+  if (args<1||
+      sp[-1].type!=T_INT)
+    error("Illegal argument to localtime");
+  t=sp[-1].u.integer;
+  tm=localtime(&t);
+  pop_stack();
+  push_string(make_shared_string("sec"));
+  push_int(tm->tm_sec);
+  push_string(make_shared_string("min"));
+  push_int(tm->tm_min);
+  push_string(make_shared_string("hour"));
+  push_int(tm->tm_hour);
+
+  push_string(make_shared_string("mday"));
+  push_int(tm->tm_mday);
+  push_string(make_shared_string("mon"));
+  push_int(tm->tm_mon);
+  push_string(make_shared_string("year"));
+  push_int(tm->tm_year);
+
+  push_string(make_shared_string("wday"));
+  push_int(tm->tm_wday);
+  push_string(make_shared_string("yday"));
+  push_int(tm->tm_yday);
+  push_string(make_shared_string("isdst"));
+  push_int(tm->tm_isdst);
+
+  push_string(make_shared_string("timezone"));
+#if !HAVE_INT_TIMEZONE
+  push_int(_tz);
+#else
+  push_int(timezone);
+#endif
+  f_aggregate_mapping(20);
+}
+
+#ifdef HAVE_STRERROR
+void f_strerror(INT32 args)
+{
+  char *s;
+  if(!args) 
+    s=strerror(errno);
+  else
+    s=strerror(sp[-args].u.integer);
+  pop_n_elems(args);
+  if(s)
+    push_text(s);
+  else
+    push_int(0);
+}
+#endif
+
+#endif
-- 
GitLab


From 41a0f47df144d56c0ccf40a410e1f825505b6e05 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 17:02:16 +0200
Subject: [PATCH 193/351] make gdb_verify fixed

Rev: src/Makefile.src:1.5
---
 src/Makefile.src | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/Makefile.src b/src/Makefile.src
index 931e4e12b7..1b1a934092 100644
--- a/src/Makefile.src
+++ b/src/Makefile.src
@@ -155,9 +155,10 @@ verbose_verify: $(SRCDIR)/test/testsuite
 
 # verify & debug VERBOSE
 gdb_verify: $(SRCDIR)/test/testsuite
-	echo >.gdbinit handle SIGUSR1 nostop noprint pass
-	echo >>.gdbinit run -m $(TMP_LIBDIR)/master.lpc $(SRCDIR)/test/test_lpc.lpc $(SRCDIR)/test/testsuite -v -v -f
+	@echo >.gdbinit handle SIGUSR1 nostop noprint pass
+	@echo >>.gdbinit run -m $(TMP_LIBDIR)/master.lpc $(LPCOPTS) $(SRCDIR)/test/test_lpc.lpc $(SRCDIR)/test/testsuite -v -v -f
 	gdb ./ulpc
+	@rm .gdbinit
 
 # run hilfe, for interactive testing
 run_hilfe:
-- 
GitLab


From 4ecaeb286524a82e205e9ab2d2c5f53f176da0ba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 17:04:42 +0200
Subject: [PATCH 194/351] mapping fixes to exec()

Rev: src/modules/files/efuns.c:1.5
---
 src/modules/files/efuns.c | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/src/modules/files/efuns.c b/src/modules/files/efuns.c
index 28cf14afc2..d5ba229368 100644
--- a/src/modules/files/efuns.c
+++ b/src/modules/files/efuns.c
@@ -252,12 +252,11 @@ void f_exece(INT32 args)
     if(sp[2-args].type != T_MAPPING)
       error("Bad argument 3 to exece().\n");
     en=sp[2-args].u.mapping;
-    array_fix_type_field(en->ind);
-    array_fix_type_field(en->val);
+    mapping_fix_type_field(en);
 
-    if(en->ind->type_field & ~BIT_STRING)
+    if(m_ind_types(en) & ~BIT_STRING)
       error("Bad argument 3 to exece().\n");
-    if(en->val->type_field & ~BIT_STRING)
+    if(m_val_types(en) & ~BIT_STRING)
       error("Bad argument 3 to exece().\n");
 
   case 2:
@@ -287,24 +286,26 @@ void f_exece(INT32 args)
 
   if(en)
   {
-    env=(char **)xalloc((1+en->ind->size) * sizeof(char *));
+    INT32 e;
+    struct array *i,*v;
 
-    for(e=0;e<en->ind->size;e++)
-    {
-      union anything *a;
-      a=low_array_get_item_ptr(en->ind,e,T_STRING);
-      push_string(a->string);
-      a->string->refs++;
+    env=(char **)xalloc((1+m_sizeof(en)) * sizeof(char *));
 
+    i=mapping_indices(en);
+    v=mapping_values(en);
+    
+    for(e=0;e<i->size;e++)
+    {
+      push_string(ITEM(i)[e].u.string);
       push_string(make_shared_string("="));
-      a=low_array_get_item_ptr(en->val,e,T_STRING);
-      push_string(a->string);
-      a->string->refs++;
-
+      push_string(ITEM(v)[e].u.string);
       f_add(3);
-
       env[e]=sp[-1].u.string->str;
+      sp--;
     }
+      
+    free_array(i);
+    free_array(v);
     env[e]=0;
   }else{
     env=environ;
-- 
GitLab


From 178cbc4cc742ff7b6818b95d95b59a314479da4b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 17:06:02 +0200
Subject: [PATCH 195/351] second argument to file->read added

Rev: src/modules/files/doc/file:1.2
Rev: src/modules/files/file.c:1.14
---
 src/modules/files/doc/file |  8 ++++++++
 src/modules/files/file.c   | 12 +++++++++++-
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/src/modules/files/doc/file b/src/modules/files/doc/file
index 53fc4eb76d..3c59c294f2 100644
--- a/src/modules/files/doc/file
+++ b/src/modules/files/doc/file
@@ -76,11 +76,19 @@ NAME
 
 SYNTAX
 	string file->read(int nbytes);
+	or
+	string file->read(int nbytes, int notall);
 
 DESCRIPTION
 	Read tries to read nbytes bytes from the file, and return it as a
 	string. If something goes wrong, zero is returned.
 
+	If a one is given as second argument to read(), read will not try
+	it's best to read as many bytes as you asked it to read, it will
+	merely try to read as many bytes as the system read function will
+	return. This mainly useful with stream devices which can return
+	exactly one row or packet at a time.
+
 SEE ALSO
 	file->write
 
diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index 40363df50a..372c47658c 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -194,7 +194,7 @@ static void free_dynamic_buffer(dynamic_buffer *b) { free(b->s.str); }
 
 static void file_read(INT32 args)
 {
-  INT32 i, r, bytes_read;
+  INT32 i, r, bytes_read, all;
   ONERROR ebuf;
 
   if(args<1 || sp[-args].type != T_INT)
@@ -203,6 +203,13 @@ static void file_read(INT32 args)
   if(FD < 0)
     error("File not open.\n");
 
+  if(args > 1 && !IS_ZERO(sp+1-args))
+  {
+    all=0;
+  }else{
+    all=1;
+  }
+
   r=sp[-args].u.integer;
 
   pop_n_elems(args);
@@ -226,6 +233,7 @@ static void file_read(INT32 args)
       {
 	r-=i;
 	bytes_read+=i;
+	if(!all) break;
       }
       else if(i==0)
       {
@@ -274,12 +282,14 @@ static void file_read(INT32 args)
       {
 	r-=i;
 	bytes_read+=i;
+	if(!all) break;
       }
       else if(i>0)
       {
 	bytes_read+=i;
 	r-=i;
 	low_make_buf_space(i - try_read, &b);
+	if(!all) break;
       }
       else if(i==0)
       {
-- 
GitLab


From 2b6af6ed192a4d879579499e277c6ec05d811e43 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 17:08:53 +0200
Subject: [PATCH 196/351] small bugfix

Rev: src/modules/gdbmmod/gdbmmod.c:1.3
---
 src/modules/gdbmmod/gdbmmod.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/modules/gdbmmod/gdbmmod.c b/src/modules/gdbmmod/gdbmmod.c
index 908e7119e9..373c1de437 100644
--- a/src/modules/gdbmmod/gdbmmod.c
+++ b/src/modules/gdbmmod/gdbmmod.c
@@ -270,7 +270,7 @@ void init_gdbmmod_programs(void)
   start_new_program();
   add_storage(sizeof(struct gdbm_glue));
   
-  add_function("create",gdbmmod_create,"function(void|string:void)",0);
+  add_function("create",gdbmmod_create,"function(void|string,void|string:void)",0);
 
   add_function("close",gdbmmod_close,"function(:void)",0);
   add_function("store",gdbmmod_store,"function(string,string:int)",0);
-- 
GitLab


From c7dbb61ac34357cac0afa373bc367d8902149f4e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 17:10:16 +0200
Subject: [PATCH 197/351] more tests added

Rev: src/test/create_testsuite:1.17
Rev: src/test/test_lpc.lpc:1.3
---
 src/test/create_testsuite | 162 ++++++++++++++++++++++++++++++++++++--
 src/test/test_lpc.lpc     |  31 +++++++-
 2 files changed, 187 insertions(+), 6 deletions(-)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 60210691d6..9ba22d67bb 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -74,6 +74,163 @@ test_program([[int b=1,c; int a() { c=b+2; return c==3; }]])
 test_true([[ ("foobar"/"o") & ({ "foo" }) ]])
 test_any([[ array a="foo bar"/" "; return sizeof(a & ({"foo"}))]],1)
 
+
+// sort
+test_equal(sort(({1,3,2,4})),({1,2,3,4}))
+test_equal(sort(({4,3,2,1})),({1,2,3,4}))
+test_equal([[lambda() {string *a=({1,2,3,4}); sort(({4,3,2,1}),a); return a; }()]],[[({4,3,2,1})]] )
+test_equal([[lambda() {string *a=({1,2,3,4}),*b=a+({}); sort(({4,3,2,1}),a,b); return b; }()]],[[({4,3,2,1})]] )
+
+
+// m_delete
+test_equal(([1:1]),m_delete(a(),0))
+test_equal(([1:1]),m_delete(([1:1,0:3]),0))
+test_any(mapping a=([1:1]); return a==m_delete(a,1),1)
+test_any([[mapping m=([]); m[1]++; return m[1];]],1)
+test_any([[mapping m=([1:1]); m[1]++; return m[1];]],2)
+test_any([[mapping m=([]); m[1]++; m[1]++; return m[1];]],2)
+
+// mapping tests
+
+test_any([[mapping m=([]);int e;
+  for(e=0;e<1000;e++) m[e]=e;
+  for(e=0;e<1000;e++) if(m[e]!=e) return 0;
+  return 1;
+]],1)
+
+test_any([[mapping m=([]);int e;
+  for(e=0;e<1000;e++) m[e]=e;
+  for(e=999;e>=0;e--) if(m[e]!=e) return 0;
+  return 1;
+]],1)
+
+
+test_any([[mapping m=([]);int e;
+  for(e=999;e>=0;e--) m[e]=e;
+  for(e=0;e<1000;e++) if(m[e]!=e) return 0;
+  return 1;
+]],1)
+
+test_any([[mapping m=([]);int e;
+  for(e=999;e>=0;e--) m[e]=e;
+  for(e=999;e>=0;e--) if(m[e]!=e) return 0;
+  return 1;
+]],1)
+
+
+test_any([[mapping m=([]);int e;
+  for(e=0;e<1000;e++) m[reverse(e)]=e;
+  for(e=0;e<1000;e++) if(m[reverse(e)]!=e) return 0;
+  return 1;
+]],1)
+
+
+test_any([[mapping m=([]);int e;
+  for(e=999;e>=0;e--) m[reverse(e)]=e;
+  for(e=0;e<1000;e++) if(m[reverse(e)]!=e) return 0;
+  return 1;
+]],1)
+
+
+test_any([[mapping m=([]);int e;
+  for(e=0;e<1000;e++) m[reverse(e)]=e;
+  for(e=0;e<1000;e++) m_delete(m,reverse(e));
+  return sizeof(m);
+]],0)
+
+test_any([[mapping m=([]);int e;
+  for(e=0;e<1000;e++) m[reverse(e)]=e;
+  for(e=0;e<1000;e+=2) m_delete(m,reverse(e));
+  for(e=0;e<1000;e+=2) if(m[reverse(e)]) return 0;
+  for(e=1;e<1000;e+=2) if(m[reverse(e)]!=e) return 0;
+  return 1;
+]],1)
+
+test_any([[mapping m=([]);int e;
+  for(e=0;e<1000;e++) m[reverse(e)]=e;
+  for(e=0;e<1000;e++) m[reverse(e)]++;
+  for(e=0;e<1000;e++) if(m[reverse(e)]!=e+1) return 0;
+  return 1;
+]],1)
+
+test_any([[mapping m=([]);int e;
+  mixed a,b;
+  a=allocate(1000);
+  b=allocate(1000);
+  for(e=0;e<1000;e++)
+  {
+    m[reverse(e)]=e;
+    a[e]=reverse(e);
+    b[e]=e;
+  }
+  add_efun("mtest_m",m);
+  add_efun("mtest_i",a);
+  add_efun("mtest_v",b);
+  return 1;
+]],1)
+
+
+test_eq([[sizeof(mtest_m)]],sizeof(mtest_i))
+test_equal(sort_array(indices(mtest_m)),sort_array(mtest_i))
+test_equal(sort_array(values(mtest_m)),sort_array(mtest_v))
+test_equal(mtest_m,copy_value(mtest_m))
+test_any([[int e; for(e=0;e<1000;e++) if(!equal(mtest_m[mtest_i[e] ],mtest_v[e])) return 0; return 1;]],1)
+
+
+test_any([[mapping m=([]);int e;
+  mixed a,b;
+  a=allocate(100);
+  b=allocate(100);
+  for(e=0;e<100;e++)
+  {
+    m[reverse(e)]=e;
+    a[e]=reverse(e);
+    b[e]=reverse(e);
+  }
+  add_efun("mtest_m2",m);
+  add_efun("mtest_i2",a);
+  add_efun("mtest_v2",b);
+  return 1;
+]],1)
+
+test_equal(sort_array(indices(mtest_m|mtest_m2)),sort_array(mtest_i|mtest_i2))
+test_equal(sort_array(indices(mtest_m&mtest_m2)),sort_array(mtest_i&mtest_i2))
+test_equal(sort_array(indices(mtest_m-mtest_m2)),sort_array(mtest_i-mtest_i2))
+test_equal(sort_array(indices(mtest_m^mtest_m2)),sort_array(mtest_i^mtest_i2))
+test_equal(sort_array(indices(mtest_m2|mtest_m)),sort_array(mtest_i2|mtest_i))
+test_equal(sort_array(indices(mtest_m2&mtest_m)),sort_array(mtest_i2&mtest_i))
+test_equal(sort_array(indices(mtest_m2-mtest_m)),sort_array(mtest_i2-mtest_i))
+test_equal(sort_array(indices(mtest_m2^mtest_m)),sort_array(mtest_i2^mtest_i))
+
+define(MTEST,[[test_equal([[mkmapping(indices(allocate($1)),reverse(indices(allocate($1))))]],[[mkmapping(reverse(indices(allocate($1))),indices(allocate($1)))]])]])
+
+MTEST(0)
+MTEST(1)
+MTEST(2)
+MTEST(3)
+MTEST(5)
+MTEST(8)
+MTEST(13)
+MTEST(21)
+MTEST(34)
+MTEST(55)
+
+define([[MTEST]])
+
+test_do(add_efun("mtest_m"); add_efun("mtest_i"); add_efun("mtest_v");)
+test_do(add_efun("mtest_m2"); add_efun("mtest_i2"); add_efun("mtest_v2");)
+
+// rows
+test_equal([[rows(({1,2,3,4,5,6,7,8,9}),({6,7,2}))]],[[({7,8,3})]])
+test_equal([[rows(({1,2,3,4,5,6,7,8,9}),({0,4,1}))]],[[({1,5,2})]])
+test_equal([[rows(({1,2,3,4,5,6,7,8,9}),({8,3,5}))]],[[({9,4,6})]])
+
+// column
+test_equal([[column(({({1,2,3}),({5,6,7}),({8,9,0})}),0)]],[[({1,5,8})]])
+test_equal([[column(({({1,2,3}),({5,6,7}),({8,9,0})}),1)]],[[({2,6,9})]])
+test_equal([[column(({({1,2,3}),({5,6,7}),({8,9,0})}),2)]],[[({3,7,0})]])
+
+
 // gc
 ifefun(gc,
 [[
@@ -1709,11 +1866,6 @@ test_true(zero_type(find_call_out(a)))
 test_do(remove_call_out(call_out_info()[-1][2]))
 test_true(!sizeof(call_out_info()) || function_name(call_out_info()[-1][2])!="a")
 
-// m_delete
-test_equal(([1:1]),m_delete(a(),0))
-test_equal(([1:1]),m_delete(([1:1,0:3]),0))
-test_any(mapping a=([1:1]); return a==m_delete(a,1),1)
-
 test_program(int b=10; mixed a() { return 1; })
 test_program(mixed b=10; mixed a() { return 1;})
 test_define_program(/test,[[int q,w,e,r,t; mixed foo() { return 10; }]])
diff --git a/src/test/test_lpc.lpc b/src/test/test_lpc.lpc
index 58b63477e5..600927a0e9 100755
--- a/src/test/test_lpc.lpc
+++ b/src/test/test_lpc.lpc
@@ -1,8 +1,13 @@
 #!/usr/local/bin/ulpc
 
+#if !efun(_verify_internals)
+#define _verify_internals()
+#endif
+
+
 int main(int argc, string *argv)
 {
-  int e, verbose, successes, errors, t;
+  int e, verbose, successes, errors, t, check;
   string *tests;
   program testprogram;
   int start, fail;
@@ -47,6 +52,11 @@ int main(int argc, string *argv)
 	t+=arg;
 	break;
 
+      case "-c":
+      case "--check":
+	check++;
+	break;
+
       default:
 	if(tests)
 	{
@@ -70,6 +80,8 @@ int main(int argc, string *argv)
     object o;
     mixed a,b;
 
+    if(check) _verify_internals();
+
     test=tests[e];	
     if(sscanf(test,"COND %s\n%s",condition,test)==2)
     {
@@ -92,6 +104,8 @@ int main(int argc, string *argv)
 	perror(test+"\n");
     }
 
+    if(check > 1) _verify_internals();
+
     switch(type)
     {
     case "COMPILE_ERROR":
@@ -123,11 +137,16 @@ int main(int argc, string *argv)
     default:
       o=clone(compile_string(test,"Test "+(e+1)));
 
+      if(check > 1) _verify_internals();
+
       a=b=0;
       if(t) trace(t);
       if(functionp(o->a)) a=o->a();
       if(functionp(o->b)) b=o->b();
       if(t) trace(0);
+
+      if(check > 1) _verify_internals();
+
       switch(type)
       {
       case "FALSE":
@@ -179,6 +198,9 @@ int main(int argc, string *argv)
 	errors++;
       }
     }
+
+    if(check > 2) _verify_internals();
+
     if(fail && errors)
       exit(1);
   }
@@ -188,6 +210,13 @@ int main(int argc, string *argv)
     perror("Errors + Successes != number of tests!\n");
     errors++;
   }
+
+  if(successes < 5000)
+  {
+    perror("Tests are missing!\n");
+    errors++;
+  }
+
   if(errors || verbose)
   {
     perror("Failed tests: "+errors+".\n");
-- 
GitLab


From 60c8321667d2b40319222ae6aa83408412778a00 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sun, 9 Jun 1996 17:12:38 +0200
Subject: [PATCH 198/351] entries added

Rev: src/ChangeLog:1.37
---
 src/ChangeLog | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 006811a3c7..5b6155400c 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,20 @@
+Sun Jun  9 16:33:16 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
+
+	* second argument to file->read() added
+	* 2 new mapping implementations, the default one is an open
+	  hashtable implementation.
+	* new efuns: sort, rows, column, _verify_internals
+	* lpc_signal.c: signal calling is now blocked when inside
+	  a signal call.
+	* soon available: glob, localtime, strerror
+
+Thu May 30 03:12:15 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
+
+	* file->read() now takes a second argument which can tell it
+	  that it sould only make one read()
+	* new efun: sort()
+	* new mapping implementation (hashed mappings)
+
 Mon May 27 03:39:20 1996  Fredrik Hubinette  <hubbe@axel.signum.se>
 
 	* uLPC v1.0E-8 released
-- 
GitLab


From 8f4f88fd718f3333e6ef0755d717442a2ad1187f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 20 Jun 1996 18:12:20 +0200
Subject: [PATCH 199/351] new callback stuff

Rev: src/builtin_efuns.c:1.19
Rev: src/callback.c:1.2
Rev: src/callback.h:1.2
Rev: src/main.c:1.6
---
 src/builtin_efuns.c |  12 +++--
 src/callback.c      | 125 ++++++++++++++++++++------------------------
 src/callback.h      |  18 +++----
 src/main.c          |  11 ++--
 4 files changed, 77 insertions(+), 89 deletions(-)

diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index d43e8809fd..b2e70f6a80 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -657,12 +657,13 @@ void f_throw(INT32 args)
   throw();
 }
 
-static struct callback_list *exit_callbacks=0;
+static struct callback *exit_callbacks=0;
 
-struct callback_list *add_exit_callback(struct array *a)
+struct callback *add_exit_callback(callback call,
+				   void *arg,
+				   callback free_func)
 {
-  return add_to_callback_list(&exit_callbacks, a);
-
+  return add_to_callback(&exit_callbacks, call, arg, free_func);
 }
 
 void f_exit(INT32 args)
@@ -674,7 +675,8 @@ void f_exit(INT32 args)
   if(sp[-args].type != T_INT)
     error("Bad argument 1 to exit.\n");
 
-  call_and_free_callback_list(& exit_callbacks);
+  call_callback(&exit_callbacks);
+  free_callback(&exit_callbacks);
 
   i=sp[-args].u.integer;
 #ifdef DEBUG
diff --git a/src/callback.c b/src/callback.c
index 414b5eb331..2cd1ef7888 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -6,108 +6,95 @@
 #include "macros.h"
 #include "callback.h"
 
-struct callback_list
+struct callback
 {
-  struct callback_list *next;
-  struct callback call;
+  struct callback *next;
+  callback_func call;
+  callback_func free_func;
+  void *arg;
 };
 
 struct callback *first_callback =0;
+struct callback *free_callbacks =0;
 
-void unlink_callback(struct callback *c)
-{
-  if(c->next) c->next->prev=c->prev;
-  if(c->prev) c->prev->next=c->next;
-}
+#define CALLBACK_CHUNK 128
 
-void link_callback(struct callback *c)
-{
-  if(first_callback) first_callback->prev=c;
-  first_callback=c;
-  c->next=first_callback;
-  c->prev=0;
-}
+struct callback_block {
+  struct callback_block *next;
+  struct callback callbacks[CALLBACK_CHUNK];
+};
 
-void do_callback(struct callback *c)
+static struct callback *get_free_callback()
 {
-  c->args->refs++;
-  push_array_items(c->args);
-  f_call_function(c->args->size);
-}
+  struct callback *tmp;
+  if(!(tmp=free_callbacks))
+  {
+    int e;
+    struct callback_block *tmp2;
+    tmp1=ALLOC_STRUCT(callback_block);
 
-void unlink_and_call_callback(struct callback *c)
-{
-  int size;
-  size=c->args->size;
-  push_array_items(c->args);
-  c->args=0;
-  f_call_function(size);
-  unlink_callback(c);
+    for(e=0;e<sizeof(CALLBACK_CHUNK);e++)
+    {
+      tmp1->callbacks[e].next=tmp;
+      tmp=tmp1->callbacks+e;
+    }
+  }
+  free_callbacks=tmp->next;
+  return tmp;
 }
 
-/*** ***/
-
-void call_callback_list(struct callback_list **ptr)
+void call_callback(struct callback **ptr)
 {
-  struct callback_list *l;
+  struct callback *l;
   while(l=*ptr)
   {
-    if(l->call.args)
+    if(l->call) l->call(l,l->arg);
+
+    if(!l->call)
     {
-      do_callback(& l->call);
-      ptr=& l->next;
-    }else{
-      unlink_callback(& l->call);
       *ptr=l->next;
       free((char *)l);
+    }else{
+      ptr=& l->next;
+      l->next=free_callbacks;
+      free_callbacks=l;
     }
   }
 }
 
-/* NOTICE, eats one reference off array! */
-struct callback_list *add_to_callback_list(struct callback_list **ptr, struct array *a)
+struct callback *add_to_callback(struct callback **ptr,
+					   callback call,
+					   void *arg,
+					   callback free_func)
 {
-  struct callback_list *l;
-  l=ALLOC_STRUCT(callback_list);
-  link_callback(& l->call);
-  l->call.args=a;
+  struct callback *l;
+  l=get_free_callback();
+  l->call=call;
+  l->arg=arg;
+
   l->next=*ptr;
   *ptr=l;
-  return l;
-}
 
-void remove_callback(struct callback_list *l)
-{
-  free_array(l->call.args);
-  l->call.args=0;
+  return l;
 }
 
-void free_callback_list(struct callback_list **ptr)
+/* It is not actually freed until next time this callback is called
+ */
+void *remove_callback(struct callback *l)
 {
-  struct callback_list *l;
-  while(l=*ptr)
-  {
-    if(l->call.args)
-      free_array(l->call.args);
-      
-    unlink_callback(& l->call);
-    *ptr=l->next;
-    free((char *)l);
-  }
+  l->call=0;
+  return l->arg;
 }
 
-void call_and_free_callback_list(struct callback_list **ptr)
+void free_callback(struct callback **ptr)
 {
-  struct callback_list *l;
+  struct callback *l;
   while(l=*ptr)
   {
-    if(l->call.args)
-      unlink_and_call_callback(& l->call);
-    else
-      unlink_callback(& l->call);
-      
+    if(l->call.arg && l->call.free_func)
+      l->call.free_func(l, l->call.arg);
     *ptr=l->next;
-    free((char *)l);
+    l->next=free_callbacks;
+    free_callbacks=l;
   }
 }
-
diff --git a/src/callback.h b/src/callback.h
index ff8fd35afa..46c4e152a7 100644
--- a/src/callback.h
+++ b/src/callback.h
@@ -9,19 +9,15 @@
 #include "array.h"
 
 /* Prototypes begin here */
-struct callback
-{
-  struct callback *next, *prev;
-  struct array *args;
-};
 struct callback_list;
-void unlink_callback(struct callback *c);
-void link_callback(struct callback *c);
-void do_callback(struct callback *c);
-void unlink_and_call_callback(struct callback *c);
+struct callback_block;
 void call_callback_list(struct callback_list **ptr);
-struct callback_list *add_to_callback_list(struct callback_list **ptr, struct array *a);
-void remove_from_callback_list(struct callback_list *l);
+struct callback_list *add_to_callback_list(struct callback_list **ptr,
+					   callback call,
+					   void *arg);
+void *remove_callback(struct callback_list *l);
+void free_callback_list(struct callback_list **ptr);
+void call_and_free_callback_list(struct callback_list **ptr);
 /* Prototypes end here */
 
 #endif
diff --git a/src/main.c b/src/main.c
index e1fc8a391d..e51e01d9bf 100644
--- a/src/main.c
+++ b/src/main.c
@@ -48,11 +48,13 @@ int t_flag=0;
 int a_flag=0;
 int l_flag=0;
 
-static struct callback_list *post_master_callbacks =0;
+static struct callback *post_master_callbacks =0;
 
-struct callback_list *add_post_master_callback(struct array *a)
+struct callback *add_post_master_callback(callback call,
+					  void *arg,
+					  callback free_func)
 {
-  return add_to_callback_list(&post_master_callbacks, a);
+  return add_to_callback_list(&post_master_callbacks, call, arg, free_func);
 }
 
 
@@ -166,7 +168,8 @@ void main(int argc, char **argv, char **env)
 
   init_modules_efuns();
   master();
-  call_and_free_callback_list(& post_master_callbacks);
+  call_callback(& post_master_callbacks);
+  free_callback(& post_master_callbacks);
   init_modules_programs();
 
   a=allocate_array_no_init(argc-e,0);
-- 
GitLab


From e8c235709f2f1cb271aa5f9efd43abd7f29c51a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 20:17:00 +0200
Subject: [PATCH 200/351] new efuns

Rev: doc/builtin/_verify_internals:1.1
Rev: doc/builtin/call_out:1.2(DEAD)
Rev: doc/builtin/call_out_info:1.3(DEAD)
Rev: doc/builtin/find_call_out:1.2(DEAD)
Rev: doc/builtin/glob:1.1
Rev: doc/builtin/localtime:1.1
Rev: doc/builtin/remove_call_out:1.2(DEAD)
---
 doc/builtin/_verify_internals | 13 +++++++++++++
 doc/builtin/call_out          | 12 ------------
 doc/builtin/call_out_info     | 22 ----------------------
 doc/builtin/find_call_out     | 13 -------------
 doc/builtin/glob              | 17 +++++++++++++++++
 doc/builtin/localtime         | 29 +++++++++++++++++++++++++++++
 doc/builtin/remove_call_out   | 14 --------------
 7 files changed, 59 insertions(+), 61 deletions(-)
 create mode 100644 doc/builtin/_verify_internals
 delete mode 100644 doc/builtin/call_out
 delete mode 100644 doc/builtin/call_out_info
 delete mode 100644 doc/builtin/find_call_out
 create mode 100644 doc/builtin/glob
 create mode 100644 doc/builtin/localtime
 delete mode 100644 doc/builtin/remove_call_out

diff --git a/doc/builtin/_verify_internals b/doc/builtin/_verify_internals
new file mode 100644
index 0000000000..b1793ffed5
--- /dev/null
+++ b/doc/builtin/_verify_internals
@@ -0,0 +1,13 @@
+NAME
+	_verify_internals - check uLPC internals
+
+SYNTAX
+	void _verify_internals();
+
+DESCRIPTION
+	This function goes through most of the internal uLPC structures and
+	generates a fatal error if one of them is found to be out of order.
+	It is only used for debugging.
+
+KEYWORDS
+	debugging
diff --git a/doc/builtin/call_out b/doc/builtin/call_out
deleted file mode 100644
index 6eccf4ad52..0000000000
--- a/doc/builtin/call_out
+++ /dev/null
@@ -1,12 +0,0 @@
-NAME
-	call_out - make a delayed call to a function
-
-SYNTAX
-	void call_out(function f, int delay, mixed ... args);
-
-DESCRIPTION
-	Call_out places a call to the function f with the argument args
-	in a queue to be called in about delay seconds.
-
-SEE ALSO
-	remove_call_out, find_call_out, call_out_info
diff --git a/doc/builtin/call_out_info b/doc/builtin/call_out_info
deleted file mode 100644
index 1b20ed3962..0000000000
--- a/doc/builtin/call_out_info
+++ /dev/null
@@ -1,22 +0,0 @@
-NAME
-	call_out_info - get info about all call outs
-
-SYNTAX
-	mixed **call_out_info();
-
-DESCRIPTION
-	This function returns an array with one entry for each entry in the
-	call out queue. The first in the queue will be in index 0. Each index
-	contains an array that looks like this:
-
-	({
-	   time_left,	/* an int */
-	   caller,	/* the object that made the call out */
-	   function,	/* the function to be called */
-	   arg1,	/* the first argument, if any */
-	   arg2,	/* the second argument, if any */
-	   ...  	/* and so on... */
-	})
-
-SEE ALSO
-	call_out, find_call_out, remove_call_out
diff --git a/doc/builtin/find_call_out b/doc/builtin/find_call_out
deleted file mode 100644
index 39e39cc456..0000000000
--- a/doc/builtin/find_call_out
+++ /dev/null
@@ -1,13 +0,0 @@
-NAME
-	find_call_out - find a call out in the queue
-
-SYNTAX
-	int find_call_out(function f);
-
-DESCRIPTION
-	This function searches the call out queue, and returns the time left
-	to this call out will be done in seconds. If no call is found,
-	zero_type(find_call_out(f)) will return 1.
-
-SEE ALSO
-	call_out, remove_call_out, call_out_info
diff --git a/doc/builtin/glob b/doc/builtin/glob
new file mode 100644
index 0000000000..a820278ff3
--- /dev/null
+++ b/doc/builtin/glob
@@ -0,0 +1,17 @@
+NAME
+	glob - match strings against globs
+
+SYNTAX
+	int glob(string glob, string str);
+	or
+	string *glob(string glob, string *arr);
+
+DESCRIPTION
+	This function matches "globs". A in the glob string a question sign
+	matches any character and an asterisk matches any string. When
+	given two strings as argument a true/false value is returned
+	which reflects if the 'str' matches 'glob'. When given an array as
+	second argument, an array containing all matching strings is returned.
+
+SEE ALSO
+	sscanf, regexp
diff --git a/doc/builtin/localtime b/doc/builtin/localtime
new file mode 100644
index 0000000000..99f5c20b01
--- /dev/null
+++ b/doc/builtin/localtime
@@ -0,0 +1,29 @@
+NAME
+	localtime - break down time() into intelligible components
+
+SYNTAX
+	mapping(string:int) localtime(int time);
+
+DESCRIPTION
+	Given a time represented as second since 1970, as returned by the
+	function time(), this function returns a mapping with the following
+	components:
+
+	sec     	seconds over the minute	0 - 59
+	min     	minutes over the hour  	0 - 59
+	hour    	what hour in the day   	0 - 23
+	mday    	day of the month       	1 - 31
+	mon     	what month             	0 - 11
+	year    	years since 1900       	0 -
+	wday    	day of week (0=sunday) 	0 - 6
+	yday    	day of year            	0 - 365
+	isdst   	is daylight saving time	0/1
+	timezone	differance between
+			local time and UTC
+	
+
+NOTA BENE
+	The 'timezone' might not be available on all platforms.
+
+SEE ALSO
+	time
\ No newline at end of file
diff --git a/doc/builtin/remove_call_out b/doc/builtin/remove_call_out
deleted file mode 100644
index 277cc9eb0a..0000000000
--- a/doc/builtin/remove_call_out
+++ /dev/null
@@ -1,14 +0,0 @@
-NAME
-	remove_call_out - remove a call out from the call out queue
-
-SYNTAX
-	int remove_call_out(function f);
-
-DESCRIPTION
-	This function finds the first call to the function f in the call
-	out queue and removes it. The time left to that call out will be
-	returned. If no call out was found, zero_type(remove_call_out(f))
-	will return 1.
-
-SEE ALSO
-	call_out_info, call_out, find_call_out
-- 
GitLab


From 1252650a6559bc594cd32d444722ec8178a23382 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 20:24:04 +0200
Subject: [PATCH 201/351] new docs

Rev: doc/operators/operators:1.1
Rev: doc/simulated/putenv:1.1
---
 doc/operators/operators | 105 ++++++++++++++++++++++++++++++++++++++++
 doc/simulated/putenv    |  11 +++++
 2 files changed, 116 insertions(+)
 create mode 100644 doc/operators/operators
 create mode 100644 doc/simulated/putenv

diff --git a/doc/operators/operators b/doc/operators/operators
new file mode 100644
index 0000000000..a6e7ed56dd
--- /dev/null
+++ b/doc/operators/operators
@@ -0,0 +1,105 @@
+NAME
+	operators - arethmics and other stuff
+
+DESCRIPTION
+	uLPC has the following operators:
+
+	a(args)	function call
+	a[b..c]	range
+	a[b]	index
+	--a	pre decrement
+	a--	post decrement
+	++a	pre increment
+	a++	post increment
+	(type)a	cast
+	~a	complement
+	!a	not
+	-a	negate
+	a/b	divide
+	a%b	modulo
+	a*b	multiply
+	a-b	subtract
+	a+b	add
+	>>	shift right
+	<<	shift left
+	a>b	greater than?
+	a<b	lesser than?
+	a>=b	greater or equal than?
+	a<=b	lesser or equal than?
+	a!=b	not equal to?
+	a==b	equal to?
+	a&b	intersection
+	a^b	xor (symmetric differance)
+	a|b	union
+	a&&b	logical and
+	a||b	logical or
+	a?b:c	condition
+	a=b	assignment
+
+	The ones at the top of the list are parsed before operators lower
+	down on the list. This means that a|b&c means a|(b&c) not (a|b)&c.
+	Look at the individual pages for fuller explanations of what they do.
+
+	Then there is also the @ "splice" operator which can only be used in
+	argument lists.
+
+	Arguments to operators are always computed from left to right.
+
+	Many (but not all) of these operators can also be used as by prepending
+	with a ` sign. For instance `+(a,b) is the same as a+b. These functions
+	are called "operator functions" and the following are currently
+	available:
+
+	`== `!= `! `< `<= `> `>= `+ `- `& `| `^ `<< `>> `* `/ `% `~
+
+	These operator functions are basically efuns, but beware, if you
+	re-define the `+ function a+b will also be redefined.
+
+	On top of all this, many operators can also be overloaded. Overloading
+	an operator lets you specify how operators works on your objects.
+	To overload an operator you simply put the corresponding operator
+	function as a method in your object. An example:
+
+	> program nine=class {
+	  int `+(int arg) { return arg+9; }
+	};
+	Result: program
+	> clone(nine)+1;
+	Result: 10
+	>
+
+	This little example defines a program that works almost like the number
+	nine. As you can see, clone(nine)+1 is the same as clone(nine)->`+(1)
+	in this case, and that is the whole point of operator overloading.
+	Note however that it would not have worked to write 1+clone(nine)
+	because operator overloading only works if the first argument is the
+	object with the overloaded function. Well, almost anyway, the operators
+	<, >, <=, >= can check both sides. In fact, the methods `<= and `>=
+	will never be called since uLPC will translate a<=b to !(a>b).
+
+	These are the operators you can overload:
+
+	`==	also overloads `!=
+	`!	This is also used by if-statements to find out if the object
+		in question is 'true' or not.
+	`<	also overloads `>=
+	`>	also overloads `<=
+	`+	
+	`-	
+	`&	
+	`|	
+	`^	
+	`<<	
+	`>>	
+	`*	
+	`/	
+	`%	
+	`~	
+
+	If you also define a function __hash to return an integer, which
+	must be equal for all objects where `== is true you can index mappings
+	on the contents of your objects rather than on the object itself.
+	More details about this will come later.
+
+SEE ALSO
+	/precompiled/mpz
diff --git a/doc/simulated/putenv b/doc/simulated/putenv
new file mode 100644
index 0000000000..5e1dbdb206
--- /dev/null
+++ b/doc/simulated/putenv
@@ -0,0 +1,11 @@
+NAME
+	putenv - put environment variable
+
+SYNTAX
+	void putenv(string varname, string value);
+
+DESCRIPTION
+	This function sets the environment variable 'varname' to 'value'.
+
+SEE ALSO
+	getenv, exece
-- 
GitLab


From 02c089c8dc10b15f961b94229850f62dbac6db8f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 20:34:42 +0200
Subject: [PATCH 202/351] document for call_out module

Rev: src/modules/call_out/doc/call_out:1.1
Rev: src/modules/call_out/doc/call_out_info:1.1
Rev: src/modules/call_out/doc/find_call_out:1.1
Rev: src/modules/call_out/doc/remove_call_out:1.1
---
 src/modules/call_out/doc/call_out        | 12 ++++++++++++
 src/modules/call_out/doc/call_out_info   | 22 ++++++++++++++++++++++
 src/modules/call_out/doc/find_call_out   | 13 +++++++++++++
 src/modules/call_out/doc/remove_call_out | 14 ++++++++++++++
 4 files changed, 61 insertions(+)
 create mode 100644 src/modules/call_out/doc/call_out
 create mode 100644 src/modules/call_out/doc/call_out_info
 create mode 100644 src/modules/call_out/doc/find_call_out
 create mode 100644 src/modules/call_out/doc/remove_call_out

diff --git a/src/modules/call_out/doc/call_out b/src/modules/call_out/doc/call_out
new file mode 100644
index 0000000000..6eccf4ad52
--- /dev/null
+++ b/src/modules/call_out/doc/call_out
@@ -0,0 +1,12 @@
+NAME
+	call_out - make a delayed call to a function
+
+SYNTAX
+	void call_out(function f, int delay, mixed ... args);
+
+DESCRIPTION
+	Call_out places a call to the function f with the argument args
+	in a queue to be called in about delay seconds.
+
+SEE ALSO
+	remove_call_out, find_call_out, call_out_info
diff --git a/src/modules/call_out/doc/call_out_info b/src/modules/call_out/doc/call_out_info
new file mode 100644
index 0000000000..1b20ed3962
--- /dev/null
+++ b/src/modules/call_out/doc/call_out_info
@@ -0,0 +1,22 @@
+NAME
+	call_out_info - get info about all call outs
+
+SYNTAX
+	mixed **call_out_info();
+
+DESCRIPTION
+	This function returns an array with one entry for each entry in the
+	call out queue. The first in the queue will be in index 0. Each index
+	contains an array that looks like this:
+
+	({
+	   time_left,	/* an int */
+	   caller,	/* the object that made the call out */
+	   function,	/* the function to be called */
+	   arg1,	/* the first argument, if any */
+	   arg2,	/* the second argument, if any */
+	   ...  	/* and so on... */
+	})
+
+SEE ALSO
+	call_out, find_call_out, remove_call_out
diff --git a/src/modules/call_out/doc/find_call_out b/src/modules/call_out/doc/find_call_out
new file mode 100644
index 0000000000..39e39cc456
--- /dev/null
+++ b/src/modules/call_out/doc/find_call_out
@@ -0,0 +1,13 @@
+NAME
+	find_call_out - find a call out in the queue
+
+SYNTAX
+	int find_call_out(function f);
+
+DESCRIPTION
+	This function searches the call out queue, and returns the time left
+	to this call out will be done in seconds. If no call is found,
+	zero_type(find_call_out(f)) will return 1.
+
+SEE ALSO
+	call_out, remove_call_out, call_out_info
diff --git a/src/modules/call_out/doc/remove_call_out b/src/modules/call_out/doc/remove_call_out
new file mode 100644
index 0000000000..277cc9eb0a
--- /dev/null
+++ b/src/modules/call_out/doc/remove_call_out
@@ -0,0 +1,14 @@
+NAME
+	remove_call_out - remove a call out from the call out queue
+
+SYNTAX
+	int remove_call_out(function f);
+
+DESCRIPTION
+	This function finds the first call to the function f in the call
+	out queue and removes it. The time left to that call out will be
+	returned. If no call out was found, zero_type(remove_call_out(f))
+	will return 1.
+
+SEE ALSO
+	call_out_info, call_out, find_call_out
-- 
GitLab


From ffec1203dd95932b030d931974fae02cda721a27 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 20:35:31 +0200
Subject: [PATCH 203/351] call out moved to a module

Rev: src/modules/call_out/.cvsignore:1.1
Rev: src/modules/call_out/Makefile.src:1.1
Rev: src/modules/call_out/call_out.c:1.1
Rev: src/modules/call_out/configure.in:1.1
---
 src/modules/call_out/.cvsignore   |   2 +
 src/modules/call_out/.gitignore   |   2 +
 src/modules/call_out/Makefile.src |  17 ++
 src/modules/call_out/call_out.c   | 359 ++++++++++++++++++++++++++++++
 src/modules/call_out/configure.in |   9 +
 5 files changed, 389 insertions(+)
 create mode 100644 src/modules/call_out/.cvsignore
 create mode 100644 src/modules/call_out/.gitignore
 create mode 100644 src/modules/call_out/Makefile.src
 create mode 100644 src/modules/call_out/call_out.c
 create mode 100644 src/modules/call_out/configure.in

diff --git a/src/modules/call_out/.cvsignore b/src/modules/call_out/.cvsignore
new file mode 100644
index 0000000000..76e8a85506
--- /dev/null
+++ b/src/modules/call_out/.cvsignore
@@ -0,0 +1,2 @@
+configure
+Makefile.in
diff --git a/src/modules/call_out/.gitignore b/src/modules/call_out/.gitignore
new file mode 100644
index 0000000000..1f3e111bcb
--- /dev/null
+++ b/src/modules/call_out/.gitignore
@@ -0,0 +1,2 @@
+/configure
+/Makefile.in
diff --git a/src/modules/call_out/Makefile.src b/src/modules/call_out/Makefile.src
new file mode 100644
index 0000000000..0de1983c20
--- /dev/null
+++ b/src/modules/call_out/Makefile.src
@@ -0,0 +1,17 @@
+SRCDIR=@srcdir@
+VPATH=@srcdir@:@srcdir@/../..:../..
+PREFLAGS=-I$(SRCDIR) -I$(SRCDIR)/../.. -I../..
+CFLAGS=$(PREFLAGS) $(OTHERFLAGS)
+
+FILES=call_out.o
+
+call_out.a: $(FILES)
+	-rm -f call_out.a
+	ar cq call_out.a $(FILES)
+	-@RANLIB@ call_out.a
+
+clean:
+	-rm -f *.o *.a
+
+depend:
+	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)
diff --git a/src/modules/call_out/call_out.c b/src/modules/call_out/call_out.c
new file mode 100644
index 0000000000..74ee5cb654
--- /dev/null
+++ b/src/modules/call_out/call_out.c
@@ -0,0 +1,359 @@
+/*\
+||| This file a part of uLPC, and is copyright by Fredrik Hubinette
+||| uLPC is distributed as GPL (General Public License)
+||| See the files COPYING and DISCLAIMER for more information.
+\*/
+#include "global.h"
+#include "array.h"
+#include "dynamic_buffer.h"
+#include "object.h"
+#include "interpret.h"
+#include "error.h"
+#include "builtin_efuns.h"
+#include "memory.h"
+#include "main.h"
+#include "backend.h"
+#include "time_stuff.h"
+#include "add_efun.h"
+
+#include "callback.h"
+
+#include <math.h>
+
+struct call_out_s
+{
+  struct timeval tv;
+  struct object *caller;
+  struct array *args;
+};
+
+typedef struct call_out_s call_out;
+
+call_out **pending_calls=0;      /* pointer to first busy pointer */
+int num_pending_calls;           /* no of busy pointers in buffer */
+static call_out **call_buffer=0; /* pointer to buffer */
+static int call_buffer_size;     /* no of pointers in buffer */
+
+static void verify_call_outs()
+{
+#ifdef DEBUG
+  struct array *v;
+  int e;
+
+  if(!d_flag) return;
+  if(!call_buffer) return;
+
+  if(num_pending_calls<0 || num_pending_calls>call_buffer_size)
+    fatal("Error in call out tables.\n");
+
+  if(pending_calls+num_pending_calls!=call_buffer+call_buffer_size)
+    fatal("Error in call out tables.\n");
+
+  for(e=0;e<num_pending_calls;e++)
+  {
+    if(e)
+    {
+      if(my_timercmp(&pending_calls[e-1]->tv,>,&pending_calls[e]->tv))
+	fatal("Error in call out order.\n");
+    }
+    
+    if(!(v=pending_calls[e]->args))
+      fatal("No arguments to call\n");
+
+    if(v->refs!=1)
+      fatal("Array should exactly have one reference.\n");
+
+    if(v->malloced_size<v->size)
+      fatal("Impossible array.\n");
+  }
+#endif
+}
+
+
+/* start a new call out, return 1 for success */
+static int new_call_out(int num_arg,struct svalue *argp)
+{
+  int e,c;
+  call_out *new,**p,**pos;
+
+  if(!call_buffer)
+  {
+    call_buffer_size=20;
+    call_buffer=(call_out **)xalloc(sizeof(call_out *)*call_buffer_size);
+    if(!call_buffer) return 0;
+    pending_calls=call_buffer+call_buffer_size;
+    num_pending_calls=0;
+  }
+
+  if(num_pending_calls==call_buffer_size)
+  {
+    /* here we need to allocate space for more pointers */
+    call_out **new_buffer;
+
+    new_buffer=(call_out **)xalloc(sizeof(call_out *)*call_buffer_size*2);
+    if(!new_buffer)
+      return 0;
+
+    MEMCPY((char *)(new_buffer+call_buffer_size),
+	   (char *)call_buffer,
+	   sizeof(call_out *)*call_buffer_size);
+    free((char *)call_buffer);
+    call_buffer=new_buffer;
+    pending_calls=call_buffer+call_buffer_size;
+    call_buffer_size*=2;
+  }
+
+  /* time to allocate a new call_out struct */
+  f_aggregate(num_arg-1);
+
+  new=(call_out *)xalloc(sizeof(call_out));
+
+  if(!new) return 0;
+  
+  if(argp[0].type==T_INT)
+  {
+    new->tv.tv_sec=argp[0].u.integer;
+    new->tv.tv_usec=0;
+  }
+  else if(argp[0].type == T_FLOAT)
+  {
+    FLOAT_TYPE tmp=argp[0].u.float_number;
+    new->tv.tv_sec=floor(tmp);
+    new->tv.tv_usec=(long)(1000000.0 * (tmp - floor(tmp)));
+  }
+  else
+  {
+    fatal("Bad timeout to new_call_out!\n");
+  }
+
+  my_add_timeval(& new->tv, &current_time);
+
+  if(fp && fp->current_object)
+  {
+    new->caller=fp->current_object;
+    new->caller->refs++;
+  }else{
+    new->caller=0;
+  }
+
+  new->args=sp[-1].u.array;
+  sp -= 2;
+
+  /* time to link it into the buffer using binsearch */
+  pos=pending_calls;
+
+  e=num_pending_calls;
+  while(e>0)
+  {
+    c=e/2;
+    if(my_timercmp(& new->tv,>,& pos[c]->tv))
+    {
+      pos+=c+1;
+      e-=c+1;
+    }else{
+      e=c;
+    }
+  }
+  pos--;
+  pending_calls--;
+  for(p=pending_calls;p<pos;p++) p[0]=p[1];
+  *pos=new;
+  num_pending_calls++;
+
+  verify_call_outs();
+  return 1;
+}
+
+void f_call_out(INT32 args)
+{
+  struct svalue tmp;
+  if(args<2)
+    error("Too few arguments to call_out.\n");
+
+  if(sp[1-args].type != T_INT && sp[1-args].type!=T_FLOAT)
+    error("Bad argument 2 to call_out.\n");
+
+  /* Swap, for compatibility */
+  tmp=sp[-args];
+  sp[-args]=sp[1-args];
+  sp[1-args]=tmp;
+
+  new_call_out(args,sp-args);
+}
+
+void do_call_outs(struct callback *ignored, void *ignored_too)
+{
+  call_out *c;
+  int args;
+  time_t tmp;
+  verify_call_outs();
+
+  tmp=(time_t)TIME(0);
+  while(num_pending_calls &&
+	my_timercmp(&pending_calls[0]->tv,<=,&current_time))
+  {
+    /* unlink call out */
+    c=pending_calls[0];
+    pending_calls++;
+    num_pending_calls--;
+
+    if(c->caller) free_object(c->caller);
+
+    args=c->args->size;
+    push_array_items(c->args);
+    free((char *)c);
+    check_destructed(sp-args);
+    if(sp[-args].type!=T_INT)
+    {
+      f_call_function(args);
+      pop_stack();
+    }else{
+      pop_n_elems(args);
+    }
+    verify_call_outs();
+
+    if(tmp != (time_t) TIME(0)) break;
+  }
+
+  if(num_pending_calls)
+    if(my_timercmp(& pending_calls[0]->tv, < , &next_timeout))
+      next_timeout = pending_calls[0]->tv;
+}
+
+static int find_call_out(struct svalue *fun)
+{
+  int e;
+  for(e=0;e<num_pending_calls;e++)
+  {
+    if(is_eq(fun, ITEM(pending_calls[e]->args)))
+      return e;
+  }
+  return -1;
+}
+
+void f_find_call_out(INT32 args)
+{
+  int e;
+  verify_call_outs();
+  e=find_call_out(sp - args);
+  pop_n_elems(args);
+  if(e==-1)
+  {
+    sp->type=T_INT;
+    sp->subtype=NUMBER_UNDEFINED;
+    sp->u.integer=-1;
+    sp++;
+  }else{
+    push_int(pending_calls[e]->tv.tv_sec - current_time.tv_sec);
+  }
+  verify_call_outs();
+}
+
+void f_remove_call_out(INT32 args)
+{
+  int e;
+  verify_call_outs();
+  e=find_call_out(sp-args);
+  if(e!=-1)
+  {
+    pop_n_elems(args);
+    push_int(pending_calls[e]->tv.tv_sec - current_time.tv_sec);
+    free_array(pending_calls[e]->args);
+    if(pending_calls[e]->caller)
+      free_object(pending_calls[e]->caller);
+    free((char*)(pending_calls[e]));
+    for(;e>0;e--)
+      pending_calls[e]=pending_calls[e-1];
+    pending_calls++;
+    num_pending_calls--;
+  }else{
+    pop_n_elems(args);
+    sp->type=T_INT;
+    sp->subtype=NUMBER_UNDEFINED;
+    sp->u.integer=-1;
+    sp++;
+  }
+  verify_call_outs();
+}
+
+/* return an array containing info about all call outs:
+ * ({  ({ delay, caller, function, args, ... }), ... })
+ */
+struct array *get_all_call_outs()
+{
+  int e;
+  struct array *ret;
+
+  verify_call_outs();
+  ret=allocate_array_no_init(num_pending_calls,0);
+  for(e=0;e<num_pending_calls;e++)
+  {
+    struct array *v;
+    v=allocate_array_no_init(pending_calls[e]->args->size+2, 0);
+    ITEM(v)[0].type=T_INT;
+    ITEM(v)[0].subtype=NUMBER_NUMBER;
+    ITEM(v)[0].u.integer=pending_calls[e]->tv.tv_sec - current_time.tv_sec;
+
+    if(pending_calls[e]->caller)
+    {
+      ITEM(v)[1].type=T_OBJECT;
+      (ITEM(v)[1].u.object=pending_calls[e]->caller) ->refs++;
+    }else{
+      ITEM(v)[1].type=T_INT;
+      ITEM(v)[1].subtype=NUMBER_NUMBER;
+      ITEM(v)[1].u.integer=0;
+    }
+
+    assign_svalues_no_free(ITEM(v)+2,ITEM(pending_calls[e]->args),pending_calls[e]->args->size,BIT_MIXED);
+
+    ITEM(ret)[e].type=T_ARRAY;
+    ITEM(ret)[e].u.array=v;
+  }
+  return ret;
+}
+
+void f_call_out_info(INT32 args)
+{
+  pop_n_elems(args);
+  push_array(get_all_call_outs());
+}
+
+void free_all_call_outs()
+{
+  int e;
+  verify_call_outs();
+  for(e=0;e<num_pending_calls;e++)
+  {
+    free_array(pending_calls[e]->args);
+    if(pending_calls[e]->caller) free_object(pending_calls[e]->caller);
+    free((char*)(pending_calls[e]));
+  }
+  if(call_buffer) free((char*)call_buffer);
+  num_pending_calls=0;
+  call_buffer=NULL;
+  pending_calls=NULL;
+}
+
+#ifdef DEBUG
+void verify_all_call_outs()
+{
+  verify_call_outs();
+}
+#endif
+
+void init_call_out_efuns(void)
+{
+  add_backend_callback(do_call_outs,0,0);
+
+  add_efun("call_out",f_call_out,"function(function,float|int,mixed...:void)",OPT_SIDE_EFFECT);
+  add_efun("call_out_info",f_call_out_info,"function(:array*)",OPT_EXTERNAL_DEPEND);
+  add_efun("find_call_out",f_find_call_out,"function(function:int)",OPT_EXTERNAL_DEPEND);
+  add_efun("remove_call_out",f_remove_call_out,"function(function:int)",OPT_SIDE_EFFECT);
+}
+
+void init_call_out_programs(void) {}
+
+void exit_call_out(void)
+{
+  free_all_call_outs();
+}
diff --git a/src/modules/call_out/configure.in b/src/modules/call_out/configure.in
new file mode 100644
index 0000000000..ae228dce80
--- /dev/null
+++ b/src/modules/call_out/configure.in
@@ -0,0 +1,9 @@
+AC_INIT(call_out.c)
+
+AC_PROG_CC
+AC_PROG_RANLIB
+AC_SUBST(RANLIB)
+
+AC_OUTPUT(Makefile,echo FOO >stamp-h )
+
+
-- 
GitLab


From 22293e6e8e7524967a924dfc15f7ab494ad53a4d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 20:40:17 +0200
Subject: [PATCH 204/351] new module

Rev: src/modules/gmpmod/.cvsignore:1.1
Rev: src/modules/gmpmod/Makefile.src:1.1
Rev: src/modules/gmpmod/configure.in:1.1
Rev: src/modules/gmpmod/doc/mpz:1.1
Rev: src/modules/gmpmod/gmp_machine.h.in:1.1
Rev: src/modules/gmpmod/mpz_glue.c:1.1
---
 src/modules/gmpmod/.cvsignore       |   2 +
 src/modules/gmpmod/.gitignore       |   2 +
 src/modules/gmpmod/Makefile.src     |  19 ++
 src/modules/gmpmod/configure.in     |  13 +
 src/modules/gmpmod/doc/mpz          |  76 +++++
 src/modules/gmpmod/gmp_machine.h.in |   7 +
 src/modules/gmpmod/mpz_glue.c       | 440 ++++++++++++++++++++++++++++
 7 files changed, 559 insertions(+)
 create mode 100644 src/modules/gmpmod/.cvsignore
 create mode 100644 src/modules/gmpmod/.gitignore
 create mode 100644 src/modules/gmpmod/Makefile.src
 create mode 100644 src/modules/gmpmod/configure.in
 create mode 100644 src/modules/gmpmod/doc/mpz
 create mode 100644 src/modules/gmpmod/gmp_machine.h.in
 create mode 100644 src/modules/gmpmod/mpz_glue.c

diff --git a/src/modules/gmpmod/.cvsignore b/src/modules/gmpmod/.cvsignore
new file mode 100644
index 0000000000..64200ddc24
--- /dev/null
+++ b/src/modules/gmpmod/.cvsignore
@@ -0,0 +1,2 @@
+Makefile.in
+configure
diff --git a/src/modules/gmpmod/.gitignore b/src/modules/gmpmod/.gitignore
new file mode 100644
index 0000000000..addfc0376f
--- /dev/null
+++ b/src/modules/gmpmod/.gitignore
@@ -0,0 +1,2 @@
+/Makefile.in
+/configure
diff --git a/src/modules/gmpmod/Makefile.src b/src/modules/gmpmod/Makefile.src
new file mode 100644
index 0000000000..9c2029bb31
--- /dev/null
+++ b/src/modules/gmpmod/Makefile.src
@@ -0,0 +1,19 @@
+SRCDIR=@srcdir@
+VPATH=@srcdir@:@srcdir@/../..:../..
+PREFLAGS=-I. -I$(SRCDIR) -I$(SRCDIR)/../.. -I../..
+CFLAGS=$(PREFLAGS) $(OTHERFLAGS)
+
+FILES=mpz_glue.o
+LIB=gmpmod.a
+
+$(LIB): $(FILES)
+	-rm -f $(LIB)
+	ar cq $(LIB) $(FILES)
+	-@RANLIB@ $(LIB)
+	echo >linker_options @LIBS@
+
+clean:
+	-rm -f *.o *.a
+
+depend:
+	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)
diff --git a/src/modules/gmpmod/configure.in b/src/modules/gmpmod/configure.in
new file mode 100644
index 0000000000..b8c1fa3b4a
--- /dev/null
+++ b/src/modules/gmpmod/configure.in
@@ -0,0 +1,13 @@
+AC_INIT(mpz_glue.c)
+AC_CONFIG_HEADER(gmp_machine.h)
+
+AC_PROG_CC
+AC_PROG_RANLIB
+AC_SUBST(RANLIB)
+
+AC_CHECK_HEADERS(gmp.h)
+AC_CHECK_LIB(gmp, mpz_set_si)
+
+AC_OUTPUT(Makefile,echo FOO >stamp-h )
+
+
diff --git a/src/modules/gmpmod/doc/mpz b/src/modules/gmpmod/doc/mpz
new file mode 100644
index 0000000000..596b815876
--- /dev/null
+++ b/src/modules/gmpmod/doc/mpz
@@ -0,0 +1,76 @@
+NAME
+	/precompiled/mpz - bignum program
+
+DESCRIPTION
+	/precompiled/mpz is a builtin program written in C. It implements
+	large, very large integers. In fact, the only limitation on these
+	integers is the available memory.
+
+	The mpz object implements all the normal integer operations.
+	(except xor) There are also some extra operators:
+
+NOTA BENE
+	This module is only available if libgmp.a was available and
+	found when uLPC was compiled.
+
+============================================================================
+NAME
+	create - initialize a bignum
+
+SYNTAX
+	object clone((program)"/precompiled/mpz");
+	or
+	object clone((program)"/precompiled/mpz",int|object|string|float i);
+
+DESCRIPTION
+	When cloning an mpz it is by default initalized to zero. However,
+	you can give a second argument to clone to initialize the new
+	object to that value. The argument can be an int, float another
+	mpz object, or a string containing an ascii number.
+
+SEE ALSO
+	builtin/clone
+
+============================================================================
+NAME
+	powm - raise and modulo
+
+SYNTAX
+	object mpz->powm(int|string|float|object a,int|string|float|object b);
+
+DESCRIPTION
+	This function returns ( mpz ** a ) % b
+
+============================================================================
+NAME
+	sqrt - square root
+
+SYNTAX
+	object mpz->sqrt();
+
+DESCRIPTION
+	This function return the the truncated integer part of the square
+	root of the value of mpz. 
+
+============================================================================
+NAME
+	probably_prime_p - is this number a prime?
+
+SYNTAX
+	int mpz->probably_prime_p();
+
+DESCRIPTION
+	This function returns 1 if mpz is a prime, and 0 most of the time
+	if it is not.
+
+============================================================================
+NAME
+	gcd - greatest common divisor
+
+SYNTAX
+	object mpz->gcd(object|int|float|string arg)
+
+DESCRIPTION
+	This function returns the greatest common divisor for arg and mpz.
+
+============================================================================
diff --git a/src/modules/gmpmod/gmp_machine.h.in b/src/modules/gmpmod/gmp_machine.h.in
new file mode 100644
index 0000000000..0a79aef13b
--- /dev/null
+++ b/src/modules/gmpmod/gmp_machine.h.in
@@ -0,0 +1,7 @@
+#ifndef GMP_MACHINE_H
+#define GMP_MACHINE_H
+
+/* Define this if you have <gmp.h> */
+#undef HAVE_GMP_H
+
+#endif
diff --git a/src/modules/gmpmod/mpz_glue.c b/src/modules/gmpmod/mpz_glue.c
new file mode 100644
index 0000000000..641196dacd
--- /dev/null
+++ b/src/modules/gmpmod/mpz_glue.c
@@ -0,0 +1,440 @@
+/*\
+||| This file a part of uLPC, and is copyright by Fredrik Hubinette
+||| uLPC is distributed as GPL (General Public License)
+||| See the files COPYING and DISCLAIMER for more information.
+\*/
+#include "global.h"
+#include "gmp_machine.h"
+#include "types.h"
+
+#ifdef HAVE_GMP_H
+
+#include "interpret.h"
+#include "svalue.h"
+#include "stralloc.h"
+#include "array.h"
+#include "macros.h"
+#include "program.h"
+#include "stralloc.h"
+#include "object.h"
+#include "lpc_types.h"
+
+#include <gmp.h>
+
+#define THIS (*(mpz_t *)(fp->current_storage))
+#define OBTOMPZ(o) (*(mpz_t *)(o->storage))
+
+static struct program *mpzmod_program;
+
+static void get_new_mpz(mpz_t tmp, struct svalue *s)
+{
+  switch(s->type)
+  {
+  case T_INT:
+    mpz_set_si(tmp, (signed long int) s->u.integer);
+    break;
+    
+  case T_FLOAT:
+    mpz_set_d(tmp, (double) s->u.float_number);
+    break;
+    
+  case T_STRING:
+    mpz_set_str(tmp, s->u.string->str, 0);
+    break;
+
+  case T_OBJECT:
+    if(s->u.object->prog != mpzmod_program)
+      error("Wrong type of object, cannot convert to mpz.\n");
+
+    mpz_set(tmp, OBTOMPZ(s->u.object));
+    break;
+    
+  default:
+    error("Bad argument 1 to mpz->create()\n");
+  }
+}
+
+static void mpzmod_create(INT32 args)
+{
+  if(args)
+  {
+    get_new_mpz(THIS, sp-args);
+    pop_n_elems(args);
+  }
+}
+
+static void mpzmod_get_int(INT32 args)
+{
+  pop_n_elems(args);
+  push_int(mpz_get_si(THIS));
+}
+
+static void mpzmod_get_float(INT32 args)
+{
+  pop_n_elems(args);
+  push_float((float)mpz_get_d(THIS));
+}
+
+static void mpzmod_get_string(INT32 args)
+{
+  struct lpc_string *s;
+  INT32 len;
+
+  pop_n_elems(args);
+  len=mpz_sizeinbase(THIS,10);
+  len++; /* For a zero */
+  if(mpz_sgn(THIS) < 0) len++; /* For the - sign */
+
+  s=begin_shared_string(len);
+  mpz_get_str(s->str,10,THIS);
+
+  len-=4;
+  if(len < 0) len = 0;
+  while(s->str[len]) len++;
+  s->len=len;
+  s=end_shared_string(s);
+  push_string(s);
+}
+
+static void mpzmod_cast(INT32 args)
+{
+  if(args < 1)
+    error("mpz->cast() called without arguments.\n");
+  if(sp[-args].type != T_STRING)
+    error("Bad argument 1 to mpz->cast().\n");
+
+  switch(sp[-args].u.string->str[0])
+  {
+  case 'i':
+    if(!strcmp(sp[-args].u.string->str, "int"))
+    {
+      mpzmod_get_int(args);
+      return;
+    }
+    break;
+
+  case 's':
+    if(!strcmp(sp[-args].u.string->str, "string"))
+    {
+      mpzmod_get_string(args);
+      return;
+    }
+    break;
+
+  case 'f':
+    if(!strcmp(sp[-args].u.string->str, "float"))
+    {
+      mpzmod_get_float(args);
+      return;
+    }
+    break;
+
+  case 'o':
+    if(!strcmp(sp[-args].u.string->str, "object"))
+    {
+      pop_n_elems(args);
+      push_object(this_object());
+    }
+    break;
+
+  case 'm':
+    if(!strcmp(sp[-args].u.string->str, "mixed"))
+    {
+      pop_n_elems(args);
+      push_object(this_object());
+    }
+    break;
+    
+  }
+
+  error("mpz->cast() to other type than string, int or float.\n");
+}
+
+static MP_INT *get_mpz(struct svalue *s)
+{
+  struct object *o;
+  switch(s->type)
+  {
+  default:
+    error("Wrong type of object, cannot convert to mpz.\n");
+    return 0;
+
+  case T_INT:
+  case T_FLOAT:
+  case T_STRING:
+    o=clone(mpzmod_program,0);
+    get_new_mpz(OBTOMPZ(o), s);
+    free_svalue(s);
+    s->u.object=o;
+    s->type=T_OBJECT;
+    return (MP_INT *)o->storage;
+    
+  case T_OBJECT:
+    if(s->u.object->prog != mpzmod_program)
+      error("Wrong type of object, cannot convert to mpz.\n");
+
+    return (MP_INT *)s->u.object->storage;
+  }
+}
+
+/* These two functions are here so we can allocate temporary
+ * objects without having to worry about them leaking in
+ * case of errors..
+ */
+static struct object *temporary;
+MP_INT *get_tmp()
+{
+  if(!temporary)
+    temporary=clone(mpzmod_program,0);
+
+  return (MP_INT *)temporary->storage;
+}
+
+static void return_temporary(INT32 args)
+{
+  pop_n_elems(args);
+  push_object(temporary);
+  temporary=0;
+}
+
+#define BINFUN(name, fun)				\
+static void name(INT32 args)				\
+{							\
+  INT32 e;						\
+  MP_INT *tmp=get_tmp();				\
+  mpz_set(tmp, THIS);					\
+  for(e=0;e<args;e++)					\
+    fun(tmp, tmp, get_mpz(sp+e-args));			\
+  return_temporary(args);				\
+}
+
+BINFUN(mpzmod_add,mpz_add)
+BINFUN(mpzmod_mul,mpz_mul)
+BINFUN(mpzmod_gcd,mpz_gcd)
+
+static void mpzmod_sub(INT32 args)
+{
+  INT32 e;
+  MP_INT *tmp=get_tmp();
+  mpz_set(tmp, THIS);
+
+  if(args)
+  {
+    for(e=0;e<args;e++)
+      mpz_sub(tmp, tmp, get_mpz(sp+e-args));
+  }else{
+    mpz_neg(tmp, tmp);
+  }
+
+  return_temporary(args);
+}
+
+static void mpzmod_div(INT32 args)
+{
+  INT32 e;
+  MP_INT *tmp=get_tmp();
+  mpz_set(tmp, THIS);
+
+  for(e=0;e<args;e++)
+  {
+    MP_INT *tmp2;
+    tmp2=get_mpz(sp+e-args);
+    if(!mpz_sgn(tmp2))
+      error("Division by zero.\n");
+    mpz_tdiv_q(tmp, tmp, tmp2);
+  }
+  return_temporary(args);
+}
+
+static void mpzmod_mod(INT32 args)
+{
+  INT32 e;
+  MP_INT *tmp=get_tmp();
+  mpz_set(tmp, THIS);
+
+  for(e=0;e<args;e++)
+  {
+    MP_INT *tmp2;
+    tmp2=get_mpz(sp+e-args);
+    if(!mpz_sgn(tmp2))
+      error("Modulo by zero.\n");
+    mpz_tdiv_r(tmp, tmp, tmp2);
+  }
+  return_temporary(args);
+}
+
+
+BINFUN(mpzmod_and,mpz_and)
+BINFUN(mpzmod_or,mpz_ior)
+
+static void mpzmod_compl(INT32 args)
+{
+  struct object *o;
+  pop_n_elems(args);
+  o=clone(mpzmod_program,0);
+  push_object(o);
+  mpz_com(OBTOMPZ(o), THIS);
+}
+
+
+#define CMPFUN(name,cmp)				\
+static void name(INT32 args)				\
+{							\
+  INT32 i;						\
+  if(!args) error("Comparison with one argument?\n");	\
+  i=mpz_cmp(THIS, get_mpz(sp-args)) cmp 0;		\
+  pop_n_elems(args);					\
+  push_int(i);						\
+}
+
+CMPFUN(mpzmod_gt, >)
+CMPFUN(mpzmod_lt, <)
+CMPFUN(mpzmod_ge, >=)
+CMPFUN(mpzmod_le, <=)
+CMPFUN(mpzmod_eq, ==)
+CMPFUN(mpzmod_nq, !=)
+
+static void mpzmod_probably_prime_p(INT32 args)
+{
+  pop_n_elems(args);
+  push_int(mpz_probab_prime_p(THIS, 25));
+}
+
+static void mpzmod_sgn(INT32 args)
+{
+  pop_n_elems(args);
+  push_int(mpz_sgn(THIS));
+}
+
+
+static void mpzmod_sqrt(INT32 args)
+{
+  struct object *o;
+  pop_n_elems(args);
+  if(mpz_sgn(THIS)<0)
+    error("mpz->sqrt() on negative number.\n");
+
+  o=clone(mpzmod_program,0);
+  push_object(o);
+  mpz_sqrt(OBTOMPZ(o), THIS);
+}
+
+static void mpzmod_lsh(INT32 args)
+{
+  MP_INT *tmp;
+  pop_n_elems(args-1);
+  push_string(int_type_string);
+  int_type_string->refs++;
+  f_cast(2);
+  tmp=get_tmp();
+  if(sp[-1].u.integer < 0)
+    error("mpz->lsh on negative number.\n");
+  mpz_mul_2exp(tmp, THIS, sp[-1].u.integer);
+  return_temporary(1);
+}
+
+static void mpzmod_rsh(INT32 args)
+{
+  MP_INT *tmp;
+  pop_n_elems(args-1);
+  push_string(int_type_string);
+  int_type_string->refs++;
+  f_cast(2);
+  tmp=get_tmp();
+  mpz_set_ui(tmp,1);
+  mpz_mul_2exp(tmp, tmp, sp[-1].u.integer);
+  mpz_tdiv_q(tmp, THIS, tmp);
+  return_temporary(1);
+}
+
+static void mpzmod_powm(INT32 args)
+{
+  MP_INT *tmp;
+  if(args < 2)
+    error("Too few arguments to mpzmod->powm()\n");
+
+  tmp=get_tmp();
+  mpz_powm(tmp, tmp, get_mpz(sp-args), get_mpz(sp+1-args));
+  return_temporary(args);
+}
+
+static void mpzmod_not(INT32 args)
+{
+  pop_n_elems(args);
+  push_int(!mpz_sgn(THIS));
+}
+
+static void init_mpz_glue(char *foo, struct object *o)
+{
+  mpz_init(THIS);
+}
+
+static void exit_mpz_glue(char *foo, struct object *o)
+{
+  mpz_clear(THIS);
+}
+
+#endif
+
+void init_gmpmod_efuns(void) {}
+void exit_gmpmod(void)
+{
+  if(temporary) free_object(temporary);
+  free_program(mpzmod_program);
+}
+
+void init_gmpmod_programs(void)
+{
+#ifdef HAVE_GMP_H
+  start_new_program();
+  add_storage(sizeof(mpz_t));
+  
+  add_function("create",mpzmod_create,"function(void|string|int|float|object:void)",0);
+
+#define MPZ_BINOP_TYPE "function(string|int|float|object...:object)"
+
+  add_function("`+",mpzmod_add,MPZ_BINOP_TYPE,0);
+  add_function("`-",mpzmod_sub,MPZ_BINOP_TYPE,0);
+  add_function("`*",mpzmod_mul,MPZ_BINOP_TYPE,0);
+  add_function("`/",mpzmod_div,MPZ_BINOP_TYPE,0);
+  add_function("`%",mpzmod_mod,MPZ_BINOP_TYPE,0);
+  add_function("`&",mpzmod_and,MPZ_BINOP_TYPE,0);
+  add_function("`|",mpzmod_or,MPZ_BINOP_TYPE,0);
+
+#define MPZ_SHIFT_TYPE "function(object|int|float|object:object)"
+  add_function("`<<",mpzmod_lsh,MPZ_SHIFT_TYPE,0);
+  add_function("`>>",mpzmod_rsh,MPZ_SHIFT_TYPE,0);
+
+#define MPZ_CMPOP_TYPE "function(string|int|float|object:int)"
+
+  add_function("`>", mpzmod_gt,MPZ_CMPOP_TYPE,0);
+  add_function("`<", mpzmod_lt,MPZ_CMPOP_TYPE,0);
+  add_function("`>=",mpzmod_ge,MPZ_CMPOP_TYPE,0);
+  add_function("`<=",mpzmod_le,MPZ_CMPOP_TYPE,0);
+
+  add_function("`==",mpzmod_le,MPZ_CMPOP_TYPE,0);
+  add_function("`!=",mpzmod_le,MPZ_CMPOP_TYPE,0);
+
+  add_function("`!",mpzmod_not,"function(:int)",0);
+
+  add_function("__hash",mpzmod_get_int,"function(:int)",0);
+  add_function("cast",mpzmod_cast,"function(string:mixed)",0);
+
+  add_function("cast_to_int",mpzmod_get_int,"function(:int)",0);
+  add_function("cast_to_string",mpzmod_get_string,"function(:string)",0);
+  add_function("cast_to_float",mpzmod_get_float,"function(:float)",0);
+
+  add_function("probably_prime_p",mpzmod_probably_prime_p,"function(:int)",0);
+  add_function("gcd",mpzmod_gcd,"function(object|string|int|float...:object)",0);
+  add_function("sqrt",mpzmod_gcd,"function(:object)",0);
+  add_function("`~",mpzmod_gcd,"function(:object)",0);
+  add_function("powm",mpzmod_gcd,"function(object|string|int|float,object|string|int|float:object)",0);
+
+  set_init_callback(init_mpz_glue);
+  set_exit_callback(exit_mpz_glue);
+
+  mpzmod_program=end_c_program("/precompiled/mpz");
+  mpzmod_program->refs++;
+#endif
+}
+
-- 
GitLab


From f5ac3358620d8784c08037fd2d57af44e1bb36aa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 20:50:06 +0200
Subject: [PATCH 205/351] strerror and << added

Rev: src/modules/files/configure.in:1.7
Rev: src/modules/files/doc/strerror:1.1
Rev: src/modules/files/efuns.c:1.6
Rev: src/modules/files/file.c:1.15
Rev: src/modules/files/file.h:1.4
Rev: src/modules/files/file_machine.h.in:1.4
---
 src/modules/files/configure.in      |  2 +-
 src/modules/files/doc/strerror      | 15 +++++++++++++++
 src/modules/files/efuns.c           | 23 +++++++++++++++++++++++
 src/modules/files/file.c            | 23 +++++++++++++++++++++++
 src/modules/files/file.h            |  1 +
 src/modules/files/file_machine.h.in |  3 +++
 6 files changed, 66 insertions(+), 1 deletion(-)
 create mode 100644 src/modules/files/doc/strerror

diff --git a/src/modules/files/configure.in b/src/modules/files/configure.in
index deb96b9132..2a1cdf33d0 100644
--- a/src/modules/files/configure.in
+++ b/src/modules/files/configure.in
@@ -13,7 +13,7 @@ if test "$ac_cv_lib_socket" = yes -o "${ac_cv_lib_ucb}" = yes; then
  AC_CHECK_LIB(nsl, main)
 fi
 
-AC_HAVE_FUNCS(socketpair getwd)
+AC_HAVE_FUNCS(socketpair getwd strerror)
 
 AC_MSG_CHECKING(size of socket buffers)
 AC_CACHE_VAL(lpc_cv_socket_buffer_max,
diff --git a/src/modules/files/doc/strerror b/src/modules/files/doc/strerror
new file mode 100644
index 0000000000..bcb7a06120
--- /dev/null
+++ b/src/modules/files/doc/strerror
@@ -0,0 +1,15 @@
+NAME
+	strerror - return a string describing an error
+
+SYNTAX
+	string strerror(int errno);
+
+DESCRIPTION
+	This function returns a description of an error code. The error
+	code is usually obtained from the file->errno() call.
+
+KEYWORDS
+	file
+
+NOTA BENE
+	This function may not be available on all platforms.
diff --git a/src/modules/files/efuns.c b/src/modules/files/efuns.c
index d5ba229368..09b389f622 100644
--- a/src/modules/files/efuns.c
+++ b/src/modules/files/efuns.c
@@ -342,6 +342,25 @@ void f_mv(INT32 args)
   push_int(!i);
 }
 
+#ifdef HAVE_STRERROR
+void f_strerror(INT32 args)
+{
+  char *s;
+
+  if(!args) 
+    error("Too few arguments to strerror()\n");
+  if(sp[-args].type != T_INT)
+    error("Bad argument 1 to strerror()\n");
+
+  s=strerror(sp[-args].u.integer);
+  pop_n_elems(args);
+  if(s)
+    push_text(s);
+  else
+    push_int(0);
+}
+#endif
+
 void init_files_efuns()
 {
   set_close_on_exec(0,1);
@@ -359,4 +378,8 @@ void init_files_efuns()
   add_efun("getcwd",f_getcwd,"function(:string)",OPT_EXTERNAL_DEPEND);
   add_efun("fork",f_fork,"function(:int)",OPT_SIDE_EFFECT);
   add_efun("exece",f_exece,"function(string,mixed*,void|mapping(string:string):int)",OPT_SIDE_EFFECT); 
+
+#ifdef HAVE_STRERROR
+  add_efun("strerror",f_strerror,"function(int:string)",0);
+#endif
 }
diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index 372c47658c..85aca57d8c 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -20,6 +20,7 @@
 #include "file.h"
 #include "error.h"
 #include "lpc_signal.h"
+#include "lpc_types.h"
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -1144,6 +1145,27 @@ static void file_query_address(INT32 args)
   push_string(make_shared_string(buffer));
 }
 
+static void file_lsh(INT32 args)
+{
+  INT32 len;
+  if(args != 1)
+    error("Too few/many args to file->`<<\n");
+
+  if(sp[-1].type != T_STRING)
+  {
+    push_string(string_type_string);
+    string_type_string->refs++;
+    f_cast();
+  }
+
+  len=sp[-1].u.string->len;
+  file_write(1);
+  if(len != sp[-1].u.integer) error("File << failed.\n");
+  pop_stack();
+
+  push_object(this_object());
+}
+
 static void file_create(INT32 args)
 {
   char *s;
@@ -1221,6 +1243,7 @@ void init_files_programs()
   add_function("connect",file_connect,"function(string,int:int)",0);
   add_function("query_address",file_query_address,"function(int|void:int)",0);
   add_function("create",file_create,"function(void|string:void)",0);
+  add_function("`<<",file_lsh,"function(mixed:object)",0);
 
   set_init_callback(init_file_struct);
   set_exit_callback(exit_file_struct);
diff --git a/src/modules/files/file.h b/src/modules/files/file.h
index 76aace9fd8..e7114ad622 100644
--- a/src/modules/files/file.h
+++ b/src/modules/files/file.h
@@ -37,6 +37,7 @@ struct my_file
 
 /* Prototypes begin here */
 struct object *file_make_object_from_fd(int fd, int mode);
+int socketpair(int family, int type, int protocol, int sv[2]);
 void get_inet_addr(struct sockaddr_in *addr,char *name);
 void exit_files();
 void init_files_programs();
diff --git a/src/modules/files/file_machine.h.in b/src/modules/files/file_machine.h.in
index 8564e516d2..9b3ee80b42 100644
--- a/src/modules/files/file_machine.h.in
+++ b/src/modules/files/file_machine.h.in
@@ -37,6 +37,9 @@
 /* Define if you have getwd.  */
 #undef HAVE_GETWD
 
+/* Define if you have strerror.  */
+#undef HAVE_STRERROR
+
 /* Define if you have a working getcwd */
 #undef HAVE_WORKING_GETCWD
 
-- 
GitLab


From cad13986d28bd54c1e0398270d6c6ed2bf72e4e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 20:50:52 +0200
Subject: [PATCH 206/351] module cleanup

Rev: src/modules/.cvsignore:1.1
Rev: src/modules/Makefile.src:1.1
Rev: src/modules/configure.in:1.1
Rev: src/modules/module_dir_marker:1.1
---
 src/modules/.cvsignore        |  2 ++
 src/modules/.gitignore        |  2 ++
 src/modules/Makefile.src      | 24 +++++++++++++++++
 src/modules/configure.in      | 50 +++++++++++++++++++++++++++++++++++
 src/modules/module_dir_marker |  1 +
 5 files changed, 79 insertions(+)
 create mode 100644 src/modules/.cvsignore
 create mode 100644 src/modules/.gitignore
 create mode 100644 src/modules/Makefile.src
 create mode 100644 src/modules/configure.in
 create mode 100644 src/modules/module_dir_marker

diff --git a/src/modules/.cvsignore b/src/modules/.cvsignore
new file mode 100644
index 0000000000..64200ddc24
--- /dev/null
+++ b/src/modules/.cvsignore
@@ -0,0 +1,2 @@
+Makefile.in
+configure
diff --git a/src/modules/.gitignore b/src/modules/.gitignore
new file mode 100644
index 0000000000..addfc0376f
--- /dev/null
+++ b/src/modules/.gitignore
@@ -0,0 +1,2 @@
+/Makefile.in
+/configure
diff --git a/src/modules/Makefile.src b/src/modules/Makefile.src
new file mode 100644
index 0000000000..b4a98b0efa
--- /dev/null
+++ b/src/modules/Makefile.src
@@ -0,0 +1,24 @@
+@SET_MAKE@
+
+MODULES=@subdirs@
+MODULE_OBJS=@MODULE_OBJS@
+
+MAKE_FLAGS = "prefix=$(prefix)" "exex_prefix=$(exex_prefix)" "CC=$(CC)" "OTHERFLAGS=$(OTHERFLAGS)" "FIXDEP=$(FIXDEP)" "DEBUGDEF=$(DEBUGDEF)"
+
+all: modules
+
+modules:
+	for a in $(MODULES) ; do ( cd $$a ; $(MAKE) $(MAKE_FLAGS) ) ; done
+	$(MAKE) linker_options
+
+linker_options: $(MODULE_OBJS)
+	( for a in $(MODULES) ; do echo modules/$$a/$$a.a ; \
+	if test -f $$a/linker_options ; then cat $$a/linker_options ; fi ; \
+	done ; ) >linker_options
+
+depend:
+	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)
+	for a in $(MODULES) ; do ( cd $$a ; ${MAKE} $(MAKE_FLAGS) depend ) ; done
+
+clean:
+	for a in $(MODULES) ; do ( cd $$a ; ${MAKE} $(MAKE_FLAGS) clean ) ; done
diff --git a/src/modules/configure.in b/src/modules/configure.in
new file mode 100644
index 0000000000..9c8f79d139
--- /dev/null
+++ b/src/modules/configure.in
@@ -0,0 +1,50 @@
+AC_INIT(module_dir_marker)
+
+AC_SET_MAKE
+
+dirs=
+MODULE_OBJS=
+module_names=
+for a in `(cd $srcdir ; echo *)`
+do
+  if test "$a" != "CVS" -a "$a" != "RCS" ; then
+    if test -d "$srcdir/$a" ; then
+      dirs="$dirs $a"
+      MODULE_OBJS="$MODULE_OBJS $a/$a.a"
+      module_names="$module_names $a"
+    fi
+  fi
+done
+
+AC_SUBST(MODULE_OBJS)
+AC_CONFIG_SUBDIRS($dirs)
+
+AC_OUTPUT(Makefile,
+[
+echo creating modlist.h
+(
+echo "void init_main_efuns(void);"
+echo "void init_main_programs(void);"
+echo "void exit_main(void);"
+
+for a in $dirs
+do
+  echo "void init_"$a"_efuns(void);"
+  echo "void init_"$a"_programs(void);"
+  echo "void exit_"$a"(void);"
+done
+echo ""
+echo "struct module module_list UGLY_WORKAROUND={"
+
+echo "  { \"main\", init_main_efuns, init_main_programs, exit_main, 0 }"
+for a in $dirs
+do
+  echo " ,{ \"$a\", init_"$a"_efuns, init_"$a"_programs, exit_"$a", 0 }"
+done
+echo "};" 
+) > ../modlist.h
+]
+,
+dirs="$module_names"
+)
+
diff --git a/src/modules/module_dir_marker b/src/modules/module_dir_marker
new file mode 100644
index 0000000000..095cf52524
--- /dev/null
+++ b/src/modules/module_dir_marker
@@ -0,0 +1 @@
+Just ignore this file...
-- 
GitLab


From f3bce627f0dcf3639d635f298ce4bd7642409546 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 20:55:52 +0200
Subject: [PATCH 207/351] module stuff moved

Rev: src/Makefile.src:1.6
---
 src/Makefile.src | 67 +++++++++++++++++++++++++++++++-----------------
 1 file changed, 44 insertions(+), 23 deletions(-)

diff --git a/src/Makefile.src b/src/Makefile.src
index 1b1a934092..36776895f8 100644
--- a/src/Makefile.src
+++ b/src/Makefile.src
@@ -3,7 +3,7 @@
 
 # Don't change this line.  Define EXTRALIBS before this line if you
 # wish to add any libraries.
-LIBS=@LIBS@ $(EXTRALIBS) `for a in $(MODULES) ; do if [ -f $$a/linker_options ]; then cat $$a/linker_options ; fi ; done`
+LIBS=@LIBS@ $(EXTRALIBS)
 
 # not used yet
 INSTALL=@INSTALL@
@@ -44,14 +44,14 @@ WARN=@WARN@
 #add extra defines here
 # Be sure to use -g and -DDEBUG when looking for bugs
 DEBUGDEF=-DDEBUG
-DEFINES=$(DEBUGDEF) -DDEFAULT_MASTER=\"$(lib_prefix)/master.lpc\"
+DEFINES=-DDEFAULT_MASTER=\"$(lib_prefix)/master.lpc\"
 
 # -O should work with all compilers
 OPTIMIZE=@OPTIMIZE@
 
 # Preprocessor flags.
 PREFLAGS=-I. -I$(SRCDIR) $(DEFINES)
-OTHERFLAGS=$(OSFLAGS) $(OPTIMIZE) $(WARN) $(PROFIL)
+OTHERFLAGS=$(DEBUGDEF) $(OSFLAGS) $(OPTIMIZE) $(WARN) $(PROFIL)
 CFLAGS=$(PREFLAGS) $(OTHERFLAGS)
 
 CC=@CC@
@@ -63,22 +63,46 @@ LDFLAGS=$(CFLAGS)
 RUNULPC=$(TMP_BUILDDIR)/ulpc -m $(TMP_LIBDIR)/master.lpc $(LPCOPTS)
 FIXDEP=$(TMP_BINDIR)/fixdepends.sh
 
-MAKE_FLAGS = "prefix=$(prefix)" "exex_prefix=$(exex_prefix)" "CC=$(CC)" "OTHERFLAGS=$(OTHERFLAGS)" "FIXDEP=$(FIXDEP)"
+MAKE_FLAGS = "prefix=$(prefix)" "exex_prefix=$(exex_prefix)" "CC=$(CC)" "OTHERFLAGS=$(OTHERFLAGS)" "FIXDEP=$(FIXDEP)" "DEBUGDEF=$(DEBUGDEF)"
 
 # Add alloca.o if you don't have alloca() on your machine.
 # Add ualarm.o if you don't have ualarm() on your machine.
 #
-OBJ=language.o peep.o add_efun.o array.o builtin_efuns.o backend.o \
-    call_out.o docode.o dynamic_buffer.o error.o fd_control.o \
-    fsort.o hashtable.o interpret.o lex.o las.o list.o \
-    lpc_types.o main.o mapping.o memory.o module.o object.o \
-    opcodes.o operators.o port.o program.o rusage.o stralloc.o \
-    stuff.o svalue.o gc.o callback.o lpc_signal.o @EXTRA_OBJS@
-
-#
-MODULES=@subdirs@
-MODULE_OBJS=@MODULE_OBJS@
-
+OBJ= \
+ add_efun.o \
+ array.o \
+ backend.o \
+ builtin_efuns.o \
+ callback.o \
+ docode.o \
+ dynamic_buffer.o \
+ error.o \
+ fd_control.o \
+ fsort.o \
+ gc.o \
+ hashtable.o \
+ interpret.o \
+ language.o \
+ las.o \
+ lex.o \
+ list.o \
+ lpc_signal.o \
+ lpc_types.o \
+ main.o \
+ mapping.o \
+ memory.o \
+ module.o \
+ object.o \
+ opcodes.o \
+ operators.o \
+ peep.o \
+ port.o \
+ program.o \
+ rusage.o \
+ stralloc.o \
+ stuff.o \
+ svalue.o \
+ @EXTRA_OBJS@
 #
 # User callable targets
 #
@@ -86,9 +110,9 @@ MODULE_OBJS=@MODULE_OBJS@
 all: $(OBJ) module_objects
 	$(MAKE) $(MAKE_FLAGS) ulpc
 
-ulpc: $(OBJ) $(MODULE_OBJS)
+ulpc: $(OBJ) modules/linker_options
 	-mv ulpc ulpc.old
-	$(LD) $(LDFLAGS) $(OBJ) $(MODULE_OBJS) -o ulpc $(LIBS)
+	$(LD) $(LDFLAGS) $(OBJ) `cat modules/linker_options` $(LIBS) -o ulpc
 
 # purify
 pure: $(OBJ) module_objects
@@ -184,19 +208,19 @@ peep.o: peep_engine.c
 # make dependencies (requires compiled uLPC)
 depend: language.c
 	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)
-	for a in $(MODULES) ; do ( cd $$a ; ${MAKE} $(MAKE_FLAGS) depend ) ; done
+	( cd modules ; $(MAKE) $(MAKE_FLAGS) depend )
 
 docs:
 	mkdir docs
 
 html_docs: docs
-	$(RUNULPC) $(TMP_BINDIR)/htmlify_docs docs $(TMP_DOCDIR) `for a in $(MODULES); do echo $(SRCDIR)/$$a/doc ; done`
+	$(RUNULPC) $(TMP_BINDIR)/htmlify_docs docs $(TMP_DOCDIR) `echo $(SRCDIR)/modules/*/doc` ; done`
 
 #
 # uLPC internal targets
 #
 module_objects:
-	for a in $(MODULES) ; do ( cd $$a ; ${MAKE} $(MAKE_FLAGS) ) ; done
+	( cd modules ; ${MAKE} $(MAKE_FLAGS) )
 
 lang.o: lang.c config.h object.h interpret.h program.h
 
@@ -229,9 +253,6 @@ machine.h: stamp-h
 stamp-h: machine.h.in config.status
 	CONFIG_FILES= CONFIG_HEADERS=machine.h ./config.status
 
-modlist.h:
-	CONFIG_FILES=modlist.h CONFIG_HEADERS= ./config.status
-
 $(SRCDIR)/test/testsuite: $(SRCDIR)/test/create_testsuite
 	m4 <$(SRCDIR)/test/create_testsuite >$(SRCDIR)/test/testsuite
 
-- 
GitLab


From 2e2dbf8e6e13bd593545f29bb70ef339781197ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 20:57:05 +0200
Subject: [PATCH 208/351] updated

Rev: src/COPYRIGHT:1.2
Rev: src/README:1.4
---
 src/COPYRIGHT | 2 +-
 src/README    | 5 +++++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/COPYRIGHT b/src/COPYRIGHT
index 4dcf08f94b..da54f99fa7 100644
--- a/src/COPYRIGHT
+++ b/src/COPYRIGHT
@@ -1,4 +1,4 @@
-uLPC, is copyright by Fredrik Hubinette, 1994
+uLPC, is copyright by Fredrik Hubinette, 1994-1996
 
 Source code herein refers to the source code, and any executables
 created from the same source code.
diff --git a/src/README b/src/README
index 6463e7e4ec..068dbcea25 100644
--- a/src/README
+++ b/src/README
@@ -4,6 +4,11 @@ This is what you need to do to install uLPC:
    Makefile from machine.h.in and Makefile.in, use --prefix=/foo/bar
    if you want to install ulpc in /foo/bar, default is /usr/local.
 
+   You might have to set the environment variables C_INCLUDE_PATH and
+   LD_LIBRARY_PATH to enable the configure script to find gdbm and gmp.
+   If the configure script does not find those libraries those modules
+   will not be available.
+
 2) edit config.h and Makefile to suit your purposes.
    I've tried to make it so that you don't have to change config.h or
    Makefile very much. If you need to do what you consider 'unnessecary
-- 
GitLab


From 5e0340a12a2b4d2c1dff29b0fcc47fe72972e94b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:02:33 +0200
Subject: [PATCH 209/351] stack check added

Rev: src/add_efun.c:1.4
---
 src/add_efun.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/add_efun.c b/src/add_efun.c
index 4ecc6d4e3d..dae55bb074 100644
--- a/src/add_efun.c
+++ b/src/add_efun.c
@@ -106,6 +106,7 @@ void add_efun(char *name, c_fun fun, char *type, INT16 flags)
 static void push_efun_entry(struct hash_entry *h)
 {
   struct efun *f;
+  check_stack(1);
   f=BASEOF(h, efun, link);
   push_string(f->link.s);
   f->link.s->refs++;
-- 
GitLab


From f5f7b15caeadc0ed7156f5406da5ed94002b3333 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:08:54 +0200
Subject: [PATCH 210/351] a few small changes

Rev: src/array.c:1.13
Rev: src/array.h:1.9
---
 src/array.c | 65 +++++++++++++++++++++++++++++------------------------
 src/array.h |  1 +
 2 files changed, 37 insertions(+), 29 deletions(-)

diff --git a/src/array.c b/src/array.c
index a820f36adb..e8fe55aae9 100644
--- a/src/array.c
+++ b/src/array.c
@@ -524,7 +524,6 @@ INT32 *get_order(struct array *v, cmpfun fun)
   return current_order;
 }
 
-
 static int set_svalue_cmpfun(struct svalue *a, struct svalue *b)
 {
   INT32 tmp;
@@ -605,6 +604,17 @@ static int alpha_svalue_cmpfun(struct svalue *a, struct svalue *b)
   }
 }
 
+void sort_array_destructively(struct array *v)
+{
+  if(!v->size) return;
+  fsort((char *)ITEM(v),
+	v->size,
+	sizeof(struct svalue),
+	(fsortfun)alpha_svalue_cmpfun);
+}
+
+
+
 /*
  * return an 'order' suitable for making mappings, lists other sets
  */
@@ -1117,8 +1127,7 @@ node *make_node_from_array(struct array *a)
 
 void push_array_items(struct array *a)
 {
-  if(sp + a->size >= &evaluator_stack[EVALUATOR_STACK_SIZE])
-    error("Array does not fit on stack.\n");
+  check_stack(a->size);
   check_array_for_destruct(a);
   if(a->refs == 1)
   {
@@ -1126,12 +1135,11 @@ void push_array_items(struct array *a)
     sp += a->size;
     a->size=0;
     free_array(a);
-    return;
   }else{
     assign_svalues_no_free(sp, ITEM(a), a->size, a->type_field);
+    sp += a->size;
+    free_array(a);
   }
-  sp += a->size;
-  free_array(a);
 }
 
 void describe_array_low(struct array *a, struct processing *p, int indent)
@@ -1211,45 +1219,40 @@ struct array *aggregate_array(INT32 args)
 struct array *explode(struct lpc_string *str,
 		       struct lpc_string *del)
 {
-  INT32 e,d;
+  INT32 e;
   struct array *ret;
   char *s, *end, *tmp;
 
   if(!del->len)
   {
     ret=allocate_array_no_init(str->len,0);
-    ret->type_field |= BIT_STRING;
     for(e=0;e<str->len;e++)
     {
       ITEM(ret)[e].type=T_STRING;
       ITEM(ret)[e].u.string=make_shared_binary_string(str->str+e,1);
     }
   }else{
-
+    struct mem_searcher searcher;
+    
     s=str->str;
     end=s+str->len;
     e=0;
-
-    while((s=MEMMEM(del->str, del->len, s, end-s)))
-    {
-      s+=del->len;
-      e++;
-    }
-
-    ret=allocate_array_no_init(e+1,0);
-    ret->type_field |= BIT_STRING;
-
-    s=str->str;
-    for(d=0;d<e;d++)
+    
+    init_memsearch(&searcher, del->str, del->len, str->len);
+    
+    while(tmp=memory_search(&searcher, s, end-s))
     {
-      tmp=MEMMEM((char *)(del->str), del->len, (char *)s, end-s);
-      ITEM(ret)[d].type=T_STRING;
-      ITEM(ret)[d].u.string=make_shared_binary_string(s,tmp-s);
+      check_stack(1);
+      push_string(make_shared_binary_string(s, tmp-s));
       s=tmp+del->len;
+      e++;
     }
-    ITEM(ret)[d].type=T_STRING;
-    ITEM(ret)[d].u.string=make_shared_binary_string(s,end-s);
+    check_stack(1);
+    push_string(make_shared_binary_string(s, end-s));
+    e++;
+    ret=aggregate_array(e);
   }
+  ret->type_field=BIT_STRING;
   return ret;
 }
 
@@ -1314,13 +1317,17 @@ struct array *copy_array_recursively(struct array *a,struct processing *p)
 
 void apply_array(struct array *a, INT32 args)
 {
-  struct svalue *argp;
   INT32 e;
   struct array *ret;
-  argp=sp-args;
+  INT32 argp;
+
+  argp=sp-args - evaluator_stack;
+
+  check_stack(a->size + args + 1);
+
   for(e=0;e<a->size;e++)
   {
-    assign_svalues_no_free(sp,argp,args,BIT_MIXED);
+    assign_svalues_no_free(sp,evaluator_stack+argp,args,BIT_MIXED);
     sp+=args;
     apply_svalue(ITEM(a)+e,args);
   }
diff --git a/src/array.h b/src/array.h
index 12c5e9ff49..9899facd11 100644
--- a/src/array.h
+++ b/src/array.h
@@ -75,6 +75,7 @@ struct array *copy_array(struct array *v);
 void check_array_for_destruct(struct array *v);
 INT32 array_find_destructed_object(struct array *v);
 INT32 *get_order(struct array *v, cmpfun fun);
+void sort_array_destructively(struct array *v);
 INT32 *get_set_order(struct array *a);
 INT32 *get_switch_order(struct array *a);
 INT32 *get_alpha_order(struct array *a);
-- 
GitLab


From 52e0752eef32464cbe68310681d69cf430639326 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:18:40 +0200
Subject: [PATCH 211/351] backend slightly rewritten

Rev: src/backend.c:1.5
Rev: src/backend.h:1.5
---
 src/backend.c | 63 +++++++++++++++++++++++----------------------------
 src/backend.h | 36 ++++++++++-------------------
 2 files changed, 40 insertions(+), 59 deletions(-)

diff --git a/src/backend.c b/src/backend.c
index 0b07f66099..6888606c41 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -13,7 +13,6 @@
 #include "object.h"
 #include "types.h"
 #include "error.h"
-#include "call_out.h"
 #include "fd_control.h"
 #include "main.h"
 #include "callback.h"
@@ -33,19 +32,22 @@ struct selectors
 
 static struct selectors selectors;
 
-callback read_callback[MAX_OPEN_FILEDESCRIPTORS];
+file_callback read_callback[MAX_OPEN_FILEDESCRIPTORS];
 void *read_callback_data[MAX_OPEN_FILEDESCRIPTORS];
-callback write_callback[MAX_OPEN_FILEDESCRIPTORS];
+file_callback write_callback[MAX_OPEN_FILEDESCRIPTORS];
 void *write_callback_data[MAX_OPEN_FILEDESCRIPTORS];
 
 static int max_fd;
-time_t current_time;
+struct timeval current_time;
+struct timeval next_timeout;
 
-static struct callback_list *backend_callbacks;
+static struct callback *backend_callbacks = 0;
 
-struct callback_list *add_backend_callback(struct array *a)
+struct callback *add_backend_callback(callback_func call,
+				      void *arg,
+				      callback_func free_func)
 {
-  return add_to_callback_list(&backend_callbacks, a);
+  return add_to_callback(&backend_callbacks, call, arg, free_func);
 }
 
 void init_backend()
@@ -54,7 +56,7 @@ void init_backend()
   FD_ZERO(&selectors.write);
 }
 
-void set_read_callback(int fd,callback cb,void *data)
+void set_read_callback(int fd,file_callback cb,void *data)
 {
 #ifdef DEBUG
   if(fd<0 || fd>=MAX_OPEN_FILEDESCRIPTORS)
@@ -83,7 +85,7 @@ void set_read_callback(int fd,callback cb,void *data)
   }
 }
 
-void set_write_callback(int fd,callback cb,void *data)
+void set_write_callback(int fd,file_callback cb,void *data)
 {
 #ifdef DEBUG
   if(fd<0 || fd>=MAX_OPEN_FILEDESCRIPTORS)
@@ -112,7 +114,7 @@ void set_write_callback(int fd,callback cb,void *data)
   }
 }
 
-callback query_read_callback(int fd)
+file_callback query_read_callback(int fd)
 {
 #ifdef DEBUG
   if(fd<0 || fd>=MAX_OPEN_FILEDESCRIPTORS)
@@ -122,7 +124,7 @@ callback query_read_callback(int fd)
   return read_callback[fd];
 }
 
-callback query_write_callback(int fd)
+file_callback query_write_callback(int fd)
 {
 #ifdef DEBUG
   if(fd<0 || fd>=MAX_OPEN_FILEDESCRIPTORS)
@@ -168,7 +170,6 @@ void do_debug()
   check_all_programs();
   verify_all_objects();
   verify_shared_strings_tables();
-  verify_all_call_outs();
 }
 #endif
 
@@ -176,7 +177,6 @@ void backend()
 {
   JMP_BUF back;
   int i, delay;
-  struct timeval timeout;
   struct selectors sets;
 
   if(SETJMP(back))
@@ -190,24 +190,26 @@ void backend()
 
   while(first_object)
   {
-    delay = get_next_call_out();
-    if(delay)
-    {
-      delay -= get_current_time();
-      if(delay < 0) delay = 0;
-    } else {
-      delay = 7 * 24 * 60 * 60; /* See you in a week */
-    }
-    timeout.tv_usec = 0;
-    timeout.tv_sec = delay;
+    next_timeout.tv_usec = 0;
+    next_timeout.tv_sec = 7 * 24 * 60 * 60;  /* See you in a week */
+    my_add_timeval(&next_timeout, &current_time);
 
+    call_callback(& backend_callbacks);
     sets=selectors;
 
-    i=select(max_fd+1, &sets.read, &sets.write, 0, &timeout);
+    alloca(0);			/* Do garbage collect */
+#ifdef DEBUG
+    if(d_flag > 1) do_debug();
+#endif
 
-    current_time = get_current_time();
-    check_signals();
+    GETTIMEOFDAY(&current_time);
+    my_subtract_timeval(&next_timeout, &current_time);
+    i=select(max_fd+1, &sets.read, &sets.write, 0, &next_timeout);
+
+    GETTIMEOFDAY(&current_time);
 
+    check_signals();
+    
     if(i>=0)
     {
       for(i=0; i<max_fd+1; i++)
@@ -234,15 +236,6 @@ void backend()
 
       }
     }
-
-    do_call_outs();
-    call_callback_list(& backend_callbacks);
-
-    alloca(0);			/* Do garbage collect */
-#ifdef DEBUG
-    if(d_flag > 1)
-      do_debug();
-#endif
   }
 
   UNSETJMP(back);
diff --git a/src/backend.h b/src/backend.h
index 0b556c8359..a1a903a8b8 100644
--- a/src/backend.h
+++ b/src/backend.h
@@ -7,35 +7,23 @@
 #define BACKEND_H
 
 #include "global.h"
+#include "time_stuff.h"
+#include "callback.h"
 
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  if HAVE_TIME_H
-#   include <time.h>
-#  endif
-# endif
-#endif
-
-#undef HAVE_SYS_TIME_H
-#undef HAVE_TIME_H
-#undef TIME_WITH_SYS_TIME
-
-extern time_t current_time;
-typedef void (*callback)(int,void *);
+extern struct timeval current_time;
+extern struct timeval next_timeout;
+typedef void (*file_callback)(int,void *);
 
 /* Prototypes begin here */
 struct selectors;
-struct callback_list *add_backend_callback(struct array *a);
+struct callback *add_backend_callback(callback_func call,
+				      void *arg,
+				      callback_func free_func);
 void init_backend();
-void set_read_callback(int fd,callback cb,void *data);
-void set_write_callback(int fd,callback cb,void *data);
-callback query_read_callback(int fd);
-callback query_write_callback(int fd);
+void set_read_callback(int fd,file_callback cb,void *data);
+void set_write_callback(int fd,file_callback cb,void *data);
+file_callback query_read_callback(int fd);
+file_callback query_write_callback(int fd);
 void *query_read_callback_data(int fd);
 void *query_write_callback_data(int fd);
 void do_debug();
-- 
GitLab


From 3beb894f2aaedec501129b123007579fab7cd370 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:27:58 +0200
Subject: [PATCH 212/351] lots of stuff changed

Rev: src/builtin_efuns.c:1.20
Rev: src/builtin_efuns.h:1.2
---
 src/builtin_efuns.c | 378 ++++++++++++++++++++++----------------------
 src/builtin_efuns.h |  26 +--
 2 files changed, 205 insertions(+), 199 deletions(-)

diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index b2e70f6a80..2df3337572 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -20,24 +20,13 @@
 #include "rusage.h"
 #include "operators.h"
 #include "fsort.h"
-#include "call_out.h"
 #include "callback.h"
 #include "gc.h"
 #include "backend.h"
 #include "main.h"
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  if HAVE_TIME_H
-#   include <time.h>
-#  endif
-# endif
-#endif
+#include "memory.h"
+#include "time_stuff.h"
+#include <math.h>
 
 #ifdef HAVE_CRYPT_H
 #include <crypt.h>
@@ -227,10 +216,10 @@ void f_search(INT32 args)
     }
     len=sp[-args].u.string->len - start;
 
-    if(len>0 && (ptr=MEMMEM(sp[1-args].u.string->str,
-			    sp[1-args].u.string->len,
-			    sp[-args].u.string->str+start,
-			    len)))
+    if(len>0 && (ptr=my_memmem(sp[1-args].u.string->str,
+			       sp[1-args].u.string->len,
+			       sp[-args].u.string->str+start,
+			       len)))
     {
       start=ptr-sp[-args].u.string->str;
     }else{
@@ -287,12 +276,14 @@ void f_clone(INT32 args)
 
 void f_call_function(INT32 args)
 {
-  struct svalue *expected_sp=sp-args+2;
+  INT32 expected_stack=sp-args+2-evaluator_stack;
+
   strict_apply_svalue(sp-args, args - 1);
-  if(sp < expected_sp)
+  if(sp < expected_stack + evaluator_stack)
   {
 #ifdef DEBUG
-    if(sp+1 != expected_sp) fatal("Stack underflow!\n");
+    if(sp+1 != expected_stack + evaluator_stack)
+      fatal("Stack underflow!\n");
 #endif
 
     pop_stack();
@@ -541,11 +532,11 @@ void f_zero_type(INT32 args)
 
 void f_all_efuns(INT32 args)
 {
-  struct svalue *save_sp;
+  INT32 stack_size;
   pop_n_elems(args);
-  save_sp=sp;
+  stack_size=sp - evaluator_stack;
   push_all_efuns_on_stack();
-  f_aggregate_mapping(sp-save_sp);
+  f_aggregate_mapping(sp - evaluator_stack - stack_size);
 }
 
 void f_allocate(INT32 args)
@@ -659,9 +650,9 @@ void f_throw(INT32 args)
 
 static struct callback *exit_callbacks=0;
 
-struct callback *add_exit_callback(callback call,
+struct callback *add_exit_callback(callback_func call,
 				   void *arg,
-				   callback free_func)
+				   callback_func free_func)
 {
   return add_to_callback(&exit_callbacks, call, arg, free_func);
 }
@@ -696,12 +687,11 @@ void f_query_host_name(INT32 args)
 
 void f_time(INT32 args)
 {
-  extern time_t current_time;
   pop_n_elems(args);
   if(args)
-    push_int(current_time);
+    push_int(current_time.tv_sec);
   else
-    push_int(get_current_time());
+    push_int((INT32)TIME(0));
 }
 
 void f_crypt(INT32 args)
@@ -969,9 +959,9 @@ static int replace_sortfun(void *a,void *b)
   return my_quick_strcmp( ((struct tupel *)a)->ind, ((struct tupel *)b)->ind);
 }
 
-struct lpc_string * replace_many(struct lpc_string *str,
-				    struct array *from,
-				    struct array *to)
+static struct lpc_string * replace_many(struct lpc_string *str,
+					struct array *from,
+					struct array *to)
 {
   char *s;
   INT32 length,e;
@@ -1187,23 +1177,47 @@ void f_functionp(INT32 args)
 
 void f_sleep(INT32 args)
 {
-  struct timeval timeout;
+  struct timeval t1,t2,t3;
   INT32 a,b;
 
-  if(!args) error("Too few arguments to sleep.\n");
-  if(sp[-args].type!=T_INT)
+  if(!args)
+    error("Too few arguments to sleep.\n");
+
+  GETTIMEOFDAY(&t1);
+
+  switch(sp[-args].type)
+  {
+  case T_INT:
+    t2.tv_sec=sp[-args].u.integer;
+    t2.tv_usec=0;
+    break;
+
+  case T_FLOAT:
+  {
+    FLOAT_TYPE f;
+    f=sp[-args].u.float_number;
+    t2.tv_sec=floor(f);
+    t2.tv_usec=(long)(1000000.0*(f-floor(f)));
+    break;
+  }
+
+  default:
     error("Bad argument 1 to sleep.\n");
-  a=get_current_time()+sp[-args].u.integer;
+  }
+
+  my_add_timeval(&t1, &t1);
   
   pop_n_elems(args);
   while(1)
   {
-    timeout.tv_usec=0;
-    b=a-get_current_time();
-    if(b<0) break;
+    GETTIMEOFDAY(&t2);
+    if(my_timercmp(&t1, > , &t2))
+      break;
 
-    timeout.tv_sec=b;
-    select(0,0,0,0,&timeout);
+    t3=t1;
+    my_subtract_timeval(&t3, &t2);
+
+    select(0,0,0,0,&t3);
     check_signals();
   }
 }
@@ -1257,10 +1271,15 @@ void f_sort(INT32 args)
       error("Argument %ld to sort() has wrong size.\n",(long)(e+1));
   }
 
-  order=get_alpha_order(sp[-args].u.array);
-  for(e=0;e<args;e++) order_array(sp[e-args].u.array,order);
-  free((char *)order);
-  pop_n_elems(args-1);
+  if(args > 1)
+  {
+    order=get_alpha_order(sp[-args].u.array);
+    for(e=0;e<args;e++) order_array(sp[e-args].u.array,order);
+    free((char *)order);
+    pop_n_elems(args-1);
+  } else {
+    sort_array_destructively(sp[-args].u.array);
+  }
 }
 
 void f_rows(INT32 args)
@@ -1320,82 +1339,56 @@ void f__verify_internals(INT32 args)
 
 #endif
 
-void init_builtin_efuns()
+#ifdef HAVE_LOCALTIME
+void f_localtime(INT32 args)
 {
-  init_operators();
+  struct tm *tm;
+  time_t t;
+  if (args<1 || sp[-1].type!=T_INT)
+    error("Illegal argument to localtime");
 
-#ifdef DEBUG
-  add_efun("_verify_internals",f__verify_internals,"function(:void)",OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND);
-#endif
+  t=sp[-1].u.integer;
+  tm=localtime(&t);
+  pop_n_elems(args);
 
-  add_efun("add_efun",f_add_efun,"function(string,void|mixed:void)",OPT_SIDE_EFFECT);
-  add_efun("aggregate",f_aggregate,"function(mixed ...:mixed *)",OPT_TRY_OPTIMIZE);
-  add_efun("aggregate_list",f_aggregate_list,"function(mixed ...:list)",OPT_TRY_OPTIMIZE);
-  add_efun("aggregate_mapping",f_aggregate_mapping,"function(mixed ...:mapping)",OPT_TRY_OPTIMIZE);
-  add_efun("all_efuns",f_all_efuns,"function(:mapping(string:mixed))",OPT_EXTERNAL_DEPEND);
-  add_efun("allocate", f_allocate, "function(int, string|void:mixed *)", 0);
-  add_efun("arrayp",  f_arrayp,  "function(mixed:int)",0);
-  add_efun("backtrace",f_backtrace,"function(:array(array(function|int|string)))",OPT_EXTERNAL_DEPEND);
-  add_efun("call_function",f_call_function,"function(mixed,mixed ...:mixed)",OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND);
-  add_efun("call_out",f_call_out,"function(function,int,mixed...:void)",OPT_SIDE_EFFECT);
-  add_efun("call_out_info",f_call_out_info,"function(:array*)",OPT_EXTERNAL_DEPEND);
-  add_efun("clone",f_clone,"function(program,mixed...:object)",OPT_EXTERNAL_DEPEND);
-  add_efun("combine_path",f_combine_path,"function(string,string:string)",0);
-  add_efun("compile_file",f_compile_file,"function(string:program)",OPT_EXTERNAL_DEPEND);
-  add_efun("compile_string",f_compile_string,"function(string,string|void:program)",OPT_EXTERNAL_DEPEND);
-  add_efun("copy_value",f_copy_value,"function(mixed:mixed)",0);
-  add_efun("crypt",f_crypt,"function(string:string)|function(string,string:int)",OPT_EXTERNAL_DEPEND);
-  add_efun("ctime",f_ctime,"function(int:string)",OPT_TRY_OPTIMIZE);
-  add_efun("destruct",f_destruct,"function(object|void:void)",OPT_SIDE_EFFECT);
-  add_efun("equal",f_equal,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE);
-  add_efun("exit",f_exit,"function(int:void)",OPT_SIDE_EFFECT);
-  add_efun("find_call_out",f_find_call_out,"function(function:int)",OPT_EXTERNAL_DEPEND);
-  add_efun("floatp",  f_floatp,  "function(mixed:int)",OPT_TRY_OPTIMIZE);
-  add_efun("function_name",f_function_name,"function(function:string)",OPT_TRY_OPTIMIZE);
-  add_efun("function_object",f_function_object,"function(function:object)",OPT_TRY_OPTIMIZE);
-  add_efun("functionp",  f_functionp,  "function(mixed:int)",OPT_TRY_OPTIMIZE);
-  add_efun("hash",f_hash,"function(string,int|void:int)",OPT_TRY_OPTIMIZE);
-  add_efun("indices",f_indices,"function(string|array:int*)|function(mapping|list:mixed*)|function(object:string*)",0);
-  add_efun("intp",   f_intp,    "function(mixed:int)",OPT_TRY_OPTIMIZE);
-  add_efun("listp",   f_listp,   "function(mixed:int)",OPT_TRY_OPTIMIZE);
-  add_efun("lower_case",f_lower_case,"function(string:string)",OPT_TRY_OPTIMIZE);
-  add_efun("mappingp",f_mappingp,"function(mixed:int)",OPT_TRY_OPTIMIZE);
-  add_efun("m_delete",f_m_delete,"function(mapping,mixed:mapping)",0);
-  add_efun("mkmapping",f_mkmapping,"function(mixed *,mixed *:mapping)",OPT_TRY_OPTIMIZE);
-  add_efun("next_object",f_next_object,"function(void|object:object)",OPT_EXTERNAL_DEPEND);
-  add_efun("object_program",f_object_program,"function(object:program)",0);
-  add_efun("objectp", f_objectp, "function(mixed:int)",0);
-  add_efun("programp",f_programp,"function(mixed:int)",0);
-  add_efun("query_host_name",f_query_host_name,"function(:string)",0);
-  add_efun("query_num_arg",f_query_num_arg,"function(:int)",OPT_EXTERNAL_DEPEND);
-  add_efun("random",f_random,"function(int:int)",OPT_EXTERNAL_DEPEND);
-  add_efun("random_seed",f_random_seed,"function(int:void)",OPT_SIDE_EFFECT);
-  add_efun("remove_call_out",f_remove_call_out,"function(function:int)",OPT_SIDE_EFFECT);
-  add_efun("replace",f_replace,"function(string,string,string:string)|function(string,string*,string*:string)|function(array,mixed,mixed:array)|function(mapping,mixed,mixed:array)",0);
-  add_efun("reverse",f_reverse,"function(int:int)|function(string:string)|function(array:array)",0);
-  add_efun("rusage", f_rusage, "function(:int *)",OPT_EXTERNAL_DEPEND);
-  add_efun("search",f_search,"function(string,string,void|int:int)|function(array,mixed,void|int:int)|function(mapping,mixed:mixed)",0);
-  add_efun("sizeof", f_sizeof, "function(string|list|array|mapping|object:int)",0);
-  add_efun("sleep", f_sleep, "function(int:void)",OPT_SIDE_EFFECT);
-  add_efun("stringp", f_stringp, "function(mixed:int)",0);
+  push_string(make_shared_string("sec"));
+  push_int(tm->tm_sec);
+  push_string(make_shared_string("min"));
+  push_int(tm->tm_min);
+  push_string(make_shared_string("hour"));
+  push_int(tm->tm_hour);
 
-  add_efun("this_object", f_this_object, "function(:object)",OPT_EXTERNAL_DEPEND);
-  add_efun("throw",f_throw,"function(mixed:void)",0);
-  add_efun("time",f_time,"function(void|int:int)",OPT_EXTERNAL_DEPEND);
-  add_efun("trace",f_trace,"function(int:int)",OPT_SIDE_EFFECT);
-  add_efun("upper_case",f_upper_case,"function(string:string)",0);
-  add_efun("values",f_values,"function(string|list:int*)|function(array|mapping|object:mixed*)",0);
-  add_efun("zero_type",f_zero_type,"function(int:int)",0);
-  add_efun("sort",f_sort,"function(array(mixed),array(mixed)...:array(mixed))",OPT_SIDE_EFFECT);
-  add_efun("column",f_column,"function(array,mixed:array)",0);
-  add_efun("rows",f_rows,"function(mixed,array:array)",0);
-#ifdef GC2
-  add_efun("gc",f_gc,"function(:int)",OPT_SIDE_EFFECT);
+  push_string(make_shared_string("mday"));
+  push_int(tm->tm_mday);
+  push_string(make_shared_string("mon"));
+  push_int(tm->tm_mon);
+  push_string(make_shared_string("year"));
+  push_int(tm->tm_year);
+
+  push_string(make_shared_string("wday"));
+  push_int(tm->tm_wday);
+  push_string(make_shared_string("yday"));
+  push_int(tm->tm_yday);
+  push_string(make_shared_string("isdst"));
+  push_int(tm->tm_isdst);
+
+#ifdef HAVE_EXTERNAL_TIMEZONE
+  push_string(make_shared_string("timezone"));
+  push_int(timezone);
+  f_aggregate_mapping(20);
+#else
+#ifdef STRUCT_TM_HAS_GMTOFF
+  push_string(make_shared_string("timezone"));
+  push_int(tm->tm_gmtoff);
+  f_aggregate_mapping(20);
+#else
+  f_aggregate_mapping(18);
+#endif
 #endif
 }
+#endif
 
 
-#if 0
 /* Check if the glob s[0..len[ matches the string m[0..mlen[ */
 static int does_match(char *s, int len, char *m, int mlen)
 {
@@ -1428,38 +1421,40 @@ void f_glob(INT32 args)
 {
   INT32 i,matches;
   struct array *a;
-  struct svalue *sval, *tmp;
+  struct svalue *sval, tmp;
   struct lpc_string *glob;
 
   if(args < 2)
     error("Too few arguments to glob().\n");
 
   if(args > 2) pop_n_elems(args-2);
+  args=2;
 
-  if (sp[1-args].type!=T_STRING)
+  if (sp[-args].type!=T_STRING)
     error("Bad argument 2 to glob().\n");
 
   glob=sp[-args].u.string;
 
-  switch(sp[-args].type)
+  switch(sp[1-args].type)
   {
   case T_STRING:
-    i=do_match(sp[1-args].u.string,
-	       sp[1-args].u.string->length,
-	       glob,
-	       glob->length);
+    i=does_match(sp[1-args].u.string->str,
+		 sp[1-args].u.string->len,
+		 glob->str,
+		 glob->len);
     pop_n_elems(2);
     push_int(i);
     break;
     
   case T_ARRAY:
-    a=sp[-args].u.array;
+    a=sp[1-args].u.array;
+    matches=0;
     for(i=0;i<a->size;i++)
     {
-      if(do_match(ITEM(a)[i].u.string,
-		  ITEM(a)[i].u.string->length,
-		  glob,
-		  glob->length))
+      if(does_match(ITEM(a)[i].u.string->str,
+		    ITEM(a)[i].u.string->len,
+		    glob->str,
+		    glob->len))
       {
 	ITEM(a)[i].u.string->refs++;
 	push_string(ITEM(a)[i].u.string);
@@ -1479,75 +1474,78 @@ void f_glob(INT32 args)
   }
 }
 
-
-/*
- * add_efun("glob",f_glob,"function(string,string:string)|function(string,array(string):array(string))",0);
- * add_efun("localtime",f_localtime,
- * "function(int:mapping(string:int))",OPT_EXTERNAL_DEPEND);
- */
-
-#if !HAVE_INT_TIMEZONE
-int _tz;
-#else
-extern long int timezone;
-#endif
-
-
-
-void f_localtime(INT32 args)
+void init_builtin_efuns()
 {
-  struct tm *tm;
-  time_t t;
-  if (args<1||
-      sp[-1].type!=T_INT)
-    error("Illegal argument to localtime");
-  t=sp[-1].u.integer;
-  tm=localtime(&t);
-  pop_stack();
-  push_string(make_shared_string("sec"));
-  push_int(tm->tm_sec);
-  push_string(make_shared_string("min"));
-  push_int(tm->tm_min);
-  push_string(make_shared_string("hour"));
-  push_int(tm->tm_hour);
-
-  push_string(make_shared_string("mday"));
-  push_int(tm->tm_mday);
-  push_string(make_shared_string("mon"));
-  push_int(tm->tm_mon);
-  push_string(make_shared_string("year"));
-  push_int(tm->tm_year);
-
-  push_string(make_shared_string("wday"));
-  push_int(tm->tm_wday);
-  push_string(make_shared_string("yday"));
-  push_int(tm->tm_yday);
-  push_string(make_shared_string("isdst"));
-  push_int(tm->tm_isdst);
+  init_operators();
+  
+  add_efun("add_efun",f_add_efun,"function(string,void|mixed:void)",OPT_SIDE_EFFECT);
+  add_efun("aggregate",f_aggregate,"function(mixed ...:mixed *)",OPT_TRY_OPTIMIZE);
+  add_efun("aggregate_list",f_aggregate_list,"function(mixed ...:list)",OPT_TRY_OPTIMIZE);
+  add_efun("aggregate_mapping",f_aggregate_mapping,"function(mixed ...:mapping)",OPT_TRY_OPTIMIZE);
+  add_efun("all_efuns",f_all_efuns,"function(:mapping(string:mixed))",OPT_EXTERNAL_DEPEND);
+  add_efun("allocate", f_allocate, "function(int, string|void:mixed *)", 0);
+  add_efun("arrayp",  f_arrayp,  "function(mixed:int)",0);
+  add_efun("backtrace",f_backtrace,"function(:array(array(function|int|string)))",OPT_EXTERNAL_DEPEND);
+  add_efun("call_function",f_call_function,"function(mixed,mixed ...:mixed)",OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND);
+  add_efun("clone",f_clone,"function(program,mixed...:object)",OPT_EXTERNAL_DEPEND);
+  add_efun("column",f_column,"function(array,mixed:array)",0);
+  add_efun("combine_path",f_combine_path,"function(string,string:string)",0);
+  add_efun("compile_file",f_compile_file,"function(string:program)",OPT_EXTERNAL_DEPEND);
+  add_efun("compile_string",f_compile_string,"function(string,string|void:program)",OPT_EXTERNAL_DEPEND);
+  add_efun("copy_value",f_copy_value,"function(mixed:mixed)",0);
+  add_efun("crypt",f_crypt,"function(string:string)|function(string,string:int)",OPT_EXTERNAL_DEPEND);
+  add_efun("ctime",f_ctime,"function(int:string)",OPT_TRY_OPTIMIZE);
+  add_efun("destruct",f_destruct,"function(object|void:void)",OPT_SIDE_EFFECT);
+  add_efun("equal",f_equal,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE);
+  add_efun("exit",f_exit,"function(int:void)",OPT_SIDE_EFFECT);
+  add_efun("floatp",  f_floatp,  "function(mixed:int)",OPT_TRY_OPTIMIZE);
+  add_efun("function_name",f_function_name,"function(function:string)",OPT_TRY_OPTIMIZE);
+  add_efun("function_object",f_function_object,"function(function:object)",OPT_TRY_OPTIMIZE);
+  add_efun("functionp",  f_functionp,  "function(mixed:int)",OPT_TRY_OPTIMIZE);
+  add_efun("glob",f_glob,"function(string,string:int)|function(string,string*:array(string))",OPT_TRY_OPTIMIZE);
+  add_efun("hash",f_hash,"function(string,int|void:int)",OPT_TRY_OPTIMIZE);
+  add_efun("indices",f_indices,"function(string|array:int*)|function(mapping|list:mixed*)|function(object:string*)",0);
+  add_efun("intp",   f_intp,    "function(mixed:int)",OPT_TRY_OPTIMIZE);
+  add_efun("listp",   f_listp,   "function(mixed:int)",OPT_TRY_OPTIMIZE);
+  add_efun("lower_case",f_lower_case,"function(string:string)",OPT_TRY_OPTIMIZE);
+  add_efun("m_delete",f_m_delete,"function(mapping,mixed:mapping)",0);
+  add_efun("mappingp",f_mappingp,"function(mixed:int)",OPT_TRY_OPTIMIZE);
+  add_efun("mkmapping",f_mkmapping,"function(mixed *,mixed *:mapping)",OPT_TRY_OPTIMIZE);
+  add_efun("next_object",f_next_object,"function(void|object:object)",OPT_EXTERNAL_DEPEND);
+  add_efun("object_program",f_object_program,"function(object:program)",0);
+  add_efun("objectp", f_objectp, "function(mixed:int)",0);
+  add_efun("programp",f_programp,"function(mixed:int)",0);
+  add_efun("query_host_name",f_query_host_name,"function(:string)",0);
+  add_efun("query_num_arg",f_query_num_arg,"function(:int)",OPT_EXTERNAL_DEPEND);
+  add_efun("random",f_random,"function(int:int)",OPT_EXTERNAL_DEPEND);
+  add_efun("random_seed",f_random_seed,"function(int:void)",OPT_SIDE_EFFECT);
+  add_efun("replace",f_replace,"function(string,string,string:string)|function(string,string*,string*:string)|function(array,mixed,mixed:array)|function(mapping,mixed,mixed:array)",0);
+  add_efun("reverse",f_reverse,"function(int:int)|function(string:string)|function(array:array)",0);
+  add_efun("rows",f_rows,"function(mixed,array:array)",0);
+  add_efun("rusage", f_rusage, "function(:int *)",OPT_EXTERNAL_DEPEND);
+  add_efun("search",f_search,"function(string,string,void|int:int)|function(array,mixed,void|int:int)|function(mapping,mixed:mixed)",0);
+  add_efun("sizeof", f_sizeof, "function(string|list|array|mapping|object:int)",0);
+  add_efun("sleep", f_sleep, "function(float|int:void)",OPT_SIDE_EFFECT);
+  add_efun("sort",f_sort,"function(array(mixed),array(mixed)...:array(mixed))",OPT_SIDE_EFFECT);
+  add_efun("stringp", f_stringp, "function(mixed:int)",0);
+  add_efun("this_object", f_this_object, "function(:object)",OPT_EXTERNAL_DEPEND);
+  add_efun("throw",f_throw,"function(mixed:void)",0);
+  add_efun("time",f_time,"function(void|int:int)",OPT_EXTERNAL_DEPEND);
+  add_efun("trace",f_trace,"function(int:int)",OPT_SIDE_EFFECT);
+  add_efun("upper_case",f_upper_case,"function(string:string)",0);
+  add_efun("values",f_values,"function(string|list:int*)|function(array|mapping|object:mixed*)",0);
+  add_efun("zero_type",f_zero_type,"function(int:int)",0);
 
-  push_string(make_shared_string("timezone"));
-#if !HAVE_INT_TIMEZONE
-  push_int(_tz);
-#else
-  push_int(timezone);
+#ifdef HAVE_LOCALTIME
+  add_efun("localtime",f_localtime,"function(int:mapping(string:int))",OPT_EXTERNAL_DEPEND);
 #endif
-  f_aggregate_mapping(20);
-}
 
-#ifdef HAVE_STRERROR
-void f_strerror(INT32 args)
-{
-  char *s;
-  if(!args) 
-    s=strerror(errno);
-  else
-    s=strerror(sp[-args].u.integer);
-  pop_n_elems(args);
-  if(s)
-    push_text(s);
-  else
-    push_int(0);
-}
+#ifdef DEBUG
+  add_efun("_verify_internals",f__verify_internals,"function(:void)",OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND);
 #endif
 
+#ifdef GC2
+  add_efun("gc",f_gc,"function(:int)",OPT_SIDE_EFFECT);
 #endif
+}
+
diff --git a/src/builtin_efuns.h b/src/builtin_efuns.h
index 9b5a8359e9..d5a2261e88 100644
--- a/src/builtin_efuns.h
+++ b/src/builtin_efuns.h
@@ -8,8 +8,10 @@
 
 #define TYPEP(ID,NAME,TYPE) void ID(INT32 args);
 
+#include "callback.h"
 
 /* Prototypes begin here */
+void f_equal(INT32 args);
 void f_aggregate(INT32 args);
 void f_trace(INT32 args);
 void f_hash(INT32 args);
@@ -17,8 +19,8 @@ void f_copy_value(INT32 args);
 void f_ctime(INT32 args);
 void f_lower_case(INT32 args);
 void f_upper_case(INT32 args);
-void f_capitalize(INT32 args);
 void f_random(INT32 args);
+void f_random_seed(INT32 args);
 void f_query_num_arg(INT32 args);
 void f_search(INT32 args);
 void f_clone(INT32 args);
@@ -27,9 +29,6 @@ void f_backtrace(INT32 args);
 void f_add_efun(INT32 args);
 void f_compile_file(INT32 args);
 void f_combine_path(INT32 args);
-void f_get_function(INT32 args);
-void f_implode(INT32 args);
-void f_explode(INT32 args);
 void f_function_object(INT32 args);
 void f_function_name(INT32 args);
 void f_zero_type(INT32 args);
@@ -39,6 +38,9 @@ void f_sizeof(INT32 args);
 void f_rusage(INT32 args);
 void f_this_object(INT32 args);
 void f_throw(INT32 args);
+struct callback *add_exit_callback(callback_func call,
+				   void *arg,
+				   callback_func free_func);
 void f_exit(INT32 args);
 void f_query_host_name(INT32 args);
 void f_time(INT32 args);
@@ -50,20 +52,26 @@ void f_next_object(INT32 args);
 void f_object_program(INT32 args);
 void f_reverse(INT32 args);
 struct tupel;
-struct lpc_string * replace_many(struct lpc_string *str,
-				    struct array *from,
-				    struct array *to);
 void f_replace(INT32 args);
 void f_compile_string(INT32 args);
+void f_mkmapping(INT32 args);
+void f_objectp(INT32 args);
+void f_functionp(INT32 args);
+void f_sleep(INT32 args);
+void f_gc(INT32 args);
 TYPEP(f_programp, "programp", T_PROGRAM)
 TYPEP(f_intp, "intpp", T_INT)
 TYPEP(f_mappingp, "mappingp", T_MAPPING)
 TYPEP(f_arrayp, "arrayp", T_ARRAY)
 TYPEP(f_listp, "listp", T_LIST)
 TYPEP(f_stringp, "stringp", T_STRING)
-TYPEP(f_objectp, "objectp", T_OBJECT)
 TYPEP(f_floatp, "floatp", T_FLOAT)
-TYPEP(f_functionp, "functionp", T_FUNCTION)
+void f_sort(INT32 args);
+void f_rows(INT32 args);
+void f_column(INT32 args);
+void f__verify_internals(INT32 args);
+void f_localtime(INT32 args);
+void f_glob(INT32 args);
 void init_builtin_efuns();
 /* Prototypes end here */
 
-- 
GitLab


From 359289d0c01fa8892ccca1ca0e52f1b4d603b673 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:29:08 +0200
Subject: [PATCH 213/351] better naming

Rev: src/callback.c:1.3
Rev: src/callback.h:1.3
---
 src/callback.c | 16 ++++++++--------
 src/callback.h | 20 ++++++++++++--------
 2 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/src/callback.c b/src/callback.c
index 2cd1ef7888..a760a8a843 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -31,12 +31,12 @@ static struct callback *get_free_callback()
   {
     int e;
     struct callback_block *tmp2;
-    tmp1=ALLOC_STRUCT(callback_block);
+    tmp2=ALLOC_STRUCT(callback_block);
 
     for(e=0;e<sizeof(CALLBACK_CHUNK);e++)
     {
-      tmp1->callbacks[e].next=tmp;
-      tmp=tmp1->callbacks+e;
+      tmp2->callbacks[e].next=tmp;
+      tmp=tmp2->callbacks+e;
     }
   }
   free_callbacks=tmp->next;
@@ -63,9 +63,9 @@ void call_callback(struct callback **ptr)
 }
 
 struct callback *add_to_callback(struct callback **ptr,
-					   callback call,
-					   void *arg,
-					   callback free_func)
+				 callback_func call,
+				 void *arg,
+				 callback_func free_func)
 {
   struct callback *l;
   l=get_free_callback();
@@ -91,8 +91,8 @@ void free_callback(struct callback **ptr)
   struct callback *l;
   while(l=*ptr)
   {
-    if(l->call.arg && l->call.free_func)
-      l->call.free_func(l, l->call.arg);
+    if(l->arg && l->free_func)
+      l->free_func(l, l->arg);
     *ptr=l->next;
     l->next=free_callbacks;
     free_callbacks=l;
diff --git a/src/callback.h b/src/callback.h
index 46c4e152a7..6ba2257f70 100644
--- a/src/callback.h
+++ b/src/callback.h
@@ -8,16 +8,20 @@
 
 #include "array.h"
 
+struct callback;
+
+typedef void (*callback_func)(struct callback *, void *);
+
 /* Prototypes begin here */
-struct callback_list;
+struct callback;
 struct callback_block;
-void call_callback_list(struct callback_list **ptr);
-struct callback_list *add_to_callback_list(struct callback_list **ptr,
-					   callback call,
-					   void *arg);
-void *remove_callback(struct callback_list *l);
-void free_callback_list(struct callback_list **ptr);
-void call_and_free_callback_list(struct callback_list **ptr);
+void call_callback(struct callback **ptr);
+struct callback *add_to_callback(struct callback **ptr,
+				 callback_func call,
+				 void *arg,
+				 callback_func free_func);
+void *remove_callback(struct callback *l);
+void free_callback(struct callback **ptr);
 /* Prototypes end here */
 
 #endif
-- 
GitLab


From 56806f0924a629fedf59ebdd3d2a25e7ac576ff5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:31:18 +0200
Subject: [PATCH 214/351] stack size increased

Rev: src/config.h:1.5
---
 src/config.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/config.h b/src/config.h
index 6fccd9fecb..f18b9efb64 100644
--- a/src/config.h
+++ b/src/config.h
@@ -9,7 +9,7 @@
 /*
  * Define the evaluator stack size, used for just about everything.
  */
-#define EVALUATOR_STACK_SIZE	50000
+#define EVALUATOR_STACK_SIZE	100000
 
 /*
  * The compiler stack is used when compiling to keep track of data.
-- 
GitLab


From 067bc17b18a9fc1404ed2ee3f1e0208810d63c6e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:32:27 +0200
Subject: [PATCH 215/351] timeval tests, and module stuff moved

Rev: src/configure.in:1.13
---
 src/configure.in | 98 ++++++++++++++++++++++++------------------------
 1 file changed, 50 insertions(+), 48 deletions(-)

diff --git a/src/configure.in b/src/configure.in
index 1b30a57638..e620c7db5e 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -261,6 +261,7 @@ AC_CHECK_FUNCS(
  getenv \
  getrlimit \
  getrusage \
+ gettimeofday \
  index \
  memchr \
  memcpy \
@@ -283,8 +284,52 @@ AC_CHECK_FUNCS(
  wait3 \
  wait4 \
  waitpid \
+ localtime \
 )
 
+AC_STRUCT_TM
+
+AC_MSG_CHECKING(extern int timezone)
+
+AC_CACHE_VAL(lpc_cv_has_external_timezone,[
+AC_TRY_LINK([
+#include <time.h>
+],[
+  int _tz;
+  _tz=timezone;
+],lpc_cv_has_external_timezone=yes,lpc_cv_has_external_timezone=no)
+])
+
+if test "$lpc_cv_has_external_timezone" = "yes"; then
+  AC_DEFINE(HAVE_EXTERNAL_TIMEZONE)
+fi
+
+AC_MSG_RESULT($lpc_cv_has_external_timezone)
+
+
+AC_MSG_CHECKING(if struct tm has tm_gmtoff)
+
+AC_CACHE_VAL(lpc_cv_struct_tm_has_gmtoff,[
+AC_TRY_LINK([
+#ifdef TM_IN_SYS_TIME
+#include <sys/time.h>
+#endif
+#include <time.h>
+#else
+],[
+  int _tz;
+  struct tm foo;
+  _tz=foo->tm_gmtoff;
+],lpc_cv_struct_tm_has_gmtoff=yes,lpc_cv_struct_tm_has_gmtoff=no)
+])
+
+if test "$lpc_cv_struct_tm_has_gmtoff" = "yes"; then
+  AC_DEFINE(STRUCT_TM_HAS_GMTOFF)
+fi
+
+AC_MSG_RESULT($lpc_cv_struct_tm_has_gmtoff)
+
+
 define(MY_CHECK_HEADERS,
 [
  AC_MSG_CHECKING(for $1 declaration)
@@ -309,6 +354,9 @@ MY_CHECK_HEADERS(popen,stdio.h unistd.h)
 MY_CHECK_HEADERS(getenv,unistd.h stdlib.h)
 MY_CHECK_HEADERS(gethostname,unistd.h)
 
+# No test for this yet...
+AC_DEFINE(HAVE_STRUCT_TIMEVAL)
+
 AC_MSG_CHECKING(return type of free)
 AC_CACHE_VAL(lpc_cv_sys_free_return,
 [AC_TRY_LINK([
@@ -792,30 +840,14 @@ fi
 
 rm -f core
 
-
-dirs=
-MODULE_OBJS=
-module_names=
-for a in `(cd $srcdir/modules ; echo *)`
-do
-  if test "$a" != "CVS" -a "$a" != "RCS" ; then
-    if test -d "$srcdir/modules/$a" ; then
-      dirs="$dirs modules/$a"
-      MODULE_OBJS="$MODULE_OBJS modules/$a/$a.a"
-      module_names="$module_names $a"
-    fi
-  fi
-done
-
 LIBDIR=`(cd $srcdir/../lib ; pwd)`
 BINDIR=`(cd $srcdir/../bin ; pwd)`
 DOCDIR=`(cd $srcdir/../doc ; pwd)`
 BUILDDIR=`pwd`
 
-AC_CONFIG_SUBDIRS($dirs)
+AC_CONFIG_SUBDIRS(modules)
 
 AC_SUBST(YACC)
-AC_SUBST(MODULE_OBJS)
 AC_SUBST(INSTALL)
 AC_SUBST(WARN)
 AC_SUBST(OPTIMIZE)
@@ -826,36 +858,6 @@ AC_SUBST(BINDIR)
 AC_SUBST(BUILDDIR)
 AC_SUBST(DOCDIR)
 
-AC_OUTPUT(Makefile,
-[
-echo "FOO" >stamp-h
-if test ! -d ./modules ; then
-  mkdir modules
-fi
-
-echo creating modlist.h
-echo "void init_main_efuns(void);" >modlist.h
-echo "void init_main_programs(void);" >>modlist.h
-echo "void exit_main(void);" >>modlist.h
-
-for a in $dirs
-do
-  echo "void init_"$a"_efuns(void);" >>modlist.h
-  echo "void init_"$a"_programs(void);" >>modlist.h
-  echo "void exit_"$a"(void);" >>modlist.h
-done
-echo "" >>modlist.h
-echo "struct module module_list UGLY_WORKAROUND={" >>modlist.h
-
-echo "  { \"main\", init_main_efuns, init_main_programs, exit_main, 0 }" >>modlist.h
-for a in $dirs
-do
-  echo " ,{ \"$a\", init_"$a"_efuns, init_"$a"_programs, exit_$a, 0 }" >>modlist.h
-done
-echo "};" >>modlist.h
-]
-,
-dirs="$module_names"
-)
+AC_OUTPUT(Makefile,[echo foo >stamp-h])
 
 
-- 
GitLab


From f0cd988a0fa6a4040dfcc1bed0121099319f872a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:33:26 +0200
Subject: [PATCH 216/351] nothing much changed

Rev: src/error.c:1.6
Rev: src/error.h:1.3
---
 src/error.c | 10 +++++-----
 src/error.h |  4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/error.c b/src/error.c
index c99d9a9243..cb0f2594f0 100644
--- a/src/error.c
+++ b/src/error.c
@@ -19,8 +19,8 @@ ONERROR *onerror_stack=0;
 my_jmp_buf *init_recovery(JMP_BUF *r)
 {
   r->fp=fp;
-  r->sp=sp;
-  r->mark_sp=mark_sp;
+  r->sp=sp-evaluator_stack;
+  r->mark_sp=mark_sp - mark_stack;
   r->previous=recoveries;
   r->onerror=onerror_stack;
   recoveries=r;
@@ -33,7 +33,7 @@ void throw()
     fatal("No error recovery context.\n");
 
 #ifdef DEBUG
-  if(sp < recoveries->sp)
+  if(sp - evaluator_stack < recoveries->sp)
     fatal("Error in error.\n");
 #endif
 
@@ -49,8 +49,8 @@ void throw()
     fp = fp->parent_frame;
   }
 
-  pop_n_elems(sp - recoveries->sp);
-  mark_sp = recoveries->mark_sp;
+  pop_n_elems(sp - evaluator_stack - recoveries->sp);
+  mark_sp = mark_stack + recoveries->mark_sp;
 
   while(recoveries->onerror != onerror_stack)
   {
diff --git a/src/error.h b/src/error.h
index 9dce4c7787..6934591dc8 100644
--- a/src/error.h
+++ b/src/error.h
@@ -30,8 +30,8 @@ typedef struct JMP_BUF
   struct JMP_BUF *previous;
   my_jmp_buf recovery;
   struct frame *fp;
-  struct svalue *sp;
-  struct svalue **mark_sp;
+  INT32 sp;
+  INT32 mark_sp;
   ONERROR *onerror;
 } JMP_BUF;
 
-- 
GitLab


From fa382f720043d95ce25f5ed286e0f46aaf938731 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:35:03 +0200
Subject: [PATCH 217/351] stack checks and operator overloading

Rev: src/interpret.c:1.10
Rev: src/interpret.h:1.3
---
 src/interpret.c | 168 +++++++++++++++++++++++++++---------------------
 src/interpret.h |  13 +++-
 2 files changed, 106 insertions(+), 75 deletions(-)

diff --git a/src/interpret.c b/src/interpret.c
index b8c13ee2b0..3e2f2a679a 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -25,17 +25,41 @@
 #include "lpc_signal.h"
 
 #define TRACE_LEN (100 + t_flag * 10)
-struct svalue evaluator_stack[EVALUATOR_STACK_SIZE];
-struct svalue *mark_stack[EVALUATOR_STACK_SIZE];
-struct frame *fp; /* frame pointer */
+
 
 /* sp points to first unused value on stack
  * (much simpler than letting it point at the last used value.)
  */
-struct svalue *sp=evaluator_stack;
+struct svalue *sp;
 
 /* mark stack, used to store markers into the normal stack */
-struct svalue **mark_sp=mark_stack;
+struct svalue **mark_sp;
+
+struct frame *fp; /* frame pointer */
+
+struct svalue evaluator_stack[EVALUATOR_STACK_SIZE];
+struct svalue *mark_stack[EVALUATOR_STACK_SIZE];
+
+void init_interpreter()
+{
+  sp=evaluator_stack;
+  mark_sp=mark_stack;
+}
+
+void exit_interpreter() {}
+
+void check_stack(INT32 size)
+{
+  if(sp - evaluator_stack + size >= EVALUATOR_STACK_SIZE)
+    error("Stack overflow.\n");
+}
+
+void check_mark_stack(INT32 size)
+{
+  if(mark_sp - mark_stack + size >= EVALUATOR_STACK_SIZE)
+    error("Stack overflow.\n");
+}
+
 
 static void eval_instruction(unsigned char *pc);
 
@@ -191,7 +215,7 @@ void print_return_value()
 void pop_n_elems(INT32 x)
 {
 #ifdef DEBUG
-  if(sp - &(evaluator_stack[0]) < x)
+  if(sp - evaluator_stack < x)
     fatal("Popping out of stack.\n");
 
   if(x < 0) fatal("Popping negative number of args....\n");
@@ -364,6 +388,9 @@ static void eval_instruction(unsigned char *pc)
     if(sp<evaluator_stack || mark_sp < mark_stack || fp->locals>sp)
       fatal("Stack error.\n");
 
+    if(sp > evaluator_stack+EVALUATOR_STACK_SIZE)
+      fatal("Stack error (overflow).\n");
+
     if(fp->fun>=0 && fp->current_object->prog &&
 	fp->locals+fp->num_locals > sp)
       fatal("Stack error.\n");
@@ -691,7 +718,6 @@ static void eval_instruction(unsigned char *pc)
       break;
 
       CASE(F_BRANCH_WHEN_ZERO);
-      check_destructed(sp-1);
       if(!IS_ZERO(sp-1))
       {
 	pc+=sizeof(INT32);
@@ -703,7 +729,6 @@ static void eval_instruction(unsigned char *pc)
       break;
       
       CASE(F_BRANCH_WHEN_NON_ZERO);
-      check_destructed(sp-1);
       if(IS_ZERO(sp-1))
       {
 	pc+=sizeof(INT32);
@@ -722,7 +747,6 @@ static void eval_instruction(unsigned char *pc)
       CJUMP(F_BRANCH_WHEN_GE,!is_lt);
 
       CASE(F_LAND);
-      check_destructed(sp-1);
       if(!IS_ZERO(sp-1))
       {
 	pc+=sizeof(INT32);
@@ -734,7 +758,6 @@ static void eval_instruction(unsigned char *pc)
       break;
 
       CASE(F_LOR);
-      check_destructed(sp-1);
       if(IS_ZERO(sp-1))
       {
 	pc+=sizeof(INT32);
@@ -812,14 +835,11 @@ static void eval_instruction(unsigned char *pc)
       {
 	sp[-1].u.float_number =- sp[-1].u.float_number;
       }else{
-	error("Bad argument to unary minus.\n");
+	o_negate();
       }
       break;
 
-      CASE(F_COMPL);
-      if(sp[-1].type != T_INT) error("Bad argument to ~.\n");
-      sp[-1].u.integer = ~ sp[-1].u.integer;
-      break;
+      CASE(F_COMPL); o_compl(); break;
 
       CASE(F_NOT);
       switch(sp[-1].type)
@@ -830,12 +850,15 @@ static void eval_instruction(unsigned char *pc)
 
       case T_FUNCTION:
       case T_OBJECT:
-	check_destructed(sp-1);
-	if(sp[-1].type == T_INT)
+	if(IS_ZERO(sp-1))
 	{
-	  sp[-1].u.integer=1;
-	  break;
+	  pop_stack();
+	  push_int(1);
+	}else{
+	  pop_stack();
+	  push_int(0);
 	}
+	break;
 
       default:
 	free_svalue(sp-1);
@@ -845,17 +868,25 @@ static void eval_instruction(unsigned char *pc)
       break;
 
       CASE(F_LSH);
-      if(sp[-2].type != T_INT) error("Bad argument 1 to <<\n");
-      if(sp[-1].type != T_INT) error("Bad argument 2 to <<\n");
-      sp--;
-      sp[-1].u.integer = sp[-1].u.integer << sp->u.integer;
+      if(sp[-2].type != T_INT)
+      {
+	o_lsh();
+      }else{
+	if(sp[-1].type != T_INT) error("Bad argument 2 to <<\n");
+	sp--;
+	sp[-1].u.integer = sp[-1].u.integer << sp->u.integer;
+      }
       break;
 
       CASE(F_RSH);
-      if(sp[-2].type != T_INT) error("Bad argument 1 to >>\n");
-      if(sp[-1].type != T_INT) error("Bad argument 2 to >>\n");
-      sp--;
-      sp[-1].u.integer = sp[-1].u.integer >> sp->u.integer;
+      if(sp[-2].type != T_INT)
+      {
+	o_rsh();
+      }else{
+	if(sp[-1].type != T_INT) error("Bad argument 2 to >>\n");
+	sp--;
+	sp[-1].u.integer = sp[-1].u.integer >> sp->u.integer;
+      }
       break;
 
       COMPARISMENT(F_EQ, is_eq(sp-2,sp-1));
@@ -889,11 +920,12 @@ static void eval_instruction(unsigned char *pc)
 
       CASE(F_RANGE); o_range(); break;
       CASE(F_COPY_VALUE);
-      copy_svalues_recursively_no_free(sp,sp-1,1,0);
-      sp++;
-      free_svalue(sp-2);
-      sp[-2]=sp[-1];
-      sp--;
+      {
+	struct svalue tmp;
+	copy_svalues_recursively_no_free(&tmp,sp-1,1,0);
+	free_svalue(sp-1);
+	sp[-1]=tmp;
+      }
       break;
 
       CASE(F_SSCANF); f_sscanf(GET_ARG()); break;
@@ -964,7 +996,6 @@ void apply_low(struct object *o, int fun, int args)
   struct frame new_frame;
   struct identifier *function;
 
-  check_signals();
   if(fun<0)
   {
     pop_n_elems(args);
@@ -972,8 +1003,9 @@ void apply_low(struct object *o, int fun, int args)
     return;
   }
 
-  if(evaluator_stack+EVALUATOR_STACK_SIZE-sp < 256)
-    error("Stack overflow.\n");
+  check_signals();
+  check_stack(256);
+  check_mark_stack(256);
 
   p=o->prog;
   if(!p)
@@ -1172,13 +1204,12 @@ void safe_apply_low(struct object *o,int fun,int args)
     sp->type = T_INT;
     sp++;
   }else{
-    struct svalue *expected_sp;
-    expected_sp=sp+1;
+    INT32 expected_stack = sp - evaluator_stack + 1;
     sp+=args;
     apply_low(o,fun,args);
-    if(sp > expected_sp)
-      pop_n_elems(sp-expected_sp);
-    if(sp < expected_sp)
+    if(sp - evaluator_stack > expected_stack)
+      pop_n_elems(sp - evaluator_stack - expected_stack);
+    if(sp - evaluator_stack < expected_stack)
     {
       sp->u.integer = 0;
       sp->subtype=NUMBER_NUMBER;
@@ -1198,37 +1229,28 @@ void safe_apply(struct object *o, char *fun ,INT32 args)
   safe_apply_low(o, find_identifier(fun, o->prog), args);
 }
 
+void apply_lfun(struct object *o, int fun, int args)
+{
+#ifdef DEBUG
+  if(fun < 0 || fun >= NUM_LFUNS)
+    fatal("Apply lfun on illegal value!\n");
+#endif
+  if(!o->prog)
+    error("Apply on destructed object.\n");
+
+  apply_low(o, o->prog->lfuns[fun], args);
+}
+
 void apply_shared(struct object *o,
 		  struct lpc_string *fun,
 		  int args)
 {
-  int fun_number;
-  fun_number = find_shared_string_identifier(fun, o->prog);
-  if(fun_number < 0)
-  {
-    pop_n_elems(args);
-    sp++;
-    sp->u.integer=0;
-    sp->type=T_INT;
-  }else{
-    apply_low(o, fun_number, args);
-  }
+  apply_low(o, find_shared_string_identifier(fun, o->prog), args);
 }
 
 void apply(struct object *o, char *fun, int args)
 {
-  int fun_number;
-
-  fun_number = find_identifier(fun, o->prog);
-  if(fun_number < 0)
-  {
-    pop_n_elems(args);
-    sp->u.integer=0;
-    sp->type=T_INT;
-    sp++;
-  }else{
-    apply_low(o, fun_number, args);
-  }
+  apply_low(o, find_identifier(fun, o->prog), args);
 }
 
 void strict_apply_svalue(struct svalue *s, INT32 args)
@@ -1333,18 +1355,20 @@ void apply_svalue(struct svalue *s, INT32 args)
     pop_n_elems(args);
     push_int(0);
   }else{
-    struct svalue *expected_sp=sp-args+1;
+    INT32 expected_stack=sp-args+1 - evaluator_stack;
+
     strict_apply_svalue(s,args);
-    if(sp > expected_sp)
+    if(sp > (expected_stack + evaluator_stack))
     {
-      pop_n_elems(sp-expected_sp);
+      pop_n_elems(sp-(expected_stack + evaluator_stack));
     }
-    else if(sp < expected_sp)
+    else if(sp < (expected_stack + evaluator_stack))
     {
       push_int(0);
     }
 #ifdef DEBUG
-    if(sp < expected_sp) fatal("Stack underflow!\n");
+    if(sp < (expected_stack + evaluator_stack))
+      fatal("Stack underflow!\n");
 #endif
   }
 }
@@ -1355,15 +1379,15 @@ void slow_check_stack()
   struct svalue *s,**m;
   struct frame *f;
 
-  check_stack();
+  debug_check_stack();
 
   if(sp > &(evaluator_stack[EVALUATOR_STACK_SIZE]))
     fatal("Stack overflow\n");
 
-  if(mark_sp < mark_stack)
-    fatal("Mark stack underflow.\n");
-
   if(mark_sp > &(mark_stack[EVALUATOR_STACK_SIZE]))
+    fatal("Mark stack overflow.\n");
+
+  if(mark_sp < mark_stack)
     fatal("Mark stack underflow.\n");
 
   for(s=evaluator_stack;s<sp;s++) check_svalue(s);
diff --git a/src/interpret.h b/src/interpret.h
index 358ecdb218..754fdf5cad 100644
--- a/src/interpret.h
+++ b/src/interpret.h
@@ -26,11 +26,12 @@ struct frame
 };
 
 #ifdef DEBUG
-#define check_stack() do{if(sp<evaluator_stack)fatal("Stack error.\n");}while(0)
+#define debug_check_stack() do{if(sp<evaluator_stack)fatal("Stack error.\n");}while(0)
 #else
-#define check_stack() 
+#define debug_check_stack() 
 #endif
-#define pop_stack() do{ free_svalue(--sp); check_stack(); }while(0)
+
+#define pop_stack() do{ free_svalue(--sp); debug_check_stack(); }while(0)
 #define push_program(P) sp->u.program=(P),sp++->type=T_PROGRAM
 #define push_int(I) sp->u.integer=(I),sp->type=T_INT,sp++->subtype=NUMBER_NUMBER
 #define push_mapping(M) sp->u.mapping=(M),sp++->type=T_MAPPING
@@ -66,9 +67,14 @@ do{ \
 }while(0)
 
 /* Prototypes begin here */
+void init_interpreter();
+void exit_interpreter();
+void check_stack(INT32 size);
+void check_mark_stack(INT32 size);
 void lvalue_to_svalue_no_free(struct svalue *to,struct svalue *lval);
 void assign_lvalue(struct svalue *lval,struct svalue *from);
 union anything *get_pointer_if_this_type(struct svalue *lval, TYPE_T t);
+void print_return_value();
 void pop_n_elems(INT32 x);
 void reset_evaluator();
 void f_catch(unsigned char *pc);
@@ -91,6 +97,7 @@ void cleanup_interpret();
 extern struct svalue *sp;
 extern struct svalue **mark_sp;
 extern struct svalue evaluator_stack[EVALUATOR_STACK_SIZE];
+extern struct svalue *mark_stack[EVALUATOR_STACK_SIZE];
 extern struct frame *fp; /* frame pointer */
 #endif
 
-- 
GitLab


From 78ec7a3f32b16793604910479461f067d9a4575d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:36:34 +0200
Subject: [PATCH 218/351] include fixed

Rev: src/lex.c:1.10
---
 src/lex.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/src/lex.c b/src/lex.c
index b272200d74..c1ec5ed7f2 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -27,19 +27,7 @@
 #include <math.h>
 #include <fcntl.h>
 #include <errno.h>
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  if HAVE_TIME_H
-#   include <time.h>
-#  endif
-# endif
-#endif
+#include "time_stuff.h"
 
 #define LEXDEBUG 0
 #define EXPANDMAX 50000
@@ -968,7 +956,7 @@ static int expand_define(struct lpc_string *s, int save_newline)
 
 /*** Handle include ****/
 
-static void handle_include(char *name)
+static void handle_include(char *name, int local_include)
 {
   int fd;
   char buf[400];
@@ -976,6 +964,7 @@ static void handle_include(char *name)
   push_string(make_shared_string(name));
   push_string(current_file);
   reference_shared_string(current_file);
+  push_int(local_include);
 
   SAFE_APPLY_MASTER("handle_include",2);
 
@@ -1243,7 +1232,7 @@ static int do_lex2(int literal, YYSTYPE *yylval)
 		continue;
 	      }
 	    }
-	    handle_include(buf);
+	    handle_include(buf, c==F_STRING);
 	    break;
 	  }
 
-- 
GitLab


From 7260713d0bd429eff278b8888caf2109975025b2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:37:38 +0200
Subject: [PATCH 219/351] type optimization added

Rev: src/lpc_types.c:1.6
Rev: src/lpc_types.h:1.3
---
 src/lpc_types.c | 224 +++++++++++++++++++++++++++++-------------------
 src/lpc_types.h |  17 ++--
 2 files changed, 146 insertions(+), 95 deletions(-)

diff --git a/src/lpc_types.c b/src/lpc_types.c
index ffbb8b274b..5def56fa39 100644
--- a/src/lpc_types.c
+++ b/src/lpc_types.c
@@ -103,6 +103,101 @@ static int type_length(char *t)
   return t-q;
 }
 
+
+#define STACK_SIZE 100000
+static unsigned char type_stack[STACK_SIZE];
+static unsigned char *type_stackp=type_stack;
+static unsigned char *mark_stack[STACK_SIZE/4];
+static unsigned char **mark_stackp=mark_stack;
+
+void reset_type_stack()
+{
+  type_stackp=type_stack;
+  mark_stackp=mark_stack;
+}
+
+void type_stack_mark()
+{
+  *mark_stackp=type_stackp;
+  mark_stackp++;
+  if(mark_stackp > mark_stack + NELEM(mark_stack))
+    yyerror("Type mark stack overflow.");
+}
+
+unsigned char *pop_stack_mark()
+{ 
+  mark_stackp--;
+  if(mark_stackp<mark_stack)
+    fatal("Type mark stack underflow\n");
+
+  return *mark_stackp;
+}
+
+void pop_type_stack()
+{ 
+  type_stackp--;
+  if(type_stackp<type_stack)
+    fatal("Type stack underflow\n");
+}
+
+void type_stack_pop_to_mark()
+{
+  type_stackp=pop_stack_mark();
+}
+
+void type_stack_reverse()
+{
+  unsigned char *a,*b,tmp;
+  a=pop_stack_mark();
+  b=type_stackp-1;
+  while(b>a) { tmp=*a; *a=*b; *b=tmp; b--; a++; }
+}
+
+void push_type(unsigned char tmp)
+{
+  *type_stackp=tmp;
+  type_stackp++;
+  if(type_stackp > type_stack + sizeof(type_stack))
+    yyerror("Type stack overflow.");
+}
+
+void push_unfinished_type(char *s)
+{
+  int e;
+  e=type_length(s);
+  for(e--;e>=0;e--) push_type(s[e]);
+}
+
+void push_finished_type(struct lpc_string *type)
+{
+  int e;
+  for(e=type->len-1;e>=0;e--) push_type(type->str[e]);
+}
+
+struct lpc_string *pop_unfinished_type()
+{
+  int len,e;
+  struct lpc_string *s;
+  len=type_stackp - pop_stack_mark();
+  s=begin_shared_string(len);
+  for(e=0;e<len;e++) s->str[e] = *--type_stackp;
+  return end_shared_string(s);
+}
+
+struct lpc_string *pop_type()
+{
+  int len,e;
+  struct lpc_string *s;
+  len=type_stackp - type_stack;
+  s=begin_shared_string(len);
+  for(e=0;e<len;e++) s->str[e] = *--type_stackp;
+  s=end_shared_string(s);
+  reset_type_stack();
+  return s;
+}
+
+
+
 static void internal_parse_typeA(char **s)
 {
   char buf[80];
@@ -634,11 +729,48 @@ static int low_get_return_type(char *a,char *b)
   switch(EXTRACT_UCHAR(a))
   {
   case T_OR:
-    a++;
-    tmp=low_get_return_type(a,b);
-    tmp+=low_get_return_type(a+type_length(a),b);
-    if(tmp==2) push_type(T_OR);
-    return tmp>0;
+    {
+      struct lpc_string *o1,*o2;
+      a++;
+      o1=o2=0;
+
+      type_stack_mark();
+      if(low_get_return_type(a,b)) 
+      {
+	o1=pop_unfinished_type();
+	type_stack_mark();
+      }
+
+      if(low_get_return_type(a+type_length(a),b))
+	o2=pop_unfinished_type();
+      else
+	pop_stack_mark();
+
+      if(o1 == o2)
+      {
+	if(!o1)
+	{
+	  return 0;
+	}else{
+	  push_finished_type(o1);
+	}
+      }
+      else if(o1 == mixed_type_string || o2 == mixed_type_string)
+      {
+	push_type(T_MIXED);
+      }
+      else
+      {
+	if(o1) push_finished_type(o1);
+	if(o2) push_finished_type(o2);
+	if(o1 && o2) push_type(T_OR);
+      }
+
+      if(o1) free_string(o1);
+      if(o2) free_string(o2);
+
+      return 1;
+    }
 
   case T_AND:
     a++;
@@ -684,88 +816,6 @@ int match_types(struct lpc_string *a,struct lpc_string *b)
 }
 
 
-#define STACK_SIZE 100000
-static unsigned char type_stack[STACK_SIZE];
-static unsigned char *type_stackp=type_stack;
-static unsigned char *mark_stack[STACK_SIZE/4];
-static unsigned char **mark_stackp=mark_stack;
-
-void reset_type_stack()
-{
-  type_stackp=type_stack;
-  mark_stackp=mark_stack;
-}
-
-void type_stack_mark()
-{
-  *mark_stackp=type_stackp;
-  mark_stackp++;
-  if(mark_stackp > mark_stack + NELEM(mark_stack))
-    yyerror("Type mark stack overflow.");
-}
-
-void pop_stack_mark()
-{ 
-  mark_stackp--;
-  if(mark_stackp<mark_stack)
-    fatal("Type mark stack underflow\n");
-}
-
-void pop_type_stack()
-{ 
-  type_stackp--;
-  if(type_stackp<type_stack)
-    fatal("Type stack underflow\n");
-}
-
-void type_stack_pop_to_mark()
-{
-  pop_stack_mark();
-  type_stackp=*mark_stackp;
-}
-
-void type_stack_reverse()
-{
-  unsigned char *a,*b,tmp;
-  a=mark_stackp[-1];
-  b=type_stackp-1;
-  while(b>a) { tmp=*a; *a=*b; *b=tmp; b--; a++; }
-  pop_stack_mark();
-}
-
-void push_type(unsigned char tmp)
-{
-  *type_stackp=tmp;
-  type_stackp++;
-  if(type_stackp > type_stack + sizeof(type_stack))
-    yyerror("Type stack overflow.");
-}
-
-void push_unfinished_type(char *s)
-{
-  int e;
-  e=type_length(s);
-  for(e--;e>=0;e--) push_type(s[e]);
-}
-
-void push_finished_type(struct lpc_string *type)
-{
-  int e;
-  for(e=type->len-1;e>=0;e--) push_type(type->str[e]);
-}
-
-
-struct lpc_string *pop_type()
-{
-  int len,e;
-  struct lpc_string *s;
-  len=type_stackp - type_stack;
-  s=begin_shared_string(len);
-  for(e=0;e<len;e++) s->str[e] = *--type_stackp;
-  s=end_shared_string(s);
-  reset_type_stack();
-  return s;
-}
 
 /* FIXME, add the index */
 static struct lpc_string *low_index_type(char *t)
diff --git a/src/lpc_types.h b/src/lpc_types.h
index 1e898a8f14..80afbbbc9d 100644
--- a/src/lpc_types.h
+++ b/src/lpc_types.h
@@ -21,23 +21,24 @@ extern struct lpc_string *any_type_string;
 
 /* Prototypes begin here */
 void init_types();
-struct lpc_string *parse_type(char *s);
-void stupid_describe_type(char *a,INT32 len);
-void simple_describe_type(struct lpc_string *s);
-char *low_describe_type(char *t);
-struct lpc_string *describe_type(struct lpc_string *type);
-TYPE_T compile_type_to_runtime_type(struct lpc_string *s);
-int match_types(struct lpc_string *a,struct lpc_string *b);
 void reset_type_stack();
 void type_stack_mark();
-void pop_stack_mark();
+unsigned char *pop_stack_mark();
 void pop_type_stack();
 void type_stack_pop_to_mark();
 void type_stack_reverse();
 void push_type(unsigned char tmp);
 void push_unfinished_type(char *s);
 void push_finished_type(struct lpc_string *type);
+struct lpc_string *pop_unfinished_type();
 struct lpc_string *pop_type();
+struct lpc_string *parse_type(char *s);
+void stupid_describe_type(char *a,INT32 len);
+void simple_describe_type(struct lpc_string *s);
+char *low_describe_type(char *t);
+struct lpc_string *describe_type(struct lpc_string *type);
+TYPE_T compile_type_to_runtime_type(struct lpc_string *s);
+int match_types(struct lpc_string *a,struct lpc_string *b);
 struct lpc_string *index_type(struct lpc_string *type);
 int check_indexing(struct lpc_string *type,
 		   struct lpc_string *index_type);
-- 
GitLab


From fa188ec9a5577e976f685c07dab71f432f8a1bba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:39:11 +0200
Subject: [PATCH 220/351] time stuff added

Rev: src/machine.h.in:1.8
---
 src/machine.h.in | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/src/machine.h.in b/src/machine.h.in
index 8dd95675d5..f2fd129327 100644
--- a/src/machine.h.in
+++ b/src/machine.h.in
@@ -214,6 +214,9 @@
 /* Define if you have getrlimit */
 #undef HAVE_GETRLIMIT
 
+/* define if you have localtime */
+#undef HAVE_LOCALTIME
+
 /* Define if you have waitpid */
 #undef HAVE_WAITPID
 
@@ -283,4 +286,16 @@
 /* Value of first constant defined by byacc/bison/yacc or whatever you use. */
 #define F_OFFSET 257
 
+/* Define this if struct tm is included in <sys/time.h> as opposed to <time.h> */
+#define TM_IN_SYS_TIME
+
+/* define this if #include <time.h> provides an external int timezone */
+#undef HAVE_EXTERNAL_TIMEZONE
+
+/* define this if your struct tm has a tm_gmtoff */
+#undef STRUCT_TM_HAS_GMTOFF
+
+/* Define if you have struct timeval */
+#define HAVE_STRUCT_TIMEVAL
+
 #endif /* MACHINE_H */
-- 
GitLab


From 6e37dc39181872ef95c81165e1b921b0465fcd84 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:40:15 +0200
Subject: [PATCH 221/351] small fixes

Rev: src/main.c:1.7
Rev: src/main.h:1.2
---
 src/main.c | 25 +++++++------------------
 src/main.h |  5 +++++
 2 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/src/main.c b/src/main.c
index e51e01d9bf..a3e1768202 100644
--- a/src/main.c
+++ b/src/main.c
@@ -23,18 +23,7 @@
 #include <locale.h>
 #endif
 
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  if HAVE_TIME_H
-#   include <time.h>
-#  endif
-# endif
-#endif
+#include "time_stuff.h"
 
 #ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>
@@ -50,11 +39,11 @@ int l_flag=0;
 
 static struct callback *post_master_callbacks =0;
 
-struct callback *add_post_master_callback(callback call,
+struct callback *add_post_master_callback(callback_func call,
 					  void *arg,
-					  callback free_func)
+					  callback_func free_func)
 {
-  return add_to_callback_list(&post_master_callbacks, call, arg, free_func);
+  return add_to_callback(&post_master_callbacks, call, arg, free_func);
 }
 
 
@@ -164,7 +153,7 @@ void main(int argc, char **argv, char **env)
   }
 #endif
 
-  current_time = get_current_time();
+  GETTIMEOFDAY(&current_time);
 
   init_modules_efuns();
   master();
@@ -214,6 +203,7 @@ void main(int argc, char **argv, char **env)
 
 void init_main_efuns()
 {
+  init_interpreter();
   init_lex();
   init_types();
   init_builtin_efuns();
@@ -228,7 +218,6 @@ void init_main_programs()
 void exit_main()
 {
   void cleanup_added_efuns();
-  void free_all_call_outs();
   void cleanup_lpc_types();
   void cleanup_program();
 
@@ -238,9 +227,9 @@ void exit_main()
   exit_lex();
   cleanup_interpret();
   cleanup_added_efuns();
-  free_all_call_outs();
   cleanup_lpc_types();
   cleanup_shared_string_table();
   cleanup_program();
+  exit_interpreter();
 }
 
diff --git a/src/main.h b/src/main.h
index 8b4e74e149..4171e9ab6d 100644
--- a/src/main.h
+++ b/src/main.h
@@ -6,9 +6,14 @@
 #ifndef MAIN_H
 #define MAIN_H
 
+#include "callback.h"
+
 extern int d_flag, t_flag, a_flag, l_flag, c_flag;
 
 /* Prototypes begin here */
+struct callback *add_post_master_callback(callback_func call,
+					  void *arg,
+					  callback_func free_func);
 void main(int argc, char **argv, char **env);
 void init_main_efuns();
 void init_main_programs();
-- 
GitLab


From f152407fe46035ad3dc3dd52a70f008663449f29 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:41:51 +0200
Subject: [PATCH 222/351] hash_svalue moved

Rev: src/mapping.c:1.7
---
 src/mapping.c | 16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/src/mapping.c b/src/mapping.c
index 9ed17cd250..8b71f34e54 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -107,20 +107,6 @@ static struct mapping *allocate_mapping(int size)
   return m;
 }
 
-unsigned INT32 hash_svalue(struct svalue *s)
-{
-  unsigned INT32 q;
-  switch(s->type)
-  {
-  case T_INT:   q=s->u.integer; break;
-  case T_FLOAT: q=(unsigned INT32)(s->u.float_number * 16843009.0); break;
-  default:      q=(unsigned INT32)s->u.refs >> 2;
-  }
-  q+=q % 997;
-  q+=((q + s->type) * 9248339);
-  
-  return q;
-}
 
 void really_free_mapping(struct mapping *m)
 {
@@ -947,6 +933,8 @@ struct mapping *copy_mapping_recursively(struct mapping *m,
   ret=allocate_mapping(MAP_SLOTS(m->size));
   doing.pointer_b=ret;
 
+  check_stack(2);
+
   LOOP(m)
   {
     /* check_destructed(& k->ind); */
-- 
GitLab


From b0ddc5993864cee6426e114a7273e760c8c1390f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:43:25 +0200
Subject: [PATCH 223/351] reorganize optimized

Rev: src/memory.c:1.2
Rev: src/memory.h:1.2
---
 src/memory.c | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/memory.h |  37 +++++++++
 2 files changed, 248 insertions(+), 1 deletion(-)

diff --git a/src/memory.c b/src/memory.c
index b02eb73c2f..a130aa5185 100644
--- a/src/memory.c
+++ b/src/memory.c
@@ -6,6 +6,7 @@
 #include "global.h"
 #include "memory.h"
 #include "error.h"
+#include "macros.h"
 
 char *xalloc(SIZE_T size)
 {
@@ -75,7 +76,9 @@ void reorder(char *memory,INT32 nitems,INT32 size,INT32 *order)
   }
 }
 
-#else
+#endif
+
+#if 0
 /*
  * This function may NOT change 'order'
  * This function is probably too slow, but it does not use
@@ -259,7 +262,45 @@ void reorder(char *memory, INT32 nitems, INT32 size,INT32 *order)
     }
   }
 }
+#endif
+
+#if 1
+/*
+ * This function may NOT change 'order'
+ * This function is hopefully fast enough...
+ */
+void reorder(char *memory, INT32 nitems, INT32 size,INT32 *order)
+{
+  INT32 e;
+  char *tmp;
+  tmp=xalloc(size * nitems);
+
+#define DOSIZE(X,Y)				\
+ case X:					\
+ {						\
+  struct Y { char tt[X]; };			\
+  struct Y *from=(struct Y *) memory;		\
+  struct Y *to=(struct Y *) tmp;		\
+  for(e=0;e<nitems;e++) to[e]=from[order[e]];	\
+  break;					\
+ }
+  
+
+  switch(size)
+  {
+    DOSIZE(1,TMP1)
+    DOSIZE(2,TMP2)
+    DOSIZE(4,TMP4)
+    DOSIZE(8,TMP8)
+    DOSIZE(16,TMP16)
+
+  default:
+    for(e=0;e<nitems;e++) MEMCPY(tmp+e*size, memory+order[e]*size, size);
+  }
 
+  MEMCPY(memory, tmp, size * nitems);
+  free(tmp);
+}
 #endif
 
 unsigned INT32 hashmem(const unsigned char *a,INT32 len,INT32 mlen)
@@ -315,3 +356,172 @@ unsigned INT32 hashstr(const unsigned char *str,INT32 maxn)
 
   return ret;
 }
+
+
+/*
+ * a quick memory search function.
+ * Written by Fredrik Hubinette (hubbe@lysator.liu.se)
+ */
+void init_memsearch(struct mem_searcher *s,
+		    char *needle,
+		    SIZE_T needlelen,
+		    SIZE_T max_haystacklen)
+{
+  s->needle=needle;
+  s->needlelen=needlelen;
+
+  switch(needlelen)
+  {
+  case 0: s->method=no_search; break;
+  case 1: s->method=use_memchr; break;
+  case 2:
+  case 3:
+  case 4:
+  case 5:
+  case 6: s->method=memchr_and_memcmp; break;
+  default:
+    if(max_haystacklen <= needlelen + 64)
+    {
+      s->method=memchr_and_memcmp;
+    }else{
+      INT32 tmp, h;
+      unsigned INT32 hsize, e, max;
+      char *q;
+      struct link *ptr;
+
+      hsize=52+(max_haystacklen >> 7)  - (needlelen >> 8);
+      max  =13+(max_haystacklen >> 4)  - (needlelen >> 5);
+
+      if(hsize > NELEM(s->set))
+      {
+	hsize=NELEM(s->set);
+      }else{
+	for(e=8;e<hsize;e+=e);
+	hsize=e;
+      }
+    
+      for(e=0;e<hsize;e++) s->set[e]=0;
+      hsize--;
+
+      if(max > needlelen) max=needlelen;
+      max=(max-sizeof(INT32)+1) & -sizeof(INT32);
+      if(max > MEMSEARCH_LINKS) max=MEMSEARCH_LINKS;
+
+      ptr=& s->links[0];
+
+      q=needle;
+
+#if BYTEORDER == 4321
+      for(tmp=e=0;e<sizeof(INT32)-1;e++)
+      {
+	tmp<<=8;
+	tmp|=*(q++);
+      }
+#endif
+
+      for(e=0;e<max;e++)
+      {
+#if BYTEORDER == 4321
+	tmp<<=8;
+	tmp|=*(q++);
+#else
+	tmp=EXTRACT_INT((unsigned char *)q);
+	q++;
+#endif
+	h=tmp;
+	h+=h>>7;
+	h+=h>>17;
+	h&=hsize;
+
+	ptr->offset=e;
+	ptr->key=tmp;
+	ptr->next=s->set[h];
+	s->set[h]=ptr;
+	ptr++;
+      }
+      s->hsize=hsize;
+      s->max=max;
+      s->method=hubbe_search;
+    }
+  }
+}
+		    
+
+char *memory_search(struct mem_searcher *s,
+		    char *haystack,
+		    SIZE_T haystacklen)
+{
+  if(s->needlelen > haystacklen) return 0;
+
+  switch(s->method)
+  {
+  case no_search:
+    return haystack;
+
+  case use_memchr:
+    return MEMCHR(haystack,s->needle[0],haystacklen);
+
+  case memchr_and_memcmp:
+    {
+      char *end,c,*needle;
+      SIZE_T needlelen;
+      
+      needle=s->needle;
+      needlelen=s->needlelen;
+      
+      end=haystack + haystacklen - needlelen+1;
+      c=needle[0];
+      needle++;
+      needlelen--;
+      while((haystack=MEMCHR(haystack,c,end-haystack)))
+	if(!MEMCMP(++haystack,needle,needlelen))
+	  return haystack-1;
+
+      return 0;
+    }
+
+  case hubbe_search:
+    {
+      INT32 tmp, h;
+      char *q, *end;
+      register struct link *ptr;
+      
+      end=haystack+haystacklen+1;
+      q=haystack + s->max - sizeof(INT32);
+      q=(char *)( ((long)q) & -sizeof(INT32));
+      for(;q<end-sizeof(INT32)+1;q+=s->max)
+      {
+	h=tmp=*(INT32 *)q;
+	
+	h+=h>>7;
+	h+=h>>17;
+	h&=s->hsize;
+	
+	for(ptr=s->set[h];ptr;ptr=ptr->next)
+	{
+	  char *where;
+	  
+	  if(ptr->key != tmp) continue;
+	  
+	  where=q-ptr->offset;
+	  if(where<haystack) continue;
+	  if(where+s->needlelen>end) return 0;
+	  
+	  if(!MEMCMP(where,s->needle,s->needlelen))
+	    return where;
+	}
+      }
+    }
+  }
+  return 0;
+}
+
+char *my_memmem(char *needle,
+		SIZE_T needlelen,
+		char *haystack,
+		SIZE_T haystacklen)
+{
+  struct mem_searcher tmp;
+  init_memsearch(&tmp, needle, needlelen, haystacklen);
+  return memory_search(&tmp, haystack, haystacklen);
+}
diff --git a/src/memory.h b/src/memory.h
index b93106c27f..b93be67a42 100644
--- a/src/memory.h
+++ b/src/memory.h
@@ -8,11 +8,48 @@
 
 #include "types.h"
 
+#define MEMSEARCH_LINKS 512
+
+struct link
+{
+  struct link *next;
+  INT32 key, offset;
+};
+
+enum methods {
+  no_search,
+  use_memchr,
+  memchr_and_memcmp,
+  hubbe_search
+};
+
+struct mem_searcher
+{
+  enum methods method;
+  char *needle;
+  SIZE_T needlelen;
+  unsigned INT32 hsize, max;
+  struct link links[MEMSEARCH_LINKS];
+  struct link *set[MEMSEARCH_LINKS];
+};
+
 /* Prototypes begin here */
 char *xalloc(SIZE_T size);
 void reorder(char *memory,INT32 nitems,INT32 size,INT32 *order);
+void reorder(char *memory, INT32 nitems, INT32 size,INT32 *order);
 unsigned INT32 hashmem(const unsigned char *a,INT32 len,INT32 mlen);
 unsigned INT32 hashstr(const unsigned char *str,INT32 maxn);
+void init_memsearch(struct mem_searcher *s,
+		    char *needle,
+		    SIZE_T needlelen,
+		    SIZE_T max_haystacklen);
+char *memory_search(struct mem_searcher *s,
+		    char *haystack,
+		    SIZE_T haystacklen);
+char *my_memmem(char *needle,
+		SIZE_T needlelen,
+		char *haystack,
+		SIZE_T haystacklen);
 /* Prototypes end here */
 
 #endif
-- 
GitLab


From e3a26eab8a92709388debb9cb2763c33de0e7ae3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:44:52 +0200
Subject: [PATCH 224/351] construcor/destructor calls optimized

Rev: src/object.c:1.10
Rev: src/object.h:1.6
---
 src/object.c | 11 +++++++----
 src/object.h |  2 ++
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/object.c b/src/object.c
index 41af09bbb0..87e73b7289 100644
--- a/src/object.c
+++ b/src/object.c
@@ -103,9 +103,9 @@ struct object *clone(struct program *p, int args)
     o->refs++;
   }
 
-  apply(o,"__INIT",0);
+  apply_lfun(o,LFUN___INIT,0);
   pop_stack();
-  apply(o,"create",args);
+  apply_lfun(o,LFUN_CREATE,args);
   pop_stack();
 
   return o;
@@ -163,8 +163,11 @@ void destruct(struct object *o)
 
   o->refs++;
 
-  safe_apply(o, "destroy", 0);
-  pop_stack();
+  if(o->prog->lfuns[LFUN_DESTROY] != -1)
+  {
+    safe_apply_low(o, o->prog->lfuns[LFUN_DESTROY], 0);
+    pop_stack();
+  }
 
   /* destructed in destroy() */
   if(!o->prog)
diff --git a/src/object.h b/src/object.h
index e4bb8cd0dd..5b8d728373 100644
--- a/src/object.h
+++ b/src/object.h
@@ -29,6 +29,8 @@ extern struct object *first_object;
 #define GET_GLOBAL(O,I) LOW_GET_GLOBAL(O,I,ID_FROM_INT((O)->prog,I))
 #define GLOBAL_FROM_INT(I) GET_GLOBAL(fp->current_object, I)
 
+#define this_object() (fp->current_object->refs++,fp->current_object)
+
 /* Prototypes begin here */
 void setup_fake_object();
 struct object *clone(struct program *p, int args);
-- 
GitLab


From 2f87b5830aac207a304ddcefc16927c90d49fade Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:49:43 +0200
Subject: [PATCH 225/351] timeval added, memmem removed

Rev: src/port.c:1.2
Rev: src/port.h:1.2
---
 src/port.c | 160 +++++++----------------------------------------------
 src/port.h |  24 ++++----
 2 files changed, 33 insertions(+), 151 deletions(-)

diff --git a/src/port.c b/src/port.c
index 325dc69657..fef10dd880 100644
--- a/src/port.c
+++ b/src/port.c
@@ -5,6 +5,7 @@
 \*/
 #include "global.h"
 #include "macros.h"
+#include "time_stuff.h"
 #include <ctype.h>
 #include <math.h>
 #include <sys/types.h>
@@ -16,6 +17,24 @@
 time_t time PROT((time_t *));
 #endif
 
+#ifndef HAVE_GETTIMEOFDAY
+void GETTIMEOFDAY(struct timeval *t)
+{
+  t->tv_sec=(long)time(0);
+  t->tv_usec=0;
+}
+#endif
+
+#ifndef HAVE_TIME
+time_t TIME(time_t *t)
+{
+  struct timeval tv;
+  GETTIMEOFDAY(&tv);
+  if(t) *t=tv.tv_sec;
+  return tv.tv_sec;
+}
+#endif
+
 /*
  * This file defines things that may have to be changem when porting
  * LPmud to new environments. Hopefully, there are #ifdef's that will take
@@ -41,8 +60,6 @@ void my_srand(int seed)
   my_rand();
 }
 
-long get_current_time(void) { return (long)time(0L); }
-
 
 #ifndef HAVE_STRTOL
 #define DIGIT(x)	(isdigit(x) ? (x) - '0' : \
@@ -166,145 +183,6 @@ char *MEMCHR(char *p,char c,int e)
 }
 #endif
 
-#ifndef HAVE_MEMMEM
-
-/*
- * a quick memmem
- * Written by Fredrik Hubinette (hubbe@lysator.liu.se)
- */
-
-#define LINKS 1024
-
-typedef struct link2_s
-{
-  struct link2_s *next;
-  INT32 key, offset;
-} link2;
-
-char *MEMMEM(char *needle, SIZE_T needlelen, char *haystack, SIZE_T haystacklen)
-{
-  if(needlelen > haystacklen) return 0;
-
-  switch(needlelen)
-  {
-  case 0: return haystack;
-  case 1: return MEMCHR(haystack,needle[0],haystacklen);
-
-  default:
-  {
-    if(haystacklen > needlelen + 64)
-    {
-      static link2 links[LINKS], *set[LINKS];
-
-      INT32 tmp, h;
-      unsigned INT32 hsize, e, max;
-      char *q, *end;
-      link2 *ptr;
-
-      hsize=52+(haystacklen >> 7)  - (needlelen >> 8);
-      max  =13+(haystacklen >> 4)  - (needlelen >> 5);
-
-      if(hsize > NELEM(set))
-      {
-	hsize=NELEM(set);
-      }else{
-	for(e=8;e<hsize;e+=e);
-	hsize=e;
-      }
-    
-      for(e=0;e<hsize;e++) set[e]=0;
-      hsize--;
-
-      if(max > needlelen) max=needlelen;
-      max=(max-sizeof(INT32)+1) & -sizeof(INT32);
-      if(max > LINKS) max=LINKS;
-
-      ptr=&links[0];
-
-      q=needle;
-
-#if BYTEORDER == 4321
-      for(tmp=e=0;e<sizeof(INT32)-1;e++)
-      {
-	tmp<<=8;
-	tmp|=*(q++);
-      }
-#endif
-
-      for(e=0;e<max;e++)
-      {
-#if BYTEORDER == 4321
-	tmp<<=8;
-	tmp|=*(q++);
-#else
-	tmp=EXTRACT_INT((unsigned char *)q);
-	q++;
-#endif
-	h=tmp;
-	h+=h>>7;
-	h+=h>>17;
-	h&=hsize;
-
-	ptr->offset=e;
-	ptr->key=tmp;
-	ptr->next=set[h];
-	set[h]=ptr;
-	ptr++;
-      }
-
-      end=haystack+haystacklen+1;
-    
-      q=haystack+max-sizeof(INT32);
-      q=(char *)( ((long)q) & -sizeof(INT32));
-      for(;q<end-sizeof(INT32)+1;q+=max)
-      {
-	h=tmp=*(INT32 *)q;
-
-	h+=h>>7;
-	h+=h>>17;
-	h&=hsize;
-      
-	for(ptr=set[h];ptr;ptr=ptr->next)
-	{
-	  char *where;
-
-	  if(ptr->key != tmp) continue;
-
-	  where=q-ptr->offset;
-	  if(where<haystack) continue;
-	  if(where+needlelen>end) return 0;
-
-	  if(!MEMCMP(where,needle,needlelen))
-	    return where;
-	}
-      }
-      return 0;
-    }
-  }
-
-  case 2:
-  case 3:
-  case 4:
-  case 5:
-  case 6: 
-  {
-    char *end,c;
-  
-    end=haystack+haystacklen-needlelen+1;
-    c=needle[0];
-    needle++;
-    needlelen--;
-    while((haystack=MEMCHR(haystack,c,end-haystack)))
-      if(!MEMCMP(++haystack,needle,needlelen))
-	return haystack-1;
-
-    return 0;
-  }
-    
-  }
-}
-
-#endif
 
 #if !defined(HAVE_INDEX) && !defined(HAVE_STRCHR)
 char *STRCHR(char *s,char c)
diff --git a/src/port.h b/src/port.h
index 225d4faa62..1833e93905 100644
--- a/src/port.h
+++ b/src/port.h
@@ -8,6 +8,20 @@
 
 #include "types.h"
 
+struct timeval;
+
+#ifndef HAVE_GETTIMEOFDAY
+void GETTIMEOFDAY(struct timeval *t);
+#else
+#  define GETTIMEOFDAY gettimeofday
+#endif
+
+#ifndef HAVE_TIME
+time_t TIME(time_t *);
+#else
+#  define TIME time
+#endif
+
 #ifndef HAVE_STRTOL
 long STRTOL(char *str,char **ptr,int base);
 #else
@@ -68,15 +82,6 @@ char *MEMCHR(char *p,char c,int e);
 #  define MEMCHR(X,Y,Z) ((char *)memchr(X,Y,Z))
 #endif
 
-#ifndef HAVE_MEMMEM
-char *MEMMEM(char *needle,
-	     SIZE_T needlelen,
-	     char *haystack,
-	     SIZE_T haystacklen);
-#else
-#  define MEMMEM memmem
-#endif
-
 #ifndef HAVE_STRCHR
 #  ifdef HAVE_INDEX
 #    define STRCHR(X,Y) ((char *)index(X,Y))
@@ -174,7 +179,6 @@ static INLINE INT32 EXTRACT_INT(unsigned char *p)
 #endif
 #endif
 
-long get_current_time(void);
 unsigned long my_rand(void);
 void my_srand(int seed);
 
-- 
GitLab


From 55806994844bf7aa183216d370150c15d3e681ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:50:39 +0200
Subject: [PATCH 226/351] private inherit and and lfun calls added

Rev: src/program.c:1.12
Rev: src/program.h:1.6
---
 src/program.c | 31 ++++++++++++++++++++++++++++++-
 src/program.h | 35 ++++++++++++++++++++++++++++++-----
 2 files changed, 60 insertions(+), 6 deletions(-)

diff --git a/src/program.c b/src/program.c
index 6ebc01c23f..a9bc0621b6 100644
--- a/src/program.c
+++ b/src/program.c
@@ -37,6 +37,30 @@
 #undef FILE_STATE
 #undef PROGRAM_STATE
 
+
+char *lfun_names[] = {
+  "__INIT",
+  "create",
+  "destroy",
+  "`+",
+  "`-",
+  "`&",
+  "`|",
+  "`^",
+  "`<<",
+  "`>>",
+  "`*",
+  "`/",
+  "`%",
+  "`~",
+  "`==",
+  "`<",
+  "`>",
+  "__hash",
+  "cast",
+  "`!",
+};
+
 struct program *first_program = 0;
 
 struct program fake_program;
@@ -457,11 +481,15 @@ struct program *end_program()
       first_program->prev=prog;
     first_program=prog;
 
+    for(i=0;i<NUM_LFUNS;i++)
+      prog->lfuns[i]=find_identifier(lfun_names[i],prog);
+
 #ifdef DEBUG
     check_program(prog);
     if(l_flag)
       dump_program_desc(prog);
 #endif
+
   }
 
   /* Clean up */
@@ -661,12 +689,13 @@ void do_inherit(struct program *p,INT32 flags, struct lpc_string *name)
 	my_yyerror("Illegal to redefine 'nomask' function/variable \"%s\"",name->str);
     }
 
+    if(fun.flags & ID_PRIVATE) fun.flags|=ID_HIDDEN;
+
     if (fun.flags & ID_PUBLIC)
       fun.flags |= flags & ~ID_PRIVATE;
     else
       fun.flags |= flags;
 
-    if(fun.flags & ID_PRIVATE) fun.flags|=ID_HIDDEN;
     fun.flags |= ID_INHERITED;
     add_to_mem_block(A_IDENTIFIER_REFERENCES, (char *)&fun, sizeof fun);
   }
diff --git a/src/program.h b/src/program.h
index 07edbb8a3c..6c3935b166 100644
--- a/src/program.h
+++ b/src/program.h
@@ -3,14 +3,39 @@
 ||| uLPC is distributed as GPL (General Public License)
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
-#ifndef EXEC_H
-#define EXEC_H
+#ifndef PROGRAM_H
+#define PROGRAM_H
 
 #include <stdarg.h>
 #include "config.h"
 #include "machine.h"
 #include "types.h"
 
+#define LFUN___INIT 0
+#define LFUN_CREATE 1
+#define LFUN_DESTROY 2
+#define LFUN_ADD 3
+#define LFUN_SUBTRACT 4
+#define LFUN_AND 5
+#define LFUN_OR 6
+#define LFUN_XOR 7
+#define LFUN_LSH 8
+#define LFUN_RSH 9
+#define LFUN_MULTIPLY 10
+#define LFUN_DIVIDE 11
+#define LFUN_MOD 12
+#define LFUN_COMPL 13
+#define LFUN_EQ 14
+#define LFUN_LT 15
+#define LFUN_GT 16
+#define LFUN___HASH 17
+#define LFUN_CAST 18
+#define LFUN_NOT 19
+
+#define NUM_LFUNS 20
+
+extern char *lfun_names[];
+
 struct svalue;
 struct module;
 struct object;
@@ -30,12 +55,11 @@ struct object;
 
 /*
  * Max program dimensions:
- * 2^16 functions
+ * 2^16 functions + global variables
  * 2^16 inherits
  * 2^16 arguments to lpc functions
- * 2^32 to efuns and C functions
+ * 2^32 efuns
  * 2^8 local variables (and arguments)
- * 2^16 global variables
  */
 
 union idptr
@@ -122,6 +146,7 @@ struct program
   unsigned INT16 num_identifier_references;
   unsigned INT16 num_identifier_indexes;
   unsigned INT16 num_inherits;
+  INT16 lfuns[NUM_LFUNS];
 };
 
 #define INHERIT_FROM_PTR(P,X) ((P)->inherits + (X)->inherit_offset)
-- 
GitLab


From f16a7db7d33621211092a4338cbb945049e03d5d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:51:13 +0200
Subject: [PATCH 227/351] modules dir fixed

Rev: src/run_autoconfig:1.3
---
 src/run_autoconfig | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/run_autoconfig b/src/run_autoconfig
index cbe3af9d3d..0fed0b518a 100755
--- a/src/run_autoconfig
+++ b/src/run_autoconfig
@@ -15,11 +15,14 @@ fix()
 
 
 fix .
+fix modules
 for a in modules/*
 do
-  case $a in
-    modules/CVS) ;;
-    modules/RCS) ;;
-    *) fix $a ;;
-  esac
+  if test -d $a ; then
+    case $a in
+      */CVS) ;;
+      */RCS) ;;
+      *) fix $a ;;
+    esac
+  fi
 done
-- 
GitLab


From 589e9517a86c6d06491c39b8c8e1d7fde8783ffd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:51:46 +0200
Subject: [PATCH 228/351] now includes time_stuff.h

Rev: src/rusage.c:1.5
---
 src/rusage.c | 15 +--------------
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/src/rusage.c b/src/rusage.c
index 9bfa61195c..15ce18bab1 100644
--- a/src/rusage.c
+++ b/src/rusage.c
@@ -6,20 +6,7 @@
 #include "global.h"
 #include <sys/types.h>
 #include <sys/stat.h>
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  if HAVE_TIME_H
-#   include <time.h>
-#  endif
-# endif
-#endif
-
+#include "time_stuff.h"
 #include <fcntl.h>
 #include <errno.h>
 #include "types.h"
-- 
GitLab


From 310899d5300dfc9050341d6e45dc1d78fb441997 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:52:36 +0200
Subject: [PATCH 229/351] string replace optimized

Rev: src/stralloc.c:1.3
---
 src/stralloc.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/stralloc.c b/src/stralloc.c
index 8c3d1317c5..6e5847e891 100644
--- a/src/stralloc.c
+++ b/src/stralloc.c
@@ -362,12 +362,15 @@ struct lpc_string *string_replace(struct lpc_string *str,
   struct lpc_string *ret;
   INT32 delimeters;
   char *s,*tmp,*r,*end;
+  struct mem_searcher searcher;
 
   s=str->str;
   end=s+str->len;
   delimeters=0;
 
-  while((s=MEMMEM(del->str,del->len,s,end-s)))
+  init_memsearch(&searcher, del->str, del->len, str->len * 2);
+
+  while((s=memory_search(&searcher,s,end-s)))
   {
     delimeters++;
     s+=del->len;
@@ -383,7 +386,7 @@ struct lpc_string *string_replace(struct lpc_string *str,
   s=str->str;
   r=ret->str;
 
-  while((tmp=MEMMEM(del->str,del->len,s,end-s)))
+  while((tmp=memory_search(&searcher,s,end-s)))
   {
     MEMCPY(r,s,tmp-s);
     r+=tmp-s;
-- 
GitLab


From 07c0737aa1ce07da6be82c9e41f6e1de728cf67a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:53:25 +0200
Subject: [PATCH 230/351] operator overloading added

Rev: src/opcodes.c:1.5
Rev: src/operators.c:1.9
Rev: src/svalue.c:1.12
Rev: src/svalue.h:1.9
---
 src/opcodes.c   | 176 ++++++++++++++++++++++++++++++++++++++++--
 src/operators.c | 201 ++++++++++++++++++++++++++++++++++++++----------
 src/svalue.c    | 176 +++++++++++++++++++++++++++++++++++++++++-
 src/svalue.h    |   6 +-
 4 files changed, 509 insertions(+), 50 deletions(-)

diff --git a/src/opcodes.c b/src/opcodes.c
index b713d7dd27..6410fc05c2 100644
--- a/src/opcodes.c
+++ b/src/opcodes.c
@@ -74,14 +74,176 @@ void f_index()
   pop_stack();
 }
 
+void cast(struct lpc_string *s)
+{
+  INT32 i;
+  
+  i=compile_type_to_runtime_type(s);
+
+  if(i != sp[-1].type)
+  {
+    if(i == T_MIXED) return;
+
+    if(sp[-2].type == T_OBJECT)
+    {
+      push_string(describe_type(s));
+      if(!sp[-2].u.object->prog)
+	error("Cast called on destructed object.\n");
+      if(sp[-2].u.object->prog->lfuns[LFUN_CAST] == -1)
+	error("No cast method in object.\n");
+      apply_lfun(sp[-2].u.object, LFUN_CAST, 1);
+      free_svalue(sp-2);
+      sp[-2]=sp[-1];
+      sp--;
+      return;
+    }
+
+    switch(i)
+    {
+    case T_MIXED:
+      break;
+
+    case T_INT:
+      switch(sp[-1].type)
+      {
+      case T_FLOAT:
+	i=(int)(sp[-1].u.float_number);
+	break;
+
+      case T_STRING:
+	i=strtol(sp[-1].u.string->str,0,0);
+	free_string(sp[-1].u.string);
+	break;
+      
+      default:
+	error("Cannot cast to int.\n");
+      }
+      
+      sp[-1].type=T_INT;
+      sp[-1].u.integer=i;
+      break;
+
+    case T_FLOAT:
+    {
+      FLOAT_TYPE f;
+      switch(sp[-1].type)
+      {
+      case T_INT:
+	f=(FLOAT_TYPE)(sp[-1].u.integer);
+	break;
+
+      case T_STRING:
+	f=STRTOD(sp[-1].u.string->str,0);
+	free_string(sp[-1].u.string);
+	break;
+      
+      default:
+	error("Cannot cast to float.\n");
+	f=0.0;
+      }
+      
+      sp[-1].type=T_FLOAT;
+      sp[-1].u.float_number=f;
+      break;
+    }
+
+    case T_STRING:
+    {
+      char buf[200];
+      switch(sp[-1].type)
+      {
+      case T_INT:
+	sprintf(buf,"%ld",(long)sp[-1].u.integer);
+	break;
+
+      case T_FLOAT:
+	sprintf(buf,"%f",(double)sp[-1].u.float_number);
+	break;
+      
+      default:
+	error("Cannot cast to string.\n");
+      }
+      
+      sp[-1].type=T_STRING;
+      sp[-1].u.string=make_shared_string(buf);
+      break;
+    }
+
+    case T_OBJECT:
+      switch(sp[-1].type)
+      {
+      case T_STRING:
+	APPLY_MASTER("cast_to_object",1);
+	break;
+	
+      case T_FUNCTION:
+	sp[-1].type = T_OBJECT;
+	break;
+      }
+      break;
+
+    case T_PROGRAM:
+      APPLY_MASTER("cast_to_program",1);
+      break;
+
+    case T_FUNCTION:
+    {
+      INT32 i;
+      if(fp->current_object->prog)
+	error("Cast to function in destructed object.\n");
+      i=find_shared_string_identifier(sp[-1].u.string,fp->current_object->prog);
+      free_string(sp[-1].u.string);
+      /* FIXME, check that it is a indeed a function */
+      if(i==-1)
+      {
+	sp[-1].type=T_FUNCTION;
+	sp[-1].subtype=i;
+	sp[-1].u.object=fp->current_object;
+	fp->current_object->refs++;
+      }else{
+	sp[-1].type=T_INT;
+	sp[-1].subtype=NUMBER_UNDEFINED;
+	sp[-1].u.integer=0;
+      }
+      break;
+    }
+
+    }
+  }
+}
+
 void f_cast()
 {
   INT32 i;
   
   i=compile_type_to_runtime_type(sp[-1].u.string);
-  pop_stack();
-  if(i != sp[-1].type)
+
+  if(i != sp[-2].type)
   {
+    if(i == T_MIXED)
+    {
+      pop_stack();
+      return;
+    }
+
+    if(sp[-2].type == T_OBJECT)
+    {
+      struct lpc_string *s;
+      s=describe_type(sp[-1].u.string);
+      pop_stack();
+      push_string(s);
+      if(!sp[-2].u.object->prog)
+	error("Cast called on destructed object.\n");
+      if(sp[-2].u.object->prog->lfuns[LFUN_CAST] == -1)
+	error("No cast method in object.\n");
+      apply_lfun(sp[-2].u.object, LFUN_CAST, 1);
+      free_svalue(sp-2);
+      sp[-2]=sp[-1];
+      sp--;
+      return;
+    }
+
+    pop_stack();
     switch(i)
     {
     case T_MIXED:
@@ -193,6 +355,8 @@ void f_cast()
     }
 
     }
+  }else{
+    pop_stack();
   }
 }
 
@@ -493,10 +657,10 @@ static INT32 low_sscanf(INT32 num_arg)
 
 	if(!contains_percent_percent)
 	{
-	  s=MEMMEM(end_str_start,
-		   end_str_end-end_str_start,
-		   input+eye,
-		   input_len-eye);
+	  s=my_memmem(end_str_start,
+		      end_str_end-end_str_start,
+		      input+eye,
+		      input_len-eye);
 	  if(!s) return matches;
 	  eye=s-input;
 	  new_eye=eye+end_str_end-end_str_start;
diff --git a/src/operators.c b/src/operators.c
index 9227d3b05a..ecbe77f120 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -20,6 +20,8 @@
 #include "add_efun.h"
 #include "peep.h"
 #include "lex.h"
+#include "program.h"
+#include "object.h"
 
 #define COMPARISON(ID,NAME,EXPR) \
 void ID(INT32 args) \
@@ -31,9 +33,7 @@ void ID(INT32 args) \
     error("Too few arguments to %s\n",NAME); \
   i=EXPR; \
   pop_n_elems(2); \
-  sp->type=T_INT; \
-  sp->u.integer=i; \
-  sp++; \
+  push_int(i); \
 }
 
 COMPARISON(f_eq,"`==", is_eq(sp-2,sp-1))
@@ -44,6 +44,17 @@ COMPARISON(f_gt,"`>" , is_gt(sp-2,sp-1))
 COMPARISON(f_ge,"`>=",!is_lt(sp-2,sp-1))
 
 
+#define CALL_OPERATOR(OP, args) \
+ if(!sp[-args].u.object->prog) \
+   error("Operator %s called in destructed object.\n",lfun_names[OP]); \
+ if(sp[-args].u.object->prog->lfuns[OP] == -1) \
+   error("No operator %s in object.\n",lfun_names[OP]); \
+ apply_lfun(sp[-args].u.object, OP, args-1); \
+ free_svalue(sp-2); \
+ sp[-2]=sp[-1]; \
+ sp--;
+
+
 void f_add(INT32 args)
 {
   INT32 e,size;
@@ -60,6 +71,9 @@ void f_add(INT32 args)
       switch(sp[-args].type)
       {
       case T_OBJECT:
+	CALL_OPERATOR(LFUN_ADD,args);
+	return;
+
       case T_PROGRAM:
       case T_FUNCTION:
 	error("Bad argument 1 to summation\n");
@@ -338,11 +352,17 @@ static int float_promote()
 
 void o_subtract()
 {
-  if (sp[-2].type != sp[-1].type && !float_promote())
+  if (sp[-2].type != sp[-1].type &&
+      !float_promote() &&
+      sp[-2].type != T_OBJECT)
     error("Subtract on different types.\n");
 
-  switch(sp[-1].type)
+  switch(sp[-2].type)
   {
+  case T_OBJECT:
+    CALL_OPERATOR(LFUN_SUBTRACT,2);
+    break;
+
   case T_ARRAY:
   {
     struct array *a;
@@ -431,11 +451,16 @@ static int generate_minus(node *n)
 
 void o_and()
 {
-  if(sp[-1].type != sp[-2].type)
+  if(sp[-1].type != sp[-2].type &&
+     sp[-2].type != T_OBJECT)
     error("Bitwise and on different types.\n");
 
   switch(sp[-2].type)
   {
+  case T_OBJECT:
+    CALL_OPERATOR(LFUN_AND,2);
+    break;
+
   case T_INT:
     sp--;
     sp[-1].u.integer &= sp[0].u.integer;
@@ -479,7 +504,13 @@ void f_and(INT32 args)
   case 0: error("Too few arguments to `&\n");
   case 1: return;
   case 2: o_and(); return;
-  default: while(--args > 0) o_and();
+  default:
+    if(sp[-args].type == T_OBJECT)
+    {
+      CALL_OPERATOR(LFUN_AND, args);
+    }else{
+      while(--args > 0) o_and();
+    }
   }
 }
 
@@ -503,11 +534,16 @@ static int generate_and(node *n)
 
 void o_or()
 {
-  if(sp[-1].type != sp[-2].type)
+  if(sp[-1].type != sp[-2].type &&
+     sp[-2].type != T_OBJECT)
     error("Bitwise or on different types.\n");
 
   switch(sp[-2].type)
   {
+  case T_OBJECT:
+    CALL_OPERATOR(LFUN_OR,2);
+    break;
+
   case T_INT:
     sp--;
     sp[-1].u.integer |= sp[0].u.integer;
@@ -552,7 +588,13 @@ void f_or(INT32 args)
   case 0: error("Too few arguments to `|\n");
   case 1: return;
   case 2: o_or(); return;
-  default: while(--args > 0) o_or();
+  default:
+    if(sp[-args].type==T_OBJECT)
+    {
+      CALL_OPERATOR(LFUN_OR, args);
+    } else {
+      while(--args > 0) o_or();
+    }
   }
 }
 
@@ -577,11 +619,16 @@ static int generate_or(node *n)
 
 void o_xor()
 {
-  if(sp[-1].type != sp[-2].type)
+  if(sp[-1].type != sp[-2].type &&
+     sp[-2].type != T_OBJECT)
     error("Bitwise xor on different types.\n");
 
   switch(sp[-2].type)
   {
+  case T_OBJECT:
+    CALL_OPERATOR(LFUN_XOR,2);
+    break;
+
   case T_INT:
     sp--;
     sp[-1].u.integer ^= sp[0].u.integer;
@@ -625,7 +672,13 @@ void f_xor(INT32 args)
   case 0: error("Too few arguments to `^\n");
   case 1: return;
   case 2: o_xor(); return;
-  default: while(--args > 0) o_xor();
+  default:
+    if(sp[-args].type==T_OBJECT)
+    {
+      CALL_OPERATOR(LFUN_XOR, args);
+    } else {
+      while(--args > 0) o_xor();
+    }
   }
 }
 
@@ -649,7 +702,16 @@ static int generate_xor(node *n)
 
 void o_lsh()
 {
-  if(sp[-2].type != T_INT) error("Bad argument 1 to <<\n");
+  if(sp[-2].type != T_INT)
+  {
+    if(sp[-2].type == T_OBJECT)
+    {
+      CALL_OPERATOR(LFUN_LSH,2);
+      return;
+    }
+
+    error("Bad argument 1 to <<\n");
+  }
   if(sp[-1].type != T_INT) error("Bad argument 2 to <<\n");
   sp--;
   sp[-1].u.integer = sp[-1].u.integer << sp->u.integer;
@@ -675,7 +737,15 @@ static int generate_lsh(node *n)
 
 void o_rsh()
 {
-  if(sp[-2].type != T_INT) error("Bad argument 1 to >>\n");
+  if(sp[-2].type != T_INT)
+  {
+    if(sp[-2].type == T_OBJECT)
+    {
+      CALL_OPERATOR(LFUN_RSH,2);
+      return;
+    }
+    error("Bad argument 1 to >>\n");
+  }
   if(sp[-1].type != T_INT) error("Bad argument 2 to >>\n");
   sp--;
   sp[-1].u.integer = sp[-1].u.integer >> sp->u.integer;
@@ -740,6 +810,12 @@ void o_multiply()
     return;
 
   default:
+    if(sp[-2].type == T_OBJECT)
+    {
+      CALL_OPERATOR(LFUN_MULTIPLY,2);
+      return;
+    }
+
     error("Bad arguments to multiply.\n");
   }
 }
@@ -751,7 +827,13 @@ void f_multiply(INT32 args)
   case 0: error("Too few arguments to `*\n");
   case 1: return;
   case 2: o_multiply(); return;
-  default: while(--args > 0) o_multiply(); 
+  default:
+    if(sp[-args].type==T_OBJECT)
+    {
+      CALL_OPERATOR(LFUN_MULTIPLY, args);
+    } else {
+      while(--args > 0) o_multiply(); 
+    }
   }
 }
 
@@ -775,11 +857,17 @@ static int generate_multiply(node *n)
 
 void o_divide()
 {
-  if(sp[-2].type!=sp[-1].type && !float_promote())
+  if(sp[-2].type!=sp[-1].type &&
+     !float_promote() &&
+     sp[-2].type != T_OBJECT)
     error("Division on different types.\n");
 
   switch(sp[-2].type)
   {
+  case T_OBJECT:
+    CALL_OPERATOR(LFUN_DIVIDE,2);
+    break;
+
   case T_STRING:
   {
     struct array *ret;
@@ -831,11 +919,17 @@ static int generate_divide(node *n)
 
 void o_mod()
 {
-  if(sp[-2].type != sp[-1].type && !float_promote())
+  if(sp[-2].type != sp[-1].type &&
+     !float_promote() &&
+     sp[-2].type != T_OBJECT)
     error("Modulo on different types.\n");
 
-  switch(sp[-1].type)
+  switch(sp[-2].type)
   {
+  case T_OBJECT:
+    CALL_OPERATOR(LFUN_MOD,2);
+    break;
+
   case T_FLOAT:
   {
     FLOAT_TYPE foo;
@@ -878,14 +972,28 @@ static int generate_mod(node *n)
 
 void o_not()
 {
-  if(sp[-1].type==T_INT)
+  switch(sp[-1].type)
   {
+  case T_INT:
     sp[-1].u.integer = !sp[-1].u.integer;
-  }else{
-    pop_stack();
-    sp->type=T_INT;
-    sp->u.integer=0;
-    sp++;
+    break;
+
+  case T_FUNCTION:
+  case T_OBJECT:
+    if(IS_ZERO(sp-1))
+    {
+      pop_stack();
+      push_int(1);
+    }else{
+      pop_stack();
+      push_int(0);
+    }
+    break;
+
+  default:
+    free_svalue(sp-1);
+    sp[-1].type=T_INT;
+    sp[-1].u.integer=0;
   }
 }
 
@@ -910,6 +1018,10 @@ void o_compl()
 {
   switch(sp[-1].type)
   {
+  case T_OBJECT:
+    CALL_OPERATOR(LFUN_COMPL,1);
+    break;
+    
   case T_INT:
     sp[-1].u.integer = ~ sp[-1].u.integer;
     break;
@@ -944,6 +1056,10 @@ void o_negate()
 {
   switch(sp[-1].type)
   {
+  case T_OBJECT:
+    CALL_OPERATOR(LFUN_SUBTRACT,1);
+    break;
+
   case T_FLOAT:
     sp[-1].u.float_number=-sp[-1].u.float_number;
     return;
@@ -1016,30 +1132,37 @@ void init_operators()
 {
   add_efun2("`==",f_eq,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
   add_efun2("`!=",f_ne,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
-  add_efun2("`<", f_lt,"function(int|float,int|float:int)|function(string,string:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
-  add_efun2("`<=",f_le,"function(int|float,int|float:int)|function(string,string:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
-  add_efun2("`>", f_gt,"function(int|float,int|float:int)|function(string,string:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
-  add_efun2("`>=",f_ge,"function(int|float,int|float:int)|function(string,string:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
+  add_efun2("`!",f_not,"function(mixed:int)",OPT_TRY_OPTIMIZE,0,generate_not);
 
-  add_efun2("`+",f_add,"function(int...:int)|!function(int...:mixed)&function(int|float...:float)|!function(int|float...:mixed)&function(string|int|float...:string)|function(array...:array)|function(mapping...:mapping)|function(list...:list)",OPT_TRY_OPTIMIZE,optimize_binary,generate_sum);
+#define CMP_TYPE "function(object,mixed:int)|function(mixed,object:int)|function(int|float,int|float:int)|function(string,string:int)"
+  add_efun2("`<", f_lt,CMP_TYPE,OPT_TRY_OPTIMIZE,0,generate_comparison);
+  add_efun2("`<=",f_le,CMP_TYPE,OPT_TRY_OPTIMIZE,0,generate_comparison);
+  add_efun2("`>", f_gt,CMP_TYPE,OPT_TRY_OPTIMIZE,0,generate_comparison);
+  add_efun2("`>=",f_ge,CMP_TYPE,OPT_TRY_OPTIMIZE,0,generate_comparison);
 
-  add_efun2("`-",f_minus,"function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(list,list:list)|function(float|int,float:float)|function(float,int:float)|function(int,int:int)|function(string,string:string)",OPT_TRY_OPTIMIZE,0,generate_minus);
+  add_efun2("`+",f_add,"function(object,mixed...:mixed)|function(int...:int)|!function(int...:mixed)&function(int|float...:float)|!function(int|float...:mixed)&function(string|int|float...:string)|function(array...:array)|function(mapping...:mapping)|function(list...:list)",OPT_TRY_OPTIMIZE,optimize_binary,generate_sum);
 
-  add_efun2("`&",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",OPT_TRY_OPTIMIZE,optimize_binary,generate_and);
+  add_efun2("`-",f_minus,"function(object,mixed...:mixed)|function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(list,list:list)|function(float|int,float:float)|function(float,int:float)|function(int,int:int)|function(string,string:string)",OPT_TRY_OPTIMIZE,0,generate_minus);
 
-  add_efun2("`|",f_or,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",OPT_TRY_OPTIMIZE,optimize_binary,generate_or);
+#define LOG_TYPE "function(object,mixed...:mixed)|function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)"
 
-  add_efun2("`^",f_xor,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",OPT_TRY_OPTIMIZE,optimize_binary,generate_xor);
+  add_efun2("`&",f_and,LOG_TYPE,OPT_TRY_OPTIMIZE,optimize_binary,generate_and);
 
-  add_efun2("`<<",f_lsh,"function(int,int:int)",OPT_TRY_OPTIMIZE,0,generate_lsh);
-  add_efun2("`>>",f_rsh,"function(int,int:int)",OPT_TRY_OPTIMIZE,0,generate_rsh);
+  add_efun2("`|",f_or,LOG_TYPE,OPT_TRY_OPTIMIZE,optimize_binary,generate_or);
 
-  add_efun2("`*",f_multiply,"function(int...:int)|!function(int...:mixed)&function(float|int...:float)|function(string*,string:string)",OPT_TRY_OPTIMIZE,optimize_binary,generate_multiply);
+  add_efun2("`^",f_xor,LOG_TYPE,OPT_TRY_OPTIMIZE,optimize_binary,generate_xor);
 
-  add_efun2("`/",f_divide,"function(int,int:int)|function(float|int,float:float)|function(float,int:float)|function(string,string:string*)",OPT_TRY_OPTIMIZE,0,generate_divide);
 
-  add_efun2("`%",f_mod,"function(int,int:int)|!function(int,int:mixed)&function(int|float,int|float:float)",OPT_TRY_OPTIMIZE,0,generate_mod);
+#define SHIFT_TYPE "function(object,mixed:mixed)|function(int,int:int)"
 
-  add_efun2("`!",f_not,"function(mixed:int)",OPT_TRY_OPTIMIZE,0,generate_not);
-  add_efun2("`~",f_compl,"function(int:int)|function(float:float)",OPT_TRY_OPTIMIZE,0,generate_compl);
+  add_efun2("`<<",f_lsh,SHIFT_TYPE,OPT_TRY_OPTIMIZE,0,generate_lsh);
+  add_efun2("`>>",f_rsh,SHIFT_TYPE,OPT_TRY_OPTIMIZE,0,generate_rsh);
+
+  add_efun2("`*",f_multiply,"function(object,mixed...:mixed)|function(int...:int)|!function(int...:mixed)&function(float|int...:float)|function(string*,string:string)",OPT_TRY_OPTIMIZE,optimize_binary,generate_multiply);
+
+  add_efun2("`/",f_divide,"function(object,mixed:mixed)|function(int,int:int)|function(float|int,float:float)|function(float,int:float)|function(string,string:string*)",OPT_TRY_OPTIMIZE,0,generate_divide);
+
+  add_efun2("`%",f_mod,"function(object,mixed:mixed)|function(int,int:int)|!function(int,int:mixed)&function(int|float,int|float:float)",OPT_TRY_OPTIMIZE,0,generate_mod);
+
+  add_efun2("`~",f_compl,"function(object:mixed)|function(int:int)|function(float:float)",OPT_TRY_OPTIMIZE,0,generate_compl);
 }
diff --git a/src/svalue.c b/src/svalue.c
index 300745e4c9..aa14b70353 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -15,6 +15,7 @@
 #include "add_efun.h"
 #include "error.h"
 #include "dynamic_buffer.h"
+#include "interpret.h"
 
 /*
  * This routine frees a short svalue given a pointer to it and
@@ -330,6 +331,86 @@ void assign_short_svalue(union anything *to,
   }
 }
 
+unsigned INT32 hash_svalue(struct svalue *s)
+{
+  unsigned INT32 q;
+
+  check_type(s->type);
+  check_refs(s);
+
+  switch(s->type)
+  {
+  case T_OBJECT:
+    if(!s->u.object->prog)
+    {
+      q=0;
+      break;
+    }
+
+    if(s->u.object->prog->lfuns[LFUN___HASH] != -1)
+    {
+      safe_apply_low(s->u.object, s->u.object->prog->lfuns[LFUN___HASH], 0);
+      if(sp[-1].type == T_INT)
+      {
+	q=sp[-1].u.integer;
+      }else{
+	q=0;
+      }
+      pop_stack();
+      break;
+    }
+
+  default:      q=(unsigned INT32)s->u.refs >> 2;
+  case T_INT:   q=s->u.integer; break;
+  case T_FLOAT: q=(unsigned INT32)(s->u.float_number * 16843009.0); break;
+  }
+  q+=q % 997;
+  q+=((q + s->type) * 9248339);
+  
+  return q;
+}
+
+int svalue_is_true(struct svalue *s)
+{
+  unsigned INT32 q;
+  check_type(s->type);
+  check_refs(s);
+
+  switch(s->type)
+  {
+  case T_INT:
+    if(s->u.integer) return 1;
+    return 0;
+
+  case T_FUNCTION:
+    check_destructed(s);
+    if(sp[-1].type==T_INT) return 0;
+    return 1;
+
+  case T_OBJECT:
+    check_destructed(s);
+    if(sp[-1].type==T_INT) return 0;
+    if(!s->u.object->prog) return 0;
+
+    if(s->u.object->prog->lfuns[LFUN_NOT]!=-1)
+    {
+      safe_apply_low(s->u.object,s->u.object->prog->lfuns[LFUN_NOT],0);
+      if(sp[-1].type == T_INT && sp[-1].u.integer == 0)
+      {
+	pop_stack();
+	return 1;
+      } else {
+	return 0;
+      }
+    }
+
+  default:
+    return 1;
+  }
+    
+}
+
+
 int is_eq(struct svalue *a, struct svalue *b)
 {
   check_type(a->type);
@@ -340,11 +421,58 @@ int is_eq(struct svalue *a, struct svalue *b)
   check_destructed(a);
   check_destructed(b);
 
-  if (a->type != b->type) return 0;
+  if (a->type != b->type)
+  {
+    if(a->type == T_OBJECT)
+    {
+      if(a->u.object->prog->lfuns[LFUN_EQ] != -1)
+      {
+      a_is_obj:
+	assign_svalue_no_free(sp, b);
+	sp++;
+	apply_lfun(a->u.object, LFUN_EQ, 1);
+	if(IS_ZERO(sp-1))
+	{
+	  pop_stack();
+	  return 0;
+	}else{
+	  pop_stack();
+	  return 1;
+	}
+      }
+    }
+
+    if(b->type == T_OBJECT)
+    {
+      if(b->u.object->prog->lfuns[LFUN_EQ] != -1)
+      {
+      b_is_obj:
+	assign_svalue_no_free(sp, a);
+	sp++;
+	apply_lfun(b->u.object, LFUN_EQ, 1);
+	if(IS_ZERO(sp-1))
+	{
+	  pop_stack();
+	  return 0;
+	}else{
+	  pop_stack();
+	  return 1;
+	}
+      }
+    }
+
+    return 0;
+  }
   switch(a->type)
   {
-  case T_LIST:
   case T_OBJECT:
+    if(a->u.object->prog->lfuns[LFUN_EQ] != -1)
+      goto a_is_obj;
+
+    if(b->u.object->prog->lfuns[LFUN_EQ] != -1)
+      goto b_is_obj;
+
+  case T_LIST:
   case T_PROGRAM:
   case T_ARRAY:
   case T_MAPPING:
@@ -444,7 +572,7 @@ int is_equal(struct svalue *a,struct svalue *b)
   return low_is_equal(a,b,0);
 }
 
-int is_lt(const struct svalue *a,const struct svalue *b)
+int is_lt(struct svalue *a,struct svalue *b)
 {
   check_type(a->type);
   check_type(b->type);
@@ -459,10 +587,52 @@ int is_lt(const struct svalue *a,const struct svalue *b)
     if(a->type == T_INT && b->type==T_FLOAT)
       return (FLOAT_TYPE)a->u.integer < b->u.float_number;
 
+    if(a->type == T_OBJECT)
+    {
+    a_is_object:
+      if(!a->u.object->prog)
+	error("Comparison on destructed object.\n");
+      if(a->u.object->prog->lfuns[LFUN_LT] == -1)
+	error("Object lacks '<\n");
+      assign_svalue_no_free(sp, b);
+      sp++;
+      apply_lfun(a->u.object, LFUN_LT, 1);
+      if(IS_ZERO(sp-1))
+      {
+	pop_stack();
+	return 0;
+      }else{
+	pop_stack();
+	return 1;
+      }
+    }
+
+    if(b->type == T_OBJECT)
+    {
+      if(!b->u.object->prog)
+	error("Comparison on destructed object.\n");
+      if(b->u.object->prog->lfuns[LFUN_GT] == -1)
+	error("Object lacks '>\n");
+      assign_svalue_no_free(sp, a);
+      sp++;
+      apply_lfun(b->u.object, LFUN_GT, 1);
+      if(IS_ZERO(sp-1))
+      {
+	pop_stack();
+	return 0;
+      }else{
+	pop_stack();
+	return 1;
+      }
+    }
+    
     error("Cannot compare different types.\n");
   }
   switch(a->type)
   {
+  case T_OBJECT:
+    goto a_is_object;
+
   default:
     error("Bad type to comparison.\n");
 
diff --git a/src/svalue.h b/src/svalue.h
index 29c3e9b7ef..4426fcc3eb 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -95,7 +95,7 @@ struct svalue
 #define NUMBER_DESTRUCTED 2
 
 #define is_gt(a,b) is_lt(b,a)
-#define IS_ZERO(X) ((X)->type==T_INT && (X)->u.integer==0)
+#define IS_ZERO(X) ((X)->type==T_INT?(X)->u.integer==0:(1<<(X)->type)&(BIT_OBJECT|BIT_FUNCTION)?!svalue_is_true(X):0)
 
 #define check_destructed(S) \
 do{ \
@@ -162,6 +162,8 @@ void assign_short_svalue_no_free(union anything *to,
 void assign_short_svalue(union anything *to,
 			 union anything *from,
 			 TYPE_T type);
+unsigned INT32 hash_svalue(struct svalue *s);
+int svalue_is_true(struct svalue *s);
 int is_eq(struct svalue *a, struct svalue *b);
 int low_is_equal(struct svalue *a,
 		 struct svalue *b,
@@ -171,7 +173,7 @@ int low_short_is_equal(const union anything *a,
 		       TYPE_T type,
 		       struct processing *p);
 int is_equal(struct svalue *a,struct svalue *b);
-int is_lt(const struct svalue *a,const struct svalue *b);
+int is_lt(struct svalue *a,struct svalue *b);
 void describe_svalue(struct svalue *s,int indent,struct processing *p);
 void clear_svalues(struct svalue *s, INT32 num);
 void copy_svalues_recursively_no_free(struct svalue *to,
-- 
GitLab


From 026a3502caba627e1e152f817c5967690983a7d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:54:23 +0200
Subject: [PATCH 231/351] instead of <time.h>

Rev: src/time_stuff.h:1.1
---
 src/time_stuff.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)
 create mode 100644 src/time_stuff.h

diff --git a/src/time_stuff.h b/src/time_stuff.h
new file mode 100644
index 0000000000..86f41d8c57
--- /dev/null
+++ b/src/time_stuff.h
@@ -0,0 +1,65 @@
+/*\
+||| This file a part of uLPC, and is copyright by Fredrik Hubinette
+||| uLPC is distributed as GPL (General Public License)
+||| See the files COPYING and DISCLAIMER for more information.
+\*/
+#ifndef TIME_STUFF_H
+#define TIME_STUFF_H
+
+#include "machine.h"
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  if HAVE_TIME_H
+#   include <time.h>
+#  endif
+# endif
+#endif
+
+#undef HAVE_SYS_TIME_H
+#undef HAVE_TIME_H
+#undef TIME_WITH_SYS_TIME
+
+#define my_timercmp(tvp, cmp, uvp) \
+  ( (tvp)->tv_sec cmp (uvp)->tv_sec || \
+    ((tvp)->tv_sec == (uvp)->tv_sec && \
+     (tvp)->tv_usec cmp (uvp)->tv_usec) )
+
+
+#define my_subtract_timeval(X, Y)		\
+  do {						\
+    struct timeval *_a=(X), *_b=(Y);		\
+    _a->tv_sec -= _b->tv_sec;			\
+    _a->tv_usec -= _a->tv_usec;			\
+    if(_b->tv_usec < 0) {			\
+      _b->tv_sec--;				\
+      _b->tv_usec+=1000000;			\
+    }						\
+  } while(0)
+
+#define my_add_timeval(X, Y)			\
+  do {						\
+    struct timeval *_a=(X), *_b=(Y);		\
+    _a->tv_sec += _b->tv_sec;			\
+    _a->tv_usec += _a->tv_usec;			\
+    if(_b->tv_usec > 1000000) {			\
+      _b->tv_sec++;				\
+      _b->tv_usec-=1000000;			\
+    }						\
+  } while(0)
+
+#ifndef HAVE_STRUCT_TIMEVAL
+struct timeval
+{
+  long tv_sec;
+  long tv_usec;
+};
+#endif
+
+
+#endif
-- 
GitLab


From 2b211665f7400f2d84d5dc532b9dbf524d39a785 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:54:40 +0200
Subject: [PATCH 232/351] work, work, work...

Rev: src/todo:1.6
---
 src/todo | 82 ++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 62 insertions(+), 20 deletions(-)

diff --git a/src/todo b/src/todo
index 260fc1f7da..a5483da868 100644
--- a/src/todo
+++ b/src/todo
@@ -142,45 +142,87 @@ patch byacc
 	done (maybe needs more fixing)
 
 fix efun->foo (always copies value)
+	fixed?
+
+rewrite sort_array
 	fixed
 
-dokumentera mera!
+putenv
+	fixed
 
-ta bort MAX_LOCAL (& MAX_GLOBAL)
+sort()
+	fixed
 
-ta bort EXPANDMAX
+++++ -> sum()
+	fixed
 
-kommentera mera
+update README
+	fixed
 
-typkollen m}ste generera b{ttre felmeddelanden..
+move the check for libsocket to the file module
+	fixed
 
-putenv? setugid? 
+add garbage collect
+	fixed
 
 function_exists()
+	not needed, just index the object.
+
+remove MAX_LOCAL (& MAX_GLOBAL)
+
+remove EXPANDMAX
+
+write more comments
+
+typkollen m}ste generera b{ttre felmeddelanden..
+
+setugid? 
+
 inherit_list()
 function_args()
 get_function_list()
 fuzzymatch()
-sort()
 this_function()
-kolla upp |vriga efunnar som skall portas 
+check what other functions needs porting
 
+add generic callbacks
 
-++++ -> sum()
+assert (check types explicitely)
+generalize foreach()
+constant
+'type wish'
 
-update README
+document file::set_nonblocking better (prototype callbacks etc.)
 
-flytta cheken f|r libsocket till modulen (och se till att moduler kan addera libs)
-(eller s{tt tillbaka AC_HAVE_DIRENT (?) i configure.in)
+fix 'private inherit'
 
-add garbage collect
+fix run time type checks.
 
-addera generisk callback
+make backtrace() show the arguments.
 
-assert (kolla typer explicit)
-generalisera foreach()
-constant
-'type wish'
-rewrite sort_array
+code_value()
+decode_value()
 
-document file::set_nonblocking better (prototype callbacks etc.)
+threads
+
+dynamic stack
+
+command line option: -L libdir
+
+rename list->multiset
+rename uLPC
+rename perror
+make a new perror
+rename add_efun -> add_constant
+rename sizeof -> size?
+
+then make a compat.h
+
+remove some simulated functions or make the optional.
+
+change object/program naming strategy
+
+make a better module interface.
+make a C++ interface.
+
+allocate stack with MAP_NORESERV
-- 
GitLab


From 7eb15e658db4446bb416def65c37a4d0918e17e2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 21:56:39 +0200
Subject: [PATCH 233/351] removed

Rev: src/call_out.c:1.4(DEAD)
Rev: src/call_out.h:1.4(DEAD)
Rev: src/make_modules:1.2(DEAD)
---
 src/call_out.c   | 313 -----------------------------------------------
 src/call_out.h   |  52 --------
 src/make_modules |  25 ----
 3 files changed, 390 deletions(-)
 delete mode 100644 src/call_out.c
 delete mode 100644 src/call_out.h
 delete mode 100755 src/make_modules

diff --git a/src/call_out.c b/src/call_out.c
deleted file mode 100644
index f596c0ce30..0000000000
--- a/src/call_out.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/*\
-||| This file a part of uLPC, and is copyright by Fredrik Hubinette
-||| uLPC is distributed as GPL (General Public License)
-||| See the files COPYING and DISCLAIMER for more information.
-\*/
-#include "global.h"
-#include "array.h"
-#include "call_out.h"
-#include "dynamic_buffer.h"
-#include "object.h"
-#include "interpret.h"
-#include "error.h"
-#include "builtin_efuns.h"
-#include "memory.h"
-#include "main.h"
-
-call_out **pending_calls=0;      /* pointer to first busy pointer */
-int num_pending_calls;           /* no of busy pointers in buffer */
-static call_out **call_buffer=0; /* pointer to buffer */
-static int call_buffer_size;     /* no of pointers in buffer */
-
-extern time_t current_time;
-
-static void verify_call_outs()
-{
-#ifdef DEBUG
-  struct array *v;
-  int e;
-
-  if(!d_flag) return;
-  if(!call_buffer) return;
-
-  if(num_pending_calls<0 || num_pending_calls>call_buffer_size)
-    fatal("Error in call out tables.\n");
-
-  if(pending_calls+num_pending_calls!=call_buffer+call_buffer_size)
-    fatal("Error in call out tables.\n");
-
-  for(e=0;e<num_pending_calls;e++)
-  {
-    if(e)
-    {
-      if(pending_calls[e-1]->time>pending_calls[e]->time)
-	fatal("Error in call out order.\n");
-    }
-    
-    if(!(v=pending_calls[e]->args))
-      fatal("No arguments to call\n");
-
-    if(v->refs!=1)
-      fatal("Array should exactly have one reference.\n");
-
-    if(v->malloced_size<v->size)
-      fatal("Impossible array.\n");
-  }
-#endif
-}
-
-
-/* start a new call out, return 1 for success */
-static int new_call_out(int num_arg,struct svalue *argp)
-{
-  int e,c;
-  call_out *new,**p,**pos;
-
-  if(!call_buffer)
-  {
-    call_buffer_size=20;
-    call_buffer=(call_out **)xalloc(sizeof(call_out *)*call_buffer_size);
-    if(!call_buffer) return 0;
-    pending_calls=call_buffer+call_buffer_size;
-    num_pending_calls=0;
-  }
-
-  if(num_pending_calls==call_buffer_size)
-  {
-    /* here we need to allocate space for more pointers */
-    call_out **new_buffer;
-
-    new_buffer=(call_out **)xalloc(sizeof(call_out *)*call_buffer_size*2);
-    if(!new_buffer)
-      return 0;
-
-    MEMCPY((char *)(new_buffer+call_buffer_size),
-	   (char *)call_buffer,
-	   sizeof(call_out *)*call_buffer_size);
-    free((char *)call_buffer);
-    call_buffer=new_buffer;
-    pending_calls=call_buffer+call_buffer_size;
-    call_buffer_size*=2;
-  }
-
-  /* time to allocate a new call_out struct */
-  f_aggregate(num_arg-1);
-
-  new=(call_out *)xalloc(sizeof(call_out));
-
-  if(!new) return 0;
-
-  new->time=current_time+argp[0].u.integer;
-  if(new->time <= current_time) new->time=current_time+1;
-
-  if(fp && fp->current_object)
-  {
-    new->caller=fp->current_object;
-    new->caller->refs++;
-  }else{
-    new->caller=0;
-  }
-
-  new->args=sp[-1].u.array;
-  sp -= 2;
-
-  /* time to link it into the buffer using binsearch */
-  pos=pending_calls;
-
-  e=num_pending_calls;
-  while(e>0)
-  {
-    c=e/2;
-    if(new->time>pos[c]->time)
-    {
-      pos+=c+1;
-      e-=c+1;
-    }else{
-      e=c;
-    }
-  }
-  pos--;
-  pending_calls--;
-  for(p=pending_calls;p<pos;p++) p[0]=p[1];
-  *pos=new;
-  num_pending_calls++;
-
-  verify_call_outs();
-  return 1;
-}
-
-void f_call_out(INT32 args)
-{
-  struct svalue tmp;
-  if(args<2)
-    error("Too few arguments to call_out.\n");
-
-  /* Swap, for compatibility */
-  tmp=sp[-args];
-  sp[-args]=sp[1-args];
-  sp[1-args]=tmp;
-
-  new_call_out(args,sp-args);
-}
-
-void do_call_outs()
-{
-  call_out *c;
-  int args;
-  verify_call_outs();
-  while(num_pending_calls &&
-	pending_calls[0]->time<=current_time &&
-	current_time==get_current_time())
-  {
-    /* unlink call out */
-    c=pending_calls[0];
-    pending_calls++;
-    num_pending_calls--;
-
-    if(c->caller) free_object(c->caller);
-
-    args=c->args->size;
-    push_array_items(c->args);
-    free((char *)c);
-    check_destructed(sp-args);
-    if(sp[-args].type!=T_INT)
-    {
-      f_call_function(args);
-      pop_stack();
-    }else{
-      pop_n_elems(args);
-    }
-    verify_call_outs();
-  }
-}
-
-static int find_call_out(struct svalue *fun)
-{
-  int e;
-  for(e=0;e<num_pending_calls;e++)
-  {
-    if(is_eq(fun, ITEM(pending_calls[e]->args)))
-      return e;
-  }
-  return -1;
-}
-
-void f_find_call_out(INT32 args)
-{
-  int e;
-  verify_call_outs();
-  e=find_call_out(sp - args);
-  pop_n_elems(args);
-  if(e==-1)
-  {
-    sp->type=T_INT;
-    sp->subtype=NUMBER_UNDEFINED;
-    sp->u.integer=-1;
-    sp++;
-  }else{
-    push_int(pending_calls[e]->time-current_time);
-  }
-  verify_call_outs();
-}
-
-void f_remove_call_out(INT32 args)
-{
-  int e;
-  verify_call_outs();
-  e=find_call_out(sp-args);
-  if(e!=-1)
-  {
-    pop_n_elems(args);
-    push_int(pending_calls[e]->time-current_time);
-    free_array(pending_calls[e]->args);
-    if(pending_calls[e]->caller)
-      free_object(pending_calls[e]->caller);
-    free((char*)(pending_calls[e]));
-    for(;e>0;e--)
-      pending_calls[e]=pending_calls[e-1];
-    pending_calls++;
-    num_pending_calls--;
-  }else{
-    pop_n_elems(args);
-    sp->type=T_INT;
-    sp->subtype=NUMBER_UNDEFINED;
-    sp->u.integer=-1;
-    sp++;
-  }
-  verify_call_outs();
-}
-
-/* return an array containing info about all call outs:
- * ({  ({ delay, caller, function, args, ... }), ... })
- */
-struct array *get_all_call_outs()
-{
-  int e;
-  struct array *ret;
-
-  verify_call_outs();
-  ret=allocate_array_no_init(num_pending_calls,0);
-  for(e=0;e<num_pending_calls;e++)
-  {
-    struct array *v;
-    v=allocate_array_no_init(pending_calls[e]->args->size+2, 0);
-    ITEM(v)[0].type=T_INT;
-    ITEM(v)[0].subtype=NUMBER_NUMBER;
-    ITEM(v)[0].u.integer=pending_calls[e]->time-current_time;
-
-    if(pending_calls[e]->caller)
-    {
-      ITEM(v)[1].type=T_OBJECT;
-      (ITEM(v)[1].u.object=pending_calls[e]->caller) ->refs++;
-    }else{
-      ITEM(v)[1].type=T_INT;
-      ITEM(v)[1].subtype=NUMBER_NUMBER;
-      ITEM(v)[1].u.integer=0;
-    }
-
-    assign_svalues_no_free(ITEM(v)+2,ITEM(pending_calls[e]->args),pending_calls[e]->args->size,BIT_MIXED);
-
-    ITEM(ret)[e].type=T_ARRAY;
-    ITEM(ret)[e].u.array=v;
-  }
-  return ret;
-}
-
-void f_call_out_info(INT32 args)
-{
-  pop_n_elems(args);
-  push_array(get_all_call_outs());
-}
-
-void free_all_call_outs()
-{
-  int e;
-  verify_call_outs();
-  for(e=0;e<num_pending_calls;e++)
-  {
-    free_array(pending_calls[e]->args);
-    if(pending_calls[e]->caller) free_object(pending_calls[e]->caller);
-    free((char*)(pending_calls[e]));
-  }
-  if(call_buffer) free((char*)call_buffer);
-  num_pending_calls=0;
-  call_buffer=NULL;
-  pending_calls=NULL;
-}
-
-time_t get_next_call_out()
-{
-  if(num_pending_calls)
-  {
-    return pending_calls[0]->time;
-  }else{
-    return 0;
-  }
-}
-
-#ifdef DEBUG
-void verify_all_call_outs()
-{
-  verify_call_outs();
-}
-#endif
diff --git a/src/call_out.h b/src/call_out.h
deleted file mode 100644
index d5b9882b21..0000000000
--- a/src/call_out.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*\
-||| This file a part of uLPC, and is copyright by Fredrik Hubinette
-||| uLPC is distributed as GPL (General Public License)
-||| See the files COPYING and DISCLAIMER for more information.
-\*/
-#ifndef CALL_OUT_H
-#define CALL_OUT_H
-
-#include "types.h"
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  if HAVE_TIME_H
-#   include <time.h>
-#  endif
-# endif
-#endif
-
-#undef HAVE_SYS_TIME_H
-#undef HAVE_TIME_H
-#undef TIME_WITH_SYS_TIME
-
-struct call_out_s
-{
-  time_t time;
-  struct object *caller;
-  struct array *args;
-};
-
-typedef struct call_out_s call_out;
-
-extern call_out **pending_calls; /* pointer to first busy pointer */
-extern int num_pending_calls; /* no of busy pointers in buffer */
-
-/* Prototypes begin here */
-void f_call_out(INT32 args);
-void do_call_outs();
-void f_find_call_out(INT32 args);
-void f_remove_call_out(INT32 args);
-struct array *get_all_call_outs();
-void f_call_out_info(INT32 args);
-void free_all_call_outs();
-time_t get_next_call_out();
-void verify_all_call_outs();
-/* Prototypes end here */
-
-#endif
diff --git a/src/make_modules b/src/make_modules
deleted file mode 100755
index 3df9692092..0000000000
--- a/src/make_modules
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-#
-# Call make in the modules subdirs
-#
-
-fullnames=`cat $1`
-
-shift
-
-#
-# This is more likely to be portable than using "$@" I think
-# Less generic, but I don't need to quote anything but spaces
-# at the moment
-#
-args=
-for arg
-do
-  args="$args \"$arg\""
-done
-
-for dir in $fullnames
-do
-  ( cd $dir ; eval $args )
-done
-
-- 
GitLab


From e09f4c02d97d492dffd6dfcc7bbc41ca73696f79 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 22:00:59 +0200
Subject: [PATCH 234/351] various optimizations

Rev: lib/simulate.lpc:1.16
---
 lib/simulate.lpc | 72 +++++++++++++++++-------------------------------
 1 file changed, 26 insertions(+), 46 deletions(-)

diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index 0eead87e02..43bd9bf82f 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -42,21 +42,19 @@ mixed *map_array(mixed *arr, mixed fun, mixed ... args)
 
   if(intp(fun))
     return arr(@args);
-
-  ret=allocate(sizeof(arr));
+  
   if(stringp(fun))
+    return column(arr, fun)(@args);
+
+  if(functionp(fun))
   {
-    for(e=0;e<sizeof(arr);e++)
-      ret[e]=arr[e][fun](@args);
-  }
-  else if(functionp(fun))
-  {
+    ret=allocate(sizeof(arr));
     for(e=0;e<sizeof(arr);e++)
       ret[e]=fun(arr[e],@args);
-  }else{
-    error("Bad argument 2 to map_array().\n");
+    return ret;
   }
-  return ret;
+
+  error("Bad argument 2 to map_array().\n");
 }
 
 mixed *filter_array(mixed *arr, mixed fun, mixed ... args)
@@ -64,29 +62,10 @@ mixed *filter_array(mixed *arr, mixed fun, mixed ... args)
   int e,d;
   mixed *ret;
 
-  ret=allocate(sizeof(arr));
-  if(stringp(fun))
-  {
-    for(e=0;e<sizeof(arr);e++)
-      if(arr[e][fun](@args))
-	ret[d++]=arr[e];
-  }
-  else if(functionp(fun))
-  {
-    for(e=0;e<sizeof(arr);e++)
-      if(fun(arr[e],@args))
-	ret[d++]=arr[e];
-  }
-  else if(intp(fun))
-  {
-    for(e=0;e<sizeof(arr);e++)
-      if(arr[e](@args))
-	ret[d++]=arr[e];
-  }
-  else
-  {
-    error("Bad argument 2 to filter_array().\n");
-  }
+  ret=map_array(arr,fun,@args);
+  for(e=0;e<sizeof(arr);e++)
+    if(ret[e])
+      ret[d++]=arr[e];
 
   return ret[0..d-1];
 }
@@ -126,13 +105,13 @@ varargs int exec(string file,string ... foo)
 {
   string path;
   if(search(file,"/"))
-    return exece(combine_path(getcwd(),file),foo);
+    return exece(combine_path(getcwd(),file),foo,getenv());
 
   path=getenv("PATH");
 
   foreach(path/":",path)
     if(file_stat(path=combine_path(path,file)))
-      return exece(path, foo);
+      return exece(path, foo,getenv());
 
   return 69;
 }
@@ -197,8 +176,8 @@ void system(string s)
   current_file=current_mode=0;
 
   p=file::pipe();
+  if(!p) error("System() failed.\n");
   p->set_close_on_exec(0);
-  if(!p) error("System failed.\n");
   if(pid=fork())
   {
     destruct(p);
@@ -229,15 +208,11 @@ varargs string code_value(mixed s,int a)
 
 mixed *sum_arrays(function foo, mixed * ... args)
 {
-  mixed *tmp,*ret;
+  mixed *ret;
   int e,d;
-  tmp=allocate(sizeof(args));
   ret=allocate(sizeof(args[0]));
   for(e=0;e<sizeof(args[0]);e++)
-  {
-    for(d=0;d<sizeof(args);d++) tmp[d]=args[d][e];
-    ret[e]=foo(@tmp);
-  }
+    ret[e]=foo(@ column(args, e));
   return ret;
 }
 
@@ -273,7 +248,7 @@ varargs mixed *sort_array(array foo,function cmp, mixed ... args)
   int len,start;
   int length;
   int foop, fooend, barp, barend;
-  
+
   if(!cmp || cmp==`>)
   {
     foo+=({});
@@ -281,10 +256,17 @@ varargs mixed *sort_array(array foo,function cmp, mixed ... args)
     return foo;
   }
 
+  if(cmp == `<)
+  {
+    foo+=({});
+    sort(foo);
+    reverse(foo);
+    return foo;
+  }
+
   length=sizeof(foo);
 
   foo+=({});
-//  perror(sprintf("DEBUG: %O\n",foo));
   bar=allocate(length);
 
   for(len=1;len<length;len*=2)
@@ -297,8 +279,6 @@ varargs mixed *sort_array(array foo,function cmp, mixed ... args)
       fooend=barp;
       barend=barp+len;
       if(barend > length) barend=length;
-      if(barend <= barp) 
-	error("OOPS");
       
       while(1)
       {
-- 
GitLab


From b27b7cc5335301e6ada2b9c02dc5974b9fa48d60 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 22:01:46 +0200
Subject: [PATCH 235/351] include fixed and putenv added

Rev: lib/master.lpc:1.7
---
 lib/master.lpc | 75 +++++++++++++++++++++++++++++++-------------------
 1 file changed, 47 insertions(+), 28 deletions(-)

diff --git a/lib/master.lpc b/lib/master.lpc
index 0be461015c..aeac7190ae 100644
--- a/lib/master.lpc
+++ b/lib/master.lpc
@@ -1,5 +1,7 @@
 string describe_backtrace(mixed *trace);
 
+string lpc_library_path;
+
 /* This function is called when an error occurs that is not caught
  * with catch(). It's argument consists of:
  * ({ error_string, backtrace }) where backtrace is the output from the
@@ -112,6 +114,11 @@ varargs mixed getenv(string s)
   return environment[s];
 }
 
+void putenv(string var, string val)
+{
+  environment[var]=val;
+}
+
 /* This function is called when all the driver is done with all setup
  * of modules, efuns, tables etc. etc. and is ready to start executing
  * _real_ programs. It receives the arguments not meant for the driver
@@ -127,28 +134,15 @@ void _main(string *argv, string *env)
 
   foreach(env,a) if(sscanf(a,"%s=%s",a,b)) environment[a]=b;
   add_efun("getenv",getenv);
+  add_efun("putenv",putenv);
 
   add_efun("write",clone(cast_to_program("/precompiled/file"),"stdout")->write);
 
-//  terminal->set_nonblocking(test,0,0);
-//  write("Gurka.\n");
-//  return;
-
-//  script=clone((program)"/precompiled/file");
-//  script->popen(({"ls"}));
-//  write(script->read(10000000));
-
-//  script->close();
-
-//  perror(sprintf("%O\n",backtrace()[-1]));
   a=backtrace()[-1][0];
   q=a/"/";
-  q[-1]="simulate.lpc";
-//  perror(sprintf("%O\n",q));
-//  perror(sprintf("%O\n",q*"/"));
-  clone(compile_file(q*"/"));
+  lpc_library_path = q[0..sizeof(q)-2] * "/";
 
-//  perror(sprintf("All efuns:\n%O\n",all_efuns()));
+  clone(compile_file(lpc_library_path+"/simulate.lpc"));
 
   if(!sizeof(argv))
   {
@@ -198,25 +192,50 @@ void compile_error(string file,int line,string err)
  * Note that previous_object cannot be trusted in ths function, because
  * the compiler calls this function.
  */
-string handle_include(string f, string current_file)
+string handle_include(string f,
+		      string current_file,
+		      int local_include)
 {
   string *tmp, path;
-/*  perror("Handle include: "+f+"\n"); */
 
-  tmp=current_file/"/";
-  tmp[-1]=f;
-  path=combine_path(getcwd(),tmp*"/");
-  if(file_stat(path)) return path;
-  
-  if(path=getenv("LPC_INCLUDE_PATH"))
+  if(local_include)
   {
-    foreach(path/":", path)
+    tmp=current_file/"/";
+    tmp[-1]=f;
+    path=combine_path(getcwd(),tmp*"/");
+    if(!file_stat(path)) return 0;
+  }
+  else
+  {
+    if(path=getenv("LPC_INCLUDE_PATH"))
+    {
+      foreach(path/":", path)
+      {
+	path=combine_path(path,f);
+	if(file_stat(path))
+	  break;
+	else
+	  path=0;
+      }
+    }
+    
+    if(!path)
     {
-      path=combine_path(path,f);
-      if(file_stat(path)) return path;
+      path=combine_path(lpc_library_path+"/include",f);
+      if(!file_stat(path)) path=0;
     }
   }
-  return 0;
+
+  if(path)
+  {
+    /* Handle preload */
+
+    if(path[-1]=='h' && path[-2]=='.' &&
+       file_stat(path[0..sizeof(path)-2]+"pre.lpc"))
+      cast_to_object(path);
+  }
+
+  return path;
 }
 
 /* It is possible that this should be a real efun,
-- 
GitLab


From 42f10583e02993e0d607777d5f23e44e92f31eed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 22:02:42 +0200
Subject: [PATCH 236/351] now modifies makefile

Rev: bin/metatest:1.3
---
 bin/metatest | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/bin/metatest b/bin/metatest
index 75bb951a09..c2ccba6cd7 100755
--- a/bin/metatest
+++ b/bin/metatest
@@ -11,19 +11,29 @@ esac
 set -e
 set -x
 
-docompile4() {
+docompile5() {
   mkdir test1
   cd test1
   $SRCPATH/src/configure --cache-file ../testcache
-  d="DEBUGDEF=$1"
-  make "$d"
-  make verify "$d"
-  make verify LPCOPTS=-d2 "$d"
-#  make verify LPCOPTS=-d99 "$d"
+
+  # Modify makefile to simplify debugging...
+  mv Makefile Makefile.orig
+  sed <Makefile.orig >Makefile "s/^DEBUGDEF=.*$/DEBUGDEF=$1/g"
+
+  make
+  make verify 
+  make verify LPCOPTS=-d2
+#  make verify LPCOPTS=-d99
   cd ..
   rm -rf test1
 }
 
+docompile4() {
+  docompile5 "$1"
+#  docompile5 "$1 -DDYNAMIC_STACK"
+#  docompile5 "$1 -DDYNAMIC_STACK -DREALLOC_STACK_ALWAYS"
+}
+
 docompile3() {
   docompile4 "$1"
   docompile4 "$1 -DFLAT_MAPPINGS"
-- 
GitLab


From bd1e29bc68509d6590361a924ade8d9a36c68f72 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 22:03:24 +0200
Subject: [PATCH 237/351] more tests added

Rev: src/test/create_testsuite:1.18
---
 src/test/create_testsuite | 109 +++++++++++++++++++++++++++++++++-----
 1 file changed, 95 insertions(+), 14 deletions(-)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 9ba22d67bb..7cb1164797 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -66,6 +66,70 @@ define(ifefun,[[cond([[all_efuns()->$1]],[[$2]])]])
 
 define(TESTNO,0)
 
+// testing < > <= >=
+define([[test_cmp]],[[
+test_true($1<$2)
+test_false($1>$2)
+test_true($2>$1)
+test_false($2<$1)
+test_true($1<=$2)
+test_false($1>=$2)
+test_true($2>=$1)
+test_false($2<=$1)
+test_true($2<=$2)
+test_true($1>=$1) ]])
+
+// mpz
+cond( [[ master()->programs["/precompiled/mpz"] ]],
+[[
+  define([[MPZ]],[[(program)"/precompiled/mpz"]])
+  test_true(programp(MPZ))
+  test_false(clone(MPZ))
+  test_do(destruct(clone(MPZ)))
+  test_eq(clone(MPZ,99)+1,100)
+  test_eq(clone(MPZ,100)*10,1000)
+  test_eq(clone(MPZ,"100")*10.0,1000)
+  test_eq(clone(MPZ,100.0)*clone(MPZ,3),300)
+  test_eq(clone(MPZ,100.0)/4,25)
+  test_eq(clone(MPZ,42)%10,2)
+  test_eq(clone(MPZ,10)<<1,20)
+  test_eq(clone(MPZ,10)>>1,5)
+  test_eq(clone(MPZ,66)+11,77)
+  test_eq(clone(MPZ,66)-11,55)
+  test_eq(clone(MPZ,17)&18,16)
+  test_eq(clone(MPZ,17)|7,31)
+  test_eq(-clone(MPZ,17),17)
+  test_eq((~clone(MPZ,17)) & 255,0xf0)
+  test_true(stringp((string)clone(MPZ,17)))
+  test_eq((string)clone(MPZ,17),"17")
+  test_true(intp((int)clone(MPZ,17)))
+  test_eq((int)clone(MPZ,17),17)
+  test_false(clone(MPZ,0))
+  test_true(clone(MPZ,1))
+
+  define([[mpz_test_cmp]],[[
+    test_cmp(clone(MPZ,$1), $2)
+    test_cmp($1, clone(MPZ,$2))
+    test_cmp(clone(MPZ, $1), clone(MPZ, $2))
+  ]])
+
+  define([[mpz_test_type1]],[[
+    mpz_test_cmp($1,$2)
+    mpz_test_cmp($1.0,$2)
+    mpz_test_cmp("$1",$2)
+  ]])
+
+  define([[mpz_test_type2]],[[
+    mpz_test_type1($1,$2)
+    mpz_test_type1($1,$2.0)
+    mpz_test_type1($1,"$2")
+  ]])
+
+  mpz_test_type2(1,2)
+  mpz_test_type2(-2,1)
+
+]]);
+
 test_compile_error_low(master()->add_precompiled_program(\"/test\",compile_string(\"int foo() { return 17; }\",\"62\")))
 
 test_any([[function f=random_seed; int t; foreach(allocate(1),t) f(t); return 1;]],1)
@@ -74,6 +138,33 @@ test_program([[int b=1,c; int a() { c=b+2; return c==3; }]])
 test_true([[ ("foobar"/"o") & ({ "foo" }) ]])
 test_any([[ array a="foo bar"/" "; return sizeof(a & ({"foo"}))]],1)
 
+// glob
+test_false(glob("foo","bar"))
+test_true(glob("foo","foo"))
+test_true(glob("f?o","foo"))
+test_true(glob("f??","foo"))
+test_true(glob("?o?","foo"))
+test_true(glob("f*","foo"))
+test_true(glob("*o","foo"))
+test_false(glob("*f","foo"))
+test_false(glob("o*","foo"))
+test_false(glob("?f?","foo"))
+test_equal([[glob("?f?",({"ff","ffff","off","fff",""}))]],[[({"off","fff"})]])
+test_equal([[glob("foo*bar",({"foobar","foobargazonk","","foofoobar","fobar","fooar"}))]],[[({"foobar","foofoobar"})]])
+
+// localtime
+cond([[all_efuns()->localtime]],
+[[
+test_true(mappingp(localtime(0)))
+]])
+
+// strerror
+cond([[all_efuns()->strerror]],
+[[
+test_do(strerror(1))
+test_true(stringp(strerror(-2)||""))
+]])
+
 
 // sort
 test_equal(sort(({1,3,2,4})),({1,2,3,4}))
@@ -287,6 +378,8 @@ cond( [[ master()->programs["/precompiled/gdbm"] ]],
   ]])
 
   GDBMTESTS
+
+  test_do(rm("test.gdbm"))
 ]])
 
 test_eq("\377"[0],255)
@@ -430,20 +523,6 @@ test_true(!(1==2))
 test_true(!(""!=""))
 test_true(""!="foo")
 
-// testing < > <= >=
-define(test_cmp,[[
-test_true($1<$2)
-test_true(!($1>$2))
-test_true($2>$1)
-test_true(!($2<$1))
-test_true($1<=$2)
-test_true(!($1>=$2))
-test_true($2>=$1)
-test_true(!($2<=$1))
-test_true($2<=$2)
-test_true($1>=$1) ]])
-
-
 test_cmp(1,2)
 test_cmp(1.0,2.0)
 test_cmp(1,2.0)
@@ -1807,6 +1886,7 @@ test_eq(sizeof((<8,7,6,5,4,7>)),6)
 
 // - sleep
 test_do(sleep(1))
+test_do(sleep(0.5))
 
 // - sum
 test_eq(sum(1,1),2)
@@ -1857,6 +1937,7 @@ test_eq(zero_type(([])[7]),1)
 
 // - call_out, call_out_info, remove_call_out, find_call_out
 test_do(call_out(a,100000))
+test_do(call_out(lambda() {},1000.0))
 test_true(arrayp(call_out_info()))
 test_true(sizeof(call_out_info()) > 0)
 test_true(call_out_info()[-1][0] > 1)
-- 
GitLab


From bb1bb7aecd588ec382c526da63a4b5aae1fe3a39 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 22:04:14 +0200
Subject: [PATCH 238/351] now ignores build dir

Rev: .cvsignore:1.7
---
 .cvsignore | 1 +
 .gitignore | 1 +
 2 files changed, 2 insertions(+)

diff --git a/.cvsignore b/.cvsignore
index 00bbbf0d2e..b66ed0fb55 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -1,3 +1,4 @@
+build
 reports
 test
 test.lpc
diff --git a/.gitignore b/.gitignore
index ada9bcc0fa..391976ae01 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,6 +30,7 @@ _$*
 *.elc
 *.ln
 core
+/build
 /reports
 /test
 /test.lpc
-- 
GitLab


From db3d4bdc59b43eeb689932d672c9414e3e68ebae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 21 Jun 1996 22:05:28 +0200
Subject: [PATCH 239/351] lots of entries added

Rev: src/ChangeLog:1.38
---
 src/ChangeLog | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 5b6155400c..5636ce265a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,29 @@
+Fri Jun 21 20:32:00 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
+
+	* simulate.lpc optimized
+	* reorganize optimized (used by lists and sort and other stuff)
+	* type checks now optimize int|int to just int
+	* #include now honours "" and <>
+	* stack size increased
+	* callback.c is actually useful now..
+	* sleep now handles floats for delays smaller than seconds.
+	* backend now handles delays shorter than seconds.
+	* backend has callbacks to allow call_out for module(s)
+	* explode and string replace optimized (memory searcher)
+	* better stack checks added
+	* `<< method added to /precompiled/file
+	* call_out moved to a module, call_out now handles floating point
+	  delays.
+	* Makefile and configure script added to the module directory.
+	* 'private inherit' now works as you might expect
+
+Wed Jun 19 01:22:53 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
+
+	* Operator overloading added.
+	* new simulated function: putenv
+	* gmp module added, implements LARGE numbers. (/precompiled/mpz)
+	* C++ style output is now possible with <<
+
 Sun Jun  9 16:33:16 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
 
 	* second argument to file->read() added
-- 
GitLab


From 3d669e36dcc27c45370575225b96d8d76cc7d55f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 22 Jun 1996 02:13:49 +0200
Subject: [PATCH 240/351] some bugfixes

Rev: bin/htmlify_docs.lpc:1.12
---
 bin/htmlify_docs.lpc | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/bin/htmlify_docs.lpc b/bin/htmlify_docs.lpc
index cfe1b84f57..acc7b2f478 100644
--- a/bin/htmlify_docs.lpc
+++ b/bin/htmlify_docs.lpc
@@ -245,6 +245,11 @@ inherit "/precompiled/regexp":is_example;
 list(string) indexes_done=(<>);
 list(string) pages_done=(<>);
 
+void done(string a)
+{
+  pages_done[a]=1;
+}
+
 string mkindex(string topic, int usehead)
 {
   string head;
@@ -272,8 +277,7 @@ string mkindex(string topic, int usehead)
     foreach(sort_array(m_indices(pages)),a)
     {
       if(a[0]!='/') continue;
-      
-      pages_done[a]=1;
+      done(a);
       ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
     }
     
@@ -286,9 +290,7 @@ string mkindex(string topic, int usehead)
     foreach(sort_array(m_indices(pages)),a)
     {
       if(search(a,"example")==-1) continue;
-
-      pages_done[a]=1;
-      
+      done(a);
       ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
     }
     
@@ -298,6 +300,8 @@ string mkindex(string topic, int usehead)
   case "other":
     head="<b>Other pages</b>\n";
     ret="<ul>\n";
+//    perror(sprintf("all pages: %O\n",sort(m_indices(pages))));
+//    perror(sprintf("pages done: %O\n",sort(m_indices(pages_done))));
     foreach(sort_array(m_indices(pages) - indices(pages_done) ),a)
     {
       if(a[0..4]=="index") continue;
@@ -312,9 +316,9 @@ string mkindex(string topic, int usehead)
     foreach(sort_array(m_indices(all_efuns())),a)
     {
       a=html_quote(a);
+      done(a);
       if(pages[a])
       {
-	pages_done[a]=1;
 	ret+="<li><a href="+pages[a]+">"+a+"</a>"+short(a)+"\n";
       }else{
 	if(writepages)
@@ -327,7 +331,8 @@ string mkindex(string topic, int usehead)
   default:
     if(!keywords[topic])
     {
-      perror("Unknown keyword "+topic+".\n");
+      if(writepages)
+	perror("Unknown keyword "+topic+".\n");
       return "";
     }
 
@@ -339,7 +344,7 @@ string mkindex(string topic, int usehead)
     foreach(sort_array(keywords[topic]),a)
     {
       a=html_quote(a);
-      pages_done[a]=1;
+      done(a);
       ret+="<li><a href="+pages[a]+">"+a+"</a>"+ short(a) +"\n";
     }
     ret+="</ul></a>\n";
@@ -564,13 +569,13 @@ string convert_page(string path, string fname)
 
 	case "LINK":
 	  sscanf(a,"%s %s",a,b);
-	  pages_done[(a/"/")[-1]]=1;
+	  done((a/"/")[-1]);
 	  tmp="<a href="+fippel_path(a)+">"+b+"</a>";
 	  break;
 
 	case "TAG":
 	  pages[a]=fippel_path(path)+"#"+a;
-	  pages_done[a]=1;
+	  done(a);
 	  tmp="<a name="+a+">";
 	  break;
 
-- 
GitLab


From 532c5645ccdbe6144824c74b9fdfce29da6c92b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 22 Jun 1996 02:17:09 +0200
Subject: [PATCH 241/351] more stuff added

Rev: .cvsignore:1.8
---
 .cvsignore | 2 ++
 .gitignore | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/.cvsignore b/.cvsignore
index b66ed0fb55..f2a2dfccc9 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -9,3 +9,5 @@ uLPC_v1.0E-8.tar.gz
 uLPC_v1.0E-9.tar.gz
 uLPC_v1.1E-12.tar.gz
 uLPC_v1.7E-12.tar.gz
+test1
+testcache
diff --git a/.gitignore b/.gitignore
index 391976ae01..f7f68b209f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,3 +41,5 @@ core
 /uLPC_v1.0E-9.tar.gz
 /uLPC_v1.1E-12.tar.gz
 /uLPC_v1.7E-12.tar.gz
+/test1
+/testcache
-- 
GitLab


From 02b49c9f5d78760a51aaf73b4cdb365b46a21597 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 22 Jun 1996 02:17:27 +0200
Subject: [PATCH 242/351] operator stuff changed

Rev: doc/index.bmml:1.5
---
 doc/index.bmml | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/doc/index.bmml b/doc/index.bmml
index 4b03625bf6..48f1e87e0e 100644
--- a/doc/index.bmml
+++ b/doc/index.bmml
@@ -53,13 +53,11 @@ $version manual
 
 	TAG operators
 
- Operators
+	LINK operators/operators Operators
 
   uLPC operators behave much like the onces in C, but have many many additional
   features. Most of this added functionality is related to the new data types.
 
-	KEYWORD_LIST operators
-
  Keyword index
 
   The rest of the written documentation is gathered here, without much
-- 
GitLab


From 5090db0bba22a45b717b03a6f5b184001431be3c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 22 Jun 1996 02:18:02 +0200
Subject: [PATCH 243/351] minor bugfix

Rev: src/lex.c:1.11
---
 src/lex.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/lex.c b/src/lex.c
index c1ec5ed7f2..eec617631d 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -966,7 +966,7 @@ static void handle_include(char *name, int local_include)
   reference_shared_string(current_file);
   push_int(local_include);
 
-  SAFE_APPLY_MASTER("handle_include",2);
+  SAFE_APPLY_MASTER("handle_include",3);
 
   if(sp[-1].type != T_STRING)
   {
-- 
GitLab


From 29b22cd455792904042184577fbdb3e859108b4f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 22 Jun 1996 02:18:17 +0200
Subject: [PATCH 244/351] make html_docs now works

Rev: src/Makefile.src:1.7
---
 src/Makefile.src | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/Makefile.src b/src/Makefile.src
index 36776895f8..25262a3f71 100644
--- a/src/Makefile.src
+++ b/src/Makefile.src
@@ -214,8 +214,7 @@ docs:
 	mkdir docs
 
 html_docs: docs
-	$(RUNULPC) $(TMP_BINDIR)/htmlify_docs docs $(TMP_DOCDIR) `echo $(SRCDIR)/modules/*/doc` ; done`
-
+	$(RUNULPC) $(TMP_BINDIR)/htmlify_docs docs $(TMP_DOCDIR) `echo $(SRCDIR)/modules/*/doc`
 #
 # uLPC internal targets
 #
-- 
GitLab


From cf7ea46760806dbdf3b12289aa51b9fe5f733926 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 22 Jun 1996 02:18:47 +0200
Subject: [PATCH 245/351] #include <> test removed

Rev: src/test/create_testsuite:1.19
---
 src/test/create_testsuite | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 7cb1164797..f8a6077c3c 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -939,9 +939,9 @@ test_any(int e; object o=clone((program)"/precompiled/file"); if(!o->open("conft
 test_any([[
 #include "conftest.h"
 ]],17)
-test_any([[
-#include <conftest.h>
-]],17)
+dnltest_any([[
+dnl#include <conftest.h>
+dnl]],17)
 test_true(intp(__LINE__))
 test_true(stringp(__FILE__))
 test_true(stringp(__DATE__))
-- 
GitLab


From f7da711e35f7247d127fff1f8d93706e0ef2a4f2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 22 Jun 1996 02:49:34 +0200
Subject: [PATCH 246/351] entry added

Rev: src/ChangeLog:1.39
---
 src/ChangeLog | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 5636ce265a..d5e882314f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+Sat Jun 22 02:46:22 1996  Fredrik Hubinette  <hubbe@axel.signum.se>
+
+	* uLPC v1.0E-7 released
+
 Fri Jun 21 20:32:00 1996  Fredrik Hubinette  <hubbe@tymin.signum.se>
 
 	* simulate.lpc optimized
-- 
GitLab


From 64efda86686703f9ef25e7cd31cb752666275bcb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 22 Jun 1996 02:50:01 +0200
Subject: [PATCH 247/351] ignores new version

Rev: .cvsignore:1.9
---
 .cvsignore | 5 +++--
 .gitignore | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/.cvsignore b/.cvsignore
index f2a2dfccc9..71018a13bf 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -2,12 +2,13 @@ build
 reports
 test
 test.lpc
+test1
+testcache
 uLPC_v1.0E-10.tar.gz
 uLPC_v1.0E-12.tar.gz
 uLPC_v1.0E-13.tar.gz
+uLPC_v1.0E-7.tar.gz
 uLPC_v1.0E-8.tar.gz
 uLPC_v1.0E-9.tar.gz
 uLPC_v1.1E-12.tar.gz
 uLPC_v1.7E-12.tar.gz
-test1
-testcache
diff --git a/.gitignore b/.gitignore
index f7f68b209f..ddeac244db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,12 +34,13 @@ core
 /reports
 /test
 /test.lpc
+/test1
+/testcache
 /uLPC_v1.0E-10.tar.gz
 /uLPC_v1.0E-12.tar.gz
 /uLPC_v1.0E-13.tar.gz
+/uLPC_v1.0E-7.tar.gz
 /uLPC_v1.0E-8.tar.gz
 /uLPC_v1.0E-9.tar.gz
 /uLPC_v1.1E-12.tar.gz
 /uLPC_v1.7E-12.tar.gz
-/test1
-/testcache
-- 
GitLab


From 76ab21cedad6087e37d00f33651d9ecf01898a98 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 22 Jun 1996 08:04:10 +0200
Subject: [PATCH 248/351] minor fix

Rev: src/modules/gmpmod/mpz_glue.c:1.2
---
 src/modules/gmpmod/mpz_glue.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/modules/gmpmod/mpz_glue.c b/src/modules/gmpmod/mpz_glue.c
index 641196dacd..c75f1c0688 100644
--- a/src/modules/gmpmod/mpz_glue.c
+++ b/src/modules/gmpmod/mpz_glue.c
@@ -373,14 +373,15 @@ static void exit_mpz_glue(char *foo, struct object *o)
 {
   mpz_clear(THIS);
 }
-
 #endif
 
 void init_gmpmod_efuns(void) {}
 void exit_gmpmod(void)
 {
+#ifdef HAVE_GMP_H
   if(temporary) free_object(temporary);
   free_program(mpzmod_program);
+#endif
 }
 
 void init_gmpmod_programs(void)
-- 
GitLab


From 52c0d3adf4cd86eecc3ce7e906f46f966dca49a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 1 Jul 1996 17:50:46 +0200
Subject: [PATCH 249/351] sleep fixed

Rev: src/builtin_efuns.c:1.21
---
 src/builtin_efuns.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index 2df3337572..1daa692e03 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -666,7 +666,7 @@ void f_exit(INT32 args)
   if(sp[-args].type != T_INT)
     error("Bad argument 1 to exit.\n");
 
-  call_callback(&exit_callbacks);
+  call_callback(&exit_callbacks, (void *)0);
   free_callback(&exit_callbacks);
 
   i=sp[-args].u.integer;
@@ -1205,13 +1205,13 @@ void f_sleep(INT32 args)
     error("Bad argument 1 to sleep.\n");
   }
 
-  my_add_timeval(&t1, &t1);
+  my_add_timeval(&t1, &t2);
   
   pop_n_elems(args);
   while(1)
   {
     GETTIMEOFDAY(&t2);
-    if(my_timercmp(&t1, > , &t2))
+    if(my_timercmp(&t1, <= , &t2))
       break;
 
     t3=t1;
-- 
GitLab


From ddea559d107f4c31e40fbc287b2edba8a91e8350 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 1 Jul 1996 17:51:11 +0200
Subject: [PATCH 250/351] bugfix

Rev: src/callback.c:1.4
Rev: src/callback.h:1.4
Rev: src/machine.h.in:1.9
Rev: src/main.c:1.8
---
 src/callback.c   | 13 ++++++-------
 src/callback.h   |  4 ++--
 src/machine.h.in |  3 +++
 src/main.c       |  2 +-
 4 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/src/callback.c b/src/callback.c
index a760a8a843..80dac89550 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -33,7 +33,7 @@ static struct callback *get_free_callback()
     struct callback_block *tmp2;
     tmp2=ALLOC_STRUCT(callback_block);
 
-    for(e=0;e<sizeof(CALLBACK_CHUNK);e++)
+    for(e=0;e<(int)sizeof(CALLBACK_CHUNK);e++)
     {
       tmp2->callbacks[e].next=tmp;
       tmp=tmp2->callbacks+e;
@@ -43,21 +43,20 @@ static struct callback *get_free_callback()
   return tmp;
 }
 
-void call_callback(struct callback **ptr)
+void call_callback(struct callback **ptr, void *arg)
 {
   struct callback *l;
   while(l=*ptr)
   {
-    if(l->call) l->call(l,l->arg);
+    if(l->call) l->call(l,l->arg, arg);
 
     if(!l->call)
     {
       *ptr=l->next;
-      free((char *)l);
-    }else{
-      ptr=& l->next;
       l->next=free_callbacks;
       free_callbacks=l;
+    }else{
+      ptr=& l->next;
     }
   }
 }
@@ -92,7 +91,7 @@ void free_callback(struct callback **ptr)
   while(l=*ptr)
   {
     if(l->arg && l->free_func)
-      l->free_func(l, l->arg);
+      l->free_func(l, l->arg, 0);
     *ptr=l->next;
     l->next=free_callbacks;
     free_callbacks=l;
diff --git a/src/callback.h b/src/callback.h
index 6ba2257f70..0836801e72 100644
--- a/src/callback.h
+++ b/src/callback.h
@@ -10,12 +10,12 @@
 
 struct callback;
 
-typedef void (*callback_func)(struct callback *, void *);
+typedef void (*callback_func)(struct callback *, void *,void *);
 
 /* Prototypes begin here */
 struct callback;
 struct callback_block;
-void call_callback(struct callback **ptr);
+void call_callback(struct callback **ptr, void *arg);
 struct callback *add_to_callback(struct callback **ptr,
 				 callback_func call,
 				 void *arg,
diff --git a/src/machine.h.in b/src/machine.h.in
index f2fd129327..70b4987c1e 100644
--- a/src/machine.h.in
+++ b/src/machine.h.in
@@ -161,6 +161,9 @@
 /* Define if you have getenv.  */
 #undef HAVE_GETENV
 
+/* Define if you have gettimeofday.  */
+#undef HAVE_GETTIMEOFDAY
+
 /* Does your unix have a putenv function? */
 #undef HAVE_PUTENV
 
diff --git a/src/main.c b/src/main.c
index a3e1768202..46c3a9608f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -157,7 +157,7 @@ void main(int argc, char **argv, char **env)
 
   init_modules_efuns();
   master();
-  call_callback(& post_master_callbacks);
+  call_callback(& post_master_callbacks, 0);
   free_callback(& post_master_callbacks);
   init_modules_programs();
 
-- 
GitLab


From 361c887fd89bcc585ffa106ddf0aaea2960d5653 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 1 Jul 1996 17:51:19 +0200
Subject: [PATCH 251/351] removed a warning

Rev: src/mapping.c:1.8
---
 src/mapping.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/mapping.c b/src/mapping.c
index 8b71f34e54..c23fab5e41 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -981,7 +981,7 @@ void mapping_search_no_free(struct svalue *to,
     k=k->next;
   }
 
-  while(h < m->hashsize)
+  while(h < (unsigned INT32)m->hashsize)
   {
     while(k)
     {
-- 
GitLab


From 0cdad287189245bb10584dad8e6eeaedab37c008 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 1 Jul 1996 17:51:26 +0200
Subject: [PATCH 252/351] bugfixes

Rev: src/time_stuff.h:1.2
---
 src/time_stuff.h | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/src/time_stuff.h b/src/time_stuff.h
index 86f41d8c57..89fde04b46 100644
--- a/src/time_stuff.h
+++ b/src/time_stuff.h
@@ -26,19 +26,18 @@
 #undef TIME_WITH_SYS_TIME
 
 #define my_timercmp(tvp, cmp, uvp) \
-  ( (tvp)->tv_sec cmp (uvp)->tv_sec || \
-    ((tvp)->tv_sec == (uvp)->tv_sec && \
-     (tvp)->tv_usec cmp (uvp)->tv_usec) )
-
+  ( (tvp)->tv_sec == (uvp)->tv_sec ? \
+    (tvp)->tv_usec cmp (uvp)->tv_usec : \
+    (tvp)->tv_sec cmp (uvp)->tv_sec )
 
 #define my_subtract_timeval(X, Y)		\
   do {						\
     struct timeval *_a=(X), *_b=(Y);		\
     _a->tv_sec -= _b->tv_sec;			\
-    _a->tv_usec -= _a->tv_usec;			\
-    if(_b->tv_usec < 0) {			\
-      _b->tv_sec--;				\
-      _b->tv_usec+=1000000;			\
+    _a->tv_usec -= _b->tv_usec;			\
+    if(_a->tv_usec < 0) {			\
+      _a->tv_sec--;				\
+      _a->tv_usec+=1000000;			\
     }						\
   } while(0)
 
@@ -46,10 +45,10 @@
   do {						\
     struct timeval *_a=(X), *_b=(Y);		\
     _a->tv_sec += _b->tv_sec;			\
-    _a->tv_usec += _a->tv_usec;			\
-    if(_b->tv_usec > 1000000) {			\
-      _b->tv_sec++;				\
-      _b->tv_usec-=1000000;			\
+    _a->tv_usec += _b->tv_usec;			\
+    if(_a->tv_usec >= 1000000) {		\
+      _a->tv_sec++;				\
+      _a->tv_usec-=1000000;			\
     }						\
   } while(0)
 
-- 
GitLab


From a2c02093f2b553420acf1b4709d78245d7c8ddbb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 1 Jul 1996 17:51:35 +0200
Subject: [PATCH 253/351] version updated

Rev: lib/simulate.lpc:1.17
---
 lib/simulate.lpc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index 43bd9bf82f..265562c1bd 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -365,7 +365,7 @@ void create()
   add_efun("sum_arrays",sum_arrays);
   add_efun("system",system);
   add_efun("this_function",this_function);
-  add_efun("version",lambda() { return "uLPC v1.0E-7"; });
+  add_efun("version",lambda() { return "uLPC v1.1E-7"; });
   add_efun("write_file",write_file);
 }
 
-- 
GitLab


From 367094380008e4f4b872a5434617bed6127a7066 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 1 Jul 1996 17:51:45 +0200
Subject: [PATCH 254/351] bugs fixed

Rev: src/backend.c:1.6
Rev: src/modules/call_out/call_out.c:1.2
---
 src/backend.c                   | 14 +++++++-
 src/modules/call_out/call_out.c | 63 +++++++++++++++++++--------------
 2 files changed, 49 insertions(+), 28 deletions(-)

diff --git a/src/backend.c b/src/backend.c
index 6888606c41..0dd97402ca 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -191,10 +191,14 @@ void backend()
   while(first_object)
   {
     next_timeout.tv_usec = 0;
+#if 0
     next_timeout.tv_sec = 7 * 24 * 60 * 60;  /* See you in a week */
+#else
+    next_timeout.tv_sec = 15; /* See you in a week */
+#endif
     my_add_timeval(&next_timeout, &current_time);
 
-    call_callback(& backend_callbacks);
+    call_callback(& backend_callbacks, (void *)0);
     sets=selectors;
 
     alloca(0);			/* Do garbage collect */
@@ -204,6 +208,13 @@ void backend()
 
     GETTIMEOFDAY(&current_time);
     my_subtract_timeval(&next_timeout, &current_time);
+
+    if(next_timeout.tv_sec < 0)
+    {
+      next_timeout.tv_usec = 0;
+      next_timeout.tv_sec = 0;
+    }
+
     i=select(max_fd+1, &sets.read, &sets.write, 0, &next_timeout);
 
     GETTIMEOFDAY(&current_time);
@@ -236,6 +247,7 @@ void backend()
 
       }
     }
+    call_callback(& backend_callbacks, (void *)1);
   }
 
   UNSETJMP(back);
diff --git a/src/modules/call_out/call_out.c b/src/modules/call_out/call_out.c
index 74ee5cb654..64f7cca89a 100644
--- a/src/modules/call_out/call_out.c
+++ b/src/modules/call_out/call_out.c
@@ -181,43 +181,52 @@ void f_call_out(INT32 args)
   new_call_out(args,sp-args);
 }
 
-void do_call_outs(struct callback *ignored, void *ignored_too)
+void do_call_outs(struct callback *ignored, void *ignored_too, void *arg)
 {
   call_out *c;
   int args;
   time_t tmp;
   verify_call_outs();
 
-  tmp=(time_t)TIME(0);
-  while(num_pending_calls &&
-	my_timercmp(&pending_calls[0]->tv,<=,&current_time))
+  if(arg)
   {
-    /* unlink call out */
-    c=pending_calls[0];
-    pending_calls++;
-    num_pending_calls--;
-
-    if(c->caller) free_object(c->caller);
-
-    args=c->args->size;
-    push_array_items(c->args);
-    free((char *)c);
-    check_destructed(sp-args);
-    if(sp[-args].type!=T_INT)
+    tmp=(time_t)TIME(0);
+    while(num_pending_calls &&
+	  my_timercmp(&pending_calls[0]->tv,<=,&current_time))
     {
-      f_call_function(args);
-      pop_stack();
-    }else{
-      pop_n_elems(args);
+      /* unlink call out */
+      c=pending_calls[0];
+      pending_calls++;
+      num_pending_calls--;
+
+      if(c->caller) free_object(c->caller);
+
+      args=c->args->size;
+      push_array_items(c->args);
+      free((char *)c);
+      check_destructed(sp-args);
+      if(sp[-args].type!=T_INT)
+      {
+	f_call_function(args);
+	pop_stack();
+      }else{
+	pop_n_elems(args);
+      }
+      verify_call_outs();
+
+      if(tmp != (time_t) TIME(0)) break;
+    }
+  }
+  else /* if(arg) */
+  {
+    if(num_pending_calls)
+    {
+      if(my_timercmp(& pending_calls[0]->tv, < , &next_timeout))
+      {
+	next_timeout = pending_calls[0]->tv;
+      }
     }
-    verify_call_outs();
-
-    if(tmp != (time_t) TIME(0)) break;
   }
-
-  if(num_pending_calls)
-    if(my_timercmp(& pending_calls[0]->tv, < , &next_timeout))
-      next_timeout = pending_calls[0]->tv;
 }
 
 static int find_call_out(struct svalue *fun)
-- 
GitLab


From 5e8e32455e1f842300eccee7696e5be7f569146e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 1 Jul 1996 17:56:02 +0200
Subject: [PATCH 255/351] entry added

Rev: src/ChangeLog:1.40
---
 src/ChangeLog | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index d5e882314f..9f308b03bd 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+Mon Jul  1 17:55:26 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
+
+	* uLPC v1.1E-8 released
+	* call_out and sleep now works again.
+
 Sat Jun 22 02:46:22 1996  Fredrik Hubinette  <hubbe@axel.signum.se>
 
 	* uLPC v1.0E-7 released
-- 
GitLab


From 47055e8b5e4715afe478d169a1eb4fa6f0791c3a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 2 Jul 1996 15:06:44 +0200
Subject: [PATCH 256/351] entry added

Rev: src/ChangeLog:1.41
---
 src/ChangeLog | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 9f308b03bd..722ff7a952 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,6 +1,12 @@
+Tue Jul  2 13:44:02 1996  Fredrik Hubinette  <hubbe@freeone.signum.se>
+
+	* uLPC v1.2E-7 released
+	* added check to see if gettimeofday takes one or two args,
+	  uLPC should now compile on HP and Linux again.
+
 Mon Jul  1 17:55:26 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
 
-	* uLPC v1.1E-8 released
+	* uLPC v1.1E-7 released
 	* call_out and sleep now works again.
 
 Sat Jun 22 02:46:22 1996  Fredrik Hubinette  <hubbe@axel.signum.se>
-- 
GitLab


From e0b956c518b5d34dd7054fdf6e05770b5f5eb638 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 2 Jul 1996 15:08:52 +0200
Subject: [PATCH 257/351] gettimeofday should now work with linux

Rev: src/configure.in:1.14
Rev: src/machine.h.in:1.10
Rev: src/port.h:1.3
---
 src/configure.in | 44 ++++++++++++++++++++++++++++++++++++++++++--
 src/machine.h.in |  3 +++
 src/port.h       |  6 +++++-
 3 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/src/configure.in b/src/configure.in
index e620c7db5e..05030647eb 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -304,8 +304,50 @@ if test "$lpc_cv_has_external_timezone" = "yes"; then
   AC_DEFINE(HAVE_EXTERNAL_TIMEZONE)
 fi
 
+# No test for this yet...
+AC_DEFINE(HAVE_STRUCT_TIMEVAL)
+
 AC_MSG_RESULT($lpc_cv_has_external_timezone)
 
+AC_MSG_CHECKING(if gettimeofday takes two arguments)
+AC_CACHE_VAL(lpc_cv_func_gettimeofday_has_two_args,
+[
+AC_TRY_RUN([
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  if HAVE_TIME_H
+#   include <time.h>
+#  endif
+# endif
+#endif
+
+#ifndef HAVE_STRUCT_TIMEVAL
+struct timeval
+{
+  long tv_sec;
+  long tv_usec;
+};
+#endif
+
+int main() {
+  struct timeval tv;
+  gettimeofday(&tv,(void *)0);
+  exit(0);
+}
+],
+lpc_cv_func_gettimeofday_has_two_args=yes,
+lpc_cv_func_gettimeofday_has_two_args=no)])
+
+if test $lpc_cv_func_gettimeofday_has_two_args = yes; then
+  AC_DEFINE(GETTIMEOFDAY_TAKES_TWO_ARGS)
+fi
+
+AC_MSG_RESULT($lpc_cv_func_gettimeofday_has_two_args)
 
 AC_MSG_CHECKING(if struct tm has tm_gmtoff)
 
@@ -354,8 +396,6 @@ MY_CHECK_HEADERS(popen,stdio.h unistd.h)
 MY_CHECK_HEADERS(getenv,unistd.h stdlib.h)
 MY_CHECK_HEADERS(gethostname,unistd.h)
 
-# No test for this yet...
-AC_DEFINE(HAVE_STRUCT_TIMEVAL)
 
 AC_MSG_CHECKING(return type of free)
 AC_CACHE_VAL(lpc_cv_sys_free_return,
diff --git a/src/machine.h.in b/src/machine.h.in
index 70b4987c1e..a971262b54 100644
--- a/src/machine.h.in
+++ b/src/machine.h.in
@@ -164,6 +164,9 @@
 /* Define if you have gettimeofday.  */
 #undef HAVE_GETTIMEOFDAY
 
+/* Define if gettimeofday takes to arguments */
+#undef GETTIMEOFDAY_TAKES_TWO_ARGS
+
 /* Does your unix have a putenv function? */
 #undef HAVE_PUTENV
 
diff --git a/src/port.h b/src/port.h
index 1833e93905..432c972670 100644
--- a/src/port.h
+++ b/src/port.h
@@ -13,7 +13,11 @@ struct timeval;
 #ifndef HAVE_GETTIMEOFDAY
 void GETTIMEOFDAY(struct timeval *t);
 #else
-#  define GETTIMEOFDAY gettimeofday
+#  ifdef GETTIMEOFDAY_TAKES_TWO_ARGS
+#    define GETTIMEOFDAY(X) gettimeofday((X),(void *)0)
+#  else
+#    define GETTIMEOFDAY gettimeofday
+#  endif
 #endif
 
 #ifndef HAVE_TIME
-- 
GitLab


From 74593697267f8f41ccc3f40ccc12ae764f0c7c78 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 2 Jul 1996 15:15:03 +0200
Subject: [PATCH 258/351] version updated

Rev: lib/simulate.lpc:1.18
---
 lib/simulate.lpc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index 265562c1bd..00ff59b076 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -365,7 +365,7 @@ void create()
   add_efun("sum_arrays",sum_arrays);
   add_efun("system",system);
   add_efun("this_function",this_function);
-  add_efun("version",lambda() { return "uLPC v1.1E-7"; });
+  add_efun("version",lambda() { return "uLPC v1.2E-7"; });
   add_efun("write_file",write_file);
 }
 
-- 
GitLab


From b04d5f0cfdccae5ac7f6bf365256ae7a1dafd077 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 8 Jul 1996 23:54:35 +0200
Subject: [PATCH 259/351] minor change

Rev: src/Makefile.src:1.8
Rev: src/configure.in:1.15
---
 src/Makefile.src | 2 +-
 src/configure.in | 4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/Makefile.src b/src/Makefile.src
index 25262a3f71..aeab125fe3 100644
--- a/src/Makefile.src
+++ b/src/Makefile.src
@@ -141,7 +141,7 @@ install:
 
 # tidy up a bit
 tidy:
-	-rm -f *.o core $(MUD_LIB)/core y.output y.tab.c y.tab.h
+	-rm -f *.o core y.output y.tab.c y.tab.h
 	-rm -f $(TMP_BINDIR)/core *.o *.i *.i~
 
 # make clean
diff --git a/src/configure.in b/src/configure.in
index 05030647eb..fda76b3a1e 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -230,7 +230,9 @@ AC_TYPE_SIGNAL
 AC_CHECK_TYPE(time_t,INT32)
 
 AC_CHECK_LIB(PW, alloca)
-AC_CHECK_LIB(crypt, crypt)
+
+dnl AC_CHECK_LIB(crypt, crypt)
+
 AC_CHECK_LIB(m, floor)
 if test "${ac_cv_lib_m}" = "no" -a "${lpc_cv_sys_os}" = "Linux"; then
   AC_MSG_WARN(I will compensate for this by adding -lc -lm)
-- 
GitLab


From 3ccfb98f7628b5a758452d0a5458dba66c8c19e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 8 Jul 1996 23:54:49 +0200
Subject: [PATCH 260/351] bugfix

Rev: src/svalue.c:1.13
---
 src/svalue.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/svalue.c b/src/svalue.c
index aa14b70353..b8f64bd25c 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -384,12 +384,12 @@ int svalue_is_true(struct svalue *s)
 
   case T_FUNCTION:
     check_destructed(s);
-    if(sp[-1].type==T_INT) return 0;
+    if(s->type==T_INT) return 0;
     return 1;
 
   case T_OBJECT:
     check_destructed(s);
-    if(sp[-1].type==T_INT) return 0;
+    if(s->type==T_INT) return 0;
     if(!s->u.object->prog) return 0;
 
     if(s->u.object->prog->lfuns[LFUN_NOT]!=-1)
-- 
GitLab


From 7cf7f8046770713820fb9bae382ccd6c42cd10a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 8 Jul 1996 23:54:59 +0200
Subject: [PATCH 261/351] more things to do :)

Rev: src/todo:1.7
---
 src/todo | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/todo b/src/todo
index a5483da868..d7d63f36d9 100644
--- a/src/todo
+++ b/src/todo
@@ -222,7 +222,13 @@ remove some simulated functions or make the optional.
 
 change object/program naming strategy
 
-make a better module interface.
+make a better module interface. (a struct maybe...)
 make a C++ interface.
 
 allocate stack with MAP_NORESERV
+
+fix sprintf.html
+
+dynamic module loading
+
+make autoconf test for mpz_get_d
-- 
GitLab


From 9cec3c7264c57d67cf844dbd36ebe6a6425a353e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 8 Jul 1996 23:55:36 +0200
Subject: [PATCH 262/351] now always checks for -lnsl

Rev: src/modules/files/configure.in:1.8
---
 src/modules/files/configure.in | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/modules/files/configure.in b/src/modules/files/configure.in
index 2a1cdf33d0..e0abbca31b 100644
--- a/src/modules/files/configure.in
+++ b/src/modules/files/configure.in
@@ -9,9 +9,7 @@ AC_HAVE_HEADERS(arpa/inet.h sys/socketvar.h netinet/in.h \
  sys/stream.h sys/protosw.h)
 AC_HEADER_DIRENT
 AC_CHECK_LIB(socket, socket)
-if test "$ac_cv_lib_socket" = yes -o "${ac_cv_lib_ucb}" = yes; then
- AC_CHECK_LIB(nsl, main)
-fi
+AC_CHECK_LIB(nsl, gethostbyname)
 
 AC_HAVE_FUNCS(socketpair getwd strerror)
 
-- 
GitLab


From e43b7a643bf073f8463b8f3bddf852ac990ed6bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 8 Jul 1996 23:55:57 +0200
Subject: [PATCH 263/351] type for file->read fixed

Rev: src/modules/files/file.c:1.16
---
 src/modules/files/file.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index 85aca57d8c..d3ada13753 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -1214,7 +1214,7 @@ void init_files_programs()
 
   add_function("open",file_open,"function(string,string:int)",0);
   add_function("close",file_close,"function(string|void:void)",0);
-  add_function("read",file_read,"function(int:string|int)",0);
+  add_function("read",file_read,"function(int,int|void:int|string)",0);
   add_function("write",file_write,"function(string:int)",0);
 
   add_function("seek",file_seek,"function(int:int)",0);
-- 
GitLab


From 05ac5124c8fc1f8ff09526bb6aa8c58dd94c5105 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 8 Jul 1996 23:58:27 +0200
Subject: [PATCH 264/351] readline module

Rev: src/modules/readlinemod/Makefile.src:1.1
Rev: src/modules/readlinemod/configure.in:1.1
Rev: src/modules/readlinemod/readline_machine.h.in:1.1
Rev: src/modules/readlinemod/readlinemod.c:1.1
---
 src/modules/readlinemod/Makefile.src          | 19 ++++
 src/modules/readlinemod/configure.in          | 15 ++++
 src/modules/readlinemod/readline_machine.h.in | 16 ++++
 src/modules/readlinemod/readlinemod.c         | 90 +++++++++++++++++++
 4 files changed, 140 insertions(+)
 create mode 100644 src/modules/readlinemod/Makefile.src
 create mode 100644 src/modules/readlinemod/configure.in
 create mode 100644 src/modules/readlinemod/readline_machine.h.in
 create mode 100644 src/modules/readlinemod/readlinemod.c

diff --git a/src/modules/readlinemod/Makefile.src b/src/modules/readlinemod/Makefile.src
new file mode 100644
index 0000000000..46940d3472
--- /dev/null
+++ b/src/modules/readlinemod/Makefile.src
@@ -0,0 +1,19 @@
+SRCDIR=@srcdir@
+VPATH=@srcdir@:@srcdir@/../..:../..
+PREFLAGS=-I. -I$(SRCDIR) -I$(SRCDIR)/../.. -I../..
+CFLAGS=$(PREFLAGS) $(OTHERFLAGS)
+
+FILES=readlinemod.o
+LIB=readlinemod.a
+
+$(LIB): $(FILES)
+	-rm -f $(LIB)
+	ar cq $(LIB) $(FILES)
+	-@RANLIB@ $(LIB)
+	echo >linker_options @LIBS@
+
+clean:
+	-rm -f *.o *.a
+
+depend:
+	gcc -MM $(PREFLAGS) $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)
diff --git a/src/modules/readlinemod/configure.in b/src/modules/readlinemod/configure.in
new file mode 100644
index 0000000000..64b90a5b5b
--- /dev/null
+++ b/src/modules/readlinemod/configure.in
@@ -0,0 +1,15 @@
+AC_INIT(readlinemod.c)
+AC_CONFIG_HEADER(readline_machine.h)
+
+AC_PROG_CC
+AC_PROG_RANLIB
+AC_SUBST(RANLIB)
+
+AC_CHECK_HEADERS(readline.h)
+AC_CHECK_HEADERS(history.h)
+AC_CHECK_LIB(termcap, tputs)
+AC_CHECK_LIB(readline, readline)
+
+AC_OUTPUT(Makefile,echo FOO >stamp-h )
+
+
diff --git a/src/modules/readlinemod/readline_machine.h.in b/src/modules/readlinemod/readline_machine.h.in
new file mode 100644
index 0000000000..df03aee30d
--- /dev/null
+++ b/src/modules/readlinemod/readline_machine.h.in
@@ -0,0 +1,16 @@
+#ifndef GDBM_MACHINE_H
+#define GDBM_MACHINE_H
+
+/* Define this if you have <readline.h> */
+#undef HAVE_READLINE_H
+
+/* Define this if you have <history.h> */
+#undef HAVE_HISTORY_H
+
+/* Define this if you have -lreadline */
+#undef HAVE_LIBREADLINE
+
+/* Define this if you have -ltermcap */
+#undef HAVE_LIBTERMCAP
+
+#endif
diff --git a/src/modules/readlinemod/readlinemod.c b/src/modules/readlinemod/readlinemod.c
new file mode 100644
index 0000000000..a84802d775
--- /dev/null
+++ b/src/modules/readlinemod/readlinemod.c
@@ -0,0 +1,90 @@
+/*\
+||| This file a part of uLPC, and is copyright by Fredrik Hubinette
+||| uLPC is distributed as GPL (General Public License)
+||| See the files COPYING and DISCLAIMER for more information.
+\*/
+#include "global.h"
+#include "readline_machine.h"
+#include "types.h"
+#include "interpret.h"
+#include "svalue.h"
+#include "stralloc.h"
+#include "array.h"
+#include "object.h"
+#include "macros.h"
+
+#if !defined(HAVE_READLINE_H) || !defined(HAVE_HISTORY_H)
+#undef HAVE_LIBREADLINE
+#endif
+
+#ifdef HAVE_LIBREADLINE
+
+#include <readline.h>
+#include <history.h>
+
+static void f_readline(INT32 args)
+{
+  char *r;
+  if(args < 1)
+    error("Too few arguments to readline().\n");
+
+  if(sp[-args].type != T_STRING)
+    error("Bad argument 1 to readline()\n");
+
+  r=readline(sp[-args].u.string->str);
+  pop_n_elems(args);
+  if(r)
+  {
+    if(*r) add_history(r);
+    push_string(make_shared_string(r));
+    free(r);
+  } else {
+    push_int(0);
+  }
+}
+
+#else
+
+#include <stdio.h>
+
+#define BLOCK 16384
+
+static void f_readline(INT32 args)
+{
+  char line[BLOCK];
+  char *r;
+  if(args < 1)
+    error("Too few arguments to readline().\n");
+
+  if(sp[-args].type != T_STRING)
+    error("Bad argument 1 to readline()\n");
+
+  puts(sp[-args].u.string->str);
+
+  pop_n_elems(args);
+  if(fgets(line,BLOCK,stdin))
+  {
+    INT32 len;
+    if(len=strlen(line))
+    {
+      if(line[len-1]=='\n')
+      {
+	push_string(make_shared_binary_string(line,len-1));
+	return;
+      }
+    }
+  }
+  push_int(0);
+}
+
+#endif
+
+void init_readlinemod_efuns(void)
+{
+  rl_bind_key('\t', rl_insert);
+  add_efun("readline",f_readline,"function(string:string)",OPT_SIDE_EFFECT);
+}
+void exit_readlinemod(void) {}
+void init_readlinemod_programs(void) { }
+
+
-- 
GitLab


From 84c7bae428fb03e20f2b579d7c3db7745e4e9647 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 8 Jul 1996 23:59:56 +0200
Subject: [PATCH 265/351] ignore some stuff

Rev: src/modules/readlinemod/.cvsignore:1.1
---
 src/modules/readlinemod/.cvsignore | 2 ++
 src/modules/readlinemod/.gitignore | 2 ++
 2 files changed, 4 insertions(+)
 create mode 100644 src/modules/readlinemod/.cvsignore
 create mode 100644 src/modules/readlinemod/.gitignore

diff --git a/src/modules/readlinemod/.cvsignore b/src/modules/readlinemod/.cvsignore
new file mode 100644
index 0000000000..64200ddc24
--- /dev/null
+++ b/src/modules/readlinemod/.cvsignore
@@ -0,0 +1,2 @@
+Makefile.in
+configure
diff --git a/src/modules/readlinemod/.gitignore b/src/modules/readlinemod/.gitignore
new file mode 100644
index 0000000000..addfc0376f
--- /dev/null
+++ b/src/modules/readlinemod/.gitignore
@@ -0,0 +1,2 @@
+/Makefile.in
+/configure
-- 
GitLab


From b4011e33ef1e667638592b77859bd72cea81f488 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 9 Jul 1996 00:00:06 +0200
Subject: [PATCH 266/351] doc for readline()

Rev: src/modules/readlinemod/doc/readline:1.1
---
 src/modules/readlinemod/doc/readline | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
 create mode 100644 src/modules/readlinemod/doc/readline

diff --git a/src/modules/readlinemod/doc/readline b/src/modules/readlinemod/doc/readline
new file mode 100644
index 0000000000..8229909316
--- /dev/null
+++ b/src/modules/readlinemod/doc/readline
@@ -0,0 +1,14 @@
+NAME
+	readline - read a line from stdin
+
+SYNTAX
+	string readline(string prompt);
+
+DESCRIPTION
+	This function writes the string 'prompt' and then waits until the
+	user has entered a line from the keyboard. If the readline library
+	was available when uLPC was compiled the user will have history and
+	line edithing at his/her disposal when entering the line.
+
+SEE ALSO
+	files/file
-- 
GitLab


From 3b26c3f5753977dd2eb38c8d610ef08672faa471 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 9 Jul 1996 00:02:38 +0200
Subject: [PATCH 267/351] entries added

Rev: src/ChangeLog:1.42
---
 src/ChangeLog | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 722ff7a952..65f1c2c300 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+Mon Jul  8 23:52:48 1996  Fredrik Hubinette  <hubbe@axel.signum.se>
+
+	* uLPC v1.0E-6 released
+	* bug in true/false values fixed
+	* readline module added
+
 Tue Jul  2 13:44:02 1996  Fredrik Hubinette  <hubbe@freeone.signum.se>
 
 	* uLPC v1.2E-7 released
-- 
GitLab


From f3c90d264fbe32fba08c1067591606e30a9beb34 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 9 Jul 1996 00:03:32 +0200
Subject: [PATCH 268/351] readline added to install docs

Rev: src/README:1.5
---
 src/README | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/README b/src/README
index 068dbcea25..98dac7f39e 100644
--- a/src/README
+++ b/src/README
@@ -5,9 +5,9 @@ This is what you need to do to install uLPC:
    if you want to install ulpc in /foo/bar, default is /usr/local.
 
    You might have to set the environment variables C_INCLUDE_PATH and
-   LD_LIBRARY_PATH to enable the configure script to find gdbm and gmp.
-   If the configure script does not find those libraries those modules
-   will not be available.
+   LD_LIBRARY_PATH to enable the configure script to find gdbm, readline
+   and gmp. If the configure script does not find those libraries those
+   modules will not be available.
 
 2) edit config.h and Makefile to suit your purposes.
    I've tried to make it so that you don't have to change config.h or
-- 
GitLab


From 16c40b3bc7be882ebc2ff0b91886a64f604848e2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 9 Jul 1996 00:04:59 +0200
Subject: [PATCH 269/351] version updated

Rev: lib/simulate.lpc:1.19
---
 lib/simulate.lpc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index 00ff59b076..41164609dd 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -365,7 +365,7 @@ void create()
   add_efun("sum_arrays",sum_arrays);
   add_efun("system",system);
   add_efun("this_function",this_function);
-  add_efun("version",lambda() { return "uLPC v1.2E-7"; });
+  add_efun("version",lambda() { return "uLPC v1.0E-6"; });
   add_efun("write_file",write_file);
 }
 
-- 
GitLab


From f0e31fe5c38e7896f5189eab381b5cff2aa9b8eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 9 Jul 1996 00:05:24 +0200
Subject: [PATCH 270/351] more tar files ignored

Rev: .cvsignore:1.10
---
 .cvsignore | 3 +++
 .gitignore | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/.cvsignore b/.cvsignore
index 71018a13bf..09d38ff56b 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -7,8 +7,11 @@ testcache
 uLPC_v1.0E-10.tar.gz
 uLPC_v1.0E-12.tar.gz
 uLPC_v1.0E-13.tar.gz
+uLPC_v1.0E-6.tar.gz
 uLPC_v1.0E-7.tar.gz
 uLPC_v1.0E-8.tar.gz
 uLPC_v1.0E-9.tar.gz
 uLPC_v1.1E-12.tar.gz
+uLPC_v1.1E-7.tar.gz
+uLPC_v1.2E-7.tar.gz
 uLPC_v1.7E-12.tar.gz
diff --git a/.gitignore b/.gitignore
index ddeac244db..79433c60cb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,8 +39,11 @@ core
 /uLPC_v1.0E-10.tar.gz
 /uLPC_v1.0E-12.tar.gz
 /uLPC_v1.0E-13.tar.gz
+/uLPC_v1.0E-6.tar.gz
 /uLPC_v1.0E-7.tar.gz
 /uLPC_v1.0E-8.tar.gz
 /uLPC_v1.0E-9.tar.gz
 /uLPC_v1.1E-12.tar.gz
+/uLPC_v1.1E-7.tar.gz
+/uLPC_v1.2E-7.tar.gz
 /uLPC_v1.7E-12.tar.gz
-- 
GitLab


From 29b4b59e82311dcd1035eb0bf17ffd61656b04c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 9 Jul 1996 00:05:35 +0200
Subject: [PATCH 271/351] now uses readline

Rev: bin/hilfe.lpc:1.6
---
 bin/hilfe.lpc | 68 +++++++++++++++++++++++++++------------------------
 1 file changed, 36 insertions(+), 32 deletions(-)

diff --git a/bin/hilfe.lpc b/bin/hilfe.lpc
index 54c6a8b963..7a9afab4e0 100755
--- a/bin/hilfe.lpc
+++ b/bin/hilfe.lpc
@@ -13,7 +13,7 @@
 
 #pragma all_inline
 
-/* #define DEBUG  */
+/* #define DEBUG */
 
 mapping variables=([]);
 string *functions=({});
@@ -169,6 +169,13 @@ void cut_buffer(int where)
 #endif
 }
 
+void print_version()
+{
+  write(version()+
+	" Running Hilfe v1.4 (Hubbe's Incremental LPC FrontEnd)\n");
+}
+
+
 int do_parse()
 {
   string tmp;
@@ -201,7 +208,7 @@ int do_parse()
 	case ".":
 	  clean_buffer();
 	  write("Input buffer flushed.\n");
-	  break;
+	  continue;
 
 	case "new":
 	  this_object()->__INIT();
@@ -216,6 +223,22 @@ int do_parse()
 		     m_values(variables));
 	  cut_buffer(4);
 	  continue;
+
+	case "help":
+	  print_version();
+	  write("Hilfe is a tool to evaluate uLPC interactively and incrementally.\n"
+		"Any uLPC function, expression or variable declaration can be intered\n"
+		"at the command line. There are also a few extra commands:\n"
+		" help       - show this text\n"
+		" quit       - exit this program\n"
+		" .          - abort current input batch\n"
+		" dump       - dump variables\n"
+		" new        - clear all function and variables\n"
+		"See the uLPC reference manual for more information.\n"
+		);
+	  cut_buffer(4);
+	  continue;
+	  
 	}
       }
     }
@@ -465,7 +488,7 @@ void stdin(string s)
   object foo;
 
 #ifdef DEBUG
-  write("input: "+code_value(s,1)+"\n");
+  write("input: '"+code_value(s,1)+"'\n");
 #endif
   s=skipwhite(s);
 
@@ -476,8 +499,7 @@ void stdin(string s)
     s=s[2..strlen(s)-1];
   }
   add_buffer(s);
-  if(!strlen(input))
-    write("> ");
+//  if(!strlen(input))  write("> ");
 }
 
 void my_write(mixed x)
@@ -485,27 +507,6 @@ void my_write(mixed x)
   write(sprintf("%O",x));
 }
 
-void read_input()
-{
-  string a,b;
-  object stdin_object;
-
-  stdin_object=clone((program)"/precompiled/file","stdin");
-  stdin_object->set_blocking();
-  while(stdin_object)
-  {
-    a=stdin_object->read(1);
-    if(!stringp(a)) continue;
-    stdin_object->set_nonblocking(0,0,0);
-    b=stdin_object->read(100000);
-    if(stringp(b)) a+=b;
-    stdin_object->set_blocking();
-    stdin(a);
-  }
-
-  write("Terminal closed.\n");
-}
-
 void signal_trap(int s)
 {
   clean_buffer();
@@ -514,14 +515,17 @@ void signal_trap(int s)
 
 void main(int argc,string *argv)
 {
+  string s;
   add_efun("write",my_write);
-  signal(signum("SIGINT"),signal_trap);
 
-  write(version()+
-	" Running Hilfe v1.3 (Hubbe's Incremental LPC FrontEnd)\n");
-  write("> ");
-
-  read_input();
+  print_version();
+  while(s=readline(strlen(input) ? ">> " : "> "))
+  {
+    signal(signum("SIGINT"),signal_trap);
+    stdin(s+"\n");
+    signal(signum("SIGINT"));
+  }
+  write("Terminal closed.\n");
   return 0;
 }
 
-- 
GitLab


From fb5afb143edf93f3d363b4d2664ca19783f8165d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 9 Jul 1996 00:07:53 +0200
Subject: [PATCH 272/351] entry added

Rev: src/ChangeLog:1.43
---
 src/ChangeLog | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 65f1c2c300..547c291635 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,6 +1,7 @@
 Mon Jul  8 23:52:48 1996  Fredrik Hubinette  <hubbe@axel.signum.se>
 
 	* uLPC v1.0E-6 released
+	* hilfe.lpc now uses readline (line editing! history!)
 	* bug in true/false values fixed
 	* readline module added
 
-- 
GitLab


From 9737fc3f21b100d3d3996806ec49ef4dca5564e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 15:07:09 +0200
Subject: [PATCH 273/351] Ignore more

Rev: .cvsignore:1.11
---
 .cvsignore | 2 ++
 .gitignore | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/.cvsignore b/.cvsignore
index 09d38ff56b..344e921aa3 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -1,3 +1,4 @@
+bottles.lpc
 build
 reports
 test
@@ -12,6 +13,7 @@ uLPC_v1.0E-7.tar.gz
 uLPC_v1.0E-8.tar.gz
 uLPC_v1.0E-9.tar.gz
 uLPC_v1.1E-12.tar.gz
+uLPC_v1.1E-6.tar.gz
 uLPC_v1.1E-7.tar.gz
 uLPC_v1.2E-7.tar.gz
 uLPC_v1.7E-12.tar.gz
diff --git a/.gitignore b/.gitignore
index 79433c60cb..15e0f5f3ac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,6 +30,7 @@ _$*
 *.elc
 *.ln
 core
+/bottles.lpc
 /build
 /reports
 /test
@@ -44,6 +45,7 @@ core
 /uLPC_v1.0E-8.tar.gz
 /uLPC_v1.0E-9.tar.gz
 /uLPC_v1.1E-12.tar.gz
+/uLPC_v1.1E-6.tar.gz
 /uLPC_v1.1E-7.tar.gz
 /uLPC_v1.2E-7.tar.gz
 /uLPC_v1.7E-12.tar.gz
-- 
GitLab


From ce56222fce7fdd60802d6efc34c3a78fa14b4490 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 15:07:45 +0200
Subject: [PATCH 274/351] New file: documens gauge

Rev: doc/lpc/gauge:1.1
---
 doc/lpc/gauge | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
 create mode 100644 doc/lpc/gauge

diff --git a/doc/lpc/gauge b/doc/lpc/gauge
new file mode 100644
index 0000000000..f352e3dda9
--- /dev/null
+++ b/doc/lpc/gauge
@@ -0,0 +1,15 @@
+NAME
+	gauge - measure system time
+
+SYNTAX
+	gauge { commands }
+	or
+	gauge ( expression )
+
+DESCRIPTION
+	Gauge measure how much cpu time is used to execute the commands
+	given as arguments. The number of milliseconds used is returned
+	as an integer.
+
+SEE ALSO
+	catch, builtin/rusage
-- 
GitLab


From 13217a77f4d91fb436815ec582e3b1d0a9bcd849 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 15:08:32 +0200
Subject: [PATCH 275/351] version updated

Rev: lib/simulate.lpc:1.20
---
 lib/simulate.lpc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index 41164609dd..d1cb9a33cd 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -365,7 +365,7 @@ void create()
   add_efun("sum_arrays",sum_arrays);
   add_efun("system",system);
   add_efun("this_function",this_function);
-  add_efun("version",lambda() { return "uLPC v1.0E-6"; });
+  add_efun("version",lambda() { return "uLPC v1.1E-6"; });
   add_efun("write_file",write_file);
 }
 
-- 
GitLab


From f3248cdc42abd8c8df185a4731bde7b51c217a66 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 15:13:14 +0200
Subject: [PATCH 276/351] Last module stuff removed

Rev: src/Makefile.src:1.9
---
 src/Makefile.src | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/src/Makefile.src b/src/Makefile.src
index aeab125fe3..52c94d91b7 100644
--- a/src/Makefile.src
+++ b/src/Makefile.src
@@ -101,8 +101,8 @@ OBJ= \
  rusage.o \
  stralloc.o \
  stuff.o \
- svalue.o \
- @EXTRA_OBJS@
+ svalue.o @EXTRA_OBJS@
+
 #
 # User callable targets
 #
@@ -117,17 +117,17 @@ ulpc: $(OBJ) modules/linker_options
 # purify
 pure: $(OBJ) module_objects
 	-mv ulpc ulpc.old
-	purify -free-queue-length=500 -inuse-at-exit=yes -chain-length=12 $(LD) $(LDFLAGS) $(OBJ) $(MODULE_OBJS) -o ulpc $(LIBS)
+	purify -free-queue-length=500 -inuse-at-exit=yes -chain-length=12 $(LD) $(LDFLAGS) $(OBJ) `cat modules/linker_options` $(LIBS) -o ulpc
 
 # purecov
 cover: $(OBJ) module_objects
 	-mv ulpc ulpc.old
-	purecov purify -free-queue-length=500 -inuse-at-exit=yes -chain-length=12 $(LD) $(LDFLAGS) $(OBJ) $(MODULE_OBJS) -o ulpc $(LIBS)
+	purecov purify -free-queue-length=500 -inuse-at-exit=yes -chain-length=12 $(LD) $(LDFLAGS) $(OBJ) `cat modules/linker_options` $(LIBS) -o ulpc
 
 # quantify
 quant: $(OBJ) module_objects
 	-mv ulpc ulpc.old
-	quantify $(LD) $(LDFLAGS) $(OBJ) $(MODULE_OBJS) -o ulpc $(LIBS) 
+	quantify $(LD) $(LDFLAGS) $(OBJ) `cat modules/linker_options` $(LIBS) -o ulpc
 
 # install
 install:
@@ -146,8 +146,7 @@ tidy:
 
 # make clean
 clean: tidy
-	-for a in $(MODULES) ; do ( cd $$a ; ${MAKE} $(MAKE_FLAGS) clean ) ; done
-	-for a in $(MODULES) ; do rm -f $$a/*.o ; done
+	-( cd modules; ${MAKE} $(MAKE_FLAGS) clean )
 	-rm -f TAGS tags
 	-rm -f yacc.acts yacc.debug yacc.tmp *.debug.log a.out
 
-- 
GitLab


From f63009ad118b6564b68ab47ba42e47d020d63845 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 15:20:28 +0200
Subject: [PATCH 277/351] bugfix for unsigned tv_sec

Rev: src/backend.c:1.7
---
 src/backend.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/src/backend.c b/src/backend.c
index 0dd97402ca..88cd20126c 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -191,11 +191,7 @@ void backend()
   while(first_object)
   {
     next_timeout.tv_usec = 0;
-#if 0
     next_timeout.tv_sec = 7 * 24 * 60 * 60;  /* See you in a week */
-#else
-    next_timeout.tv_sec = 15; /* See you in a week */
-#endif
     my_add_timeval(&next_timeout, &current_time);
 
     call_callback(& backend_callbacks, (void *)0);
@@ -207,10 +203,11 @@ void backend()
 #endif
 
     GETTIMEOFDAY(&current_time);
-    my_subtract_timeval(&next_timeout, &current_time);
 
-    if(next_timeout.tv_sec < 0)
+    if(my_timercmp(&next_timeout, > , &current_time))
     {
+      my_subtract_timeval(&next_timeout, &current_time);
+    }else{
       next_timeout.tv_usec = 0;
       next_timeout.tv_sec = 0;
     }
-- 
GitLab


From dda1a512be1b31ec63b0e811b4249ccd0611865a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 15:32:08 +0200
Subject: [PATCH 278/351] sizeof() moved to operators.c

Rev: src/builtin_efuns.c:1.22
Rev: src/builtin_efuns.h:1.3
---
 src/builtin_efuns.c | 49 +++------------------------------------------
 src/builtin_efuns.h |  1 -
 2 files changed, 3 insertions(+), 47 deletions(-)

diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index 1daa692e03..f8593a52c7 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -557,51 +557,6 @@ void f_allocate(INT32 args)
   push_array( allocate_array(size) );
 }
 
-void f_sizeof(INT32 args)
-{
-  INT32 tmp;
-  if(args<1)
-    error("Too few arguments to sizeof()\n");
-
-  pop_n_elems(args-1);
-  switch(sp[-1].type)
-  {
-  case T_STRING:
-    tmp=sp[-1].u.string->len;
-    free_string(sp[-1].u.string);
-    break;
-
-  case T_ARRAY:
-    tmp=sp[-1].u.array->size;
-    free_array(sp[-1].u.array);
-    break;
-
-  case T_MAPPING:
-    tmp=m_sizeof(sp[-1].u.mapping);
-    free_mapping(sp[-1].u.mapping);
-    break;
-
-  case T_LIST:
-    tmp=sp[-1].u.list->ind->size;
-    free_list(sp[-1].u.list);
-    break;
-
-  case T_OBJECT:
-    if(!sp[-1].u.object->prog)
-      error("sizeof() on destructed object.\n");
-    tmp=sp[-1].u.object->prog->num_identifier_indexes;
-    free_object(sp[-1].u.object);
-    break;
-
-  default:
-    error("Bad argument 1 to sizeof().\n");
-    return; /* make apcc happy */
-  }
-  sp[-1].type=T_INT;
-  sp[-1].subtype=NUMBER_NUMBER;
-  sp[-1].u.integer=tmp;
-}
-
 void f_rusage(INT32 args)
 {
   INT32 *rus,e;
@@ -1524,7 +1479,6 @@ void init_builtin_efuns()
   add_efun("rows",f_rows,"function(mixed,array:array)",0);
   add_efun("rusage", f_rusage, "function(:int *)",OPT_EXTERNAL_DEPEND);
   add_efun("search",f_search,"function(string,string,void|int:int)|function(array,mixed,void|int:int)|function(mapping,mixed:mixed)",0);
-  add_efun("sizeof", f_sizeof, "function(string|list|array|mapping|object:int)",0);
   add_efun("sleep", f_sleep, "function(float|int:void)",OPT_SIDE_EFFECT);
   add_efun("sort",f_sort,"function(array(mixed),array(mixed)...:array(mixed))",OPT_SIDE_EFFECT);
   add_efun("stringp", f_stringp, "function(mixed:int)",0);
@@ -1547,5 +1501,8 @@ void init_builtin_efuns()
 #ifdef GC2
   add_efun("gc",f_gc,"function(:int)",OPT_SIDE_EFFECT);
 #endif
+
+
+
 }
 
diff --git a/src/builtin_efuns.h b/src/builtin_efuns.h
index d5a2261e88..6f0b141d50 100644
--- a/src/builtin_efuns.h
+++ b/src/builtin_efuns.h
@@ -34,7 +34,6 @@ void f_function_name(INT32 args);
 void f_zero_type(INT32 args);
 void f_all_efuns(INT32 args);
 void f_allocate(INT32 args);
-void f_sizeof(INT32 args);
 void f_rusage(INT32 args);
 void f_this_object(INT32 args);
 void f_throw(INT32 args);
-- 
GitLab


From 52829c82341acd03ab90c229896a9aa71bae4e2b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 15:33:30 +0200
Subject: [PATCH 279/351] bugs fixed, commens added

Rev: src/callback.c:1.5
Rev: src/callback.h:1.5
---
 src/callback.c | 36 ++++++++++++++++++++++++++++++++----
 src/callback.h |  1 +
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/src/callback.c b/src/callback.c
index 80dac89550..2e4a78a684 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -6,6 +6,14 @@
 #include "macros.h"
 #include "callback.h"
 
+/*
+ * This file is used to simplify the management of callbacks when certain
+ * events occur. The callbacks are managed as linked lists, allocated in
+ * chunks.
+ */
+
+/* FIXME: free all chunks of memory at exit */
+
 struct callback
 {
   struct callback *next;
@@ -14,9 +22,6 @@ struct callback
   void *arg;
 };
 
-struct callback *first_callback =0;
-struct callback *free_callbacks =0;
-
 #define CALLBACK_CHUNK 128
 
 struct callback_block {
@@ -24,6 +29,11 @@ struct callback_block {
   struct callback callbacks[CALLBACK_CHUNK];
 };
 
+static struct callback_block *callback_chunks=0;
+static struct callback *first_callback =0;
+static struct callback *free_callbacks =0;
+
+/* Return the first free callback struct, allocate more if needed */
 static struct callback *get_free_callback()
 {
   struct callback *tmp;
@@ -32,6 +42,8 @@ static struct callback *get_free_callback()
     int e;
     struct callback_block *tmp2;
     tmp2=ALLOC_STRUCT(callback_block);
+    tmp2->next=callback_chunks;
+    callback_chunks=tmp2;
 
     for(e=0;e<(int)sizeof(CALLBACK_CHUNK);e++)
     {
@@ -43,6 +55,9 @@ static struct callback *get_free_callback()
   return tmp;
 }
 
+/* Traverse a linked list of callbacks and call all the active callbacks
+ * in the list. Deactivated callbacks are freed and placed in the free list.
+ */
 void call_callback(struct callback **ptr, void *arg)
 {
   struct callback *l;
@@ -61,6 +76,7 @@ void call_callback(struct callback **ptr, void *arg)
   }
 }
 
+/* Add a callback to the linked list pointed to by ptr. */
 struct callback *add_to_callback(struct callback **ptr,
 				 callback_func call,
 				 void *arg,
@@ -77,7 +93,8 @@ struct callback *add_to_callback(struct callback **ptr,
   return l;
 }
 
-/* It is not actually freed until next time this callback is called
+/* This function deactivates a callback.
+ * It is not actually freed until next time this callback is "called"
  */
 void *remove_callback(struct callback *l)
 {
@@ -85,6 +102,7 @@ void *remove_callback(struct callback *l)
   return l->arg;
 }
 
+/* Free all the callbacks in a linked list of callbacks */
 void free_callback(struct callback **ptr)
 {
   struct callback *l;
@@ -97,3 +115,13 @@ void free_callback(struct callback **ptr)
     free_callbacks=l;
   }
 }
+
+void cleanup_callbacks()
+{
+  while(callback_chunks)
+  {
+    struct callback_block *tmp=callback_chunks;
+    callback_chunks=tmp->next;
+    free((char *)tmp);
+  }
+}
diff --git a/src/callback.h b/src/callback.h
index 0836801e72..b582126e85 100644
--- a/src/callback.h
+++ b/src/callback.h
@@ -22,6 +22,7 @@ struct callback *add_to_callback(struct callback **ptr,
 				 callback_func free_func);
 void *remove_callback(struct callback *l);
 void free_callback(struct callback **ptr);
+void cleanup_callbacks();
 /* Prototypes end here */
 
 #endif
-- 
GitLab


From dcad55bb4f3ee3b0dbf5b5033daf37bf6ac99b5c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 15:35:17 +0200
Subject: [PATCH 280/351] added checks for mmap/munmap

Rev: src/configure.in:1.16
---
 src/configure.in | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/src/configure.in b/src/configure.in
index fda76b3a1e..a2a383c075 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -2,6 +2,8 @@ AC_INIT(interpret.c)
 AC_PROG_CC
 AC_C_CROSS
 
+#############################################################################
+
 # We need some special hacks when running slowaris
 AC_PATH_PROG(uname_prog,uname,no)
 AC_MSG_CHECKING(operating system)
@@ -32,6 +34,8 @@ dnl  LIBS="$LIBS -lthread"
 dnl fi
 dnl
 
+#############################################################################
+
 OLD_CFLAGS="$CFLAGS"
 OPTIMIZE="";
 
@@ -84,6 +88,8 @@ else
   fi
 fi
 
+#############################################################################
+
 AC_MSG_CHECKING(ansi prototype capability)
 AC_CACHE_VAL(lpc_cv_sys_ansi_prototypes,
 [
@@ -99,12 +105,16 @@ else
   exit 1
 fi
 
+#############################################################################
+
 AC_CONFIG_HEADER(machine.h)
 AC_PROG_INSTALL
 AC_PROG_CPP
 AC_PROG_RANLIB
 AC_SET_MAKE
 
+#############################################################################
+
 AC_MSG_CHECKING(for yacc clone that handles %pure_parser)
 AC_CACHE_VAL(lpc_cv_prog_working_yacc,
 [
@@ -183,6 +193,8 @@ lpc_cv_prog_working_yacc="$YACC"
 YACC="$lpc_cv_prog_working_yacc"
 AC_MSG_RESULT($YACC)
 
+#############################################################################
+
 AC_MSG_CHECKING(first yacc define)
 AC_CACHE_VAL(lpc_cv_yacc_first,
 [
@@ -210,11 +222,13 @@ AC_DEFINE_UNQUOTED(F_OFFSET,$lpc_cv_yacc_first)
 
 rm -rf conftest.y y.tab.c y.tab.h conftest.out
 
+#############################################################################
+
 AC_HEADER_TIME
 AC_HEADER_STDC
 AC_CHECK_HEADERS(sys/rusage.h time.h sys/time.h unistd.h stdlib.h memory.h \
 values.h string.h fcntl.h sys/filio.h sys/sockio.h crypt.h locale.h \
-sys/resource.h sys/select.h netdb.h)
+sys/resource.h sys/select.h sys/mman.h)
 
 AC_SIZEOF_TYPE(char *)
 AC_SIZEOF_TYPE(long)
@@ -229,7 +243,7 @@ AC_TYPE_UID_T
 AC_TYPE_SIGNAL
 AC_CHECK_TYPE(time_t,INT32)
 
-AC_CHECK_LIB(PW, alloca)
+dnl AC_CHECK_LIB(PW, alloca)
 
 dnl AC_CHECK_LIB(crypt, crypt)
 
@@ -252,6 +266,7 @@ fi
 LIBOBJS="${OLD_LIBOBJS}"
 
 AC_FUNC_STRCOLL
+AC_FUNC_MMAP
 
 AC_CHECK_FUNCS(
  _crypt \
@@ -265,6 +280,7 @@ AC_CHECK_FUNCS(
  getrusage \
  gettimeofday \
  index \
+ localtime \
  memchr \
  memcpy \
  memset \
@@ -286,11 +302,13 @@ AC_CHECK_FUNCS(
  wait3 \
  wait4 \
  waitpid \
- localtime \
+ munmap \
 )
 
 AC_STRUCT_TM
 
+#############################################################################
+
 AC_MSG_CHECKING(extern int timezone)
 
 AC_CACHE_VAL(lpc_cv_has_external_timezone,[
@@ -306,10 +324,14 @@ if test "$lpc_cv_has_external_timezone" = "yes"; then
   AC_DEFINE(HAVE_EXTERNAL_TIMEZONE)
 fi
 
+AC_MSG_RESULT($lpc_cv_has_external_timezone)
+
+#############################################################################
+
 # No test for this yet...
 AC_DEFINE(HAVE_STRUCT_TIMEVAL)
 
-AC_MSG_RESULT($lpc_cv_has_external_timezone)
+#############################################################################
 
 AC_MSG_CHECKING(if gettimeofday takes two arguments)
 AC_CACHE_VAL(lpc_cv_func_gettimeofday_has_two_args,
-- 
GitLab


From 9d615282f765d7eb1290450a93afbd5b5ea3f9b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 15:41:09 +0200
Subject: [PATCH 281/351] if bugfixed, for optimized

Rev: src/docode.c:1.6
---
 src/docode.c | 52 +++++++++++++++++++++++++---------------------------
 1 file changed, 25 insertions(+), 27 deletions(-)

diff --git a/src/docode.c b/src/docode.c
index a99b16402f..c7b606bb57 100644
--- a/src/docode.c
+++ b/src/docode.c
@@ -130,10 +130,6 @@ static int do_jump(int token,INT32 lbl)
 
 static int do_docode2(node *n,int flags);
 
-#define DO_LVALUE 1
-#define DO_NOT_COPY 2
-#define DO_POP 4
-
 #define ins_label(L) do_jump(F_LABEL, L)
 
 static void do_pop(int x)
@@ -266,6 +262,8 @@ static int do_docode2(node *n,int flags)
 
   case '?':
   {
+    int adroppings , bdroppings;
+
     if(!CDDR(n))
     {
       tmp1=do_jump_when_zero(CAR(n), -1);
@@ -282,28 +280,29 @@ static int do_docode2(node *n,int flags)
       return 0;
     }
 
-    tmp1=count_args(CDDR(n));
-    tmp2=count_args(CADR(n));
+    tmp1=do_jump_when_zero(CAR(n),-1);
 
-    if(tmp2 < tmp1) tmp1=tmp2;
+    adroppings=do_docode(CADR(n), flags);
+    tmp3=emit(F_POP_N_ELEMS,0);
 
-    if(tmp1 == -1)
-      fatal("Unknown number of args in ? :\n");
+    /* Else */
+    tmp2=do_jump(F_BRANCH,-1);
+    emit(F_LABEL, tmp1);
 
-    tmp2=do_jump_when_zero(CAR(n),-1);
+    bdroppings=do_docode(CDDR(n), flags);
+    if(adroppings < bdroppings)
+    {
+      do_pop(bdroppings - adroppings);
+    }
 
-    tmp3=do_docode(CADR(n), flags);
-    if(tmp3 < tmp1) fatal("Count arguments was wrong.\n");
-    do_pop(tmp3 - tmp1);
+    if(adroppings > bdroppings)
+    {
+      update_arg(tmp3,adroppings-bdroppings);
+      adroppings=bdroppings;
+    }
 
-    tmp3=do_jump(F_BRANCH,-1);
     emit(F_LABEL, tmp2);
-
-    tmp2=do_docode(CDDR(n), flags);
-    if(tmp2 < tmp1) fatal("Count arguments was wrong.\n");
-    do_pop(tmp2 - tmp1);
-    emit(F_LABEL, tmp3);
-    return tmp1;
+    return adroppings;
   }
       
   case F_AND_EQ:
@@ -499,14 +498,13 @@ static int do_docode2(node *n,int flags)
 
     if(CDR(n))
     {
-      tmp1=do_jump(F_BRANCH,-1);
+      do_jump_when_zero(CAR(n),current_break);
       tmp2=ins_label(-1);
-      if(CDR(n)) DO_CODE_BLOCK(CADR(n));
+      DO_CODE_BLOCK(CADR(n));
       ins_label(current_continue);
-      if(CDR(n)) DO_CODE_BLOCK(CDDR(n));
-      emit(F_LABEL,tmp1);
+      DO_CODE_BLOCK(CDDR(n));
     }else{
-      tmp2=PC;
+      tmp2=ins_label(-1);
     }
     do_jump_when_non_zero(CAR(n),tmp2);
     ins_label(current_break);
@@ -882,8 +880,8 @@ static int do_docode2(node *n,int flags)
     DO_CODE_BLOCK(CAR(n));
     ins_label(current_continue);
     ins_label(current_break);
-    emit2(F_DUMB_RETURN);
-    emit(F_LABEL,tmp1);
+    emit2(F_THROW_ZERO);
+    ins_label(tmp1);
 
     current_break=break_save;
     current_continue=continue_save;
-- 
GitLab


From b208c1c6735234238b6af89df4dafe39b5f83dd0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 15:45:56 +0200
Subject: [PATCH 282/351] --local and pop bugfixed, optimizations added

Rev: src/interpret.c:1.11
Rev: src/interpret.h:1.4
---
 src/interpret.c | 157 ++++++++++++++++++++++++++++++++++++++----------
 src/interpret.h |   7 ++-
 2 files changed, 128 insertions(+), 36 deletions(-)

diff --git a/src/interpret.c b/src/interpret.c
index 3e2f2a679a..5ded231dd9 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -24,29 +24,80 @@
 #include "builtin_efuns.h"
 #include "lpc_signal.h"
 
+#ifdef HAVE_MMAP
+
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#ifdef MMAP_NORESERV
+#define USE_MMAP_FOR_STACK
+
+/* Fixme: just multiplying by 32 is not what we want /Hubbe */
+#define EVALUATOR_STACK_SIZE EVALUATOR_STACK_SIZE*32
+#endif
+#endif
+
 #define TRACE_LEN (100 + t_flag * 10)
 
 
 /* sp points to first unused value on stack
  * (much simpler than letting it point at the last used value.)
  */
-struct svalue *sp;
+struct svalue *sp;     /* Current position */
+struct svalue *evaluator_stack; /* Start of stack */
 
 /* mark stack, used to store markers into the normal stack */
-struct svalue **mark_sp;
+struct svalue **mark_sp; /* Current position */
+struct svalue **mark_stack; /* Start of stack */
 
 struct frame *fp; /* frame pointer */
 
-struct svalue evaluator_stack[EVALUATOR_STACK_SIZE];
-struct svalue *mark_stack[EVALUATOR_STACK_SIZE];
-
 void init_interpreter()
 {
+#ifdef USE_MMAP_FOR_STACK
+  int fd;
+
+#ifndef MAP_VARIABLE
+#define MAP_VARIABLE 0
+#endif
+
+#ifndef MAP_PRIVATE
+#define MAP_PRIVATE 0
+#endif
+
+#ifdef MAP_ANONYMOUS
+  fd=-1;
+#else
+#define MAP_ANONYMOUS 0
+  fd=open("/dev/zero");
+  if(fd < 0) fatal("Failed to open /dev/zero.\n");
+#endif
+
+#define MMALLOC(X,Y) (Y *)mmap(0,X*sizeof(Y),PROT_READ|PROT_WRITE, MAP_NORESERV | MAP_PRIVATE | MAP_ANONYMOUS, fd, 0)
+
+  evaluator_stack=MMALLOC(EVALUATOR_STACK_SIZE,struct svalue);
+  mark_stack=MMALLOC(EVALUATOR_STACK_SIZE, struct svalue *);
+
+  if(fd != -1) close(fd);
+
+  if(!evaluator_stack || !mark_sp) fatal("Failed to mmap() stack space.\n");
+#else
+  evaluator_stack=(struct svalue *)malloc(EVALUATOR_STACK_SIZE*sizeof(struct svalue));
+  mark_stack=(struct svalue **)malloc(EVALUATOR_STACK_SIZE*sizeof(struct svalue *));
+#endif
   sp=evaluator_stack;
   mark_sp=mark_stack;
 }
 
-void exit_interpreter() {}
+void exit_interpreter()
+{
+}
 
 void check_stack(INT32 size)
 {
@@ -69,6 +120,7 @@ static void eval_instruction(unsigned char *pc);
  * array[index]   : { array, index } 
  * mapping[index] : { mapping, index } 
  * list[index] : { list, index } 
+ * object[index] : { object, index }
  * local variable : { svalue_pointer, nothing } 
  * global variable : { svalue_pointer/short_svalue_pointer, nothing } 
  */
@@ -309,25 +361,6 @@ void reset_evaluator()
   pop_n_elems(sp - evaluator_stack);
 }
 
-/* Put catch outside of eval_instruction, so
- * the setjmp won't affect the optimization of
- * eval_instruction
- */
-void f_catch(unsigned char *pc)
-{
-  JMP_BUF tmp;
-  if(SETJMP(tmp))
-  {
-    *sp=throw_value;
-    throw_value.type=T_INT;
-    sp++;
-  }else{
-    eval_instruction(pc);
-    push_int(0);
-  }
-  UNSETJMP(tmp);
-}
-
 #ifdef DEBUG
 #define BACKLOG 512
 struct backlog
@@ -370,6 +403,8 @@ void dump_backlog(void)
 
 #endif
 
+static int o_catch(unsigned char *pc);
+
 static void eval_instruction(unsigned char *pc)
 {
   unsigned INT32 instr, prefix=0;
@@ -386,14 +421,14 @@ static void eval_instruction(unsigned char *pc)
     sp[3].type=99;
 
     if(sp<evaluator_stack || mark_sp < mark_stack || fp->locals>sp)
-      fatal("Stack error.\n");
+      fatal("Stack error (generic).\n");
 
     if(sp > evaluator_stack+EVALUATOR_STACK_SIZE)
       fatal("Stack error (overflow).\n");
 
     if(fp->fun>=0 && fp->current_object->prog &&
 	fp->locals+fp->num_locals > sp)
-      fatal("Stack error.\n");
+      fatal("Stack error (stupid!).\n");
 
     if(d_flag)
     {
@@ -573,8 +608,8 @@ static void eval_instruction(unsigned char *pc)
       CASE(F_POST_DEC_LOCAL);
       instr=GET_ARG();
       if(fp->locals[instr].type != T_INT) error("Bad argument to --\n");
-      assign_svalue_no_free(sp--,fp->locals+instr);
-      fp->locals[instr].u.integer++;
+      assign_svalue_no_free(sp++,fp->locals+instr);
+      fp->locals[instr].u.integer--;
       break;
 
       CASE(F_DEC_LOCAL_AND_POP);
@@ -709,6 +744,7 @@ static void eval_instruction(unsigned char *pc)
       /* Stack machine stuff */
       CASE(F_POP_VALUE); pop_stack(); break;
       CASE(F_POP_N_ELEMS); pop_n_elems(GET_ARG()); break;
+      CASE(F_MARK2); *(mark_sp++)=sp;
       CASE(F_MARK); *(mark_sp++)=sp; break;
 
       /* Jumps */
@@ -769,8 +805,15 @@ static void eval_instruction(unsigned char *pc)
       break;
 
       CASE(F_CATCH);
-      f_catch(pc+sizeof(INT32));
-      pc+=EXTRACT_INT(pc);
+      if(o_catch(pc+sizeof(INT32)))
+	return; /* There was a return inside the evaluated code */
+      else
+	pc+=EXTRACT_INT(pc);
+      break;
+
+      CASE(F_THROW_ZERO);
+      push_int(0);
+      f_throw(1);
       break;
 
       CASE(F_SWITCH)
@@ -928,6 +971,16 @@ static void eval_instruction(unsigned char *pc)
       }
       break;
 
+      CASE(F_SIZEOF);
+      instr=lpc_sizeof(sp-1);
+      pop_stack();
+      push_int(instr);
+      break;
+
+      CASE(F_SIZEOF_LOCAL);
+      push_int(lpc_sizeof(fp->locals+GET_ARG()));
+      break;
+
       CASE(F_SSCANF); f_sscanf(GET_ARG()); break;
 
       CASE(F_CALL_LFUN);
@@ -936,6 +989,13 @@ static void eval_instruction(unsigned char *pc)
 		sp - *--mark_sp);
       break;
 
+      CASE(F_CALL_LFUN_AND_POP);
+      apply_low(fp->current_object,
+		GET_ARG()+fp->context.identifier_level,
+		sp - *--mark_sp);
+      pop_stack();
+      break;
+
     default:
       instr -= F_MAX_OPCODE - F_OFFSET;
 #ifdef DEBUG
@@ -950,6 +1010,28 @@ static void eval_instruction(unsigned char *pc)
   }
 }
 
+/* Put catch outside of eval_instruction, so
+ * the setjmp won't affect the optimization of
+ * eval_instruction
+ */
+static int o_catch(unsigned char *pc)
+{
+  JMP_BUF tmp;
+  if(SETJMP(tmp))
+  {
+    *sp=throw_value;
+    throw_value.type=T_INT;
+    sp++;
+    UNSETJMP(tmp);
+    return 0;
+  }else{
+    eval_instruction(pc);
+    UNSETJMP(tmp);
+    return 1;
+  }
+}
+
+
 int apply_low_safe_and_stupid(struct object *o, INT32 offset)
 {
   JMP_BUF tmp;
@@ -976,7 +1058,7 @@ int apply_low_safe_and_stupid(struct object *o, INT32 offset)
     eval_instruction(o->prog->program + offset);
 #ifdef DEBUG
     if(sp<evaluator_stack)
-      fatal("Stack error.\n");
+      fatal("Stack error (simple).\n");
 #endif
     ret=0;
   }
@@ -1135,7 +1217,7 @@ void apply_low(struct object *o, int fun, int args)
     eval_instruction(pc);
 #ifdef DEBUG
     if(sp<evaluator_stack)
-      fatal("Stack error.\n");
+      fatal("Stack error (also simple).\n");
 #endif
   }
 
@@ -1441,4 +1523,13 @@ void cleanup_interpret()
   }
 #endif
   reset_evaluator();
+
+#ifdef USE_MMAP_FOR_STACK
+  munmap((char *)evaluator_stack, EVALUATOR_STACK_SIZE*sizeof(struct svalue));
+  munmap((char *)mark_stack, EVALUATOR_STACK_SIZE*sizeof(struct svalue *));
+#else
+  free((char *)evaluator_stack);
+  free((char *)mark_stack);
+#endif
+
 }
diff --git a/src/interpret.h b/src/interpret.h
index 754fdf5cad..ed2bf26332 100644
--- a/src/interpret.h
+++ b/src/interpret.h
@@ -41,6 +41,7 @@ struct frame
 #define push_object(O) sp->u.object=(O),sp++->type=T_OBJECT
 #define push_float(F) sp->u.float_number=(F),sp++->type=T_FLOAT
 #define push_text(T) sp->u.string=make_shared_string(T),sp++->type=T_STRING
+#define push_svalue(S) (assign_svalue_no_free(sp,(S)),sp++)
 
 #define APPLY_MASTER(FUN,ARGS) \
 do{ \
@@ -77,13 +78,13 @@ union anything *get_pointer_if_this_type(struct svalue *lval, TYPE_T t);
 void print_return_value();
 void pop_n_elems(INT32 x);
 void reset_evaluator();
-void f_catch(unsigned char *pc);
 struct backlog;
 void dump_backlog(void);
 int apply_low_safe_and_stupid(struct object *o, INT32 offset);
 void apply_low(struct object *o, int fun, int args);
 void safe_apply_low(struct object *o,int fun,int args);
 void safe_apply(struct object *o, char *fun ,INT32 args);
+void apply_lfun(struct object *o, int fun, int args);
 void apply_shared(struct object *o,
 		  struct lpc_string *fun,
 		  int args);
@@ -96,8 +97,8 @@ void cleanup_interpret();
 
 extern struct svalue *sp;
 extern struct svalue **mark_sp;
-extern struct svalue evaluator_stack[EVALUATOR_STACK_SIZE];
-extern struct svalue *mark_stack[EVALUATOR_STACK_SIZE];
+extern struct svalue *evaluator_stack;
+extern struct svalue **mark_stack;
 extern struct frame *fp; /* frame pointer */
 #endif
 
-- 
GitLab


From 52c2629cd3f12c2885bf7b6e6a66cbea04bbc276 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 15:46:57 +0200
Subject: [PATCH 283/351] gauge can now take a block of code as argument

Rev: src/language.y:1.14
---
 src/language.y | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/language.y b/src/language.y
index 4a6a39f6a7..a63046b446 100644
--- a/src/language.y
+++ b/src/language.y
@@ -12,7 +12,8 @@
 %token F_ADD_256 F_ADD_512 F_ADD_768 F_ADD_1024 F_ADD_256X
 %token F_PREFIX_256 F_PREFIX_512 F_PREFIX_768 F_PREFIX_1024
 %token F_PREFIX_CHARX256 F_PREFIX_WORDX256 F_PREFIX_24BITX256
-%token F_POP_VALUE F_POP_N_ELEMS F_MARK F_CALL_LFUN
+%token F_POP_VALUE F_POP_N_ELEMS F_MARK F_MARK2
+%token F_CALL_LFUN F_CALL_LFUN_AND_POP
 
 %token F_BRANCH F_BRANCH_WHEN_ZERO F_BRANCH_WHEN_NON_ZERO
 %token F_BRANCH_WHEN_LT F_BRANCH_WHEN_GT
@@ -34,7 +35,6 @@
 %token F_CLEAR_LOCAL
 %token F_CONSTANT F_FLOAT F_STRING
 %token F_NUMBER F_NEG_NUMBER F_CONST_1 F_CONST0 F_CONST1 F_BIGNUM
-
 /*
  * These are the predefined functions that can be accessed from LPC.
  */
@@ -42,7 +42,7 @@
 %token F_INC F_DEC F_POST_INC F_POST_DEC F_INC_AND_POP F_DEC_AND_POP
 %token F_INC_LOCAL F_INC_LOCAL_AND_POP F_POST_INC_LOCAL
 %token F_DEC_LOCAL F_DEC_LOCAL_AND_POP F_POST_DEC_LOCAL
-%token F_RETURN F_DUMB_RETURN F_RETURN_0
+%token F_RETURN F_DUMB_RETURN F_RETURN_0 F_THROW_ZERO
 
 %token F_ASSIGN F_ASSIGN_AND_POP
 %token F_ASSIGN_LOCAL F_ASSIGN_LOCAL_AND_POP
@@ -60,6 +60,8 @@
 %token F_CAST
 %token F_FOREACH
 
+%token F_SIZEOF F_SIZEOF_LOCAL
+
 /*
  * These are token values that needn't have an associated code for the
  * compiled file
@@ -1038,13 +1040,13 @@ comma_expr_or_maxint: /* empty */ { $$=mkintnode(0x7fffffff); }
                     | comma_expr
                     ;
 
-gauge: F_GAUGE '(' unused ')'
+gauge: F_GAUGE catch_arg
   {
     $$=mkopernode("`-",
 		  mkopernode("`-",
 			     mknode(F_INDEX,mkefuncallnode("rusage",0),
 				    mkintnode(GAUGE_RUSAGE_INDEX)),
-			     mknode(F_ARG_LIST,$3,
+			     mknode(F_ARG_LIST,$2,
 				    mknode(F_INDEX,mkefuncallnode("rusage",0),
 					   mkintnode(GAUGE_RUSAGE_INDEX)))),0);
   } ;
-- 
GitLab


From 06abc058f593272ea618e761bb5bd55cc635e78e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:00:19 +0200
Subject: [PATCH 284/351] names for opcodes added, more operaors names added

Rev: src/lex.c:1.12
---
 src/lex.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/src/lex.c b/src/lex.c
index eec617631d..cb68bde713 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -195,12 +195,14 @@ struct keyword instr_names[]=
 { "indirect",		F_INDIRECT },
 { "jump",               F_BRANCH },
 { "local function call",F_CALL_LFUN },
+{ "local function call and pop",F_CALL_LFUN_AND_POP },
 { "local function",	F_LFUN },	
 { "local",		F_LOCAL },	
 { "ltosval2",		F_LTOSVAL2 },
 { "lvalue to svalue",	F_LTOSVAL },	
 { "lvalue_list",	F_LVALUE_LIST },	
 { "mark",               F_MARK },
+{ "mark mark",          F_MARK2 },
 { "negative number",	F_NEG_NUMBER },
 { "number",             F_NUMBER },
 { "pop",		F_POP_VALUE },	
@@ -241,6 +243,9 @@ struct keyword instr_names[]=
 { "branch if >=",	F_BRANCH_WHEN_GE },
 { "branch if ==",	F_BRANCH_WHEN_EQ },
 { "branch if !=",	F_BRANCH_WHEN_NE },
+{ "sizeof",		F_SIZEOF },
+{ "sizeof local",	F_SIZEOF_LOCAL },
+{ "throw(0)",		F_THROW_ZERO },
 };
 
 struct instr instrs[F_MAX_INSTR - F_OFFSET];
@@ -1540,6 +1545,13 @@ static int do_lex2(int literal, YYSTYPE *yylval)
       case '|': tmp="`|"; break;
       case '^': tmp="`^"; break;
       case '~': tmp="`~"; break;
+      case '[':
+	if(GOBBLE(']'))
+	{
+	  tmp="`[]";
+	  if(GOBBLE('=')) tmp="`[]=";
+	  break;
+	}
 
       default:
 	yyerror("Illegal ` identifier.");
-- 
GitLab


From 626301746db2874055d33d4e57aefb1cb3ac5fce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:00:48 +0200
Subject: [PATCH 285/351] l_sizeof added

Rev: src/list.h:1.3
---
 src/list.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/list.h b/src/list.h
index e072f0af66..fe51e27181 100644
--- a/src/list.h
+++ b/src/list.h
@@ -17,6 +17,8 @@ struct list
 
 #define free_list(L) do{ struct list *l_=(L); if(!--l_->refs) really_free_list(l_); }while(0)
 
+#define l_sizeof(L) ((L)->ind->size)
+
 /* Prototypes begin here */
 int list_member(struct list *l, struct svalue *ind);
 void really_free_list(struct list *l);
-- 
GitLab


From 370426a1f6198e6198a957e0080fbb2b4b19b201 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:01:42 +0200
Subject: [PATCH 286/351] mmap defines added, and some bugs fixed

Rev: src/machine.h.in:1.11
---
 src/machine.h.in | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/machine.h.in b/src/machine.h.in
index a971262b54..164149bb7b 100644
--- a/src/machine.h.in
+++ b/src/machine.h.in
@@ -22,6 +22,9 @@
 /* Define if you have the <memory.h> header file.  */
 #undef HAVE_MEMORY_H
 
+/* Define if you have the <sys/mman.h> header file.  */
+#undef HAVE_SYS_MMAN_H
+
 /* Define if you have the <crypt.h> header file.  */
 #undef HAVE_CRYPT_H
 
@@ -52,9 +55,6 @@
 /* Define if you have the <unistd.h> header file.  */
 #undef HAVE_UNISTD_H
 
-/* Define if you have the <netdb.h> header file.  */
-#undef HAVE_NETDB_H
-
 /* more header files */
 #undef HAVE_FCNTL_H
 #undef HAVE_SYS_FILIO_H
@@ -190,6 +190,12 @@
 /* Define if you have memset.  */
 #undef HAVE_MEMSET
 
+/* Define if you have mmap() */
+#undef HAVE_MMAP
+
+/* Define if you have munmap() */
+#undef HAVE_MUNMAP
+
 /* Define if you have strcspn.  */
 #undef HAVE_STRCSPN
 
-- 
GitLab


From 6fb22acf76858e95c764df85eaf8376fd28e01a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:02:07 +0200
Subject: [PATCH 287/351] nothing much changed

Rev: src/main.c:1.9
---
 src/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main.c b/src/main.c
index 46c3a9608f..3e594598d5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -230,6 +230,6 @@ void exit_main()
   cleanup_lpc_types();
   cleanup_shared_string_table();
   cleanup_program();
-  exit_interpreter();
+  cleanup_callbacks();
 }
 
-- 
GitLab


From cde51b8dc1400f504995ee87ad8c78caa7e54432 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:03:19 +0200
Subject: [PATCH 288/351] Started working on index overloading..

Rev: src/object.c:1.11
Rev: src/object.h:1.7
---
 src/object.c | 127 ++++++++++++++++++++++++++-------------------------
 src/object.h |  16 +++----
 2 files changed, 70 insertions(+), 73 deletions(-)

diff --git a/src/object.c b/src/object.c
index 87e73b7289..76e51043f5 100644
--- a/src/object.c
+++ b/src/object.c
@@ -246,57 +246,10 @@ void really_free_object(struct object *o)
   GC_FREE();
 }
 
-void object_index_no_free(struct svalue *to,
-			  struct object *o,
-			  struct svalue *index)
-{
-  struct program *p;
-  int f;
-
-  if(!o || !(p=o->prog))
-  {
-    error("Lookup in destructed object.\n");
-    return; /* make gcc happy */
-  }
-
-  if(index->type != T_STRING)
-    error("Lookup on non-string value.\n");
-
-  f=find_shared_string_identifier(index->u.string, p);
-  if(f < 0)
-  {
-    to->type=T_INT;
-    to->subtype=NUMBER_UNDEFINED;
-    to->u.integer=0;
-  }else{
-    struct identifier *i;
-    i=ID_FROM_INT(p, f);
-
-    if(i->flags & IDENTIFIER_FUNCTION)
-    {
-      to->type=T_FUNCTION;
-      to->subtype=f;
-      to->u.object=o;
-      o->refs++;
-    }
-    else if(i->run_time_type == T_MIXED)
-    {
-      struct svalue *s;
-      s=(struct svalue *)LOW_GET_GLOBAL(o,f,i);
-      check_destructed(s);
-      assign_svalue_no_free(to,s);
-    }
-    else
-    {
-      union anything *u;
-      u=(union anything *)LOW_GET_GLOBAL(o,f,i);
-      check_short_destructed(u,i->run_time_type);
-      assign_from_short_svalue_no_free(to,u,i->run_time_type);
-    }
-  }
-}
 
-static void low_object_index(struct svalue *to,struct object *o, INT32 f)
+static void low_object_index_no_free(struct svalue *to,
+				     struct object *o,
+				     INT32 f)
 {
   struct identifier *i;
   struct program *p=o->prog;
@@ -326,9 +279,9 @@ static void low_object_index(struct svalue *to,struct object *o, INT32 f)
   }
 }
 
-void object_index(struct svalue *to,
-		  struct object *o,
-		  struct svalue *index)
+void object_index_no_free(struct svalue *to,
+			  struct object *o,
+			  struct svalue *index)
 {
   struct program *p;
   int f;
@@ -345,19 +298,42 @@ void object_index(struct svalue *to,
   f=find_shared_string_identifier(index->u.string, p);
   if(f < 0)
   {
-    free_svalue(to);
     to->type=T_INT;
     to->subtype=NUMBER_UNDEFINED;
     to->u.integer=0;
   }else{
-    free_svalue(to);
-    low_object_index(to, o, f);
+    low_object_index_no_free(to, o, f);
+  }
+}
+
+
+void object_index_no_free2(struct svalue *to,
+			   struct object *o,
+			   struct svalue *index)
+{
+  struct program *p;
+
+  if(!o || !(p=o->prog))
+  {
+    error("Lookup in destructed object.\n");
+    return; /* make gcc happy */
+  }
+
+  if(p->lfuns[LFUN_INDEX] != -1)
+  {
+    push_svalue(index);
+    apply_lfun(o,LFUN_INDEX,1);
+    to=sp;
+    sp--;
+  } else {
+    object_index_no_free(to,o,index);
   }
 }
 
-void object_low_set_index(struct object *o,
-			  int f,
-			  struct svalue *from)
+
+static void object_low_set_index(struct object *o,
+				 int f,
+				 struct svalue *from)
 {
   struct identifier *i;
   struct program *p;
@@ -414,10 +390,32 @@ void object_set_index(struct object *o,
   }
 }
 
+void object_set_index2(struct object *o,
+		       struct svalue *index,
+		       struct svalue *from)
+{
+  struct program *p;
+
+  if(!o || !(p=o->prog))
+  {
+    error("Lookup in destructed object.\n");
+    return; /* make gcc happy */
+  }
+
+  if(p->lfuns[LFUN_ASSIGN_INDEX] != -1)
+  {
+    push_svalue(index);
+    push_svalue(from);
+    apply_lfun(o,LFUN_ASSIGN_INDEX,2);
+    pop_stack();
+  } else {
+    object_set_index(o,index,from);
+  }
+}
 
-union anything *object_low_get_item_ptr(struct object *o,
-					int f,
-					TYPE_T type)
+static union anything *object_low_get_item_ptr(struct object *o,
+					       int f,
+					       TYPE_T type)
 {
   struct identifier *i;
   struct program *p;
@@ -465,6 +463,9 @@ union anything *object_get_item_ptr(struct object *o,
   if(index->type != T_STRING)
     error("Lookup on non-string value.\n");
 
+  if(p->lfuns[LFUN_ASSIGN_INDEX] != -1)
+    error("Cannot do incremental operations on overloaded index (yet).\n");
+
   f=find_shared_string_identifier(index->u.string, p);
   if(f < 0)
   {
@@ -643,7 +644,7 @@ struct array *object_values(struct object *o)
   a=allocate_array_no_init(p->num_identifier_indexes,0);
   for(e=0;e<(int)p->num_identifier_indexes;e++)
   {
-    low_object_index(ITEM(a)+e, o, p->identifier_index[e]);
+    low_object_index_no_free(ITEM(a)+e, o, p->identifier_index[e]);
   }
   return a;
 }
diff --git a/src/object.h b/src/object.h
index 5b8d728373..cb4322b135 100644
--- a/src/object.h
+++ b/src/object.h
@@ -41,18 +41,15 @@ void really_free_object(struct object *o);
 void object_index_no_free(struct svalue *to,
 			  struct object *o,
 			  struct svalue *index);
-void object_index(struct svalue *to,
-		  struct object *o,
-		  struct svalue *index);
-void object_low_set_index(struct object *o,
-			  int f,
-			  struct svalue *from);
+void object_index_no_free2(struct svalue *to,
+			   struct object *o,
+			   struct svalue *index);
 void object_set_index(struct object *o,
 		      struct svalue *index,
 		      struct svalue *from);
-union anything *object_low_get_item_ptr(struct object *o,
-					int f,
-					TYPE_T type);
+void object_set_index2(struct object *o,
+		       struct svalue *index,
+		       struct svalue *from);
 union anything *object_get_item_ptr(struct object *o,
 				    struct svalue *index,
 				    TYPE_T type);
@@ -61,7 +58,6 @@ int object_equal_p(struct object *a, struct object *b, struct processing *p);
 void cleanup_objects();
 struct array *object_indices(struct object *o);
 struct array *object_values(struct object *o);
-void gc_check_object(struct object *o);
 void gc_mark_object_as_referenced(struct object *o);
 void gc_check_all_objects();
 void gc_mark_all_objects();
-- 
GitLab


From 4c573c8d697c103d95402b99943ac67d08fc6d47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:03:48 +0200
Subject: [PATCH 289/351] sizeof moved and optimized

Rev: src/operators.c:1.10
---
 src/operators.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/src/operators.c b/src/operators.c
index ecbe77f120..ee1d097ba4 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -312,7 +312,8 @@ static int generate_comparison(node *n)
 {
   if(count_args(CDR(n))==2)
   {
-    do_docode(CDR(n),DO_NOT_COPY);
+    if(do_docode(CDR(n),DO_NOT_COPY) != 2)
+      fatal("Count args was wrong in generate_comparison.\n");
 
     if(CAR(n)->u.sval.u.efun->function == f_eq)
       emit2(F_EQ);
@@ -1128,6 +1129,28 @@ void o_range()
   }
 }
 
+void f_sizeof(INT32 args)
+{
+  INT32 tmp;
+  if(args<1)
+    error("Too few arguments to sizeof()\n");
+
+  tmp=lpc_sizeof(sp-args);
+
+  pop_n_elems(args);
+  push_int(tmp);
+}
+
+static int generate_sizeof(node *n)
+{
+  node **arg;
+  if(count_args(CDR(n)) != 1) return 0;
+  if(do_docode(CDR(n),DO_NOT_COPY) != 1)
+    fatal("Count args was wrong in sizeof().\n");
+  emit2(F_SIZEOF);
+  return 1;
+}
+
 void init_operators()
 {
   add_efun2("`==",f_eq,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
@@ -1165,4 +1188,5 @@ void init_operators()
   add_efun2("`%",f_mod,"function(object,mixed:mixed)|function(int,int:int)|!function(int,int:mixed)&function(int|float,int|float:float)",OPT_TRY_OPTIMIZE,0,generate_mod);
 
   add_efun2("`~",f_compl,"function(object:mixed)|function(int:int)|function(float:float)",OPT_TRY_OPTIMIZE,0,generate_compl);
+  add_efun2("sizeof", f_sizeof, "function(string|list|array|mapping|object:int)",0,0,generate_sizeof);
 }
-- 
GitLab


From 4e7b1731bda52cbb531f9831ad2f5e101cb88cd7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:04:07 +0200
Subject: [PATCH 290/351] new opcodes added

Rev: src/peep.c:1.3
---
 src/peep.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/peep.c b/src/peep.c
index a066b94d94..45fe7ef002 100644
--- a/src/peep.c
+++ b/src/peep.c
@@ -29,9 +29,12 @@ static int hasarg(int opcode)
   case F_NUMBER:
   case F_NEG_NUMBER:
   case F_CALL_LFUN:
+  case F_CALL_LFUN_AND_POP:
   case F_SSCANF:
   case F_POP_N_ELEMS:
 
+  case F_SIZEOF_LOCAL:
+
   case F_ASSIGN_GLOBAL:
   case F_ASSIGN_GLOBAL_AND_POP:
   case F_ASSIGN_LOCAL:
-- 
GitLab


From c67d3411cc406b2c98b0f599f618b6f325b222f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:04:33 +0200
Subject: [PATCH 291/351] lots of small optimizations added

Rev: src/peep.in:1.3
---
 src/peep.in | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/src/peep.in b/src/peep.in
index 838c5cd822..41b3ecc6ad 100644
--- a/src/peep.in
+++ b/src/peep.in
@@ -5,8 +5,11 @@ POP_VALUE POP_N_ELEMS : POP_N_ELEMS ($2a + 1)
 POP_N_ELEMS POP_N_ELEMS : POP_N_ELEMS ($1a + $2a)
 POP_N_ELEMS(1) : POP_VALUE
 
+MARK MARK: MARK2
+
 ASSIGN_GLOBAL POP_VALUE : ASSIGN_GLOBAL_AND_POP($1a)
 ASSIGN_LOCAL  POP_VALUE : ASSIGN_LOCAL_AND_POP($1a)
+CALL_LFUN POP_VALUE : CALL_LFUN_AND_POP($1a)
 NUMBER(0) : CONST0
 NUMBER(1) : CONST1
 NUMBER(-1) : CONST_1
@@ -59,6 +62,15 @@ LOCAL_LVALUE DEC_AND_POP : DEC_LOCAL_AND_POP ($1a)
 DEC_LOCAL POP_VALUE : DEC_LOCAL_AND_POP ($1a)
 POST_DEC_LOCAL POP_VALUE : DEC_LOCAL_AND_POP ($1a)
 
+ASSIGN_LOCAL_AND_POP LOCAL ($1a) : ASSIGN_LOCAL ($1a)
+ASSIGN_LOCAL_AND_POP LOCAL ($1a) RETURN : RETURN
+ASSIGN_GLOBAL_AND_POP GLOBAL ($1a) : ASSIGN_GLOBAL ($1a)
+DEC_LOCAL_AND_POP LOCAL ($1a) : DEC_LOCAL ($1a)
+INC_LOCAL_AND_POP LOCAL ($1a) : INC_LOCAL ($1a)
+
+GLOBAL_LVALUE INC_AND_POP GLOBAL($1a): GLOBAL_LVALUE($1a) INC
+GLOBAL_LVALUE DEC_AND_POP GLOBAL($1a): GLOBAL_LVALUE($1a) DEC
+
 CONST1 BRANCH_WHEN_ZERO:
 CONST0 BRANCH_WHEN_ZERO: BRANCH($2a)
 CONST1 BRANCH_WHEN_NON_ZERO: BRANCH($2a)
@@ -84,3 +96,6 @@ LT NOT: GE
 GT NOT: LE
 LE NOT: GT
 GE NOT: LT
+
+LOCAL SIZEOF: SIZEOF_LOCAL ($1a)
+
-- 
GitLab


From 774b06b4a6a6b09ee23393ace28842e12a947d31 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:05:10 +0200
Subject: [PATCH 292/351] index operator lfuns added

Rev: src/program.c:1.13
Rev: src/program.h:1.7
---
 src/program.c | 2 ++
 src/program.h | 4 +++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/program.c b/src/program.c
index a9bc0621b6..e89f1b9aba 100644
--- a/src/program.c
+++ b/src/program.c
@@ -59,6 +59,8 @@ char *lfun_names[] = {
   "__hash",
   "cast",
   "`!",
+  "`[]",
+  "`[]=",
 };
 
 struct program *first_program = 0;
diff --git a/src/program.h b/src/program.h
index 6c3935b166..cdcaa87628 100644
--- a/src/program.h
+++ b/src/program.h
@@ -31,8 +31,10 @@
 #define LFUN___HASH 17
 #define LFUN_CAST 18
 #define LFUN_NOT 19
+#define LFUN_INDEX 20
+#define LFUN_ASSIGN_INDEX 21
 
-#define NUM_LFUNS 20
+#define NUM_LFUNS 22
 
 extern char *lfun_names[];
 
-- 
GitLab


From bcf2a365733b09becacbf6e00b419dfd57c09a1e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:07:11 +0200
Subject: [PATCH 293/351] small bugfix

Rev: src/rusage.c:1.6
---
 src/rusage.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/rusage.c b/src/rusage.c
index 15ce18bab1..ec7fa32b8d 100644
--- a/src/rusage.c
+++ b/src/rusage.c
@@ -157,7 +157,6 @@ INT32 *low_rusage()
 #else /*HAVE_TIMES */
 #if defined(HAVE_CLOCK) && defined(CLOCKS_PER_SECOND)
 
-
 #define NEED_CONVERT_TIME
 static long convert_time(long t,long tick);
 INT32 *low_rusage()
@@ -170,7 +169,10 @@ INT32 *low_rusage()
 
 INT32 *low_rusage()
 {
-  rusage_values[0]=get_current_time()*1000; /* Wrong, but who cares */
+  /* This is totally wrong, but hey, if you can't do it _right_... */
+  struct timeval tm;
+  GETTIMEOFDAY(&tm);
+  rusage_values[0]=tm.tv_sec*1000 + tm.tv_usec/1000;
   return rusage_values;
 }
 #endif /* HAVE_CLOCK */
-- 
GitLab


From 94767643cc4d8df2b40603234b262096a78ec9b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:08:11 +0200
Subject: [PATCH 294/351] lpc_sizeof added, and hashfunction changed

Rev: src/svalue.c:1.14
---
 src/svalue.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/src/svalue.c b/src/svalue.c
index b8f64bd25c..33779ef0b4 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -362,7 +362,7 @@ unsigned INT32 hash_svalue(struct svalue *s)
 
   default:      q=(unsigned INT32)s->u.refs >> 2;
   case T_INT:   q=s->u.integer; break;
-  case T_FLOAT: q=(unsigned INT32)(s->u.float_number * 16843009.0); break;
+  case T_FLOAT: q=(unsigned INT32)(s->u.float_number * 16843009.731757771173); break;
   }
   q+=q % 997;
   q+=((q + s->type) * 9248339);
@@ -936,3 +936,21 @@ void gc_mark_short_svalue(union anything *u, TYPE_T type)
   }
 }
 #endif /* GC2 */
+
+INT32 lpc_sizeof(struct svalue *s)
+{
+  switch(s->type)
+  {
+  case T_STRING: return s->u.string->len;
+  case T_ARRAY: return s->u.array->size;
+  case T_MAPPING: return m_sizeof(s->u.mapping);
+  case T_LIST: return l_sizeof(s->u.list);
+  case T_OBJECT:
+    if(!s->u.object->prog)
+      error("sizeof() on destructed object.\n");
+    return s->u.object->prog->num_identifier_indexes;
+  default:
+    error("Bad argument 1 to sizeof().\n");
+    return 0; /* make apcc happy */
+  }
+}
-- 
GitLab


From 3a58222cc6579d94c5c8b8714dea54934c8be6a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:08:20 +0200
Subject: [PATCH 295/351] lpc_sizeof added

Rev: src/svalue.h:1.10
---
 src/svalue.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/svalue.h b/src/svalue.h
index 4426fcc3eb..397ae0dfda 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -186,6 +186,7 @@ TYPE_FIELD gc_check_svalues(struct svalue *s, int num);
 void gc_check_short_svalue(union anything *u, TYPE_T type);
 void gc_mark_svalues(struct svalue *s, int num);
 void gc_mark_short_svalue(union anything *u, TYPE_T type);
+INT32 lpc_sizeof(struct svalue *s);
 /* Prototypes end here */
 
 #endif
-- 
GitLab


From f8aa09a87e5e6d0f3a16286cf7c36f178a7d7552 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:12:26 +0200
Subject: [PATCH 296/351] backend callback now removed when not needed

Rev: src/modules/call_out/call_out.c:1.3
---
 src/modules/call_out/call_out.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/src/modules/call_out/call_out.c b/src/modules/call_out/call_out.c
index 64f7cca89a..6e2a6e7ca9 100644
--- a/src/modules/call_out/call_out.c
+++ b/src/modules/call_out/call_out.c
@@ -164,6 +164,9 @@ static int new_call_out(int num_arg,struct svalue *argp)
   return 1;
 }
 
+static struct callback *call_out_backend_callback=0;
+void do_call_outs(struct callback *ignored, void *ignored_too, void *arg);
+
 void f_call_out(INT32 args)
 {
   struct svalue tmp;
@@ -179,6 +182,12 @@ void f_call_out(INT32 args)
   sp[1-args]=tmp;
 
   new_call_out(args,sp-args);
+
+  /* We do not add this callback until we actually have
+   * call outs to take care of.
+   */
+  if(!call_out_backend_callback)
+    call_out_backend_callback=add_backend_callback(do_call_outs,0,0);
 }
 
 void do_call_outs(struct callback *ignored, void *ignored_too, void *arg)
@@ -225,6 +234,15 @@ void do_call_outs(struct callback *ignored, void *ignored_too, void *arg)
       {
 	next_timeout = pending_calls[0]->tv;
       }
+    }else{
+      if(call_out_backend_callback)
+      {
+	/* There are no call outs queued, let's remove
+	 * the taxing backend callback...
+	 */
+	remove_callback(call_out_backend_callback);
+	call_out_backend_callback=0;
+      }
     }
   }
 }
@@ -352,8 +370,6 @@ void verify_all_call_outs()
 
 void init_call_out_efuns(void)
 {
-  add_backend_callback(do_call_outs,0,0);
-
   add_efun("call_out",f_call_out,"function(function,float|int,mixed...:void)",OPT_SIDE_EFFECT);
   add_efun("call_out_info",f_call_out_info,"function(:array*)",OPT_EXTERNAL_DEPEND);
   add_efun("find_call_out",f_find_call_out,"function(function:int)",OPT_EXTERNAL_DEPEND);
-- 
GitLab


From 85ef2af0c57f6e7535c1114cbb0d60516c63d61c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:12:52 +0200
Subject: [PATCH 297/351] netdb stuff moved to this configure file

Rev: src/modules/files/configure.in:1.9
---
 src/modules/files/configure.in | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/modules/files/configure.in b/src/modules/files/configure.in
index e0abbca31b..1406ce315e 100644
--- a/src/modules/files/configure.in
+++ b/src/modules/files/configure.in
@@ -6,7 +6,7 @@ AC_PROG_RANLIB
 AC_SUBST(RANLIB)
 
 AC_HAVE_HEADERS(arpa/inet.h sys/socketvar.h netinet/in.h \
- sys/stream.h sys/protosw.h)
+ sys/stream.h sys/protosw.h netdb.h)
 AC_HEADER_DIRENT
 AC_CHECK_LIB(socket, socket)
 AC_CHECK_LIB(nsl, gethostbyname)
-- 
GitLab


From ab47a34a17ef23d0403e30433f2016a3c60caa02 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:13:05 +0200
Subject: [PATCH 298/351] netdb stuff addedd

Rev: src/modules/files/file_machine.h.in:1.5
---
 src/modules/files/file_machine.h.in | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/modules/files/file_machine.h.in b/src/modules/files/file_machine.h.in
index 9b3ee80b42..1a6ffd7432 100644
--- a/src/modules/files/file_machine.h.in
+++ b/src/modules/files/file_machine.h.in
@@ -16,6 +16,9 @@
 /* Define if you have the <sys/protosw.h> header file.  */
 #undef HAVE_SYS_PROTOSW_H
 
+/* Define if you have the <netdb.h> header file.  */
+#undef HAVE_NETDB_H
+
 /* Define if you have dirent.h.  */
 #undef HAVE_DIRENT_H
 
-- 
GitLab


From be7eb696a93801caa2ab023c66acbc50bd1bdd45 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:14:04 +0200
Subject: [PATCH 299/351] mpz module now checks for mpz_t before compiling

Rev: src/modules/gmpmod/configure.in:1.2
Rev: src/modules/gmpmod/gmp_machine.h.in:1.2
Rev: src/modules/gmpmod/mpz_glue.c:1.3
---
 src/modules/gmpmod/configure.in     | 14 ++++++++++++++
 src/modules/gmpmod/gmp_machine.h.in |  3 +++
 src/modules/gmpmod/mpz_glue.c       |  4 ++++
 3 files changed, 21 insertions(+)

diff --git a/src/modules/gmpmod/configure.in b/src/modules/gmpmod/configure.in
index b8c1fa3b4a..115872c0e9 100644
--- a/src/modules/gmpmod/configure.in
+++ b/src/modules/gmpmod/configure.in
@@ -8,6 +8,20 @@ AC_SUBST(RANLIB)
 AC_CHECK_HEADERS(gmp.h)
 AC_CHECK_LIB(gmp, mpz_set_si)
 
+AC_MSG_CHECKING(if libgmp is new enough)
+AC_CACHE_VAL(lpc_cv_lib_gmp_is_new_enough,
+[
+AC_TRY_COMPILE([#include <gmp.h>],[
+mpz_t foo;
+return 0;
+],lpc_cv_lib_gmp_is_new_enough=yes,lpc_cv_lib_gmp_is_new_enough=no)
+])
+
+AC_MSG_RESULT($lpc_cv_lib_gmp_is_new_enough)
+if $lpc_cv_lib_gmp_is_new_enough = yes; then
+  AC_DEFINE(HAVE_NEW_GMP)
+fi
+
 AC_OUTPUT(Makefile,echo FOO >stamp-h )
 
 
diff --git a/src/modules/gmpmod/gmp_machine.h.in b/src/modules/gmpmod/gmp_machine.h.in
index 0a79aef13b..d53e0cbc1c 100644
--- a/src/modules/gmpmod/gmp_machine.h.in
+++ b/src/modules/gmpmod/gmp_machine.h.in
@@ -4,4 +4,7 @@
 /* Define this if you have <gmp.h> */
 #undef HAVE_GMP_H
 
+/* Define this if your gmp is version 2.0 or newer */
+#undef HAVE_NEW_GMP
+
 #endif
diff --git a/src/modules/gmpmod/mpz_glue.c b/src/modules/gmpmod/mpz_glue.c
index c75f1c0688..5c2e502ec9 100644
--- a/src/modules/gmpmod/mpz_glue.c
+++ b/src/modules/gmpmod/mpz_glue.c
@@ -7,6 +7,10 @@
 #include "gmp_machine.h"
 #include "types.h"
 
+#ifndef HAVE_NEW_GMP
+#undef HAVE_GMP_H
+#endif
+
 #ifdef HAVE_GMP_H
 
 #include "interpret.h"
-- 
GitLab


From f99da61d58273cb9e2be66d082926fa67660b08f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:18:18 +0200
Subject: [PATCH 300/351] now looks for readline.h in strange places

Rev: src/modules/readlinemod/configure.in:1.2
---
 src/modules/readlinemod/configure.in | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/modules/readlinemod/configure.in b/src/modules/readlinemod/configure.in
index 64b90a5b5b..b71783e957 100644
--- a/src/modules/readlinemod/configure.in
+++ b/src/modules/readlinemod/configure.in
@@ -5,8 +5,7 @@ AC_PROG_CC
 AC_PROG_RANLIB
 AC_SUBST(RANLIB)
 
-AC_CHECK_HEADERS(readline.h)
-AC_CHECK_HEADERS(history.h)
+AC_CHECK_HEADERS(readline.h history.h readline/readline.h history/history.h)
 AC_CHECK_LIB(termcap, tputs)
 AC_CHECK_LIB(readline, readline)
 
-- 
GitLab


From ac08ab4f1e6550dcb35f67017b00b5fce787b644 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:20:20 +0200
Subject: [PATCH 301/351] bug fixed when readline wasn't found

Rev: src/modules/readlinemod/readlinemod.c:1.2
---
 src/modules/readlinemod/readlinemod.c | 34 +++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 5 deletions(-)

diff --git a/src/modules/readlinemod/readlinemod.c b/src/modules/readlinemod/readlinemod.c
index a84802d775..23187a8f4c 100644
--- a/src/modules/readlinemod/readlinemod.c
+++ b/src/modules/readlinemod/readlinemod.c
@@ -13,14 +13,31 @@
 #include "object.h"
 #include "macros.h"
 
-#if !defined(HAVE_READLINE_H) || !defined(HAVE_HISTORY_H)
+#if !defined(HAVE_READLINE_H) || !defined(HAVE_READLINE_READLINE_H)
+#undef HAVE_LIBREADLINE
+#endif
+
+#if !defined(HAVE_HISTORY_H) || !defined(HAVE_READLINE_HISTORY_H)
 #undef HAVE_LIBREADLINE
 #endif
 
 #ifdef HAVE_LIBREADLINE
 
+#ifdef HAVE_READLINE_READLINE_H
+#include <readline/readline.h>
+#else
+#ifdef HAVE_READLINE_H
 #include <readline.h>
+#endif
+#endif
+
+#ifdef HAVE_READLINE_HISTORY_H
+#include <readline/history.h>
+#else
+#ifdef HAVE_HISTORY_H
 #include <history.h>
+#endif
+#endif
 
 static void f_readline(INT32 args)
 {
@@ -43,6 +60,12 @@ static void f_readline(INT32 args)
   }
 }
 
+void init_readlinemod_efuns(void)
+{
+  rl_bind_key('\t', rl_insert);
+  add_efun("readline",f_readline,"function(string:string)",OPT_SIDE_EFFECT);
+}
+
 #else
 
 #include <stdio.h>
@@ -59,7 +82,8 @@ static void f_readline(INT32 args)
   if(sp[-args].type != T_STRING)
     error("Bad argument 1 to readline()\n");
 
-  puts(sp[-args].u.string->str);
+  fwrite(sp[-args].u.string->str,1,sp[-args].u.string->len,stdout);
+  fflush(stdout);
 
   pop_n_elems(args);
   if(fgets(line,BLOCK,stdin))
@@ -77,13 +101,13 @@ static void f_readline(INT32 args)
   push_int(0);
 }
 
-#endif
-
 void init_readlinemod_efuns(void)
 {
-  rl_bind_key('\t', rl_insert);
   add_efun("readline",f_readline,"function(string:string)",OPT_SIDE_EFFECT);
 }
+
+#endif
+
 void exit_readlinemod(void) {}
 void init_readlinemod_programs(void) { }
 
-- 
GitLab


From 03444d05d70ccf92698b120758f6c9e93108c491 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:21:28 +0200
Subject: [PATCH 302/351] tests for ++ and -- added

Rev: src/test/create_testsuite:1.20
---
 src/test/create_testsuite | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index f8a6077c3c..1e7eecb8cb 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -130,6 +130,20 @@ cond( [[ master()->programs["/precompiled/mpz"] ]],
 
 ]]);
 
+// ++
+test_any([[int e; e++; return e;]],1)
+test_any([[int e; ++e; return e;]],1)
+test_any([[int e; return e++;]],0)
+test_any([[int e; return ++e;]],1)
+test_any([[int e; if(e++) return 0; return e;]],1)
+
+// --
+test_any([[int e; e--; return e;]],-1)
+test_any([[int e; --e; return e;]],-1)
+test_any([[int e; return e--;]],0)
+test_any([[int e; return --e;]],-1)
+test_any([[int e; if(e--) return 0; return e;]],-1)
+
 test_compile_error_low(master()->add_precompiled_program(\"/test\",compile_string(\"int foo() { return 17; }\",\"62\")))
 
 test_any([[function f=random_seed; int t; foreach(allocate(1),t) f(t); return 1;]],1)
-- 
GitLab


From cb03099f050dd98af766bb4d9b29b5af8943dc2f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Sat, 3 Aug 1996 16:22:54 +0200
Subject: [PATCH 303/351] entries added

Rev: src/ChangeLog:1.44
---
 src/ChangeLog | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 547c291635..5df47ee8df 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,29 @@
+Thu Aug  1 15:26:12 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
+
+	* Makefile.src: a few bugs fixed
+	* backend.c: now handles unsigned tv_sec better
+	* callback.c: bugs fixed, comments added
+	* configure.in: now checks for mmap
+	* docode.c: if() no longer uses count_args
+	* docode.c: one jump eliminated from for() loops
+	* interpret.c: stack now allocated with mmap when possible
+	* interpret.c: catch() inline warning removed...
+	* interpret.c: F_DEC_LOCAL_AND_POP now works...
+	* interpret.c: new opcodes: F_MARK2, F_SIZEOF, F_SIZEOF_LOCAL
+	*             F_CALL_LFUN_AND_POP
+	* language.y: gauge can now take a block of code as argument
+	* lex.c: added `[] and `[]=
+	* rusage.c: bug fixed when no rusage() was found
+	* mpz module now checks that libgmp is new enough
+	* readline module now checks for both <readline.h> and
+	  <readline/readline.h>
+
+Mon Jul 22 12:04:34 1996  Fredrik Hubinette  <hubbe@freeone.signum.se>
+
+	* interpret.c (catch): return should now work from inside catch
+	  all catch statements are now exited through return or throw
+	* readlinemod: now checks for <readline/readline.h> too
+
 Mon Jul  8 23:52:48 1996  Fredrik Hubinette  <hubbe@axel.signum.se>
 
 	* uLPC v1.0E-6 released
-- 
GitLab


From 5f28e9070b88293b13cb9db11b04646d8a8fbcf0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 6 Aug 1996 00:03:04 +0200
Subject: [PATCH 304/351] regexp() fixed

Rev: lib/simulate.lpc:1.21
---
 lib/simulate.lpc | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index d1cb9a33cd..266178226d 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -324,9 +324,11 @@ function get_function(object o, string a)
 
 string *regexp(string *s, string reg)
 {
+  
   regexp::create(reg);
-  return filter_array(s,match);
+  s=filter_array(s,match);
   regexp::create(); /* Free compiled regexp */
+  return s;
 }
 
 list mklist(mixed *a)
-- 
GitLab


From a7622ce0294ba43e4d5d9dc8103d12959ef8dac1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 6 Aug 1996 00:05:27 +0200
Subject: [PATCH 305/351] if(foo && bar) optimized

Rev: src/docode.c:1.7
---
 src/docode.c | 63 ++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 44 insertions(+), 19 deletions(-)

diff --git a/src/docode.c b/src/docode.c
index c7b606bb57..10cf1fc050 100644
--- a/src/docode.c
+++ b/src/docode.c
@@ -119,9 +119,9 @@ INT32 pop_address()
 
 static int label_no=0;
 
-static int alloc_label() { return ++label_no; }
+int alloc_label() { return ++label_no; }
 
-static int do_jump(int token,INT32 lbl)
+int do_jump(int token,INT32 lbl)
 {
   if(lbl==-1) lbl=alloc_label();
   emit(token, lbl);
@@ -132,7 +132,7 @@ static int do_docode2(node *n,int flags);
 
 #define ins_label(L) do_jump(F_LABEL, L)
 
-static void do_pop(int x)
+void do_pop(int x)
 {
   switch(x)
   {
@@ -156,44 +156,66 @@ int do_docode(node *n,INT16 flags)
 }
 
 
-static INT32 do_jump_when_zero(node *n,int j);
+void do_jump_when_zero(node *n,int j);
 
-static int do_jump_when_non_zero(node *n,int j)
+void do_jump_when_non_zero(node *n,int j)
 {
   if(!node_is_tossable(n))
   {
     if(node_is_true(n))
-      return do_jump(F_BRANCH,j);
+    {
+      do_jump(F_BRANCH,j);
+      return;
+    }
 
     if(node_is_false(n))
-      return -1;
+      return;
   }
 
-  if(n->token == F_NOT)
-    return do_jump_when_zero(CAR(n), j);
+  switch(n->token)
+  {
+  case F_NOT:
+    do_jump_when_zero(CAR(n), j);
+    return;
+  case F_OR:
+    do_jump_when_non_zero(CAR(n), j);
+    do_jump_when_non_zero(CDR(n), j);
+    return;
+  }
 
   if(do_docode(n, DO_NOT_COPY)!=1)
     fatal("Infernal compiler skiterror.\n");
-  return do_jump(F_BRANCH_WHEN_NON_ZERO,j);
+  do_jump(F_BRANCH_WHEN_NON_ZERO,j);
 }
 
-static INT32 do_jump_when_zero(node *n,int j)
+void do_jump_when_zero(node *n,int j)
 {
   if(!node_is_tossable(n))
   {
     if(node_is_true(n))
-      return -1;
+      return;
 
     if(node_is_false(n))
-      return do_jump(F_BRANCH,j);
+    {
+      do_jump(F_BRANCH,j);
+      return;
+    }
   }
 
-  if(n->token == F_NOT)
-    return do_jump_when_non_zero(CAR(n), j);
+  switch(n->token)
+  {
+  case F_NOT:
+    do_jump_when_non_zero(CAR(n), j);
+    return;
+  case F_AND:
+    do_jump_when_zero(CAR(n), j);
+    do_jump_when_zero(CDR(n), j);
+    return;
+  }
 
   if(do_docode(n, DO_NOT_COPY)!=1)
     fatal("Infernal compiler skiterror.\n");
-  return do_jump(F_BRANCH_WHEN_ZERO,j);
+  do_jump(F_BRANCH_WHEN_ZERO,j);
 }
 
 static INT32 count_cases(node *n)
@@ -266,7 +288,8 @@ static int do_docode2(node *n,int flags)
 
     if(!CDDR(n))
     {
-      tmp1=do_jump_when_zero(CAR(n), -1);
+      tmp1=alloc_label();
+      do_jump_when_zero(CAR(n), tmp1);
       DO_CODE_BLOCK(CADR(n));
       emit(F_LABEL, tmp1);
       return 0;
@@ -274,13 +297,15 @@ static int do_docode2(node *n,int flags)
 
     if(!CADR(n))
     {
-      tmp1=do_jump_when_non_zero(CAR(n), -1);
+      tmp1=alloc_label();
+      do_jump_when_non_zero(CAR(n), tmp1);
       DO_CODE_BLOCK(CDDR(n));
       emit(F_LABEL,tmp1);
       return 0;
     }
 
-    tmp1=do_jump_when_zero(CAR(n),-1);
+    tmp1=alloc_label();
+    do_jump_when_zero(CAR(n),tmp1);
 
     adroppings=do_docode(CADR(n), flags);
     tmp3=emit(F_POP_N_ELEMS,0);
-- 
GitLab


From a4e1c404e78822332247281a66d93ff57bbd84a0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 6 Aug 1996 00:05:44 +0200
Subject: [PATCH 306/351] nothing much fixed

Rev: src/global.h:1.3
---
 src/global.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/global.h b/src/global.h
index e8be108dbf..42db89f81c 100644
--- a/src/global.h
+++ b/src/global.h
@@ -52,18 +52,22 @@ char *alloca ();
 
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
+#undef HAVE_STDLIB_H
 #endif
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#undef HAVE_UNISTD_H
 #endif
 
 #ifdef HAVE_STRING_H
 #include <string.h>
+#undef HAVE_STRING_H
 #endif
 
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
+#undef HAVE_MEMORY_H
 #endif
 
 #if defined(__GNUC__) && !defined(DEBUG) && !defined(lint)
-- 
GitLab


From 647d8baa6f33764fbc426024a2b7dc39301c9b3b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 6 Aug 1996 00:06:06 +0200
Subject: [PATCH 307/351] --loop now WORKS

Rev: src/interpret.c:1.12
---
 src/interpret.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/interpret.c b/src/interpret.c
index 5ded231dd9..30b3c004f4 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -829,7 +829,7 @@ static void eval_instruction(unsigned char *pc)
       }
       
       LOOP(F_INC_LOOP, ++, <);
-      LOOP(F_DEC_LOOP, --, <);
+      LOOP(F_DEC_LOOP, --, >);
       LOOP(F_INC_NEQ_LOOP, ++, !=);
       LOOP(F_DEC_NEQ_LOOP, --, !=);
 
-- 
GitLab


From 6891181c637785b79700af89a3f371245d89ab63 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 6 Aug 1996 00:07:12 +0200
Subject: [PATCH 308/351] --loop and ++look now works are are USED

Rev: src/las.c:1.12
---
 src/las.c | 120 ++++++++++++++++++++++++++++++++----------------------
 1 file changed, 71 insertions(+), 49 deletions(-)

diff --git a/src/las.c b/src/las.c
index 58df15ca01..deeca16c9d 100644
--- a/src/las.c
+++ b/src/las.c
@@ -21,6 +21,7 @@
 #include "docode.h"
 #include "main.h"
 #include "memory.h"
+#include "operators.h"
 
 #define LASDEBUG
 
@@ -1064,22 +1065,6 @@ void fix_type_field(node *n)
     n->type = get_type_of_svalue(& n->u.sval);
     break;
 
-    /* Not yet checked, but we know what they should return */
-  case F_NOT:
-  case F_LT:
-  case F_LE:
-  case F_EQ:
-  case F_NE:
-  case F_GT:
-  case F_GE:
-  case F_MOD:
-  case F_XOR:
-  case F_LSH:
-  case F_RSH:
-  case F_COMPL:
-    copy_shared_string(n->type,int_type_string);
-    break;
-
   case F_ARG_LIST:
     if(!CAR(n) || CAR(n)->type==void_type_string)
     {
@@ -1347,12 +1332,24 @@ static void optimize(node *n)
       }
 
       last=&(CDDR(n));
-      tmp1=last?*last:(node *)NULL;
+      tmp1=*last;
+
+      while(tmp1 && 
+	    tmp1->token == F_CAST &&
+	    tmp1->type == void_type_string)
+      {
+	last=&CAR(tmp1);
+	tmp1=*last;
+      }
+
       if(tmp1 && (tmp1->token==F_INC ||
 		  tmp1->token==F_POST_INC ||
 		  tmp1->token==F_DEC ||
 		  tmp1->token==F_POST_DEC))
       {
+	node *opnode, **arg1, **arg2;
+	int oper;
+
 	/* does it increment or decrement ? */
 	if(tmp1->token==F_INC || tmp1->token==F_POST_INC)
 	  inc=1;
@@ -1361,61 +1358,85 @@ static void optimize(node *n)
 
 	/* for(; x op y; z ++) p; */
 
-	if(CAR(n)->token!=F_GT &&
-	   CAR(n)->token!=F_GE &&
-	   CAR(n)->token!=F_LE &&
-	   CAR(n)->token!=F_LT &&
-	   CAR(n)->token!=F_NE)
+	opnode=CAR(n);
+
+	if(opnode->token == F_APPLY &&
+	   CAR(opnode) &&
+	   CAR(opnode)->token == F_CONSTANT &&
+	   CAR(opnode)->u.sval.type == T_FUNCTION &&
+	   CAR(opnode)->u.sval.subtype == -1)
+	{
+	  if(CAR(opnode)->u.sval.u.efun->function == f_gt)
+	    oper=F_GT;
+	  else if(CAR(opnode)->u.sval.u.efun->function == f_ge)
+	    oper=F_GE;
+	  else if(CAR(opnode)->u.sval.u.efun->function == f_lt)
+	    oper=F_LT;
+	  else if(CAR(opnode)->u.sval.u.efun->function == f_le)
+	    oper=F_LE;
+	  else if(CAR(opnode)->u.sval.u.efun->function == f_ne)
+	    oper=F_NE;
+	  else
+	    break;
+	}else{
 	  break;
+	}
+
+	if(count_args(CDR(opnode)) != 2) break;
+	arg1=my_get_arg(&CDR(opnode), 0);
+	arg2=my_get_arg(&CDR(opnode), 1);
 
-	if(!node_is_eq(CAAR(n),CAR(tmp1)) || /* x == z */
-	   depend_p(CDAR(n),CDAR(n)) ||	/* does y depend on y? */
-	   depend_p(CDAR(n),CAAR(n)) ||	/* does y depend on x? */
-	   depend_p(CDAR(n),CADR(n))) /* does y depend on p? */
+	/* it was not on the form for(; x op y; z++) p; */
+	if(!node_is_eq(*arg1,CAR(tmp1)) || /* x == z */
+	   depend_p(*arg2,*arg2) ||	/* does y depend on y? */
+	   depend_p(*arg2,*arg1) ||	/* does y depend on x? */
+	   depend_p(*arg2,CADR(n))) /* does y depend on p? */
 	{
 	  /* it was not on the form for(; x op y; x++) p; */
-	  if(!node_is_eq(CADR(n),CAR(tmp1)) || /* y == z */
-	     depend_p(CAAR(n),CDAR(n)) || /* does x depend on y? */
-	     depend_p(CAAR(n),CAAR(n)) || /* does x depend on x? */
-	     depend_p(CAAR(n),CADR(n)) /* does x depend on p? */
+	  if(!node_is_eq(*arg2,CAR(tmp1)) || /* y == z */
+	     depend_p(*arg1,*arg2) || /* does x depend on y? */
+	     depend_p(*arg1,*arg1) || /* does x depend on x? */
+	     depend_p(*arg1,CADR(n)) /* does x depend on p? */
 	     )
 	  {
 	    /* it was not on the form for(; x op y; y++) p; */
 	    break;
 	  }else{
+	    node **tmparg;
 	    /* for(; x op y; y++) p; -> for(; y op^-1 x; y++) p; */
 
-	    switch(CAR(n)->token)
+	    switch(oper)
 	    {
-	    case F_LT: CAR(n)->token=F_GT; break;
-	    case F_LE: CAR(n)->token=F_GE; break;
-	    case F_GT: CAR(n)->token=F_LT; break;
-	    case F_GE: CAR(n)->token=F_LE; break;
+	    case F_LT: oper=F_GT; break;
+	    case F_LE: oper=F_GE; break;
+	    case F_GT: oper=F_LT; break;
+	    case F_GE: oper=F_LE; break;
 	    }
-	    tmp2=CAAR(n);
-	    CAAR(n)=CDAR(n);
-	    CDAR(n)=tmp2;
+	    
+	    tmparg=arg1;
+	    arg1=arg2;
+	    arg2=tmparg;
 	  }
 	}
 	if(inc)
 	{
-	  if(CAR(n)->token==F_LE)
-	    tmp3=mkopernode("`+",CDAR(n),mkintnode(1));
-	  else if(CAR(n)->token==F_LT)
-	    tmp3=CDAR(n);
+	  if(oper==F_LE)
+	    tmp3=mkopernode("`+",*arg2,mkintnode(1));
+	  else if(oper==F_LT)
+	    tmp3=*arg2;
 	  else
 	    break;
 	}else{
-	  if(CAR(n)->token==F_GE)
-	    tmp3=mknode(F_SUBTRACT,CDAR(n),mkintnode(1));
-	  else if(CAR(n)->token==F_GT)
-	    tmp3=CDAR(n);
+	  if(oper==F_GE)
+	    tmp3=mkopernode("`-",*arg2,mkintnode(1));
+	  else if(oper==F_GT)
+	    tmp3=*arg2;
 	  else
 	    break;
 	}
 
 	*last=0;
-	if(CAR(n)->token==F_NE)
+	if(oper==F_NE)
 	{
 	  if(inc)
 	    token=F_INC_NEQ_LOOP;
@@ -1427,8 +1448,8 @@ static void optimize(node *n)
 	  else
 	    token=F_DEC_LOOP;
 	}
-	tmp2=mknode(token,mknode(F_VAL_LVAL,tmp3,CAAR(n)),CADR(n));
-	CAAR(n) = CADR(n) = CDAR(n) = CDDR(n)=0;
+	tmp2=mknode(token,mknode(F_VAL_LVAL,tmp3,*arg1),CADR(n));
+	*arg1 = *arg2 = CADR(n) = CDDR(n)=0;
 
 	if(inc)
 	{
@@ -1436,6 +1457,7 @@ static void optimize(node *n)
 	}else{
 	  tmp1->token=F_INC;
 	}
+
 	tmp1=mknode(F_ARG_LIST,mkcastnode(void_type_string,tmp1),tmp2);
 	goto use_tmp1;
       }
-- 
GitLab


From d63edd191cc4956d22f0487ff1cfee4feffe95f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 6 Aug 1996 00:07:56 +0200
Subject: [PATCH 309/351] bugfix!

Rev: src/memory.c:1.3
---
 src/memory.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/memory.c b/src/memory.c
index a130aa5185..928322d5e2 100644
--- a/src/memory.c
+++ b/src/memory.c
@@ -386,7 +386,7 @@ void init_memsearch(struct mem_searcher *s,
     }else{
       INT32 tmp, h;
       unsigned INT32 hsize, e, max;
-      char *q;
+      unsigned char *q;
       struct link *ptr;
 
       hsize=52+(max_haystacklen >> 7)  - (needlelen >> 8);
@@ -409,7 +409,7 @@ void init_memsearch(struct mem_searcher *s,
 
       ptr=& s->links[0];
 
-      q=needle;
+      q=(unsigned char *)needle;
 
 #if BYTEORDER == 4321
       for(tmp=e=0;e<sizeof(INT32)-1;e++)
@@ -425,7 +425,7 @@ void init_memsearch(struct mem_searcher *s,
 	tmp<<=8;
 	tmp|=*(q++);
 #else
-	tmp=EXTRACT_INT((unsigned char *)q);
+	tmp=EXTRACT_INT(q);
 	q++;
 #endif
 	h=tmp;
-- 
GitLab


From c1a1c0558b66c1e83c51e851670b3987fcb56ddb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 6 Aug 1996 00:08:26 +0200
Subject: [PATCH 310/351] added tests for 8-bit searches and more tests for
 for()

Rev: src/test/create_testsuite:1.21
---
 src/test/create_testsuite | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 1e7eecb8cb..839381bdf2 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -856,6 +856,11 @@ test_any(while(1) if(1) break; return 1,1)
 test_any(int e; for(e=0;e<10;e++) break; return e,0)
 test_any(int e; for(e=0;e<10;e++) continue; return e,10)
 test_any(int e;string t=""; for(e=0;e<10;e++) t+=e; return t,"0123456789")
+test_any(int e;string t=""; for(e=0;e<=10;e++) t+=e; return t,"012345678910")
+test_any(int e;string t=""; for(e=9;e>0;e--) t+=e; return t,"987654321")
+test_any(int e;string t=""; for(e=9;e>=0;e--) t+=e; return t,"9876543210")
+test_any(int e;string t=""; for(e=9;e!=0;e--) t+=e;  return t,"987654321")
+test_any(int e;string t=""; for(e=2;e!=10;e++) t+=e; return t,"23456789")
 test_any(int e;string t=""; for(e=0;e>-10;e--) t+=e; return t,"0-1-2-3-4-5-6-7-8-9")
 
 // foreach
@@ -1889,7 +1894,7 @@ test_search3($1,($1[1..0x7fffffff]))
 
 test_search4("SUNE")
 test_search4("-------------------+")
-test_search4("+-------------------")
+test_search4("�-------------------")
 test_search4(sprintf("%'argel-bargel glop-glyf?'2000n"))
 
 // - sizeof
-- 
GitLab


From dfe53c8de9761272549d389f1abdd1416b16d59d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 6 Aug 1996 00:17:37 +0200
Subject: [PATCH 311/351] minor bugfix

Rev: src/modules/gmpmod/configure.in:1.3
---
 src/modules/gmpmod/configure.in | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/modules/gmpmod/configure.in b/src/modules/gmpmod/configure.in
index 115872c0e9..9cecf8fc30 100644
--- a/src/modules/gmpmod/configure.in
+++ b/src/modules/gmpmod/configure.in
@@ -17,9 +17,11 @@ return 0;
 ],lpc_cv_lib_gmp_is_new_enough=yes,lpc_cv_lib_gmp_is_new_enough=no)
 ])
 
-AC_MSG_RESULT($lpc_cv_lib_gmp_is_new_enough)
-if $lpc_cv_lib_gmp_is_new_enough = yes; then
+if test "$lpc_cv_lib_gmp_is_new_enough" = yes; then
+  AC_MSG_RESULT(yes)
   AC_DEFINE(HAVE_NEW_GMP)
+else
+  AC_MSG_RESULT(no)
 fi
 
 AC_OUTPUT(Makefile,echo FOO >stamp-h )
-- 
GitLab


From 7f90d25a4c4214a53d6a1a831d166c11467b992f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 6 Aug 1996 13:34:28 +0200
Subject: [PATCH 312/351] now possible to IGNore signals

Rev: src/lpc_signal.c:1.12
---
 src/lpc_signal.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/src/lpc_signal.c b/src/lpc_signal.c
index 97d7234a37..a2659bc411 100644
--- a/src/lpc_signal.c
+++ b/src/lpc_signal.c
@@ -296,12 +296,6 @@ static void f_signal(int args)
   if(args < 1)
     error("Too few arguments to signal()\n");
 
-  if(args == 1)
-  {
-    push_int(0);
-    args++;
-  }
-  
   if(sp[-args].type != T_INT)
   {
     error("Bad argument 1 to signal()\n");
@@ -313,9 +307,11 @@ static void f_signal(int args)
     error("Signal out of range.\n");
   }
 
-  assign_svalue(signal_callbacks + signum, sp+1-args);
-  if(IS_ZERO(sp+1-args))
+  if(args == 1)
   {
+    push_int(0);
+    args++;
+
     switch(signum)
     {
     case SIGCHLD:
@@ -329,9 +325,15 @@ static void f_signal(int args)
     default:
       func=(sigfunctype) SIG_DFL;
     }
-  }else{
-    func=receive_signal;
+  } else {
+    if(IS_ZERO(sp+1-args))
+    {
+      func=(sigfunctype) SIG_IGN;
+    }else{
+      func=receive_signal;
+    }
   }
+  assign_svalue(signal_callbacks + signum, sp+1-args);
   my_signal(signum, func);
   pop_n_elems(args);
 }
-- 
GitLab


From 3d2fb2b8573914f8812d7871c38c4286cb4db6aa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 6 Aug 1996 13:43:11 +0200
Subject: [PATCH 313/351] sscanf now accept field sizes for %s and %c

Rev: src/opcodes.c:1.6
---
 src/opcodes.c | 424 +++++++++++++++++++++++++++-----------------------
 1 file changed, 229 insertions(+), 195 deletions(-)

diff --git a/src/opcodes.c b/src/opcodes.c
index 6410fc05c2..d0ed78db3b 100644
--- a/src/opcodes.c
+++ b/src/opcodes.c
@@ -429,7 +429,7 @@ static INT32 low_sscanf(INT32 num_arg)
   int match_len;
   struct svalue sval;
   int e,cnt,matches,eye,arg;
-  int no_assign;
+  int no_assign,field_length;
   char set[256];
   struct svalue *argp;
   
@@ -473,245 +473,279 @@ static INT32 low_sscanf(INT32 num_arg)
     }
 #endif
 
+    no_assign=0;
+    field_length=-1;
+
     cnt++;
     if(cnt>=match_len)
       error("Error in sscanf format string.\n");
 
-    if(match[cnt]=='*')
+    while(1)
     {
-      no_assign=1;
-      cnt++;
-      if(cnt>=match_len)
-        error("Error in sscanf format string.\n");
-    }else{
-      no_assign=0;
-    }
+      switch(match[cnt])
+      {
+      case '*':
+	no_assign=1;
+	cnt++;
+	if(cnt>=match_len)
+	  error("Error in sscanf format string.\n");
+	continue;
+
+      case '0': case '1': case '2': case '3': case '4':
+      case '5': case '6': case '7': case '8': case '9':
+      {
+	char *t;
+	field_length=STRTOL(match+cnt,&t,10);
+	cnt=t-match;
+	continue;
+      }
 
-    switch(match[cnt])
-    {
-    case 'c':
-      if(eye>=input_len) return matches;
-      sval.type=T_INT;
-      sval.subtype=NUMBER_NUMBER;
-      sval.u.integer=EXTRACT_UCHAR(input+eye);
-      eye++;
-      break;
+      case 'c':
+	if(field_length == -1) field_length = 1;
+	if(eye+field_length > input_len) return matches;
+	sval.type=T_INT;
+	sval.subtype=NUMBER_NUMBER;
+	sval.u.integer=0;
+	while(--field_length >= 0)
+	{
+	  sval.u.integer<<=8;
+	  sval.u.integer|=EXTRACT_UCHAR(input+eye);
+	  eye++;
+	}
+	break;
 
-    case 'd':
-    {
-      char * t;
-
-      if(eye>=input_len) return matches;
-      sval.u.integer=STRTOL(input+eye,&t,10);
-      if(input + eye == t) return matches;
-      eye=t-input;
-      sval.type=T_INT;
-      sval.subtype=NUMBER_NUMBER;
-      break;
-    }
+      case 'd':
+      {
+	char * t;
+
+	if(eye>=input_len) return matches;
+	sval.u.integer=STRTOL(input+eye,&t,10);
+	if(input + eye == t) return matches;
+	eye=t-input;
+	sval.type=T_INT;
+	sval.subtype=NUMBER_NUMBER;
+	break;
+      }
 
-    case 'x':
-    {
-      char * t;
-
-      if(eye>=input_len) return matches;
-      sval.u.integer=STRTOL(input+eye,&t,16);
-      if(input + eye == t) return matches;
-      eye=t-input;
-      sval.type=T_INT;
-      sval.subtype=NUMBER_NUMBER;
-      break;
-    }
+      case 'x':
+      {
+	char * t;
+
+	if(eye>=input_len) return matches;
+	sval.u.integer=STRTOL(input+eye,&t,16);
+	if(input + eye == t) return matches;
+	eye=t-input;
+	sval.type=T_INT;
+	sval.subtype=NUMBER_NUMBER;
+	break;
+      }
 
-    case 'o':
-    {
-      char * t;
-
-      if(eye>=input_len) return matches;
-      sval.u.integer=STRTOL(input+eye,&t,8);
-      if(input + eye == t) return matches;
-      eye=t-input;
-      sval.type=T_INT;
-      sval.subtype=NUMBER_NUMBER;
-      break;
-    }
+      case 'o':
+      {
+	char * t;
+
+	if(eye>=input_len) return matches;
+	sval.u.integer=STRTOL(input+eye,&t,8);
+	if(input + eye == t) return matches;
+	eye=t-input;
+	sval.type=T_INT;
+	sval.subtype=NUMBER_NUMBER;
+	break;
+      }
 
-    case 'D':
-    {
-      char * t;
-
-      if(eye>=input_len) return matches;
-      sval.u.integer=STRTOL(input+eye,&t,0);
-      if(input + eye == t) return matches;
-      eye=t-input;
-      sval.type=T_INT;
-      sval.subtype=NUMBER_NUMBER;
-      break;
-    }
+      case 'D':
+      {
+	char * t;
+
+	if(eye>=input_len) return matches;
+	sval.u.integer=STRTOL(input+eye,&t,0);
+	if(input + eye == t) return matches;
+	eye=t-input;
+	sval.type=T_INT;
+	sval.subtype=NUMBER_NUMBER;
+	break;
+      }
 
-    case 'f':
-    {
-      char * t;
+      case 'f':
+      {
+	char * t;
 
-      if(eye>=input_len) return matches;
-      sval.u.float_number=STRTOD(input+eye,&t);
-      if(input + eye == t) return matches;
-      eye=t-input;
-      sval.type=T_FLOAT;
+	if(eye>=input_len) return matches;
+	sval.u.float_number=STRTOD(input+eye,&t);
+	if(input + eye == t) return matches;
+	eye=t-input;
+	sval.type=T_FLOAT;
 #ifdef __CHECKER__
-      sval.subtype=0;
+	sval.subtype=0;
 #endif
-      break;
-    }
+	break;
+      }
 
-    case 's':
-      if(cnt+1>=match_len)
-      {
-	sval.type=T_STRING;
+      case 's':
+	if(field_length != -1)
+	{
+	  if(input_len - eye < field_length)
+	    return matches;
+
+	  sval.type=T_STRING;
 #ifdef __CHECKER__
-	sval.subtype=0;
+	  sval.subtype=0;
 #endif
-	sval.u.string=make_shared_binary_string(input+eye,input_len-eye);
-	break;
-      }else{
-	char *end_str_start;
-	char *end_str_end;
-	char *s=0;		/* make gcc happy */
-	char *p=0;		/* make gcc happy */
-	int start,contains_percent_percent, new_eye;
-
-	start=eye;
-	end_str_start=match+cnt+1;
-          
-	s=match+cnt+1;
-      test_again:
-	if(*s=='%')
+	  sval.u.string=make_shared_binary_string(input+eye,field_length);
+	  eye+=field_length;
+	  break;
+	}
+
+	if(cnt+1>=match_len)
 	{
-	  s++;
-	  if(*s=='*') s++;
-	  switch(*s)
+	  sval.type=T_STRING;
+#ifdef __CHECKER__
+	  sval.subtype=0;
+#endif
+	  sval.u.string=make_shared_binary_string(input+eye,input_len-eye);
+	  eye=input_len;
+	  break;
+	}else{
+	  char *end_str_start;
+	  char *end_str_end;
+	  char *s=0;		/* make gcc happy */
+	  char *p=0;		/* make gcc happy */
+	  int start,contains_percent_percent, new_eye;
+
+	  start=eye;
+	  end_str_start=match+cnt+1;
+          
+	  s=match+cnt+1;
+	test_again:
+	  if(*s=='%')
 	  {
-	  case 'n':
 	    s++;
-	    goto test_again;
+	    if(*s=='*') s++;
+	    switch(*s)
+	    {
+	    case 'n':
+	      s++;
+	      goto test_again;
 	      
-	  case 's':
-	    error("Illigal to have two adjecent %%s.\n");
-	    return 0;		/* make gcc happy */
+	    case 's':
+	      error("Illigal to have two adjecent %%s.\n");
+	      return 0;		/* make gcc happy */
 	      
-	    /* sscanf("foo-bar","%s%d",a,b) might not work as expected */
-	  case 'd':
-	    for(e=0;e<256;e++) set[e]=1;
-	    for(e='0';e<='9';e++) set[e]=0;
-	    set['-']=0;
-	    goto match_set;
-
-	  case 'o':
-	    for(e=0;e<256;e++) set[e]=1;
-	    for(e='0';e<='7';e++) set[e]=0;
-	    goto match_set;
-
-	  case 'x':
-	    for(e=0;e<256;e++) set[e]=1;
-	    for(e='0';e<='9';e++) set[e]=0;
-	    for(e='a';e<='f';e++) set[e]=0;
-	    goto match_set;
-
-	  case 'D':
-	    for(e=0;e<256;e++) set[e]=1;
-	    for(e='0';e<='9';e++) set[e]=0;
-	    set['-']=0;
-	    set['x']=0;
-	    goto match_set;
-
-	  case 'f':
-	    for(e=0;e<256;e++) set[e]=1;
-	    for(e='0';e<='9';e++) set[e]=0;
-	    set['.']=set['-']=0;
-	    goto match_set;
-
-	  case '[':		/* oh dear */
-	    read_set(match,s-match+1,set,match_len);
-	    for(e=0;e<256;e++) set[e]=!set[e];
-	    goto match_set;
+	      /* sscanf("foo-bar","%s%d",a,b) might not work as expected */
+	    case 'd':
+	      for(e=0;e<256;e++) set[e]=1;
+	      for(e='0';e<='9';e++) set[e]=0;
+	      set['-']=0;
+	      goto match_set;
+
+	    case 'o':
+	      for(e=0;e<256;e++) set[e]=1;
+	      for(e='0';e<='7';e++) set[e]=0;
+	      goto match_set;
+
+	    case 'x':
+	      for(e=0;e<256;e++) set[e]=1;
+	      for(e='0';e<='9';e++) set[e]=0;
+	      for(e='a';e<='f';e++) set[e]=0;
+	      goto match_set;
+
+	    case 'D':
+	      for(e=0;e<256;e++) set[e]=1;
+	      for(e='0';e<='9';e++) set[e]=0;
+	      set['-']=0;
+	      set['x']=0;
+	      goto match_set;
+
+	    case 'f':
+	      for(e=0;e<256;e++) set[e]=1;
+	      for(e='0';e<='9';e++) set[e]=0;
+	      set['.']=set['-']=0;
+	      goto match_set;
+
+	    case '[':		/* oh dear */
+	      read_set(match,s-match+1,set,match_len);
+	      for(e=0;e<256;e++) set[e]=!set[e];
+	      goto match_set;
+	    }
 	  }
-	}
 
-	contains_percent_percent=0;
+	  contains_percent_percent=0;
 
-	for(e=cnt;e<match_len;e++)
-	{
-	  if(match[e]=='%')
+	  for(e=cnt;e<match_len;e++)
 	  {
-	    if(match[e+1]=='%')
+	    if(match[e]=='%')
 	    {
-	      contains_percent_percent=1;
-	      e++;
-	    }else{
-	      break;
+	      if(match[e+1]=='%')
+	      {
+		contains_percent_percent=1;
+		e++;
+	      }else{
+		break;
+	      }
 	    }
 	  }
-	}
 	   
-	end_str_end=match+e;
+	  end_str_end=match+e;
 
-	if(!contains_percent_percent)
-	{
-	  s=my_memmem(end_str_start,
-		      end_str_end-end_str_start,
-		      input+eye,
-		      input_len-eye);
-	  if(!s) return matches;
-	  eye=s-input;
-	  new_eye=eye+end_str_end-end_str_start;
-	}else{
-	  for(;eye<input_len;eye++)
+	  if(!contains_percent_percent)
 	  {
-	    p=input+eye;
-	    for(s=end_str_start;s<end_str_end;s++,p++)
+	    s=my_memmem(end_str_start,
+			end_str_end-end_str_start,
+			input+eye,
+			input_len-eye);
+	    if(!s) return matches;
+	    eye=s-input;
+	    new_eye=eye+end_str_end-end_str_start;
+	  }else{
+	    for(;eye<input_len;eye++)
 	    {
-	      if(*s!=*p) break;
-	      if(*s=='%') s++;
+	      p=input+eye;
+	      for(s=end_str_start;s<end_str_end;s++,p++)
+	      {
+		if(*s!=*p) break;
+		if(*s=='%') s++;
+	      }
+	      if(s==end_str_end)
+		break;
 	    }
-	    if(s==end_str_end)
-	      break;
+	    if(eye==input_len)
+	      return matches;
+	    new_eye=p-input;
 	  }
-	  if(eye==input_len)
-	    return matches;
-	  new_eye=p-input;
-	}
 
-	sval.type=T_STRING;
+	  sval.type=T_STRING;
 #ifdef __CHECKER__
-	sval.subtype=0;
+	  sval.subtype=0;
 #endif
-	sval.u.string=make_shared_binary_string(input+start,eye-start);
+	  sval.u.string=make_shared_binary_string(input+start,eye-start);
 
-	cnt=end_str_end-match-1;
-	eye=new_eye;
-	break;
-      }
+	  cnt=end_str_end-match-1;
+	  eye=new_eye;
+	  break;
+	}
 
-    case '[':
-      cnt=read_set(match,cnt+1,set,match_len);
+      case '[':
+	cnt=read_set(match,cnt+1,set,match_len);
 
-    match_set:
-      for(e=eye;eye<input_len && set[EXTRACT_UCHAR(input+eye)];eye++);
-      sval.type=T_STRING;
+      match_set:
+	for(e=eye;eye<input_len && set[EXTRACT_UCHAR(input+eye)];eye++);
+	sval.type=T_STRING;
 #ifdef __CHECKER__
-      sval.subtype=0;
+	sval.subtype=0;
 #endif
-      sval.u.string=make_shared_binary_string(input+e,eye-e);
-      break;
+	sval.u.string=make_shared_binary_string(input+e,eye-e);
+	break;
 
-    case 'n':
-      sval.type=T_INT;
-      sval.subtype=NUMBER_NUMBER;
-      sval.u.integer=eye;
-      break;
+      case 'n':
+	sval.type=T_INT;
+	sval.subtype=NUMBER_NUMBER;
+	sval.u.integer=eye;
+	break;
     
-    default:
-      error("Unknown sscanf token %%%c\n",match[cnt]);
+      default:
+	error("Unknown sscanf token %%%c\n",match[cnt]);
+      }
+      break;
     }
     matches++;
 
-- 
GitLab


From d9680315d261913171ac51a2d0a25dad7c633fe6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 6 Aug 1996 13:47:58 +0200
Subject: [PATCH 314/351] call outs now has ids

Rev: src/modules/call_out/call_out.c:1.4
Rev: src/modules/call_out/doc/call_out:1.2
Rev: src/modules/call_out/doc/find_call_out:1.2
Rev: src/modules/call_out/doc/remove_call_out:1.2
---
 src/modules/call_out/call_out.c          | 25 ++++++++++++++++--------
 src/modules/call_out/doc/call_out        |  6 ++++--
 src/modules/call_out/doc/find_call_out   | 10 ++++++++--
 src/modules/call_out/doc/remove_call_out |  5 ++++-
 4 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/src/modules/call_out/call_out.c b/src/modules/call_out/call_out.c
index 6e2a6e7ca9..513419a3c3 100644
--- a/src/modules/call_out/call_out.c
+++ b/src/modules/call_out/call_out.c
@@ -71,7 +71,7 @@ static void verify_call_outs()
 
 
 /* start a new call out, return 1 for success */
-static int new_call_out(int num_arg,struct svalue *argp)
+static struct array * new_call_out(int num_arg,struct svalue *argp)
 {
   int e,c;
   call_out *new,**p,**pos;
@@ -161,7 +161,8 @@ static int new_call_out(int num_arg,struct svalue *argp)
   num_pending_calls++;
 
   verify_call_outs();
-  return 1;
+
+  return new->args;
 }
 
 static struct callback *call_out_backend_callback=0;
@@ -170,6 +171,7 @@ void do_call_outs(struct callback *ignored, void *ignored_too, void *arg);
 void f_call_out(INT32 args)
 {
   struct svalue tmp;
+  struct array *v;
   if(args<2)
     error("Too few arguments to call_out.\n");
 
@@ -181,7 +183,9 @@ void f_call_out(INT32 args)
   sp[-args]=sp[1-args];
   sp[1-args]=tmp;
 
-  new_call_out(args,sp-args);
+  v=new_call_out(args,sp-args);
+  v->refs++;
+  push_array(v);
 
   /* We do not add this callback until we actually have
    * call outs to take care of.
@@ -250,11 +254,16 @@ void do_call_outs(struct callback *ignored, void *ignored_too, void *arg)
 static int find_call_out(struct svalue *fun)
 {
   int e;
+
+  if(fun->type == T_ARRAY)
+    for(e=0;e<num_pending_calls;e++)
+      if(pending_calls[e]->args == fun->u.array)
+	return e;
+
   for(e=0;e<num_pending_calls;e++)
-  {
     if(is_eq(fun, ITEM(pending_calls[e]->args)))
       return e;
-  }
+
   return -1;
 }
 
@@ -370,10 +379,10 @@ void verify_all_call_outs()
 
 void init_call_out_efuns(void)
 {
-  add_efun("call_out",f_call_out,"function(function,float|int,mixed...:void)",OPT_SIDE_EFFECT);
+  add_efun("call_out",f_call_out,"function(function,float|int,mixed...:mixed)",OPT_SIDE_EFFECT);
   add_efun("call_out_info",f_call_out_info,"function(:array*)",OPT_EXTERNAL_DEPEND);
-  add_efun("find_call_out",f_find_call_out,"function(function:int)",OPT_EXTERNAL_DEPEND);
-  add_efun("remove_call_out",f_remove_call_out,"function(function:int)",OPT_SIDE_EFFECT);
+  add_efun("find_call_out",f_find_call_out,"function(mixed:int)",OPT_EXTERNAL_DEPEND);
+  add_efun("remove_call_out",f_remove_call_out,"function(mixed:int)",OPT_SIDE_EFFECT);
 }
 
 void init_call_out_programs(void) {}
diff --git a/src/modules/call_out/doc/call_out b/src/modules/call_out/doc/call_out
index 6eccf4ad52..33d3446c86 100644
--- a/src/modules/call_out/doc/call_out
+++ b/src/modules/call_out/doc/call_out
@@ -2,11 +2,13 @@ NAME
 	call_out - make a delayed call to a function
 
 SYNTAX
-	void call_out(function f, int delay, mixed ... args);
+	mixed call_out(function f, int delay, mixed ... args);
 
 DESCRIPTION
 	Call_out places a call to the function f with the argument args
-	in a queue to be called in about delay seconds.
+	in a queue to be called in about delay seconds. The return value
+	identifies this call out. The return value can be sent to
+	find_call_out or remove_call_out to remove the call out again.
 
 SEE ALSO
 	remove_call_out, find_call_out, call_out_info
diff --git a/src/modules/call_out/doc/find_call_out b/src/modules/call_out/doc/find_call_out
index 39e39cc456..019ea4d2fe 100644
--- a/src/modules/call_out/doc/find_call_out
+++ b/src/modules/call_out/doc/find_call_out
@@ -3,10 +3,16 @@ NAME
 
 SYNTAX
 	int find_call_out(function f);
+	or
+	int find_call_out(mixed id);
 
 DESCRIPTION
-	This function searches the call out queue, and returns the time left
-	to this call out will be done in seconds. If no call is found,
+	This function searches the call out queue. If given a function as
+	argument, it looks for the first call out scheduled to that function.
+	The argument can also be a call out id as returned by call_out, in
+	which case that call_out will be found. (Unless it has already been
+	called.) find_call_out will then return how many seconds remains
+	before that call will be executed. If no call is found,
 	zero_type(find_call_out(f)) will return 1.
 
 SEE ALSO
diff --git a/src/modules/call_out/doc/remove_call_out b/src/modules/call_out/doc/remove_call_out
index 277cc9eb0a..b730c6ed7d 100644
--- a/src/modules/call_out/doc/remove_call_out
+++ b/src/modules/call_out/doc/remove_call_out
@@ -3,12 +3,15 @@ NAME
 
 SYNTAX
 	int remove_call_out(function f);
+	or
+	int remove_call_out(function id);
 
 DESCRIPTION
 	This function finds the first call to the function f in the call
 	out queue and removes it. The time left to that call out will be
 	returned. If no call out was found, zero_type(remove_call_out(f))
-	will return 1.
+	will return 1. You can also give a call out id as argument. (as
+	returned by call_out)
 
 SEE ALSO
 	call_out_info, call_out, find_call_out
-- 
GitLab


From 8d545abbe774a764d098efce0750ccf3f7333c83 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 6 Aug 1996 13:48:20 +0200
Subject: [PATCH 315/351] sscanf now accepts field sizes for %s and %c

Rev: doc/lpc/sscanf:1.2
---
 doc/lpc/sscanf | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/doc/lpc/sscanf b/doc/lpc/sscanf
index 22526c5210..2ddc785129 100644
--- a/doc/lpc/sscanf
+++ b/doc/lpc/sscanf
@@ -16,7 +16,9 @@ DESCRIPTION
 		hexadecimal (leading 0x) or decimal.
 	%f	gives a float
 	%c	matches one char and returns it as an integer
+	%2c	matches two chars and returns them as an integer (short)
 	%s	gives a string
+	%5s	gives a string of 5 characters (5 can be any number)
 	%[set]	matches a string containing a given set of characters.
 		(thos given inside the brackets) %[^set] means any character
 		ecept those inside brackets. %[0-9H] means any number or 'H'.
-- 
GitLab


From 8e6ba5dda83f1a3ffff96919fc77b2bbc1a150c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 6 Aug 1996 13:48:30 +0200
Subject: [PATCH 316/351] now possible to IGNore signals

Rev: doc/builtin/signal:1.2
---
 doc/builtin/signal | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/doc/builtin/signal b/doc/builtin/signal
index eadd0008fc..5fe23bc839 100644
--- a/doc/builtin/signal
+++ b/doc/builtin/signal
@@ -19,5 +19,7 @@ DESCRIPTION
 	If no second argument is given, the signal handler for that signal
 	is restored to the default handler.
 
+	If the second argument is zero, the signal will be completely ignored.
+
 SEE ALSO
 	kill, signame, signum
-- 
GitLab


From 8e3724097265defdbc63ce29436ddcd436d6ef73 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 6 Aug 1996 13:48:52 +0200
Subject: [PATCH 317/351] tests added for sscanf %4c and signal(foo,0)

Rev: src/test/create_testsuite:1.22
---
 src/test/create_testsuite | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 839381bdf2..fa8c8d89f5 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -420,6 +420,7 @@ test_do(signal(signum("SIGUSR1"),lambda() { add_efun("AFJLLAF",17); }))
 test_do(kill(getpid(),signum("SIGUSR1")))
 test_eq(AFJLLAF,17)
 test_do(add_efun("AFJLLAF"))
+test_do(signal(signum("SIGUSR1",0)))
 test_do(signal(signum("SIGUSR1")))
 
 // typeof
@@ -501,6 +502,14 @@ test_any([[mixed a,b; sscanf("abcdeFGji","%[a-z]%s",a,b); return b]],"FGji")
 test_any([[mixed a,b; return sscanf("foo-%-bar","%s-%%-%s",a,b);]],2)
 test_any([[mixed a,b; sscanf("foo-%-bar","%s-%%-%s",a,b); return a]],"foo")
 test_any([[mixed a,b; sscanf("foo-%-bar","%s-%%-%s",a,b); return b]],"bar")
+test_any([[mixed a; sscanf("ab","%2c",a); return a]],'a'*256+'b')
+test_any([[mixed a; sscanf("abc","%3c",a); return a]],'a'*256*256+'b'*256+'c')
+test_any([[mixed a; sscanf("abc","%2c",a); return a]],'a'*256+'b')
+test_any([[mixed a; sscanf("ac","%3c",a); return a]],0)
+test_any([[mixed a; sscanf("ab","%2s",a); return a]],"ab")
+test_any([[mixed a; sscanf("abc","%3s",a); return a]],"abc")
+test_any([[mixed a; sscanf("abc","%2s",a); return a]],"ab")
+test_any([[mixed a; sscanf("ac","%3s",a); return a]],0)
 
 // Basics
 test_true(1)
-- 
GitLab


From d4e41272364f2e4de56b5f6fa92be749e43f4870 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 6 Aug 1996 13:51:57 +0200
Subject: [PATCH 318/351] entries added

Rev: src/ChangeLog:1.45
---
 src/ChangeLog | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 5df47ee8df..cabb09f384 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,17 @@
+Tue Aug  6 13:33:51 1996  Fredrik Hubinette  <hubbe@axel.signum.se>
+
+	* call_out.c: call outs now have unique ids, so you can remove
+	  them individually.
+	* opcodes.c: sscanf now accepts field sizes for %c and %s
+	* lpc_signal.c: signal(signum,0) now means SIG_IGN
+
+Tue Aug  6 00:02:14 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
+
+        * memory.c: fixed a bug in memory searcher (8 bit chars)
+        * las.c: fixed so that the --loop and ++loop works again
+	* docode.c: if(foo && bar) opimized (one jump less)
+	* simulate.c (regexp): now frees regexp correctly
+
 Thu Aug  1 15:26:12 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
 
 	* Makefile.src: a few bugs fixed
-- 
GitLab


From 7e17ed3617ae03ada150d0aba0b191d6730054f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 6 Aug 1996 14:08:39 +0200
Subject: [PATCH 319/351] tests for call_out added

Rev: src/test/create_testsuite:1.23
---
 src/test/create_testsuite | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index fa8c8d89f5..242422d770 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -1965,7 +1965,10 @@ test_eq(zero_type(([])[7]),1)
 
 // - call_out, call_out_info, remove_call_out, find_call_out
 test_do(call_out(a,100000))
-test_do(call_out(lambda() {},1000.0))
+test_true(call_out(lambda() {},1000.0))
+test_true(remove_call_out(call_out(lambda() {},1000.0)) != -1)
+test_true(find_call_out(call_out(lambda() {},1000.0)) > 990)
+test_false(zero_type(remove_call_out(call_out(lambda() {},1000.0))))
 test_true(arrayp(call_out_info()))
 test_true(sizeof(call_out_info()) > 0)
 test_true(call_out_info()[-1][0] > 1)
-- 
GitLab


From ed36ce234cd789ea84b2289dae8a1ef38fcdcca4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 12 Aug 1996 18:13:28 +0200
Subject: [PATCH 320/351] more debug added, bugs in type_field fixed..

Rev: src/array.c:1.14
---
 src/array.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/src/array.c b/src/array.c
index e8fe55aae9..23894e04a2 100644
--- a/src/array.c
+++ b/src/array.c
@@ -105,7 +105,13 @@ void really_free_array(struct array *v)
     fatal("Tried to free the empty_array.\n");
 #endif
 
+#ifdef DEBUG
+  if(d_flag > 1)  array_check_type_field(v);
+#endif
+
+  v->refs++;
   free_svalues(ITEM(v), v->size, v->type_field);
+  v->refs--;
   array_free_no_free(v);
 }
 
@@ -1421,9 +1427,12 @@ void gc_check_all_arrays()
 
       /* Ugly, but we are not allowed to change type_field
        * at the same time as the array is being built...
+       * Actually we just need beter primitives for building arrays.
        */
       if(!(a->type_field & BIT_UNFINISHED) || a->refs!=1)
 	a->type_field = t;
+      else
+	a->type_field |= t;
     }
 
     a=a->next;
@@ -1472,3 +1481,31 @@ void gc_free_all_unreferenced_arrays()
 
 #endif /* GC2 */
 
+#ifdef DEBUG
+
+void debug_dump_type_field(TYPE_FIELD t)
+{
+  int e;
+  for(e=0;e<MAX_TYPE;e++)
+    if(t & (1<<e))
+      fprintf(stderr," %s",get_name_of_type(e));
+
+  for(;e<16;e++)
+    if(t & (1<<e))
+      fprintf(stderr," <%d>",e);
+}
+
+void debug_dump_array(struct array *a)
+{
+  fprintf(stderr,"Refs=%d, next=%p, prev=%p, size=%d, malloced_size=%d\n",
+	  a->refs,
+	  a->next,
+	  a->prev,
+	  a->size,
+	  a->malloced_size);
+  fprintf(stderr,"Type field = ");
+  debug_dump_type_field(a->type_field);
+  fprintf(stderr,"\n");
+  simple_describe_array(a);
+}
+#endif
-- 
GitLab


From 38bddc7e7f8a6d7fa8e8d700309faf4ef97153e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 12 Aug 1996 18:15:53 +0200
Subject: [PATCH 321/351] now includes <crypt.h>

Rev: src/builtin_efuns.c:1.23
---
 src/builtin_efuns.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c
index f8593a52c7..de64478002 100644
--- a/src/builtin_efuns.c
+++ b/src/builtin_efuns.c
@@ -27,11 +27,13 @@
 #include "memory.h"
 #include "time_stuff.h"
 #include <math.h>
+#include <ctype.h>
 
 #ifdef HAVE_CRYPT_H
 #include <crypt.h>
 #endif
 
+
 void f_equal(INT32 args)
 {
   int i;
-- 
GitLab


From 2d31fbc5ce3711d3fed59d7f8baf808807192564 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 12 Aug 1996 18:18:39 +0200
Subject: [PATCH 322/351] now checks for <setjmp.h>

Rev: src/configure.in:1.17
Rev: src/error.h:1.4
---
 src/configure.in | 2 +-
 src/error.h      | 8 +++++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/configure.in b/src/configure.in
index a2a383c075..c7a64cf976 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -228,7 +228,7 @@ AC_HEADER_TIME
 AC_HEADER_STDC
 AC_CHECK_HEADERS(sys/rusage.h time.h sys/time.h unistd.h stdlib.h memory.h \
 values.h string.h fcntl.h sys/filio.h sys/sockio.h crypt.h locale.h \
-sys/resource.h sys/select.h sys/mman.h)
+sys/resource.h sys/select.h sys/mman.h setjmp.h)
 
 AC_SIZEOF_TYPE(char *)
 AC_SIZEOF_TYPE(long)
diff --git a/src/error.h b/src/error.h
index 6934591dc8..e10d270379 100644
--- a/src/error.h
+++ b/src/error.h
@@ -6,9 +6,15 @@
 #ifndef ERROR_H
 #define ERROR_H
 
+#include "machine.h"
+
+#ifdef HAVE_SETJMP_H
 #include <setjmp.h>
+#undef HAVE_SETJMP_H
+#endif
+
 #include <stdarg.h>
-#include "machine.h"
+
 #include "svalue.h"
 
 
-- 
GitLab


From 0f887e2e1f0a29b8ec3e1d5323c9b67a98f1d065 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 12 Aug 1996 18:34:43 +0200
Subject: [PATCH 323/351] added stack_size variable

Rev: src/interpret.c:1.13
Rev: src/interpret.h:1.5
---
 src/interpret.c | 51 +++++++++++++++++++++++++------------------------
 src/interpret.h |  1 +
 2 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/src/interpret.c b/src/interpret.c
index 30b3c004f4..b981692d0a 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -38,8 +38,6 @@
 #ifdef MMAP_NORESERV
 #define USE_MMAP_FOR_STACK
 
-/* Fixme: just multiplying by 32 is not what we want /Hubbe */
-#define EVALUATOR_STACK_SIZE EVALUATOR_STACK_SIZE*32
 #endif
 #endif
 
@@ -51,6 +49,7 @@
  */
 struct svalue *sp;     /* Current position */
 struct svalue *evaluator_stack; /* Start of stack */
+int stack_size = EVALUATOR_STACK_SIZE;
 
 /* mark stack, used to store markers into the normal stack */
 struct svalue **mark_sp; /* Current position */
@@ -81,15 +80,15 @@ void init_interpreter()
 
 #define MMALLOC(X,Y) (Y *)mmap(0,X*sizeof(Y),PROT_READ|PROT_WRITE, MAP_NORESERV | MAP_PRIVATE | MAP_ANONYMOUS, fd, 0)
 
-  evaluator_stack=MMALLOC(EVALUATOR_STACK_SIZE,struct svalue);
-  mark_stack=MMALLOC(EVALUATOR_STACK_SIZE, struct svalue *);
+  evaluator_stack=MMALLOC(stack_size,struct svalue);
+  mark_stack=MMALLOC(stack_size, struct svalue *);
 
   if(fd != -1) close(fd);
 
   if(!evaluator_stack || !mark_sp) fatal("Failed to mmap() stack space.\n");
 #else
-  evaluator_stack=(struct svalue *)malloc(EVALUATOR_STACK_SIZE*sizeof(struct svalue));
-  mark_stack=(struct svalue **)malloc(EVALUATOR_STACK_SIZE*sizeof(struct svalue *));
+  evaluator_stack=(struct svalue *)malloc(stack_size*sizeof(struct svalue));
+  mark_stack=(struct svalue **)malloc(stack_size*sizeof(struct svalue *));
 #endif
   sp=evaluator_stack;
   mark_sp=mark_stack;
@@ -101,13 +100,13 @@ void exit_interpreter()
 
 void check_stack(INT32 size)
 {
-  if(sp - evaluator_stack + size >= EVALUATOR_STACK_SIZE)
+  if(sp - evaluator_stack + size >= stack_size)
     error("Stack overflow.\n");
 }
 
 void check_mark_stack(INT32 size)
 {
-  if(mark_sp - mark_stack + size >= EVALUATOR_STACK_SIZE)
+  if(mark_sp - mark_stack + size >= stack_size)
     error("Stack overflow.\n");
 }
 
@@ -423,7 +422,7 @@ static void eval_instruction(unsigned char *pc)
     if(sp<evaluator_stack || mark_sp < mark_stack || fp->locals>sp)
       fatal("Stack error (generic).\n");
 
-    if(sp > evaluator_stack+EVALUATOR_STACK_SIZE)
+    if(sp > evaluator_stack+stack_size)
       fatal("Stack error (overflow).\n");
 
     if(fp->fun>=0 && fp->current_object->prog &&
@@ -455,7 +454,7 @@ static void eval_instruction(unsigned char *pc)
 	set_nonblocking(2,0);
 
       file=get_line(pc-1,fp->context.prog,&linep);
-      while((f=strchr(file,'/'))) file=f+1;
+      while((f=STRCHR(file,'/'))) file=f+1;
       fprintf(stderr,"- %s:%4ld:(%lx): %-25s %4ld %4ld\n",
 	      file,(long)linep,
 	      (long)(pc-fp->context.prog->program-1),
@@ -1131,7 +1130,7 @@ void apply_low(struct object *o, int fun, int args)
     if(fp && fp->pc)
     {
       file=get_line(fp->pc,fp->context.prog,&linep);
-      while((f=strchr(file,'/'))) file=f+1;
+      while((f=STRCHR(file,'/'))) file=f+1;
     }else{
       linep=0;
       file="-";
@@ -1171,11 +1170,10 @@ void apply_low(struct object *o, int fun, int args)
 
   if(function->flags & IDENTIFIER_C_FUNCTION)
   {
-#if 0
-    function->func.c_fun(args);
-#else
-    (*function->func.c_fun)(args);
+#ifdef DEBUG
+    if(d_flag) check_signals();
 #endif
+    (*function->func.c_fun)(args);
   }else{
     int num_args;
     int num_locals;
@@ -1352,7 +1350,7 @@ void strict_apply_svalue(struct svalue *s, INT32 args)
     if(fp && fp->pc)
     {
       file=get_line(fp->pc,fp->context.prog,&linep);
-      while((f=strchr(file,'/'))) file=f+1;
+      while((f=STRCHR(file,'/'))) file=f+1;
     }else{
       linep=0;
       file="-";
@@ -1463,10 +1461,10 @@ void slow_check_stack()
 
   debug_check_stack();
 
-  if(sp > &(evaluator_stack[EVALUATOR_STACK_SIZE]))
+  if(sp > &(evaluator_stack[stack_size]))
     fatal("Stack overflow\n");
 
-  if(mark_sp > &(mark_stack[EVALUATOR_STACK_SIZE]))
+  if(mark_sp > &(mark_stack[stack_size]))
     fatal("Mark stack overflow.\n");
 
   if(mark_sp < mark_stack)
@@ -1483,17 +1481,20 @@ void slow_check_stack()
     s=*m;
   }
 
-  if(s > &(evaluator_stack[EVALUATOR_STACK_SIZE]))
+  if(s > &(evaluator_stack[stack_size]))
     fatal("Mark stack exceeds svalue stack\n");
 
   for(f=fp;f;f=f->parent_frame)
   {
-    if(f->locals < evaluator_stack ||
-       f->locals > &(evaluator_stack[EVALUATOR_STACK_SIZE]))
+    if(f->locals)
+    {
+      if(f->locals < evaluator_stack ||
+	f->locals > &(evaluator_stack[stack_size]))
       fatal("Local variable pointer points to Finsp�ng.\n");
 
-    if(f->args < 0 || f->args > EVALUATOR_STACK_SIZE)
-      fatal("FEL FEL FEL! HELP!! (corrupted frame)\n");
+      if(f->args < 0 || f->args > stack_size)
+	fatal("FEL FEL FEL! HELP!! (corrupted frame)\n");
+    }
   }
 }
 #endif
@@ -1525,8 +1526,8 @@ void cleanup_interpret()
   reset_evaluator();
 
 #ifdef USE_MMAP_FOR_STACK
-  munmap((char *)evaluator_stack, EVALUATOR_STACK_SIZE*sizeof(struct svalue));
-  munmap((char *)mark_stack, EVALUATOR_STACK_SIZE*sizeof(struct svalue *));
+  munmap((char *)evaluator_stack, stack_size*sizeof(struct svalue));
+  munmap((char *)mark_stack, stack_size*sizeof(struct svalue *));
 #else
   free((char *)evaluator_stack);
   free((char *)mark_stack);
diff --git a/src/interpret.h b/src/interpret.h
index ed2bf26332..1b0bc3b0d7 100644
--- a/src/interpret.h
+++ b/src/interpret.h
@@ -100,5 +100,6 @@ extern struct svalue **mark_sp;
 extern struct svalue *evaluator_stack;
 extern struct svalue **mark_stack;
 extern struct frame *fp; /* frame pointer */
+extern int stack_size;
 #endif
 
-- 
GitLab


From 5cf1c2db668336c190c61055d4b2cc2d7cbbf880 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 12 Aug 1996 18:46:07 +0200
Subject: [PATCH 324/351] small fix

Rev: src/language.y:1.15
Rev: src/las.c:1.13
---
 src/language.y | 1 -
 src/las.c      | 1 -
 2 files changed, 2 deletions(-)

diff --git a/src/language.y b/src/language.y
index a63046b446..122b1c8e14 100644
--- a/src/language.y
+++ b/src/language.y
@@ -158,7 +158,6 @@
 #include <memory.h>
 #endif
 
-#include <setjmp.h>
 #include "interpret.h"
 #include "array.h"
 #include "object.h"
diff --git a/src/las.c b/src/las.c
index deeca16c9d..c30cfab659 100644
--- a/src/las.c
+++ b/src/las.c
@@ -3,7 +3,6 @@
 ||| uLPC is distributed as GPL (General Public License)
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
-#include <setjmp.h>
 #include "global.h"
 #include "language.h"
 #include "interpret.h"
-- 
GitLab


From 1f3518ce1a67b3bf096d3c9df94bd842c2d79d4b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 12 Aug 1996 18:48:12 +0200
Subject: [PATCH 325/351] sv_flags not used unless SV_INTERRUPT is defined

Rev: src/lpc_signal.c:1.13
---
 src/lpc_signal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/lpc_signal.c b/src/lpc_signal.c
index a2659bc411..d137e59e38 100644
--- a/src/lpc_signal.c
+++ b/src/lpc_signal.c
@@ -174,9 +174,9 @@ static int my_signal(int sig, sigfunctype fun)
 #ifdef HAVE_SIGVEC
   {
     struct sigvec action;
+    MEMSET((char *)&action, 0, sizeof(action));
     action.sv_handler= fun;
     action.sv_mask=-1;
-    action.sv_flags=0;
 #ifdef SA_INTERRUPT
     if(fun != SIG_IGN)
       action.sv_flags=SV_INTERRUPT;
-- 
GitLab


From eeff02ee3f0e8d888fc02d768ae2a58cafeac0be Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 12 Aug 1996 18:48:30 +0200
Subject: [PATCH 326/351] now checks for <setjmp.h>

Rev: src/machine.h.in:1.12
---
 src/machine.h.in | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/machine.h.in b/src/machine.h.in
index 164149bb7b..767db662fe 100644
--- a/src/machine.h.in
+++ b/src/machine.h.in
@@ -55,6 +55,9 @@
 /* Define if you have the <unistd.h> header file.  */
 #undef HAVE_UNISTD_H
 
+/* Define if you have the <setjmp.h> header file.  */
+#undef HAVE_SETJMP_H
+
 /* more header files */
 #undef HAVE_FCNTL_H
 #undef HAVE_SYS_FILIO_H
-- 
GitLab


From 9f243ba32a67d926f195af614911c25bba6fb18b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 12 Aug 1996 18:51:04 +0200
Subject: [PATCH 327/351] added -s <stacksize>

Rev: src/main.c:1.10
---
 src/main.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/src/main.c b/src/main.c
index 3e594598d5..cf8a359059 100644
--- a/src/main.c
+++ b/src/main.c
@@ -94,6 +94,27 @@ void main(int argc, char **argv, char **env)
 	  }
 	  break;
 
+	case 's':
+	  if(!p[1])
+	  {
+	    e++;
+	    if(e >= argc)
+	    {
+	      fprintf(stderr,"Missing argument to -s\n");
+	      exit(1);
+	    }
+	    p=argv[e];
+	  }
+	  stack_size=STRTOL(p+1,&p,0);
+	  p+=strlen(p);
+
+	  if(stack_size < 256)
+	  {
+	    fprintf(stderr,"Stack size must at least be 256.\n");
+	    exit(1);
+	  }
+	  break;
+
 	case 'd':
 	  if(p[1]>='0' && p[1]<='9')
 	    d_flag+=STRTOL(p+1,&p,10);
-- 
GitLab


From 4613e5409d8b707617e81268d46f776f62cb7233 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 12 Aug 1996 18:51:57 +0200
Subject: [PATCH 328/351] strtol -> STRTOL

Rev: src/opcodes.c:1.7
---
 src/opcodes.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/opcodes.c b/src/opcodes.c
index d0ed78db3b..74e26d36f6 100644
--- a/src/opcodes.c
+++ b/src/opcodes.c
@@ -111,7 +111,7 @@ void cast(struct lpc_string *s)
 	break;
 
       case T_STRING:
-	i=strtol(sp[-1].u.string->str,0,0);
+	i=STRTOL(sp[-1].u.string->str,0,0);
 	free_string(sp[-1].u.string);
 	break;
       
@@ -257,7 +257,7 @@ void f_cast()
 	break;
 
       case T_STRING:
-	i=strtol(sp[-1].u.string->str,0,0);
+	i=STRTOL(sp[-1].u.string->str,0,0);
 	free_string(sp[-1].u.string);
 	break;
       
-- 
GitLab


From dd1981f31c5cfa9c60ad0ddbd23c806576f9e9fd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 12 Aug 1996 18:52:16 +0200
Subject: [PATCH 329/351] more debug added

Rev: src/stralloc.c:1.4
---
 src/stralloc.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/stralloc.c b/src/stralloc.c
index 6e5847e891..f6d77b5f10 100644
--- a/src/stralloc.c
+++ b/src/stralloc.c
@@ -25,6 +25,10 @@ static unsigned int StrHash(const char *s,int len)
 #ifdef DEBUG
 void check_string(struct lpc_string *s)
 {
+  StrHash(s->str, s->len);
+  if(full_hash_value != s->hval)
+    fatal("Hash value changed?\n");
+
   if(debug_findstring(s) !=s)
     fatal("Shared string not shared.\n");
 
@@ -133,7 +137,7 @@ static struct lpc_string *propagate_shared_string(const struct lpc_string *s,int
 #ifdef DEBUG
 struct lpc_string *debug_findstring(const struct lpc_string *foo)
 {
-  return propagate_shared_string(foo, StrHash(foo->str, foo->len));
+  return propagate_shared_string(foo, foo->hval % HTABLE_SIZE);
 }
 #endif
 
-- 
GitLab


From 453f4cabd24eb1d9a0d65874ab9f463bd48f72ad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 12 Aug 1996 18:56:30 +0200
Subject: [PATCH 330/351] bugfixes...

Rev: src/svalue.c:1.15
Rev: src/svalue.h:1.11
---
 src/svalue.c | 19 +++++++++++--------
 src/svalue.h |  7 +++++++
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/src/svalue.c b/src/svalue.c
index 33779ef0b4..40edf996f1 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -17,6 +17,10 @@
 #include "dynamic_buffer.h"
 #include "interpret.h"
 
+
+struct svalue dest_ob_zero = { T_INT, 0, 0 };
+
+
 /*
  * This routine frees a short svalue given a pointer to it and
  * its type.
@@ -383,13 +387,10 @@ int svalue_is_true(struct svalue *s)
     return 0;
 
   case T_FUNCTION:
-    check_destructed(s);
-    if(s->type==T_INT) return 0;
+    if(!s->u.object->prog) return 0;
     return 1;
 
   case T_OBJECT:
-    check_destructed(s);
-    if(s->type==T_INT) return 0;
     if(!s->u.object->prog) return 0;
 
     if(s->u.object->prog->lfuns[LFUN_NOT]!=-1)
@@ -410,7 +411,6 @@ int svalue_is_true(struct svalue *s)
     
 }
 
-
 int is_eq(struct svalue *a, struct svalue *b)
 {
   check_type(a->type);
@@ -418,8 +418,8 @@ int is_eq(struct svalue *a, struct svalue *b)
   check_refs(a);
   check_refs(b);
 
-  check_destructed(a);
-  check_destructed(b);
+  safe_check_destructed(a);
+  safe_check_destructed(b);
 
   if (a->type != b->type)
   {
@@ -579,6 +579,9 @@ int is_lt(struct svalue *a,struct svalue *b)
   check_refs(a);
   check_refs(b);
 
+  safe_check_destructed(a);
+  safe_check_destructed(b);
+
   if (a->type != b->type)
   {
     if(a->type == T_FLOAT && b->type==T_INT)
@@ -832,7 +835,6 @@ TYPE_FIELD gc_check_svalues(struct svalue *s, int num)
   f=0;
   for(e=0;e<num;e++,s++)
   {
-    f|= 1 << s->type;
     switch(s->type)
     {
     case T_FUNCTION:
@@ -856,6 +858,7 @@ TYPE_FIELD gc_check_svalues(struct svalue *s, int num)
       gc_check(s->u.refs);
       break;
     }
+    f|= 1 << s->type;
   }
 
   return f;
diff --git a/src/svalue.h b/src/svalue.h
index 397ae0dfda..f0d04d039a 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -108,6 +108,12 @@ do{ \
   } \
 }while(0)
 
+/* var MUST be a variable!!! */
+#define safe_check_destructed(var) do{ \
+  if((var->type == T_OBJECT || var->type==T_FUNCTION) && !var->u.object->prog) \
+    var=&dest_ob_zero; \
+}while(0)
+
 #define check_short_destructed(U,T) \
 do{ \
   union anything *_u=(U); \
@@ -131,6 +137,7 @@ do{ \
 
 #endif
 
+extern struct svalue dest_ob_zero;
 
 /* Prototypes begin here */
 void free_short_svalue(union anything *s,TYPE_T type);
-- 
GitLab


From a264cbda621c353cd56f2371a6c276bb494d417e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 12 Aug 1996 18:56:55 +0200
Subject: [PATCH 331/351] debug modified so it doesn't kill uLPC by accident..

Rev: src/modules/call_out/call_out.c:1.5
---
 src/modules/call_out/call_out.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/modules/call_out/call_out.c b/src/modules/call_out/call_out.c
index 513419a3c3..08f13f4066 100644
--- a/src/modules/call_out/call_out.c
+++ b/src/modules/call_out/call_out.c
@@ -60,8 +60,8 @@ static void verify_call_outs()
     if(!(v=pending_calls[e]->args))
       fatal("No arguments to call\n");
 
-    if(v->refs!=1)
-      fatal("Array should exactly have one reference.\n");
+    if(v->refs < 1)
+      fatal("Array should have at least one reference.\n");
 
     if(v->malloced_size<v->size)
       fatal("Impossible array.\n");
-- 
GitLab


From 28ab08cf065ebcbe519f317ccd1d34950f3a5ce1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 12 Aug 1996 18:57:13 +0200
Subject: [PATCH 332/351] bugfix, no more memory trashes...

Rev: src/modules/files/file.c:1.17
---
 src/modules/files/file.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index d3ada13753..b2b05ebdbc 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -46,6 +46,14 @@
 #include <netdb.h>
 #endif
 
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
 #define FD (*(int*)(fp->current_storage))
 #define THIS (files + FD)
 
@@ -451,14 +459,12 @@ static void file_open(INT32 args)
   if(!( flags &  (FILE_READ | FILE_WRITE)))
     error("Must open file for at least one of read and write.\n");
 
-  THIS->errno = 0;
-
  retry:
   fd=open(sp[-args].u.string->str,map(flags), 00666);
 
   if(fd >= MAX_OPEN_FILEDESCRIPTORS)
   {
-    THIS->errno=EBADF;
+    /* THIS->errno=EBADF;  THIS is invalid here...*/
     close(fd);
     fd=-1;
   }
@@ -467,13 +473,14 @@ static void file_open(INT32 args)
     if(errno == EINTR)
       goto retry;
 
-    THIS->errno=errno;
+    /* THIS->errno=EBADF;  THIS is invalid here...*/
   }
   else
   {
-    set_close_on_exec(fd,1);
     init_fd(fd,flags);
     FD=fd;
+    THIS->errno = 0;
+    set_close_on_exec(fd,1);
   }
 
   pop_n_elems(args);
@@ -1028,14 +1035,14 @@ static void file_open_socket(INT32 args)
   fd=socket(AF_INET, SOCK_STREAM, 0);
   if(fd >= MAX_OPEN_FILEDESCRIPTORS)
   {
-    THIS->errno = EBADF;
+    /* THIS->errno = EBADF;   THIS is invalid here ..*/
     pop_n_elems(args);
     push_int(0);
     return;
   }
   if(fd < 0)
   {
-    THIS->errno=errno;
+    /* THIS->errno = errno;   THIS is invalid here ..*/
     pop_n_elems(args);
     push_int(0);
     return;
-- 
GitLab


From 361ca429f26da6e240c08af16e05aafe0e1d1488 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 12 Aug 1996 18:57:47 +0200
Subject: [PATCH 333/351] doc fixed..

Rev: src/modules/gdbmmod/doc/gdbm:1.2
---
 src/modules/gdbmmod/doc/gdbm | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/modules/gdbmmod/doc/gdbm b/src/modules/gdbmmod/doc/gdbm
index 1811ac0486..2270467e18 100644
--- a/src/modules/gdbmmod/doc/gdbm
+++ b/src/modules/gdbmmod/doc/gdbm
@@ -144,6 +144,7 @@ SYNTAX
 DESCRIPTION
 	When opening the database with the 'f' flag writings to the database
 	can be cached in memory for a long time. Calling sync will write
-	all such caches to disk and not return until 
+	all such caches to disk and not return until everything is stored
+	on the disk.
 
 ============================================================================
-- 
GitLab


From 673ac3923067b5b2d06797ba485593924e9d9fc3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 12 Aug 1996 18:58:04 +0200
Subject: [PATCH 334/351] more mapping tests added

Rev: src/test/create_testsuite:1.24
---
 src/test/create_testsuite | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index 242422d770..f9044479c7 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -288,9 +288,9 @@ test_any([[mapping m=([]);int e;
   b=allocate(100);
   for(e=0;e<100;e++)
   {
-    m[reverse(e)]=e;
-    a[e]=reverse(e);
-    b[e]=reverse(e);
+    m[reverse(e-50)]=e-50;
+    a[e]=reverse(e-50);
+    b[e]=reverse(e-50);
   }
   add_efun("mtest_m2",m);
   add_efun("mtest_i2",a);
@@ -298,14 +298,18 @@ test_any([[mapping m=([]);int e;
   return 1;
 ]],1)
 
-test_equal(sort_array(indices(mtest_m|mtest_m2)),sort_array(mtest_i|mtest_i2))
-test_equal(sort_array(indices(mtest_m&mtest_m2)),sort_array(mtest_i&mtest_i2))
-test_equal(sort_array(indices(mtest_m-mtest_m2)),sort_array(mtest_i-mtest_i2))
-test_equal(sort_array(indices(mtest_m^mtest_m2)),sort_array(mtest_i^mtest_i2))
-test_equal(sort_array(indices(mtest_m2|mtest_m)),sort_array(mtest_i2|mtest_i))
-test_equal(sort_array(indices(mtest_m2&mtest_m)),sort_array(mtest_i2&mtest_i))
-test_equal(sort_array(indices(mtest_m2-mtest_m)),sort_array(mtest_i2-mtest_i))
-test_equal(sort_array(indices(mtest_m2^mtest_m)),sort_array(mtest_i2^mtest_i))
+test_any([[int e;mapping q=([]),p=([]); for(e=0;e<1000;e++) { p[reverse(e)]=e; q+=([reverse(e):e]); if(!equal(sort(indices(p)),sort(indices(q)))) return 0; } return 1;]],1)
+test_any([[mapping m=([]); m+=(["foo":"bar"]); m+=(["bar":"foo"]); m+=(["foo":"foo"]); return m["foo"]=="foo" && m["bar"]=="foo"]],1)
+test_any([[mixed m=([]); m+=(["foo":"bar"]); m+=(["bar":"foo"]); m+=(["foo":"foo"]); return m["foo"]=="foo" && m["bar"]=="foo"]],1)
+
+test_equal(sort(indices(mtest_m|mtest_m2)),sort(mtest_i|mtest_i2))
+test_equal(sort(indices(mtest_m&mtest_m2)),sort(mtest_i&mtest_i2))
+test_equal(sort(indices(mtest_m-mtest_m2)),sort(mtest_i-mtest_i2))
+test_equal(sort(indices(mtest_m^mtest_m2)),sort(mtest_i^mtest_i2))
+test_equal(sort(indices(mtest_m2|mtest_m)),sort(mtest_i2|mtest_i))
+test_equal(sort(indices(mtest_m2&mtest_m)),sort(mtest_i2&mtest_i))
+test_equal(sort(indices(mtest_m2-mtest_m)),sort(mtest_i2-mtest_i))
+test_equal(sort(indices(mtest_m2^mtest_m)),sort(mtest_i2^mtest_i))
 
 define(MTEST,[[test_equal([[mkmapping(indices(allocate($1)),reverse(indices(allocate($1))))]],[[mkmapping(reverse(indices(allocate($1))),indices(allocate($1)))]])]])
 
@@ -1752,6 +1756,13 @@ test_true(stringp(ctime(0)))
 
 // - destruct
 // FIXME put tests for destruct here.
+test_do(add_efun("PROG",compile_string("int foo() { return 1; }")));
+test_any([[object o=clone(PROG); destruct(o); return o]],0);
+test_any([[object o=clone(PROG); destruct(o); return objectp(o)]],0);
+test_any([[object *o=({clone(PROG)}); destruct(o[0]); return o-({0}) ]],({}));
+test_any([[mapping o=(["foo":clone(PROG)]); destruct(o["foo"]); return o["foo"]; ]],0);
+dnl test_any([[object t; mapping o=([t=clone(PROG):"foo"]); destruct(t); return sizeof(o)]],0);
+test_do([[object t,*o=({}); o+=({t=clone(PROG)}); destruct(t); o=({});]]);
 
 // - equal
 // equl is already tested by this script
-- 
GitLab


From 3378c302a6355c92533d08c18a0100d599a2222e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 13 Aug 1996 12:35:50 +0200
Subject: [PATCH 335/351] added -s <stacksize>

Rev: doc/lpc/command_line_options:1.2
---
 doc/lpc/command_line_options | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/lpc/command_line_options b/doc/lpc/command_line_options
index 8e39eb6ced..a81182db1c 100644
--- a/doc/lpc/command_line_options
+++ b/doc/lpc/command_line_options
@@ -26,4 +26,4 @@ These options can be specified on the command line to uLPC:
 -a<number>	   set asdebug
 	This controls debug output for the code generator.
 
-	
+-s<number>	   Set evaluator stack size.
-- 
GitLab


From af3c05f5c794d5de7fe9f601fccf4fd16eac6eed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 13 Aug 1996 12:36:25 +0200
Subject: [PATCH 336/351] ignore more

Rev: .cvsignore:1.12
---
 .cvsignore | 3 +++
 .gitignore | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/.cvsignore b/.cvsignore
index 344e921aa3..ab5fe50bda 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -1,5 +1,8 @@
+245lpc.tar.gz
+LPCsim.lpc
 bottles.lpc
 build
+mudlib
 reports
 test
 test.lpc
diff --git a/.gitignore b/.gitignore
index 15e0f5f3ac..52302b224a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,8 +30,11 @@ _$*
 *.elc
 *.ln
 core
+/245lpc.tar.gz
+/LPCsim.lpc
 /bottles.lpc
 /build
+/mudlib
 /reports
 /test
 /test.lpc
-- 
GitLab


From 29099f898e5907f2e187045d54ae36d37664889b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 13 Aug 1996 12:37:01 +0200
Subject: [PATCH 337/351] new file describing the index operator

Rev: doc/operators/index:1.1
---
 doc/operators/index | 53 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100644 doc/operators/index

diff --git a/doc/operators/index b/doc/operators/index
new file mode 100644
index 0000000000..2e04962ce8
--- /dev/null
+++ b/doc/operators/index
@@ -0,0 +1,53 @@
+NAME
+	index - get/set an element in an array/string/mapping/object
+
+SYNTAX
+	a [ b ]
+	or
+	a [ b ] = c
+	or
+	a -> b
+
+DESCRIPTION
+	This operator does a lookup in 'a' to find the element named 'b' in
+	'a'. The last syntax (a->b) is equal to a [ "b" ]. Different usage
+	applies	to different types.
+
+	Strings	With strings, the index operator can only be used to get values
+		not change them. The index must be an integer, and the return
+		value will be the ascii value of the corresponding character
+		in the string. The first character is numbered 0.
+	Arrays	As with strings, arrays can only be indexed on integers.
+		However, values can also be changed by using indexing on the
+		left side of an assignment. The values in the array can have
+		any type. As with strings, the first index is 0.
+	Mappings	Mappings can be indexed on any type of value, quite
+		often they are indexed on strings. Values can be changed
+		as with arrays. Mappings do not have a fixed size, nor do they
+		have a specific order in which the values are stored. If you
+		attempt to set a value in a mapping that does not already
+		exists, the mapping will grow to include the new value.
+		There is no 'first' index for mappings.
+	Lists	Lists can be also be indexed on any value, but the return
+		value only reflects a true/false status depending on weather
+		that index was present in the list. As with mappings, lists
+		will grow when you try to set a value in it that is does not
+		already exists. However lists will only grow if the inserted
+		'c' is nonzero.
+	Object	Objects can only be indexed on strings. It then gets/sets the
+		value of the variable with that name. If the 'variable' isn't
+		a variable at all, but a function it will return a pointer to
+		that function but you can't change it.
+
+EXAMPLES
+	"foobar"[2]	returns 111  /* ascii for 'o' */
+	"foobar"[0]	returns 102  /* ascii for 'f' */
+	({1,2,3})[1]	returns 2
+	([1:2})[1]	returns 2
+	(<1,2,3>)[2]	returns 1
+
+KEYWORDS
+	operators
+
+SEE ALSO
+	index
-- 
GitLab


From 53368e50c269883f600d2cdb20cd7466fef61436 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 13 Aug 1996 12:37:12 +0200
Subject: [PATCH 338/351] doc on index operator fixed

Rev: doc/types/array:1.6
---
 doc/types/array | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/doc/types/array b/doc/types/array
index d07e772eeb..37f2cd554d 100644
--- a/doc/types/array
+++ b/doc/types/array
@@ -11,8 +11,13 @@ DESCRIPTION
 	allocated and does not need to be declared as in C. The values in
 	the array can be set when creating the array as in the first
 	construction or anytime afterwards like this: arr[index]=data where
-	index is an integer greater or equal to 0 and smaller than the array
-	size. Note that arrays are shared and use reference counts to keep
+	index is an integer. Index is normally 0 <= index < sizeof(arr), and
+	refers to the corresponding element in the array. If index is less
+	than zero, it is the same as doing arr[sizeof(arr)+index]. This
+	means that negative index will index the array from the end rather
+	than from the beginning.
+
+	Note that arrays are shared and use reference counts to keep
 	track of their references. This will have the effect that you can
 	have two variables pointing to the same array, and when you change
 	an index in in it, both variables will show the change.
-- 
GitLab


From ea5330992d99685577a47d925d9ff1e5f593fff5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 13 Aug 1996 12:37:21 +0200
Subject: [PATCH 339/351] entries added

Rev: src/ChangeLog:1.46
---
 src/ChangeLog | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index cabb09f384..29a4f75138 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,16 @@
+Tue Aug 13 12:16:06 1996  Fredrik Hubinette  <hubbe@freeone.signum.se>
+
+	* gpmmod should now work with older versions of GMP.
+
+Mon Aug 12 18:08:12 1996  Fredrik Hubinette  <hubbe@sparky.signum.se>
+
+	* array.c: some bugs in type_field fixed
+	* array.c: more debug added
+	* main.c: -s <stacksize> added
+	* svalue.c: made is_eq 'safe' (it does not change the svalue argument)
+	* svalue.c: type_field bug fixed in garbage collect
+	* file.c: a memory trashing bug fixed when opening files...
+
 Tue Aug  6 13:33:51 1996  Fredrik Hubinette  <hubbe@axel.signum.se>
 
 	* call_out.c: call outs now have unique ids, so you can remove
-- 
GitLab


From bc7ca8c9fd85be32ef09b22b99941f0e81b86e04 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 13 Aug 1996 12:37:50 +0200
Subject: [PATCH 340/351] should now work with older versions of GMP

Rev: src/modules/gmpmod/configure.in:1.4
Rev: src/modules/gmpmod/gmp_machine.h.in:1.3
Rev: src/modules/gmpmod/mpz_glue.c:1.4
---
 src/modules/gmpmod/configure.in     | 16 ----------------
 src/modules/gmpmod/gmp_machine.h.in |  3 ---
 src/modules/gmpmod/mpz_glue.c       | 13 +++++--------
 3 files changed, 5 insertions(+), 27 deletions(-)

diff --git a/src/modules/gmpmod/configure.in b/src/modules/gmpmod/configure.in
index 9cecf8fc30..b8c1fa3b4a 100644
--- a/src/modules/gmpmod/configure.in
+++ b/src/modules/gmpmod/configure.in
@@ -8,22 +8,6 @@ AC_SUBST(RANLIB)
 AC_CHECK_HEADERS(gmp.h)
 AC_CHECK_LIB(gmp, mpz_set_si)
 
-AC_MSG_CHECKING(if libgmp is new enough)
-AC_CACHE_VAL(lpc_cv_lib_gmp_is_new_enough,
-[
-AC_TRY_COMPILE([#include <gmp.h>],[
-mpz_t foo;
-return 0;
-],lpc_cv_lib_gmp_is_new_enough=yes,lpc_cv_lib_gmp_is_new_enough=no)
-])
-
-if test "$lpc_cv_lib_gmp_is_new_enough" = yes; then
-  AC_MSG_RESULT(yes)
-  AC_DEFINE(HAVE_NEW_GMP)
-else
-  AC_MSG_RESULT(no)
-fi
-
 AC_OUTPUT(Makefile,echo FOO >stamp-h )
 
 
diff --git a/src/modules/gmpmod/gmp_machine.h.in b/src/modules/gmpmod/gmp_machine.h.in
index d53e0cbc1c..0a79aef13b 100644
--- a/src/modules/gmpmod/gmp_machine.h.in
+++ b/src/modules/gmpmod/gmp_machine.h.in
@@ -4,7 +4,4 @@
 /* Define this if you have <gmp.h> */
 #undef HAVE_GMP_H
 
-/* Define this if your gmp is version 2.0 or newer */
-#undef HAVE_NEW_GMP
-
 #endif
diff --git a/src/modules/gmpmod/mpz_glue.c b/src/modules/gmpmod/mpz_glue.c
index 5c2e502ec9..944861b340 100644
--- a/src/modules/gmpmod/mpz_glue.c
+++ b/src/modules/gmpmod/mpz_glue.c
@@ -7,10 +7,6 @@
 #include "gmp_machine.h"
 #include "types.h"
 
-#ifndef HAVE_NEW_GMP
-#undef HAVE_GMP_H
-#endif
-
 #ifdef HAVE_GMP_H
 
 #include "interpret.h"
@@ -25,12 +21,13 @@
 
 #include <gmp.h>
 
-#define THIS (*(mpz_t *)(fp->current_storage))
-#define OBTOMPZ(o) (*(mpz_t *)(o->storage))
+
+#define THIS (*(MP_INT **)(fp->current_storage))
+#define OBTOMPZ(o) (*(MP_INT **)(o->storage))
 
 static struct program *mpzmod_program;
 
-static void get_new_mpz(mpz_t tmp, struct svalue *s)
+static void get_new_mpz(MP_INT *tmp, struct svalue *s)
 {
   switch(s->type)
   {
@@ -392,7 +389,7 @@ void init_gmpmod_programs(void)
 {
 #ifdef HAVE_GMP_H
   start_new_program();
-  add_storage(sizeof(mpz_t));
+  add_storage(sizeof(MP_INT *));
   
   add_function("create",mpzmod_create,"function(void|string|int|float|object:void)",0);
 
-- 
GitLab


From 9caa732b2caa48b6f9dc7ab5d0ef02377ae18c74 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 15 Aug 1996 01:37:57 +0200
Subject: [PATCH 341/351] minor fixes

Rev: bin/metatest:1.4
---
 bin/metatest | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/bin/metatest b/bin/metatest
index c2ccba6cd7..c29a892845 100755
--- a/bin/metatest
+++ b/bin/metatest
@@ -28,16 +28,10 @@ docompile5() {
   rm -rf test1
 }
 
-docompile4() {
-  docompile5 "$1"
-#  docompile5 "$1 -DDYNAMIC_STACK"
-#  docompile5 "$1 -DDYNAMIC_STACK -DREALLOC_STACK_ALWAYS"
-}
-
 docompile3() {
-  docompile4 "$1"
-  docompile4 "$1 -DFLAT_MAPPINGS"
-  docompile4 "$1 -DOLD_MAPPINGS"
+  docompile5 "$1"
+  docompile5 "$1 -DFLAT_MAPPINGS"
+  docompile5 "$1 -DOLD_MAPPINGS"
 }
 
 docompile2() {
-- 
GitLab


From 00460640e1c689685dc297fd5a2ce5d15e74fda6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 15 Aug 1996 01:38:10 +0200
Subject: [PATCH 342/351] operator overloading added

Rev: doc/lpc/cast:1.2
---
 doc/lpc/cast | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/doc/lpc/cast b/doc/lpc/cast
index 0ce25fc9fb..c55f817036 100644
--- a/doc/lpc/cast
+++ b/doc/lpc/cast
@@ -21,8 +21,23 @@ DESCRIPTION
 	given by that string. It will then put the program in a chache in
 	case you cast the same string to a program again later.
 
+	Castring from string to object will call cast_to_object in the
+	master object and request an object to return. The standard master
+	object will consider the string a file name, cast it to a program
+	and return a clone of that file. If the same cast is attempted again
+	later, the _same_ object will be returned.
+
+	When casting an object, the method o->cast will be called with a string
+	with the name of the type as argument. o->cast can then return any
+	value.
+
 	In all other cases, casts are just compiler hints.
 
+EXAMPLES
+	(program)"/precompiled/file"	// returns the file program
+	(object)"/precompiled/file"	// returns a clone of the file program
+	(int)(object)"/precompiled/mpz" // returns 0
+
 KEYWORDS
 	lpc
 
-- 
GitLab


From e84cccc11d433d7ed766925910ad8a0d7c52204f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 15 Aug 1996 01:38:30 +0200
Subject: [PATCH 343/351] commend about #define foo bar // added

Rev: doc/lpc/preprocessor:1.4
---
 doc/lpc/preprocessor | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/doc/lpc/preprocessor b/doc/lpc/preprocessor
index 3c45c0d9db..8a9f42c1c0 100644
--- a/doc/lpc/preprocessor
+++ b/doc/lpc/preprocessor
@@ -56,6 +56,16 @@ DESCRIPTION
 	'identifier(something1,something2d)' would be replaced with
 	the replacement string. And in the replacement string, arg1 and arg2
 	will be replaced with something1 and something2.
+
+BUGS
+	Note that it is not a good idea to do something like this:
+
+	#define foo bar // a comment
+
+	The comment will be included in the define, and thus inserted in the
+	code. This will have the effect that the rest of the line will be
+	ignored when the word foo is used. Not exactly what you might expect.
+
 ============================================================================
 DIRECTIVE
 	#undef
@@ -127,7 +137,7 @@ DESCRIPTION
 
 EXAMPLES
 	#if !efun(write_file)
-	#error Move object is missing
+	#error Write file efun is missing
 	#endif
 ============================================================================
 DIRECTIVE
-- 
GitLab


From 969206c41a7e6a5fae6fc70c16e9aafc388e3255 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 15 Aug 1996 01:39:09 +0200
Subject: [PATCH 344/351] version updated

Rev: lib/simulate.lpc:1.22
---
 lib/simulate.lpc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/simulate.lpc b/lib/simulate.lpc
index 266178226d..fc16910306 100644
--- a/lib/simulate.lpc
+++ b/lib/simulate.lpc
@@ -367,7 +367,7 @@ void create()
   add_efun("sum_arrays",sum_arrays);
   add_efun("system",system);
   add_efun("this_function",this_function);
-  add_efun("version",lambda() { return "uLPC v1.1E-6"; });
+  add_efun("version",lambda() { return "uLPC v0.000002"; });
   add_efun("write_file",write_file);
 }
 
-- 
GitLab


From 404e713b49c3ea2eeb40fcad0ce25c2e85ca8611 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 15 Aug 1996 01:39:26 +0200
Subject: [PATCH 345/351] expandmax changed

Rev: src/lex.c:1.13
---
 src/lex.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/lex.c b/src/lex.c
index cb68bde713..6f19a50801 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -30,7 +30,7 @@
 #include "time_stuff.h"
 
 #define LEXDEBUG 0
-#define EXPANDMAX 50000
+#define EXPANDMAX 500000
 
 struct lpc_string *current_file;
 
-- 
GitLab


From 2c1bbbe3bc173a3c213515747968d1e8bb66c9da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 15 Aug 1996 01:39:41 +0200
Subject: [PATCH 346/351] (cast)mpz documented

Rev: src/modules/gmpmod/doc/mpz:1.2
---
 src/modules/gmpmod/doc/mpz | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/src/modules/gmpmod/doc/mpz b/src/modules/gmpmod/doc/mpz
index 596b815876..6bd4668b92 100644
--- a/src/modules/gmpmod/doc/mpz
+++ b/src/modules/gmpmod/doc/mpz
@@ -74,3 +74,25 @@ DESCRIPTION
 	This function returns the greatest common divisor for arg and mpz.
 
 ============================================================================
+NAME
+	cast - cast to other type
+
+SYNTAX
+	object mpz->gcd( "string" | "int" | "float" );
+	or
+	(string) mpz
+	or
+	(int) mpz
+	or
+	(float) mpz
+
+
+DESCRIPTION
+	This function converts an mpz to a string, int or float. This is
+	nessesary when you want to view, store or use the result of an mpz
+	calculation.
+
+SEE ALSO
+	cast
+
+============================================================================
-- 
GitLab


From fc656ecaf73656856bbf36ada247d20382d7267d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Thu, 15 Aug 1996 01:40:04 +0200
Subject: [PATCH 347/351] mapping addition test modified

Rev: src/test/create_testsuite:1.25
---
 src/test/create_testsuite | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/test/create_testsuite b/src/test/create_testsuite
index f9044479c7..7e1a7c6dc3 100755
--- a/src/test/create_testsuite
+++ b/src/test/create_testsuite
@@ -299,8 +299,7 @@ test_any([[mapping m=([]);int e;
 ]],1)
 
 test_any([[int e;mapping q=([]),p=([]); for(e=0;e<1000;e++) { p[reverse(e)]=e; q+=([reverse(e):e]); if(!equal(sort(indices(p)),sort(indices(q)))) return 0; } return 1;]],1)
-test_any([[mapping m=([]); m+=(["foo":"bar"]); m+=(["bar":"foo"]); m+=(["foo":"foo"]); return m["foo"]=="foo" && m["bar"]=="foo"]],1)
-test_any([[mixed m=([]); m+=(["foo":"bar"]); m+=(["bar":"foo"]); m+=(["foo":"foo"]); return m["foo"]=="foo" && m["bar"]=="foo"]],1)
+test_any([[mapping m=([]); m+=(["foo":"bar"]); m+=(["bar":"foo"]); m+=(["foo":"foo"]); if(sizeof(m)==3) return 1; return m["foo"]=="foo" && m["bar"]=="foo"]],1)
 
 test_equal(sort(indices(mtest_m|mtest_m2)),sort(mtest_i|mtest_i2))
 test_equal(sort(indices(mtest_m&mtest_m2)),sort(mtest_i&mtest_i2))
-- 
GitLab


From 5c28f5c0038baf1a38efa6cdaca2e030c2ad1ab3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 19 Aug 1996 22:53:37 +0200
Subject: [PATCH 348/351] fixed

Rev: doc/builtin/destruct:1.3
---
 doc/builtin/destruct | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/builtin/destruct b/doc/builtin/destruct
index 6a3567e9dc..22b2bfefc4 100644
--- a/doc/builtin/destruct
+++ b/doc/builtin/destruct
@@ -8,7 +8,7 @@ DESCRIPTION
 	Destruct marks an object as destructed, all pointers and function
 	pointers to this object will become zero. The destructed object will
 	be freed from memory as soon as possible. This will also call
-	o->destroyed.
+	o->destroy.
 
 KEYWORDS
 	object
-- 
GitLab


From cfbf7244adde3df7ca575cb7a3ae5c999e0a9a27 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Mon, 19 Aug 1996 22:54:43 +0200
Subject: [PATCH 349/351] ignored

Rev: .cvsignore:1.13
---
 .cvsignore | 1 +
 .gitignore | 1 +
 2 files changed, 2 insertions(+)

diff --git a/.cvsignore b/.cvsignore
index ab5fe50bda..f1f841b61f 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -8,6 +8,7 @@ test
 test.lpc
 test1
 testcache
+uLPC_v0.000002.tar.gz
 uLPC_v1.0E-10.tar.gz
 uLPC_v1.0E-12.tar.gz
 uLPC_v1.0E-13.tar.gz
diff --git a/.gitignore b/.gitignore
index 52302b224a..26e7ec5bc9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,6 +40,7 @@ core
 /test.lpc
 /test1
 /testcache
+/uLPC_v0.000002.tar.gz
 /uLPC_v1.0E-10.tar.gz
 /uLPC_v1.0E-12.tar.gz
 /uLPC_v1.0E-13.tar.gz
-- 
GitLab


From 0839bb1ef253adb693a197f97da7e6d745a49aa3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 13 Sep 1996 02:29:42 +0200
Subject: [PATCH 350/351] comment added

Rev: src/ChangeLog:1.47
---
 src/ChangeLog | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/ChangeLog b/src/ChangeLog
index 29a4f75138..d8f50fe7ed 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+Tue Aug 20 01:16:48 1996  Fredrik Hubinette  <hubbe@signum.se>
+
+	* version 0.000002 released
+
 Tue Aug 13 12:16:06 1996  Fredrik Hubinette  <hubbe@freeone.signum.se>
 
 	* gpmmod should now work with older versions of GMP.
-- 
GitLab


From c96524a7b4d07d4411207126d7e5a81ad8d15c96 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Fri, 13 Sep 1996 02:33:07 +0200
Subject: [PATCH 351/351] small bugfix

Rev: src/modules/gmpmod/mpz_glue.c:1.5
---
 src/modules/gmpmod/mpz_glue.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/modules/gmpmod/mpz_glue.c b/src/modules/gmpmod/mpz_glue.c
index 944861b340..d13479dc7d 100644
--- a/src/modules/gmpmod/mpz_glue.c
+++ b/src/modules/gmpmod/mpz_glue.c
@@ -22,8 +22,8 @@
 #include <gmp.h>
 
 
-#define THIS (*(MP_INT **)(fp->current_storage))
-#define OBTOMPZ(o) (*(MP_INT **)(o->storage))
+#define THIS ((MP_INT *)(fp->current_storage))
+#define OBTOMPZ(o) ((MP_INT *)(o->storage))
 
 static struct program *mpzmod_program;
 
@@ -389,7 +389,7 @@ void init_gmpmod_programs(void)
 {
 #ifdef HAVE_GMP_H
   start_new_program();
-  add_storage(sizeof(MP_INT *));
+  add_storage(sizeof(MP_INT));
   
   add_function("create",mpzmod_create,"function(void|string|int|float|object:void)",0);
 
-- 
GitLab