Mercurial > hg > xemacs-beta
view src/tests.c @ 4921:17362f371cc2
add more byte-code assertions and better failure output
-------------------- ChangeLog entries follow: --------------------
src/ChangeLog addition:
2010-02-03 Ben Wing <ben@xemacs.org>
* alloc.c (Fmake_byte_code):
* bytecode.h:
* lisp.h:
* lread.c:
* lread.c (readevalloop):
* lread.c (Fread):
* lread.c (Fread_from_string):
* lread.c (read_list_conser):
* lread.c (read_list):
* lread.c (vars_of_lread):
* symbols.c:
* symbols.c (Fdefine_function):
Turn on the "compiled-function annotation hack". Implement it
properly by hooking into Fdefalias(). Note in the docstring to
`defalias' that we do this. Remove some old broken code and
change code that implemented the old kludgy way of hooking into
the Lisp reader into bracketed by `#ifdef
COMPILED_FUNCTION_ANNOTATION_HACK_OLD_WAY', which is not enabled.
Also enable byte-code metering when DEBUG_XEMACS -- this is a form
of profiling for computing histograms of which sequences of two
bytecodes are used most often.
* bytecode-ops.h:
* bytecode-ops.h (OPCODE):
New file. Extract out all the opcodes and declare them using
OPCODE(), a bit like frame slots and such. This way the file can
be included multiple times if necessary to iterate multiple times
over the byte opcodes.
* bytecode.c:
* bytecode.c (NUM_REMEMBERED_BYTE_OPS):
* bytecode.c (OPCODE):
* bytecode.c (assert_failed_with_remembered_ops):
* bytecode.c (READ_UINT_2):
* bytecode.c (READ_INT_1):
* bytecode.c (READ_INT_2):
* bytecode.c (PEEK_INT_1):
* bytecode.c (PEEK_INT_2):
* bytecode.c (JUMP_RELATIVE):
* bytecode.c (JUMP_NEXT):
* bytecode.c (PUSH):
* bytecode.c (POP_WITH_MULTIPLE_VALUES):
* bytecode.c (DISCARD):
* bytecode.c (UNUSED):
* bytecode.c (optimize_byte_code):
* bytecode.c (optimize_compiled_function):
* bytecode.c (Fbyte_code):
* bytecode.c (vars_of_bytecode):
* bytecode.c (init_opcode_table_multi_op):
* bytecode.c (reinit_vars_of_bytecode):
* emacs.c (main_1):
* eval.c (funcall_compiled_function):
* symsinit.h:
Any time we change either the instruction pointer or the stack
pointer, assert that we're going to move it to a valid location.
This should catch failures right when they occur rather than
sometime later. This requires that we pass in another couple of
parameters into some functions (only with error-checking enabled,
see below).
Also keep track, using a circular queue, of the last 100 byte
opcodes seen, and when we hit an assert failure during byte-code
execution, output the contents of the queue in a nice readable
fashion. This requires that bytecode-ops.h be included a second
time so that a table mapping opcodes to the name of their operation
can be constructed. This table is constructed in new function
reinit_vars_of_bytecode().
Everything in the last two paras happens only when
ERROR_CHECK_BYTE_CODE.
Add some longish comments describing how the arrays that hold the
stack and instructions, and the pointers used to access them, work.
* gc.c:
Import some code from my `latest-fix' workspace to mark the
staticpro's in order from lowest to highest, rather than highest to
lowest, so it's easier to debug when something goes wrong.
* lisp.h (abort_with_message): Renamed from abort_with_msg().
* symbols.c (defsymbol_massage_name_1):
* symbols.c (defsymbol_nodump):
* symbols.c (defsymbol):
* symbols.c (defkeyword):
* symeval.h (DEFVAR_SYMVAL_FWD_OBJECT):
Make the various calls to staticpro() instead call staticpro_1(),
passing in the name of the C var being staticpro'ed, so that it
shows up in staticpro_names. Otherwise staticpro_names just has
1000+ copies of the word `location'.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Wed, 03 Feb 2010 08:01:55 -0600 |
parents | b8afe0f9cbe3 |
children | 19a72041c5ed |
line wrap: on
line source
/* C support for testing XEmacs - see tests/automated/c-tests.el Copyright (C) 2000 Martin Buchholz Copyright (C) 2001, 2002 Ben Wing. Copyright (C) 2006 The Free Software Foundation, Inc. This file is part of XEmacs. XEmacs 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. XEmacs 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 XEmacs; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Author: Martin Buchholz This file provides support for running tests for XEmacs that cannot be written entirely in Lisp. These tests are run automatically via tests/automated/c-tests.el, or can be run by hand using M-x */ #include <config.h> #include "lisp.h" #include "buffer.h" #include "lstream.h" #include "elhash.h" #include "opaque.h" #include "file-coding.h" /* XCODING_SYSTEM_EOL_TYPE and its values */ static Lisp_Object Vtest_function_list; DEFUN ("test-data-format-conversion", Ftest_data_format_conversion, 0, 0, "", /* Return list of results of test TO_EXTERNAL_FORMAT() and TO_INTERNAL_FORMAT(). For use by the automated test suite. See tests/automated/c-tests. Each element is a list (DESCRIPTION, STATUS, REASON). DESCRIPTION is a string describing the test. STATUS is a symbol, either t (pass) or nil (fail). REASON is nil or a string describing the failure (not required). */ ()) { void *ptr; Bytecount len; Lisp_Object string, opaque, conversion_result = Qnil; Ibyte int_foo[] = "\n\nfoo\nbar"; Extbyte ext_unix[]= "\n\nfoo\nbar"; Extbyte ext_dos[] = "\r\n\r\nfoo\r\nbar"; Extbyte ext_mac[] = "\r\rfoo\rbar"; Lisp_Object opaque_dos = make_opaque (ext_dos, sizeof (ext_dos) - 1); Lisp_Object string_foo = make_string (int_foo, sizeof (int_foo) - 1); Extbyte ext_latin[] = "f\372b\343\340"; Ibyte int_latin1[] = "f\200\372b\200\343\200\340"; Ibyte int_latin2[] = "f\201\372b\201\343\201\340"; #ifdef MULE Extbyte ext_latin12[]= "f\033-A\372b\343\340\033-B"; Extbyte ext_tilde[] = "f~b~~"; Lisp_Object string_latin2 = make_string (int_latin2, sizeof (int_latin2) - 1); #endif Lisp_Object opaque_latin = make_opaque (ext_latin, sizeof (ext_latin) - 1); Lisp_Object opaque0_latin = make_opaque (ext_latin, sizeof (ext_latin)); Lisp_Object string_latin1 = make_string (int_latin1, sizeof (int_latin1) - 1); int autodetect_eol_p = !NILP (Fsymbol_value (intern ("eol-detection-enabled-p"))); /* Check for expected strings before and after conversion. Conversions depend on whether MULE is defined. */ /* #### Any code below that uses iso-latin-2-with-esc is ill-conceived. */ #ifdef MULE #define DFC_CHECK_DATA_COND_MULE(ptr,len, \ constant_string_mule, \ constant_string_non_mule, \ description) \ DFC_CHECK_DATA (ptr, len, constant_string_mule, description) #define DFC_CHECK_DATA_COND_MULE_NUL(ptr,len, \ constant_string_mule, \ constant_string_non_mule, \ description) \ DFC_CHECK_DATA_NUL (ptr, len, constant_string_mule, description) #else #define DFC_CHECK_DATA_COND_MULE(ptr,len, \ constant_string_mule, \ constant_string_non_mule, \ description) \ DFC_CHECK_DATA (ptr, len, constant_string_non_mule, description) #define DFC_CHECK_DATA_COND_MULE_NUL(ptr,len, \ constant_string_mule, \ constant_string_non_mule, \ description) \ DFC_CHECK_DATA_NUL (ptr, len, constant_string_non_mule, description) #endif /* These now only apply to base coding systems, and need to test `eol-detection-enabled-p' at runtime. */ #define DFC_CHECK_DATA_COND_EOL(ptr,len, \ constant_string_eol, \ constant_string_non_eol, \ description) do { \ if (autodetect_eol_p) \ DFC_CHECK_DATA (ptr, len, constant_string_eol, description); \ else \ DFC_CHECK_DATA (ptr, len, constant_string_non_eol, description); \ } while (0) #define DFC_CHECK_DATA_COND_EOL_NUL(ptr,len, \ constant_string_eol, \ constant_string_non_eol, \ description) do { \ if (autodetect_eol_p) \ DFC_CHECK_DATA_NUL (ptr, len, constant_string_eol, description); \ else \ DFC_CHECK_DATA_NUL (ptr, len, constant_string_non_eol, description); \ } while (0) /* Check for expected strings before and after conversion. */ #define DFC_CHECK_DATA(ptr,len,constant_string,test) do { \ DFC_INITIALIZE (test); \ DFC_CHECK_LENGTH (len, sizeof (constant_string) - 1, test); \ DFC_CHECK_CONTENT (ptr, constant_string, len, test); \ DFC_RESULT_PASS (test); \ } while (0) /* Macro version that includes the trailing NULL byte. */ #define DFC_CHECK_DATA_NUL(ptr,len,constant_string,test) do { \ DFC_INITIALIZE (test); \ DFC_CHECK_LENGTH (len, sizeof (constant_string), test); \ DFC_CHECK_CONTENT (ptr, constant_string, len, test); \ DFC_RESULT_PASS (test); \ } while (0) /* WARNING WARNING WARNING! The following macros are NOT protected by "do { ... } while (0)"!! */ #define DFC_INITIALIZE(test_name) if (0) #define DFC_CHECK_LENGTH(len1,len2,str1) \ else if ((len1) != (len2)) \ conversion_result = \ Fcons (list3 (build_string(str1), Qnil, build_string("wrong length")), \ conversion_result) #define DFC_CHECK_CONTENT(str1,str2,len1,str3) \ else if (memcmp (str1, str2, len1)) \ conversion_result = \ Fcons (list3 (build_string(str3), Qnil, \ build_string("octet comparison failed")), \ conversion_result) #define DFC_RESULT_PASS(str1) \ else \ conversion_result = \ Fcons (list3 (build_string(str1), Qt, Qnil), \ conversion_result) #ifdef MULE ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (DATA, (int_latin2, sizeof (int_latin2)), ALLOCA, (ptr, len), intern ("iso-8859-2")); DFC_CHECK_DATA_NUL (ptr, len, ext_latin, "Latin-2 DATA, ALLOCA, Latin 2/NUL"); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (LISP_STRING, string_latin2, ALLOCA, (ptr, len), intern ("iso-8859-2")); DFC_CHECK_DATA (ptr, len, ext_latin, "Latin-2 Lisp string, ALLOCA, Latin 2"); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (LISP_STRING, string_latin1, ALLOCA, (ptr, len), intern ("iso-latin-2-with-esc")); DFC_CHECK_DATA (ptr, len, ext_latin12, "Latin-1 Lisp string, ALLOCA, Latin 2/ESC"); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (DATA, (int_latin2, sizeof (int_latin2) - 1), MALLOC, (ptr, len), intern ("iso-8859-2")); DFC_CHECK_DATA (ptr, len, ext_latin, "Latin-2 DATA, MALLOC, Latin-2"); xfree (ptr, void *); TO_EXTERNAL_FORMAT (DATA, (int_latin2, sizeof (int_latin2) - 1), LISP_OPAQUE, opaque, intern ("iso-8859-2")); DFC_CHECK_DATA (XOPAQUE_DATA (opaque), XOPAQUE_SIZE (opaque), ext_latin, "Latin-2 DATA, Lisp opaque, Latin-2"); ptr = NULL, len = rand(); TO_INTERNAL_FORMAT (DATA, (ext_latin, sizeof (ext_latin) - 1), ALLOCA, (ptr, len), intern ("iso-latin-2-with-esc")); DFC_CHECK_DATA (ptr, len, int_latin2, "Latin-2/ESC, ALLOCA, Latin-1 DATA"); ptr = NULL, len = rand(); TO_INTERNAL_FORMAT (DATA, (ext_latin, sizeof (ext_latin) - 1), MALLOC, (ptr, len), intern ("iso-latin-2-with-esc")); DFC_CHECK_DATA (ptr, len, int_latin2, "Latin-2/ESC, MALLOC, Latin-1 DATA"); xfree (ptr, void *); TO_INTERNAL_FORMAT (DATA, (ext_latin, sizeof (ext_latin) - 1), LISP_STRING, string, intern ("iso-latin-2-with-esc")); DFC_CHECK_DATA (XSTRING_DATA (string), XSTRING_LENGTH (string), int_latin2, "Latin-2/ESC, Lisp string, Latin-2"); TO_INTERNAL_FORMAT (LISP_OPAQUE, opaque_latin, LISP_STRING, string, intern ("iso-latin-2-with-esc")); DFC_CHECK_DATA (XSTRING_DATA (string), XSTRING_LENGTH (string), int_latin2, "Lisp opaque, Lisp string, Latin-2/ESC"); TO_INTERNAL_FORMAT (LISP_OPAQUE, opaque0_latin, LISP_STRING, string, intern ("iso-latin-2-with-esc")); DFC_CHECK_DATA_NUL (XSTRING_DATA (string), XSTRING_LENGTH (string), int_latin2, "Lisp opaque, Lisp string, Latin-2/ESC/NUL"); TO_INTERNAL_FORMAT (LISP_OPAQUE, opaque0_latin, LISP_BUFFER, Fcurrent_buffer(), intern ("iso-latin-2-with-esc")); DFC_CHECK_DATA_NUL (BUF_BYTE_ADDRESS (current_buffer, BUF_PT (current_buffer)), sizeof (int_latin2), int_latin2, "Lisp opaque, Lisp buffer, Latin-2/ESC/NUL"); TO_INTERNAL_FORMAT (LISP_OPAQUE, opaque_latin, LISP_BUFFER, Fcurrent_buffer(), intern ("iso-8859-1")); DFC_CHECK_DATA (BUF_BYTE_ADDRESS (current_buffer, BUF_PT (current_buffer)), sizeof (int_latin1) - 1, int_latin1, "Lisp opaque, Lisp buffer, Latin-1"); TO_INTERNAL_FORMAT (DATA, (ext_latin12, sizeof (ext_latin12) - 1), ALLOCA, (ptr, len), intern ("iso-latin-2-with-esc")); DFC_CHECK_DATA (ptr, len, int_latin1, "DATA, ALLOCA, Latin-1"); #endif /* MULE */ ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (DATA, (int_latin1, sizeof (int_latin1) - 1), ALLOCA, (ptr, len), Qbinary); DFC_CHECK_DATA_COND_MULE (ptr, len, ext_latin, int_latin1, "Latin-1 DATA, ALLOCA, binary"); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (DATA, (int_latin1, sizeof (int_latin1)), ALLOCA, (ptr, len), Qbinary); DFC_CHECK_DATA_COND_MULE_NUL (ptr, len, ext_latin, int_latin1, "Latin-1 DATA, ALLOCA, binary/NUL"); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (DATA, (int_latin2, sizeof (int_latin2) - 1), ALLOCA, (ptr, len), Qbinary); DFC_CHECK_DATA_COND_MULE (ptr, len, ext_tilde, int_latin2, "Latin-2 DATA, ALLOCA, binary"); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (DATA, (int_latin1, sizeof (int_latin1) - 1), ALLOCA, (ptr, len), intern ("iso-8859-1")); DFC_CHECK_DATA_COND_MULE (ptr, len, ext_latin, int_latin1, "Latin-1 DATA, ALLOCA, Latin-1"); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (LISP_STRING, string_latin1, ALLOCA, (ptr, len), Qbinary); DFC_CHECK_DATA_COND_MULE (ptr, len, ext_latin, int_latin1, "Latin-1 Lisp string, ALLOCA, binary"); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (LISP_STRING, string_latin1, ALLOCA, (ptr, len), Qbinary); DFC_CHECK_DATA_COND_MULE (ptr, len, ext_latin, int_latin1, "Latin-1 Lisp string, ALLOCA, binary"); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (LISP_STRING, string_latin1, ALLOCA, (ptr, len), intern ("iso-8859-1")); DFC_CHECK_DATA_COND_MULE (ptr, len, ext_latin, int_latin1, "Latin-1 Lisp string, ALLOCA, Latin-1"); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (DATA, (int_latin1, sizeof (int_latin1) - 1), MALLOC, (ptr, len), Qbinary); DFC_CHECK_DATA_COND_MULE (ptr, len, ext_latin, int_latin1, "Latin-1 DATA, MALLOC, binary"); xfree (ptr, void *); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (DATA, (int_latin2, sizeof (int_latin2)), MALLOC, (ptr, len), Qbinary); DFC_CHECK_DATA_COND_MULE_NUL (ptr, len, ext_tilde, int_latin2, "Latin-2 DATA, MALLOC, binary/NUL"); xfree (ptr, void *); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (DATA, (int_latin1, sizeof (int_latin1) - 1), MALLOC, (ptr, len), intern ("iso-8859-1")); DFC_CHECK_DATA_COND_MULE (ptr, len, ext_latin, int_latin1, "Latin-1 DATA, MALLOC, Latin-1"); xfree (ptr, void *); TO_EXTERNAL_FORMAT (DATA, (int_latin1, sizeof (int_latin1) - 1), LISP_OPAQUE, opaque, Qbinary); DFC_CHECK_DATA_COND_MULE (XOPAQUE_DATA (opaque), XOPAQUE_SIZE (opaque), ext_latin, int_latin1, "Latin-1 DATA, Lisp opaque, binary"); TO_EXTERNAL_FORMAT (DATA, (int_latin2, sizeof (int_latin2)), LISP_OPAQUE, opaque, Qbinary); DFC_CHECK_DATA_COND_MULE_NUL (XOPAQUE_DATA (opaque), XOPAQUE_SIZE (opaque), ext_tilde, int_latin2, "Latin-2 DATA, Lisp opaque, binary"); TO_EXTERNAL_FORMAT (DATA, (int_latin1, sizeof (int_latin1) - 1), LISP_OPAQUE, opaque, intern ("iso-8859-1")); DFC_CHECK_DATA_COND_MULE (XOPAQUE_DATA (opaque), XOPAQUE_SIZE (opaque), ext_latin, int_latin1, "Latin-1 DATA, Lisp opaque, Latin-1"); ptr = NULL, len = rand(); TO_INTERNAL_FORMAT (DATA, (ext_latin, sizeof (ext_latin) - 1), ALLOCA, (ptr, len), Qbinary); DFC_CHECK_DATA_COND_MULE (ptr, len, int_latin1, ext_latin, "Latin-1 DATA, ALLOCA, binary"); ptr = NULL, len = rand(); TO_INTERNAL_FORMAT (DATA, (ext_latin, sizeof (ext_latin)), ALLOCA, (ptr, len), intern ("iso-8859-1")); DFC_CHECK_DATA_COND_MULE_NUL (ptr, len, int_latin1, ext_latin, "Latin-1 DATA, ALLOCA, Latin-1"); ptr = NULL, len = rand(); TO_INTERNAL_FORMAT (DATA, (ext_latin, sizeof (ext_latin)), MALLOC, (ptr, len), intern ("iso-8859-1")); DFC_CHECK_DATA_COND_MULE_NUL (ptr, len, int_latin1, ext_latin, "Latin-1 DATA, MALLOC, Latin-1"); xfree (ptr, void *); ptr = NULL, len = rand(); TO_INTERNAL_FORMAT (DATA, (ext_latin, sizeof (ext_latin)), MALLOC, (ptr, len), Qnil); DFC_CHECK_DATA_COND_MULE_NUL (ptr, len, int_latin1, ext_latin, "Latin-1 DATA, MALLOC, nil"); xfree (ptr, void *); TO_INTERNAL_FORMAT (DATA, (ext_latin, sizeof (ext_latin) - 1), LISP_STRING, string, intern ("iso-8859-1")); DFC_CHECK_DATA_COND_MULE (XSTRING_DATA (string), XSTRING_LENGTH (string), int_latin1, ext_latin, "Latin-1 DATA, Lisp stirng, Latin-1"); TO_INTERNAL_FORMAT (LISP_OPAQUE, opaque_latin, LISP_STRING, string, intern ("iso-8859-1")); DFC_CHECK_DATA_COND_MULE (XSTRING_DATA (string), XSTRING_LENGTH (string), int_latin1, ext_latin, "Latin-1 Lisp opaque, Lisp string, Latin-1"); TO_INTERNAL_FORMAT (LISP_OPAQUE, opaque0_latin, LISP_STRING, string, intern ("iso-8859-1")); DFC_CHECK_DATA_COND_MULE_NUL (XSTRING_DATA (string), XSTRING_LENGTH (string), int_latin1, ext_latin, "Latin-1 Lisp opaque, Lisp string, Latin-1/NUL"); /* This next group used to use the COND_EOL macros, but with the new Mule, they all specify an EOL convention, and all XEmacsen can grok them. */ ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (DATA, (int_foo, sizeof (int_foo)), MALLOC, (ptr, len), Qbinary); DFC_CHECK_DATA_NUL (ptr, len, ext_unix, "ASCII DATA, MALLOC, binary/LF/NUL"); xfree (ptr, void *); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (DATA, (int_foo, sizeof (int_foo) - 1), LISP_OPAQUE, opaque, intern ("raw-text-mac")); DFC_CHECK_DATA (XOPAQUE_DATA (opaque), XOPAQUE_SIZE (opaque), ext_mac, "ASCII DATA, Lisp opaque, binary/CR"); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (LISP_STRING, string_foo, ALLOCA, (ptr, len), intern ("raw-text-dos")); DFC_CHECK_DATA (ptr, len, ext_dos, "ASCII Lisp string, ALLOCA, binary/CRLF"); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (DATA, (int_foo, sizeof (int_foo) - 1), ALLOCA, (ptr, len), intern ("raw-text-unix")); DFC_CHECK_DATA (ptr, len, ext_unix, "ASCII DATA, ALLOCA, binary/LF"); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (LISP_STRING, string_foo, MALLOC, (ptr, len), intern ("no-conversion-mac")); DFC_CHECK_DATA (ptr, len, ext_mac, "ASCII Lisp string, MALLOC, binary/CR"); xfree (ptr, void *); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (DATA, (int_foo, sizeof (int_foo) - 1), ALLOCA, (ptr, len), intern ("no-conversion-dos")); DFC_CHECK_DATA (ptr, len, ext_dos, "ASCII DATA, ALLOCA, binary/CRLF"); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (DATA, (int_foo, sizeof (int_foo)), ALLOCA, (ptr, len), intern ("no-conversion-unix")); DFC_CHECK_DATA_NUL (ptr, len, ext_unix, "ASCII DATA, ALLOCA, binary/LF/NUL"); /* Oh, Lawdy, Lawdy, Lawdy, this done broke mah heart! I tried using the technique Fget_coding_system (call2 (intern ("coding-system-change-eol-conversion"), intern ("undecided"), $EOL_TYPE)); XCODING_SYSTEM_EOL_TYPE (cs_to_use) = $EOL_DETECT_TYPE; with EOL_TYPE = Qlf (for no-detect) and Qnil (for auto-detect), and with EOL_DETECT_TYPE = EOL_LF and EOL_AUTODETECT respectively, but this doesn't seem to work on the `undecided' coding system. The coding-system-eol-type attribute on the coding system itself needs to be changed, too. I'm not sure at the moment how `set-eol-detection' works its magic, but the code below gives correct test results without default EOL detection, with default EOL detection, and with Mule. Ship it! Mule. You'll envy the dead. */ { /* Check eol autodetection doesn't happen when disabled -- cheat. */ Lisp_Object cs_to_use = Fget_coding_system (intern ("undecided-unix")); TO_INTERNAL_FORMAT (LISP_OPAQUE, opaque_dos, LISP_BUFFER, Fcurrent_buffer(), cs_to_use); DFC_CHECK_DATA (BUF_BYTE_ADDRESS (current_buffer, BUF_PT (current_buffer)), sizeof (ext_dos) - 1, ext_dos, "DOS Lisp opaque, Lisp buffer, undecided-unix"); /* Check eol autodetection works when enabled -- honest. */ cs_to_use = Fget_coding_system (call2 (intern ("coding-system-change-eol-conversion"), intern ("undecided"), Qnil)); XCODING_SYSTEM_EOL_TYPE (cs_to_use) = EOL_AUTODETECT; TO_INTERNAL_FORMAT (LISP_OPAQUE, opaque_dos, LISP_BUFFER, Fcurrent_buffer(), cs_to_use); DFC_CHECK_DATA (BUF_BYTE_ADDRESS (current_buffer, BUF_PT (current_buffer)), sizeof (int_foo) - 1, int_foo, "DOS Lisp opaque, Lisp buffer, undecided"); /* reset to default */ XCODING_SYSTEM_EOL_TYPE (cs_to_use) = autodetect_eol_p ? EOL_AUTODETECT : EOL_LF; } /* Does eol-detection-enabled-p reflect the actual state of affairs? This probably could be tested in Lisp somehow. Should it? */ TO_INTERNAL_FORMAT (LISP_OPAQUE, opaque_dos, LISP_BUFFER, Fcurrent_buffer(), intern ("undecided")); if (autodetect_eol_p) DFC_CHECK_DATA (BUF_BYTE_ADDRESS (current_buffer, BUF_PT (current_buffer)), sizeof (int_foo) - 1, int_foo, "DOS Lisp opaque, Lisp buffer, autodetect eol"); else DFC_CHECK_DATA (BUF_BYTE_ADDRESS (current_buffer, BUF_PT (current_buffer)), sizeof (ext_dos) - 1, ext_dos, "DOS Lisp opaque, Lisp buffer, no autodetect eol"); TO_INTERNAL_FORMAT (DATA, (ext_mac, sizeof (ext_mac) - 1), LISP_STRING, string, intern ("iso-8859-1")); DFC_CHECK_DATA_COND_EOL (XSTRING_DATA (string), XSTRING_LENGTH (string), int_foo, ext_mac, "Mac DATA, Lisp string, Latin-1/EOL"); { Lisp_Object stream = make_fixed_buffer_input_stream (ext_dos, sizeof (ext_dos) - 1); TO_INTERNAL_FORMAT (LISP_LSTREAM, stream, LISP_STRING, string, intern ("iso-8859-1")); DFC_CHECK_DATA_COND_EOL (XSTRING_DATA (string), XSTRING_LENGTH (string), int_foo, ext_dos, "DOS lstream, Lisp string, Latin-1/EOL"); } TO_INTERNAL_FORMAT (DATA, (ext_unix, sizeof (ext_unix) - 1), LISP_STRING, string, intern ("no-conversion")); DFC_CHECK_DATA_COND_EOL (XSTRING_DATA (string), XSTRING_LENGTH (string), int_foo, ext_unix, "Unix DATA, Lisp string, no-conversion"); ptr = NULL, len = rand(); TO_EXTERNAL_FORMAT (LISP_OPAQUE, opaque_dos, ALLOCA, (ptr, len), Qbinary); DFC_CHECK_DATA (ptr, len, ext_dos, "DOS Lisp opaque, ALLOCA, binary"); return conversion_result; } /* Hash Table testing */ typedef struct { Lisp_Object hash_table; EMACS_INT sum; } test_hash_tables_data; static int test_hash_tables_mapper (Lisp_Object UNUSED (key), Lisp_Object value, void *extra_arg) { test_hash_tables_data *p = (test_hash_tables_data *) extra_arg; p->sum += XINT (value); return 0; } static int test_hash_tables_modifying_mapper (Lisp_Object key, Lisp_Object value, void *extra_arg) { test_hash_tables_data *p = (test_hash_tables_data *) extra_arg; Fputhash (make_int (- XINT (key)), make_int (2 * XINT (value)), p->hash_table); p->sum += XINT (value); return 0; } static int test_hash_tables_predicate (Lisp_Object key, Lisp_Object UNUSED (value), void *UNUSED (extra_arg)) { return XINT (key) < 0; } DEFUN ("test-hash-tables", Ftest_hash_tables, 0, 0, "", /* Return list of results of testing C interface to hash tables. For use by the automated test suite. See tests/automated/c-tests. Each element is a list (DESCRIPTION, STATUS, REASON). DESCRIPTION is a string describing the test. STATUS is a symbol, either t (pass) or nil (fail). REASON is nil or a string describing the failure (not required). */ ()) { Lisp_Object hash_result = Qnil; test_hash_tables_data data; data.hash_table = make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL); Fputhash (make_int (1), make_int (2), data.hash_table); Fputhash (make_int (3), make_int (4), data.hash_table); data.sum = 0; elisp_maphash_unsafe (test_hash_tables_mapper, data.hash_table, (void *) &data); hash_result = Fcons (list3 (build_string ("simple mapper"), (data.sum == 2 + 4) ? Qt : Qnil, build_string ("sum != 2 + 4")), hash_result); data.sum = 0; elisp_maphash (test_hash_tables_modifying_mapper, data.hash_table, (void *) &data); hash_result = Fcons (list3 (build_string ("modifying mapper"), (data.sum == 2 + 4) ? Qt : Qnil, build_string ("sum != 2 + 4")), hash_result); /* hash table now contains: (1, 2) (3, 4) (-1, 2*2) (-3, 2*4) */ data.sum = 0; elisp_maphash_unsafe (test_hash_tables_mapper, data.hash_table, (void *) &data); hash_result = Fcons (list3 (build_string ("simple mapper"), (data.sum == 3 * (2 + 4)) ? Qt : Qnil, build_string ("sum != 3 * (2 + 4)")), hash_result); /* Remove entries with negative keys, added by modifying mapper */ elisp_map_remhash (test_hash_tables_predicate, data.hash_table, 0); data.sum = 0; elisp_maphash_unsafe (test_hash_tables_mapper, data.hash_table, (void *) &data); hash_result = Fcons (list3 (build_string ("remove negatives mapper"), (data.sum == 2 + 4) ? Qt : Qnil, build_string ("sum != 2 + 4")), hash_result); return hash_result; } #ifdef NEW_GC #define TESTS_DEFSUBR(Fname) do { \ DEFSUBR_MC_ALLOC (Fname); \ defsubr (S##Fname); \ Vtest_function_list = \ Fcons (intern (subr_name (S##Fname)), \ Vtest_function_list); \ } while (0) #else /* not NEW_GC */ #define TESTS_DEFSUBR(Fname) do { \ DEFSUBR (Fname); \ Vtest_function_list = \ Fcons (intern (subr_name (&S##Fname)), \ Vtest_function_list); \ } while (0) #endif /* not NEW_GC */ void syms_of_tests (void) { Vtest_function_list = Qnil; TESTS_DEFSUBR (Ftest_data_format_conversion); TESTS_DEFSUBR (Ftest_hash_tables); /* Add other test functions here with TESTS_DEFSUBR */ } void vars_of_tests (void) { DEFVAR_LISP ("test-function-list", &Vtest_function_list /* List of all test functions defined in tests.c. For use by the automated test suite. See tests/automated/c-tests. */ ); }