commit: Correct a typo from Mats' merge, process.el, thank you the byte-compiler
13 years, 4 months
Aidan Kehoe
changeset: 5555:a39cd9dc92ba
tag: tip
user: Aidan Kehoe <kehoea(a)parhasard.net>
date: Wed Aug 24 11:22:30 2011 +0100
files: lisp/ChangeLog lisp/process.el
description:
Correct a typo from Mats' merge, process.el, thank you the byte-compiler
lisp/ChangeLog addition:
2011-08-24 Aidan Kehoe <kehoea(a)parhasard.net>
* process.el (shell-command-on-region):
Correct typo from the merge, nnot -> not.
diff -r a42e686a01bf -r a39cd9dc92ba lisp/ChangeLog
--- a/lisp/ChangeLog Wed Aug 24 11:07:26 2011 +0100
+++ b/lisp/ChangeLog Wed Aug 24 11:22:30 2011 +0100
@@ -1,3 +1,8 @@
+2011-08-24 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * process.el (shell-command-on-region):
+ Correct typo from the merge, nnot -> not.
+
2011-08-24 Aidan Kehoe <kehoea(a)parhasard.net>
* cl-macs.el (apply-partially):
diff -r a42e686a01bf -r a39cd9dc92ba lisp/process.el
--- a/lisp/process.el Wed Aug 24 11:07:26 2011 +0100
+++ b/lisp/process.el Wed Aug 24 11:22:30 2011 +0100
@@ -453,7 +453,7 @@
t)
nil shell-command-switch command))
(let ((shell-buffer (get-buffer "*Shell Command Output*")))
- (and shell-buffer (nnot (eq shell-buffer (current-buffer)))
+ (and shell-buffer (not (eq shell-buffer (current-buffer)))
(kill-buffer shell-buffer)))
;; Don't muck with mark unless REPLACE says we should.
(and replace swap (exchange-point-and-mark t)))
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
commit: Automated merge with file:///Sources/xemacs-21.5-checked-out
13 years, 4 months
Aidan Kehoe
changeset: 5554:a42e686a01bf
parent: 5552:85210c453a97
parent: 5553:62edcc6a11ec
user: Aidan Kehoe <kehoea(a)parhasard.net>
date: Wed Aug 24 11:07:26 2011 +0100
description:
Automated merge with file:///Sources/xemacs-21.5-checked-out
diff -r 85210c453a97 -r a42e686a01bf lisp/ChangeLog
--- a/lisp/ChangeLog Tue Aug 23 04:41:45 2011 +0900
+++ b/lisp/ChangeLog Wed Aug 24 11:07:26 2011 +0100
@@ -1,3 +1,11 @@
+2011-08-24 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * cl-macs.el (apply-partially):
+ Add an assertion to this compiler macro, requiring that the order
+ of the placeholders corresponding to the arguments in the
+ constants vector of the constructed compiled function be the same
+ as the order of the arguments to #'apply-partially.
+
2011-08-12 Aidan Kehoe <kehoea(a)parhasard.net>
* cl-macs.el:
diff -r 85210c453a97 -r a42e686a01bf lisp/cl-macs.el
--- a/lisp/cl-macs.el Tue Aug 23 04:41:45 2011 +0900
+++ b/lisp/cl-macs.el Wed Aug 24 11:07:26 2011 +0100
@@ -3519,6 +3519,13 @@
(let* ((placeholders (mapcar 'quote-maybe (mapcar 'gensym args)))
(compiled (byte-compile-sexp
`#'(lambda (&rest args) (apply ,@placeholders args)))))
+ (assert (equal (intersection
+ (mapcar 'quote-maybe (compiled-function-constants
+ compiled))
+ placeholders :test 'equal :stable t)
+ placeholders)
+ t "This macro requires that the relative order is the same\
+in the constants vector and in the arguments")
`(make-byte-code
',(compiled-function-arglist compiled)
,(compiled-function-instructions compiled)
diff -r 85210c453a97 -r a42e686a01bf tests/ChangeLog
--- a/tests/ChangeLog Tue Aug 23 04:41:45 2011 +0900
+++ b/tests/ChangeLog Wed Aug 24 11:07:26 2011 +0100
@@ -1,3 +1,9 @@
+2011-08-24 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * automated/lisp-tests.el:
+ Add a test of apply partially that depends on the relative order
+ of its arguments.
+
2011-08-12 Aidan Kehoe <kehoea(a)parhasard.net>
* automated/lisp-tests.el:
diff -r 85210c453a97 -r a42e686a01bf tests/automated/lisp-tests.el
--- a/tests/automated/lisp-tests.el Tue Aug 23 04:41:45 2011 +0900
+++ b/tests/automated/lisp-tests.el Wed Aug 24 11:07:26 2011 +0100
@@ -2929,10 +2929,13 @@
;; Basic tests of #'apply-partially.
(let* ((four 4)
(times-four (apply-partially '* four))
- (plus-twelve (apply-partially '+ 6 (* 3 2))))
+ (plus-twelve (apply-partially '+ 6 (* 3 2)))
+ (construct-list (apply-partially 'list (incf four) (incf four)
+ (incf four))))
(Assert (eql (funcall times-four 6) 24))
(Assert (eql (funcall times-four 4 4) 64))
(Assert (eql (funcall plus-twelve (funcall times-four 4) 4 4) 36))
- (Check-Error wrong-number-of-arguments (apply-partially)))
+ (Check-Error wrong-number-of-arguments (apply-partially))
+ (Assert (equal (funcall construct-list) '(5 6 7))))
;;; end of lisp-tests.el
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
commit: Add an assertion about argument order to #'apply-partially compiler macro
13 years, 4 months
Aidan Kehoe
changeset: 5553:62edcc6a11ec
parent: 5550:b908c7265a2b
user: Aidan Kehoe <kehoea(a)parhasard.net>
date: Wed Aug 24 11:06:41 2011 +0100
files: lisp/ChangeLog lisp/cl-macs.el tests/ChangeLog tests/automated/lisp-tests.el
description:
Add an assertion about argument order to #'apply-partially compiler macro
lisp/ChangeLog addition:
2011-08-24 Aidan Kehoe <kehoea(a)parhasard.net>
* cl-macs.el (apply-partially):
Add an assertion to this compiler macro, requiring that the order
of the placeholders corresponding to the arguments in the
constants vector of the constructed compiled function be the same
as the order of the arguments to #'apply-partially.
tests/ChangeLog addition:
2011-08-24 Aidan Kehoe <kehoea(a)parhasard.net>
* automated/lisp-tests.el:
Add a test of apply partially that depends on the relative order
of its arguments.
diff -r b908c7265a2b -r 62edcc6a11ec lisp/ChangeLog
--- a/lisp/ChangeLog Fri Aug 12 16:02:30 2011 +0100
+++ b/lisp/ChangeLog Wed Aug 24 11:06:41 2011 +0100
@@ -1,3 +1,11 @@
+2011-08-24 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * cl-macs.el (apply-partially):
+ Add an assertion to this compiler macro, requiring that the order
+ of the placeholders corresponding to the arguments in the
+ constants vector of the constructed compiled function be the same
+ as the order of the arguments to #'apply-partially.
+
2011-08-12 Aidan Kehoe <kehoea(a)parhasard.net>
* cl-macs.el:
diff -r b908c7265a2b -r 62edcc6a11ec lisp/cl-macs.el
--- a/lisp/cl-macs.el Fri Aug 12 16:02:30 2011 +0100
+++ b/lisp/cl-macs.el Wed Aug 24 11:06:41 2011 +0100
@@ -3519,6 +3519,13 @@
(let* ((placeholders (mapcar 'quote-maybe (mapcar 'gensym args)))
(compiled (byte-compile-sexp
`#'(lambda (&rest args) (apply ,@placeholders args)))))
+ (assert (equal (intersection
+ (mapcar 'quote-maybe (compiled-function-constants
+ compiled))
+ placeholders :test 'equal :stable t)
+ placeholders)
+ t "This macro requires that the relative order is the same\
+in the constants vector and in the arguments")
`(make-byte-code
',(compiled-function-arglist compiled)
,(compiled-function-instructions compiled)
diff -r b908c7265a2b -r 62edcc6a11ec tests/ChangeLog
--- a/tests/ChangeLog Fri Aug 12 16:02:30 2011 +0100
+++ b/tests/ChangeLog Wed Aug 24 11:06:41 2011 +0100
@@ -1,3 +1,9 @@
+2011-08-24 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * automated/lisp-tests.el:
+ Add a test of apply partially that depends on the relative order
+ of its arguments.
+
2011-08-12 Aidan Kehoe <kehoea(a)parhasard.net>
* automated/lisp-tests.el:
diff -r b908c7265a2b -r 62edcc6a11ec tests/automated/lisp-tests.el
--- a/tests/automated/lisp-tests.el Fri Aug 12 16:02:30 2011 +0100
+++ b/tests/automated/lisp-tests.el Wed Aug 24 11:06:41 2011 +0100
@@ -2929,10 +2929,13 @@
;; Basic tests of #'apply-partially.
(let* ((four 4)
(times-four (apply-partially '* four))
- (plus-twelve (apply-partially '+ 6 (* 3 2))))
+ (plus-twelve (apply-partially '+ 6 (* 3 2)))
+ (construct-list (apply-partially 'list (incf four) (incf four)
+ (incf four))))
(Assert (eql (funcall times-four 6) 24))
(Assert (eql (funcall times-four 4 4) 64))
(Assert (eql (funcall plus-twelve (funcall times-four 4) 4 4) 36))
- (Check-Error wrong-number-of-arguments (apply-partially)))
+ (Check-Error wrong-number-of-arguments (apply-partially))
+ (Assert (equal (funcall construct-list) '(5 6 7))))
;;; end of lisp-tests.el
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
commit: Fix performance regression in refactored syntax cache setup.
13 years, 4 months
Stephen J. Turnbull
changeset: 5552:85210c453a97
tag: tip
user: Stephen J. Turnbull <stephen(a)xemacs.org>
date: Tue Aug 23 04:41:45 2011 +0900
files: src/ChangeLog src/syntax.c src/syntax.h
description:
Fix performance regression in refactored syntax cache setup.
More doc improvements.
* syntax.h (enum syntax_source):
New. Specify whether syntax is from property or buffer.
(struct syntax_cache):
Use enum syntax_source source, instead of no_syntax_table_prop
and use_code.
Improve comments.
(SOURCE_IS_TABLE):
New predicate.
(SYNTAX_CODE_FROM_CACHE):
Use it instead of use_code, and adjust logic.
* syntax.c (syntax_cache_table_was_changed):
Check cache->source (cache->no_syntax_table_prop is gone).
(reset_syntax_cache_range):
All information about OBJECT and BUFFER is in CACHE already.
Also reset markers in OBJECT if it is a buffer.
Rename INFINITE to VALID_EVERYWHERE.
(init_syntax_cache):
Initialize source (cache->no_syntax_table_prop is gone).
Maybe initialize start and end to null markers.
Initialize cache range with reset_syntax_cache_range.
(update_syntax_cache):
Use source instead of no_syntax_table_prop and use_code.
(setup_syntax_cache):
Add header comment. Improve other comments.
Make calls to reset_syntax_cache_range and init_syntax_cache match
their prototypes.
(init_buffer_syntax_cache):
Use init_syntax_cache to do the work.
(signal_syntax_cache_extent_changed):
Make call to reset_syntax_cache_range match its prototype.
Improve local variable naming.
diff -r 40a52efbf3a3 -r 85210c453a97 src/ChangeLog
--- a/src/ChangeLog Sun Aug 14 13:51:14 2011 +0200
+++ b/src/ChangeLog Tue Aug 23 04:41:45 2011 +0900
@@ -1,3 +1,41 @@
+2011-08-23 Stephen Turnbull <stephen(a)xemacs.org>
+
+ Fix performance regression in refactored syntax cache setup.
+ More doc improvements.
+
+ * syntax.h (enum syntax_source):
+ New. Specify whether syntax is from property or buffer.
+ (struct syntax_cache):
+ Use enum syntax_source source, instead of no_syntax_table_prop
+ and use_code.
+ Improve comments.
+ (SOURCE_IS_TABLE):
+ New predicate.
+ (SYNTAX_CODE_FROM_CACHE):
+ Use it instead of use_code, and adjust logic.
+
+ * syntax.c (syntax_cache_table_was_changed):
+ Check cache->source (cache->no_syntax_table_prop is gone).
+ (reset_syntax_cache_range):
+ All information about OBJECT and BUFFER is in CACHE already.
+ Also reset markers in OBJECT if it is a buffer.
+ Rename INFINITE to VALID_EVERYWHERE.
+ (init_syntax_cache):
+ Initialize source (cache->no_syntax_table_prop is gone).
+ Maybe initialize start and end to null markers.
+ Initialize cache range with reset_syntax_cache_range.
+ (update_syntax_cache):
+ Use source instead of no_syntax_table_prop and use_code.
+ (setup_syntax_cache):
+ Add header comment. Improve other comments.
+ Make calls to reset_syntax_cache_range and init_syntax_cache match
+ their prototypes.
+ (init_buffer_syntax_cache):
+ Use init_syntax_cache to do the work.
+ (signal_syntax_cache_extent_changed):
+ Make call to reset_syntax_cache_range match its prototype.
+ Improve local variable naming.
+
2011-08-08 Stephen J. Turnbull <stephen(a)xemacs.org>
* syntax.c (update_syntax_cache):
diff -r 40a52efbf3a3 -r 85210c453a97 src/syntax.c
--- a/src/syntax.c Sun Aug 14 13:51:14 2011 +0200
+++ b/src/syntax.c Tue Aug 23 04:41:45 2011 +0900
@@ -273,7 +273,7 @@
syntax_cache_table_was_changed (struct buffer *buf)
{
struct syntax_cache *cache = buf->syntax_cache;
- if (cache->no_syntax_table_prop)
+ if (cache->source == syntax_source_buffer_table)
{
cache->syntax_table =
BUFFER_SYNTAX_TABLE (buf);
@@ -284,59 +284,96 @@
static void
reset_syntax_cache_range (struct syntax_cache *cache, /* initialized cache */
- Lisp_Object object) /* string or buffer */
+ int valid_everywhere) /* non-zero if we can assume
+ syntax-table properties
+ never need be respected
+ in the life of the cache */
{
- /* reinitialize cache parameters */
- if (BUFFERP (object))
+ if (BUFFERP (cache->object))
{
/* make known region zero-length and reset insertion behavior */
- Fset_marker (cache->start, make_int (1), object);
- Fset_marker (cache->end, make_int (1), object);
+ Fset_marker (cache->start, make_int (1), cache->object);
+ Fset_marker (cache->end, make_int (1), cache->object);
Fset_marker_insertion_type (cache->start, Qnil);
Fset_marker_insertion_type (cache->end, Qt);
}
- else
+ /* #### Should reset "cache->source" here?
+ If so, also reset tables. */
+ if (valid_everywhere)
{
- /* invalidate the known region markers */
- Fset_marker (cache->start, Qnil, Qnil);
- Fset_marker (cache->end, Qnil, Qnil);
+ cache->prev_change = EMACS_INT_MIN;
+ cache->next_change = EMACS_INT_MAX;
}
- cache->no_syntax_table_prop = 1;
- if (lookup_syntax_properties)
+ else /* valid nowhere */
{
cache->prev_change = -1;
cache->next_change = -1;
}
- else
- {
- cache->prev_change = EMACS_INT_MIN;
- cache->next_change = EMACS_INT_MAX;
- }
}
-/* init_syntax_cache
- Arguments:
- cache: pointer to a zero-ed struct syntax_cache
- object: a Lisp string or buffer
- buffer: NULL or the struct buffer of buffer */
static void
-init_syntax_cache (struct syntax_cache *cache, /* cache must be zero'ed */
+init_syntax_cache (struct syntax_cache *cache, /* xzero'ed memory */
Lisp_Object object, /* string or buffer */
- struct buffer *buffer) /* may not be NULL */
+ struct buffer *buffer) /* buffer; if OBJECT is a
+ buffer, this is the same */
{
- /* initialize cache resources */
cache->object = object;
cache->buffer = buffer;
+
+ cache->source = syntax_source_buffer_table;
cache->syntax_table =
BUFFER_SYNTAX_TABLE (cache->buffer);
cache->mirror_table =
BUFFER_MIRROR_SYNTAX_TABLE (cache->buffer);
- cache->start = Fmake_marker();
- cache->end = Fmake_marker();
+
+ /* Qnil avoids GC'ing markers, which are useless for strings. */
+ cache->start = BUFFERP (object) ? Fmake_marker () : Qnil;
+ cache->end = BUFFERP (object) ? Fmake_marker () : Qnil;
+
+ reset_syntax_cache_range (cache, 0);
}
/* external syntax cache API */
+/* At this time (hg rev 5551:dab422055bab) setup_syntax_cache() is called
+ directly once in setup_buffer_syntax_cache and twice in regex.c. The
+ calls in regex.c are obfuscated, so it's hard to tell, but it looks like
+ they can be called with OBJECT being a buffer.
+
+ "You are in a confusing maze of initializations, all alike."
+
+ reset_syntax_cache_range (3 uses in setup_syntax_cache,
+ signal_syntax_cache_extent_changed, and init_buffer_syntax_cache)
+ reinitializes:
+ 1. if BUFFERP(OBJECT), marker positions to 1 (giving a null range)
+ 2. if BUFFERP(OBJECT), marker movement type
+ 3. cache range per VALID_EVERYWHERE
+
+ init_syntax_cache (2 uses in init_buffer_syntax_cache and
+ setup_syntax_cache) initializes:
+ 1. source to syntax_source_buffer_table
+ 2. syntax_table and mirror_syntax table to BUFFER's tables
+ 3. marker members to BUFFERP(OBJECT) ? markers w/o position : Qnil
+ 4. cache range with VALID_EVERYWHERE==0
+ 5. object and buffer to corresponding arguments.
+
+ init_buffer_syntax_cache (1 use in buffer.c) initializes:
+ 0. allocation of buffer's cache memory (done by allocator)
+ 1. cache memory to zero (done by allocator)
+ 2. cache to buffer's cache
+ 3. cache members by init_syntax_cache with object==buffer==BUF.
+
+ setup_buffer_syntax_cache (1 call in font-lock.c, 1 use in search.c,
+ and 7 uses in this file) initializes:
+ 0. buffer's syntax cache by calling setup_syntax_cache.
+
+ setup_buffer_syntax_cache and setup_syntax_cache are called by functions
+ that analyze text using character syntax. They are called repeatedly on
+ the same cache. init_syntax_cache and init_buffer_syntax_cache are
+ conceptually called once for each cache. reset_syntax_cache_range may
+ be called repeatedly on the same cache. The last three are for internal
+ use by the syntax setup code and buffer initialization. */
+
struct syntax_cache * /* return CACHE or the cache of OBJECT */
setup_syntax_cache (struct syntax_cache *cache, /* may be NULL only if
OBJECT is a buffer */
@@ -344,22 +381,37 @@
is associated with */
struct buffer *buffer, /* the buffer to use as source
of the syntax table */
- Charxpos UNUSED (from), /* initial position of cache */
- int UNUSED (count)) /* direction? see code */
+ Charxpos from, /* initial position of cache */
+ int count) /* direction? see code */
{
- /* If OBJECT is a buffer, use its cache, otherwise use CACHE.
- Initialize CACHE. Invalidate the cache if the syntax-table property is
- being respected, otherwise make it valid for the whole object. */
+ /* If OBJECT is a buffer, use its cache; else use CACHE and initialize it.
+ Invalidate the cache if the syntax-table property is being respected;
+ else make it valid for the whole object. */
if (BUFFERP (object))
{
cache = XBUFFER (object)->syntax_cache;
+ if (!lookup_syntax_properties)
+ reset_syntax_cache_range (cache, 1);
}
else
{
xzero (*cache);
init_syntax_cache (cache, object, buffer);
}
- reset_syntax_cache_range (cache, object);
+
+ if (lookup_syntax_properties)
+ {
+ if (count <= 0)
+ {
+ --from;
+ from = buffer_or_string_clip_to_accessible_char (cache->object,
+ from);
+ }
+ /* If lookup_syntax_properties && BUFFERP (object), this
+ optimization may matter. */
+ if (!(from >= cache->prev_change && from < cache->next_change))
+ update_syntax_cache (cache, from, count);
+ }
#ifdef NOT_WORTH_THE_EFFORT
update_mirror_syntax_if_dirty (cache->mirror_table);
@@ -454,24 +506,21 @@
if (!NILP (Fsyntax_table_p (tmp_table)))
{
- cache->use_code = 0;
+ cache->source = syntax_source_property_table;
cache->syntax_table = tmp_table;
cache->mirror_table = XCHAR_TABLE (tmp_table)->mirror_table;
- cache->no_syntax_table_prop = 0;
#ifdef NOT_WORTH_THE_EFFORT
update_mirror_syntax_if_dirty (cache->mirror_table);
#endif /* NOT_WORTH_THE_EFFORT */
}
else if (CONSP (tmp_table) && INTP (XCAR (tmp_table)))
{
- cache->use_code = 1;
+ cache->source = syntax_source_property_code;
cache->syntax_code = XINT (XCAR (tmp_table));
- cache->no_syntax_table_prop = 0;
}
else
{
- cache->use_code = 0;
- cache->no_syntax_table_prop = 1;
+ cache->source = syntax_source_buffer_table;
cache->syntax_table = BUFFER_SYNTAX_TABLE (cache->buffer);
cache->mirror_table = BUFFER_MIRROR_SYNTAX_TABLE (cache->buffer);
#ifdef NOT_WORTH_THE_EFFORT
@@ -501,14 +550,15 @@
void
init_buffer_syntax_cache (struct buffer *buf)
{
+ struct syntax_cache *cache;
#ifdef NEW_GC
- buf->syntax_cache = XSYNTAX_CACHE (ALLOC_NORMAL_LISP_OBJECT (syntax_cache));
+ cache = XSYNTAX_CACHE (ALLOC_NORMAL_LISP_OBJECT (syntax_cache));
#else /* not NEW_GC */
- buf->syntax_cache = xnew_and_zero (struct syntax_cache);
+ cache = xnew_and_zero (struct syntax_cache);
#endif /* not NEW_GC */
- init_syntax_cache (buf->syntax_cache, wrap_buffer(buf), buf);
- reset_syntax_cache_range (buf->syntax_cache, wrap_buffer(buf));
+ init_syntax_cache (cache, wrap_buffer (buf), buf);
+ buf->syntax_cache = cache;
}
/* finalize the syntax cache for BUF */
@@ -535,18 +585,18 @@
void
signal_syntax_cache_extent_changed (EXTENT extent)
{
- Lisp_Object buffer = Fextent_object (wrap_extent (extent));
- if (BUFFERP (buffer))
+ Lisp_Object object = Fextent_object (wrap_extent (extent));
+ if (BUFFERP (object))
{
- struct syntax_cache *cache = XBUFFER (buffer)->syntax_cache;
- Bytexpos start = extent_endpoint_byte (extent, 0);
- Bytexpos end = extent_endpoint_byte (extent, 1);
- Bytexpos start2 = byte_marker_position (cache->start);
- Bytexpos end2 = byte_marker_position (cache->end);
+ struct syntax_cache *cache = XBUFFER (object)->syntax_cache;
+ Bytexpos extent_start = extent_endpoint_byte (extent, 0);
+ Bytexpos extent_end = extent_endpoint_byte (extent, 1);
+ Bytexpos cache_start = byte_marker_position (cache->start);
+ Bytexpos cache_end = byte_marker_position (cache->end);
/* If the extent is entirely before or entirely after the cache
range, it doesn't overlap. Otherwise, invalidate the range. */
- if (!(end < start2 || start > end2))
- reset_syntax_cache_range (cache, buffer);
+ if (!(extent_end < cache_start || extent_start > cache_end))
+ reset_syntax_cache_range (cache, 0);
}
}
diff -r 40a52efbf3a3 -r 85210c453a97 src/syntax.h
--- a/src/syntax.h Sun Aug 14 13:51:14 2011 +0200
+++ b/src/syntax.h Tue Aug 23 04:41:45 2011 +0900
@@ -234,20 +234,21 @@
#### sjt sez: I'm not sure I believe that last claim. That seems to
require that we use directional information, etc, but that is ignored in
the current implementation. */
+
+enum syntax_source { syntax_source_property_code = 0,
+ syntax_source_property_table = 1,
+ syntax_source_buffer_table = 2 };
+#define SOURCE_IS_TABLE(source) (source)
+
struct syntax_cache
{
#ifdef NEW_GC
NORMAL_LISP_OBJECT_HEADER header;
#endif /* NEW_GC */
- int use_code; /* Non-zero if a syntax-table property
- specified a syntax code. When zero, the
- syntax_code member is invalid. Otherwise
- the syntax_table member is invalid. */
- int no_syntax_table_prop; /* If non-zero, there was no `syntax-table'
- property on the current range, and so we're
- using the buffer's syntax table.
- Then we must invalidate the cache if the
- buffer's syntax table is changed. */
+ enum syntax_source source; /* Source of syntax information: the buffer's
+ syntax table, a syntax table specified by
+ a syntax-table property, or a syntax code
+ specified by a syntax-table property. */
Lisp_Object object; /* The buffer or string the current syntax
cache applies to, or Qnil for a string of
text not coming from a buffer or string. */
@@ -260,6 +261,7 @@
Lisp_Object mirror_table; /* Mirror table for this table. */
Lisp_Object start, end; /* Markers to keep track of the known region
in a buffer.
+ Both are Qnil if object is a string.
Normally these correspond to prev_change
and next_change, respectively, except when
insertions and deletions occur. Then
@@ -269,7 +271,8 @@
We'd like to use an extent, but it seems
that having an extent over the entire
buffer causes serious slowdowns in extent
- operations! Yuck! */
+ operations! Yuck!
+ #### May not be true any more. */
Charxpos next_change; /* Position of the next extent change. */
Charxpos prev_change; /* Position of the previous extent change. */
};
@@ -341,9 +344,10 @@
#define SYNTAX_FROM_CACHE(cache, c) \
SYNTAX_FROM_CODE (SYNTAX_CODE_FROM_CACHE (cache, c))
-#define SYNTAX_CODE_FROM_CACHE(cache, c) \
- ((cache)->use_code ? (cache)->syntax_code \
-: SYNTAX_CODE ((cache)->mirror_table, c))
+#define SYNTAX_CODE_FROM_CACHE(cache, c) \
+ (SOURCE_IS_TABLE ((cache)->source) \
+ ? SYNTAX_CODE ((cache)->mirror_table, c) \
+: (cache)->syntax_code)
#ifdef NOT_WORTH_THE_EFFORT
/* If we really cared about the theoretical performance hit of the dirty
@@ -356,9 +360,10 @@
functions and could execute arbitrary Lisp very easily), etc. The QUIT
problem is the biggest one, probably, and one of the main reasons it's
probably just not worth it. */
-#define SYNTAX_CODE_FROM_CACHE(cache, c) \
- ((cache)->use_code ? (cache)->syntax_code \
-: SYNTAX_CODE_1 ((cache)->mirror_table, c))
+#define SYNTAX_CODE_FROM_CACHE(cache, c) \
+ (SOURCE_IS_TABLE ((cache)->source) \
+ ? SYNTAX_CODE_1 ((cache)->mirror_table, c) \
+: (cache)->syntax_code)
#endif
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
[AC21.5] Fix a nasty performange regression in syntax cache
13 years, 4 months
Stephen J. Turnbull
APPROVE COMMIT 21.5
Revision 5543:fbe90e6f7a43 "Initialize start and end properly (to new
markers, not Qnil)" introduced a bad performance regression, resulting
in map_extents (a fairly expensive function) being called ~15,000,000
times instead of ~100,000 times while fontifying python-mode.el.
xemacs -vanilla -eval '(find-lib "python-mode")'
-eval "(profile-command 'font-lock-fontify-buffer)"
to see the evil for yourself. :-/
All versions up to 5551:40a52efbf3a3 "Reflect change of location of
packages to share/" are affected. I recommend you avoid using those
versions if possible. If you must use one and run into performance
problems, setting `lookup-syntax-properties' to nil will probably help
performance (untested) but will definitely break cc-mode and cperl.
The attached patch fixes the issue, and due to the performance
regression, I'm going to commit it now. There's a bunch of other
stuff in there, refactoring and docs etc. Sorry about that, but I
needed to do most of the refactoring to figure out what was going
wrong.
FWIW, I'm fairly sure that the hunk "@@ -344,22 +381,37 @@" is what
actually fixes the regression.
diff -r 40a52efbf3a3 src/ChangeLog
--- a/src/ChangeLog Sun Aug 14 13:51:14 2011 +0200
+++ b/src/ChangeLog Tue Aug 23 04:32:35 2011 +0900
@@ -1,3 +1,41 @@
+2011-08-23 Stephen Turnbull <stephen(a)xemacs.org>
+
+ Fix performance regression in refactored syntax cache setup.
+ More doc improvements.
+
+ * syntax.h (enum syntax_source):
+ New. Specify whether syntax is from property or buffer.
+ (struct syntax_cache):
+ Use enum syntax_source source, instead of no_syntax_table_prop
+ and use_code.
+ Improve comments.
+ (SOURCE_IS_TABLE):
+ New predicate.
+ (SYNTAX_CODE_FROM_CACHE):
+ Use it instead of use_code, and adjust logic.
+
+ * syntax.c (syntax_cache_table_was_changed):
+ Check cache->source (cache->no_syntax_table_prop is gone).
+ (reset_syntax_cache_range):
+ All information about OBJECT and BUFFER is in CACHE already.
+ Also reset markers in OBJECT if it is a buffer.
+ Rename INFINITE to VALID_EVERYWHERE.
+ (init_syntax_cache):
+ Initialize source (cache->no_syntax_table_prop is gone).
+ Maybe initialize start and end to null markers.
+ Initialize cache range with reset_syntax_cache_range.
+ (update_syntax_cache):
+ Use source instead of no_syntax_table_prop and use_code.
+ (setup_syntax_cache):
+ Add header comment. Improve other comments.
+ Make calls to reset_syntax_cache_range and init_syntax_cache match
+ their prototypes.
+ (init_buffer_syntax_cache):
+ Use init_syntax_cache to do the work.
+ (signal_syntax_cache_extent_changed):
+ Make call to reset_syntax_cache_range match its prototype.
+ Improve local variable naming.
+
2011-08-08 Stephen J. Turnbull <stephen(a)xemacs.org>
* syntax.c (update_syntax_cache):
diff -r 40a52efbf3a3 src/syntax.c
--- a/src/syntax.c Sun Aug 14 13:51:14 2011 +0200
+++ b/src/syntax.c Tue Aug 23 04:32:35 2011 +0900
@@ -273,7 +273,7 @@
syntax_cache_table_was_changed (struct buffer *buf)
{
struct syntax_cache *cache = buf->syntax_cache;
- if (cache->no_syntax_table_prop)
+ if (cache->source == syntax_source_buffer_table)
{
cache->syntax_table =
BUFFER_SYNTAX_TABLE (buf);
@@ -284,59 +284,96 @@
static void
reset_syntax_cache_range (struct syntax_cache *cache, /* initialized cache */
- Lisp_Object object) /* string or buffer */
+ int valid_everywhere) /* non-zero if we can assume
+ syntax-table properties
+ never need be respected
+ in the life of the cache */
{
- /* reinitialize cache parameters */
- if (BUFFERP (object))
+ if (BUFFERP (cache->object))
{
/* make known region zero-length and reset insertion behavior */
- Fset_marker (cache->start, make_int (1), object);
- Fset_marker (cache->end, make_int (1), object);
+ Fset_marker (cache->start, make_int (1), cache->object);
+ Fset_marker (cache->end, make_int (1), cache->object);
Fset_marker_insertion_type (cache->start, Qnil);
Fset_marker_insertion_type (cache->end, Qt);
}
- else
+ /* #### Should reset "cache->source" here?
+ If so, also reset tables. */
+ if (valid_everywhere)
{
- /* invalidate the known region markers */
- Fset_marker (cache->start, Qnil, Qnil);
- Fset_marker (cache->end, Qnil, Qnil);
+ cache->prev_change = EMACS_INT_MIN;
+ cache->next_change = EMACS_INT_MAX;
}
- cache->no_syntax_table_prop = 1;
- if (lookup_syntax_properties)
+ else /* valid nowhere */
{
cache->prev_change = -1;
cache->next_change = -1;
}
- else
- {
- cache->prev_change = EMACS_INT_MIN;
- cache->next_change = EMACS_INT_MAX;
- }
}
-/* init_syntax_cache
- Arguments:
- cache: pointer to a zero-ed struct syntax_cache
- object: a Lisp string or buffer
- buffer: NULL or the struct buffer of buffer */
static void
-init_syntax_cache (struct syntax_cache *cache, /* cache must be zero'ed */
+init_syntax_cache (struct syntax_cache *cache, /* xzero'ed memory */
Lisp_Object object, /* string or buffer */
- struct buffer *buffer) /* may not be NULL */
+ struct buffer *buffer) /* buffer; if OBJECT is a
+ buffer, this is the same */
{
- /* initialize cache resources */
cache->object = object;
cache->buffer = buffer;
+
+ cache->source = syntax_source_buffer_table;
cache->syntax_table =
BUFFER_SYNTAX_TABLE (cache->buffer);
cache->mirror_table =
BUFFER_MIRROR_SYNTAX_TABLE (cache->buffer);
- cache->start = Fmake_marker();
- cache->end = Fmake_marker();
+
+ /* Qnil avoids GC'ing markers, which are useless for strings. */
+ cache->start = BUFFERP (object) ? Fmake_marker () : Qnil;
+ cache->end = BUFFERP (object) ? Fmake_marker () : Qnil;
+
+ reset_syntax_cache_range (cache, 0);
}
/* external syntax cache API */
+/* At this time (hg rev 5551:dab422055bab) setup_syntax_cache() is called
+ directly once in setup_buffer_syntax_cache and twice in regex.c. The
+ calls in regex.c are obfuscated, so it's hard to tell, but it looks like
+ they can be called with OBJECT being a buffer.
+
+ "You are in a confusing maze of initializations, all alike."
+
+ reset_syntax_cache_range (3 uses in setup_syntax_cache,
+ signal_syntax_cache_extent_changed, and init_buffer_syntax_cache)
+ reinitializes:
+ 1. if BUFFERP(OBJECT), marker positions to 1 (giving a null range)
+ 2. if BUFFERP(OBJECT), marker movement type
+ 3. cache range per VALID_EVERYWHERE
+
+ init_syntax_cache (2 uses in init_buffer_syntax_cache and
+ setup_syntax_cache) initializes:
+ 1. source to syntax_source_buffer_table
+ 2. syntax_table and mirror_syntax table to BUFFER's tables
+ 3. marker members to BUFFERP(OBJECT) ? markers w/o position : Qnil
+ 4. cache range with VALID_EVERYWHERE==0
+ 5. object and buffer to corresponding arguments.
+
+ init_buffer_syntax_cache (1 use in buffer.c) initializes:
+ 0. allocation of buffer's cache memory (done by allocator)
+ 1. cache memory to zero (done by allocator)
+ 2. cache to buffer's cache
+ 3. cache members by init_syntax_cache with object==buffer==BUF.
+
+ setup_buffer_syntax_cache (1 call in font-lock.c, 1 use in search.c,
+ and 7 uses in this file) initializes:
+ 0. buffer's syntax cache by calling setup_syntax_cache.
+
+ setup_buffer_syntax_cache and setup_syntax_cache are called by functions
+ that analyze text using character syntax. They are called repeatedly on
+ the same cache. init_syntax_cache and init_buffer_syntax_cache are
+ conceptually called once for each cache. reset_syntax_cache_range may
+ be called repeatedly on the same cache. The last three are for internal
+ use by the syntax setup code and buffer initialization. */
+
struct syntax_cache * /* return CACHE or the cache of OBJECT */
setup_syntax_cache (struct syntax_cache *cache, /* may be NULL only if
OBJECT is a buffer */
@@ -344,22 +381,37 @@
is associated with */
struct buffer *buffer, /* the buffer to use as source
of the syntax table */
- Charxpos UNUSED (from), /* initial position of cache */
- int UNUSED (count)) /* direction? see code */
+ Charxpos from, /* initial position of cache */
+ int count) /* direction? see code */
{
- /* If OBJECT is a buffer, use its cache, otherwise use CACHE.
- Initialize CACHE. Invalidate the cache if the syntax-table property is
- being respected, otherwise make it valid for the whole object. */
+ /* If OBJECT is a buffer, use its cache; else use CACHE and initialize it.
+ Invalidate the cache if the syntax-table property is being respected;
+ else make it valid for the whole object. */
if (BUFFERP (object))
{
cache = XBUFFER (object)->syntax_cache;
+ if (!lookup_syntax_properties)
+ reset_syntax_cache_range (cache, 1);
}
else
{
xzero (*cache);
init_syntax_cache (cache, object, buffer);
}
- reset_syntax_cache_range (cache, object);
+
+ if (lookup_syntax_properties)
+ {
+ if (count <= 0)
+ {
+ --from;
+ from = buffer_or_string_clip_to_accessible_char (cache->object,
+ from);
+ }
+ /* If lookup_syntax_properties && BUFFERP (object), this
+ optimization may matter. */
+ if (!(from >= cache->prev_change && from < cache->next_change))
+ update_syntax_cache (cache, from, count);
+ }
#ifdef NOT_WORTH_THE_EFFORT
update_mirror_syntax_if_dirty (cache->mirror_table);
@@ -454,24 +506,21 @@
if (!NILP (Fsyntax_table_p (tmp_table)))
{
- cache->use_code = 0;
+ cache->source = syntax_source_property_table;
cache->syntax_table = tmp_table;
cache->mirror_table = XCHAR_TABLE (tmp_table)->mirror_table;
- cache->no_syntax_table_prop = 0;
#ifdef NOT_WORTH_THE_EFFORT
update_mirror_syntax_if_dirty (cache->mirror_table);
#endif /* NOT_WORTH_THE_EFFORT */
}
else if (CONSP (tmp_table) && INTP (XCAR (tmp_table)))
{
- cache->use_code = 1;
+ cache->source = syntax_source_property_code;
cache->syntax_code = XINT (XCAR (tmp_table));
- cache->no_syntax_table_prop = 0;
}
else
{
- cache->use_code = 0;
- cache->no_syntax_table_prop = 1;
+ cache->source = syntax_source_buffer_table;
cache->syntax_table = BUFFER_SYNTAX_TABLE (cache->buffer);
cache->mirror_table = BUFFER_MIRROR_SYNTAX_TABLE (cache->buffer);
#ifdef NOT_WORTH_THE_EFFORT
@@ -501,14 +550,15 @@
void
init_buffer_syntax_cache (struct buffer *buf)
{
+ struct syntax_cache *cache;
#ifdef NEW_GC
- buf->syntax_cache = XSYNTAX_CACHE (ALLOC_NORMAL_LISP_OBJECT (syntax_cache));
+ cache = XSYNTAX_CACHE (ALLOC_NORMAL_LISP_OBJECT (syntax_cache));
#else /* not NEW_GC */
- buf->syntax_cache = xnew_and_zero (struct syntax_cache);
+ cache = xnew_and_zero (struct syntax_cache);
#endif /* not NEW_GC */
- init_syntax_cache (buf->syntax_cache, wrap_buffer(buf), buf);
- reset_syntax_cache_range (buf->syntax_cache, wrap_buffer(buf));
+ init_syntax_cache (cache, wrap_buffer (buf), buf);
+ buf->syntax_cache = cache;
}
/* finalize the syntax cache for BUF */
@@ -535,18 +585,18 @@
void
signal_syntax_cache_extent_changed (EXTENT extent)
{
- Lisp_Object buffer = Fextent_object (wrap_extent (extent));
- if (BUFFERP (buffer))
+ Lisp_Object object = Fextent_object (wrap_extent (extent));
+ if (BUFFERP (object))
{
- struct syntax_cache *cache = XBUFFER (buffer)->syntax_cache;
- Bytexpos start = extent_endpoint_byte (extent, 0);
- Bytexpos end = extent_endpoint_byte (extent, 1);
- Bytexpos start2 = byte_marker_position (cache->start);
- Bytexpos end2 = byte_marker_position (cache->end);
+ struct syntax_cache *cache = XBUFFER (object)->syntax_cache;
+ Bytexpos extent_start = extent_endpoint_byte (extent, 0);
+ Bytexpos extent_end = extent_endpoint_byte (extent, 1);
+ Bytexpos cache_start = byte_marker_position (cache->start);
+ Bytexpos cache_end = byte_marker_position (cache->end);
/* If the extent is entirely before or entirely after the cache
range, it doesn't overlap. Otherwise, invalidate the range. */
- if (!(end < start2 || start > end2))
- reset_syntax_cache_range (cache, buffer);
+ if (!(extent_end < cache_start || extent_start > cache_end))
+ reset_syntax_cache_range (cache, 0);
}
}
diff -r 40a52efbf3a3 src/syntax.h
--- a/src/syntax.h Sun Aug 14 13:51:14 2011 +0200
+++ b/src/syntax.h Tue Aug 23 04:32:35 2011 +0900
@@ -234,20 +234,21 @@
#### sjt sez: I'm not sure I believe that last claim. That seems to
require that we use directional information, etc, but that is ignored in
the current implementation. */
+
+enum syntax_source { syntax_source_property_code = 0,
+ syntax_source_property_table = 1,
+ syntax_source_buffer_table = 2 };
+#define SOURCE_IS_TABLE(source) (source)
+
struct syntax_cache
{
#ifdef NEW_GC
NORMAL_LISP_OBJECT_HEADER header;
#endif /* NEW_GC */
- int use_code; /* Non-zero if a syntax-table property
- specified a syntax code. When zero, the
- syntax_code member is invalid. Otherwise
- the syntax_table member is invalid. */
- int no_syntax_table_prop; /* If non-zero, there was no `syntax-table'
- property on the current range, and so we're
- using the buffer's syntax table.
- Then we must invalidate the cache if the
- buffer's syntax table is changed. */
+ enum syntax_source source; /* Source of syntax information: the buffer's
+ syntax table, a syntax table specified by
+ a syntax-table property, or a syntax code
+ specified by a syntax-table property. */
Lisp_Object object; /* The buffer or string the current syntax
cache applies to, or Qnil for a string of
text not coming from a buffer or string. */
@@ -260,6 +261,7 @@
Lisp_Object mirror_table; /* Mirror table for this table. */
Lisp_Object start, end; /* Markers to keep track of the known region
in a buffer.
+ Both are Qnil if object is a string.
Normally these correspond to prev_change
and next_change, respectively, except when
insertions and deletions occur. Then
@@ -269,7 +271,8 @@
We'd like to use an extent, but it seems
that having an extent over the entire
buffer causes serious slowdowns in extent
- operations! Yuck! */
+ operations! Yuck!
+ #### May not be true any more. */
Charxpos next_change; /* Position of the next extent change. */
Charxpos prev_change; /* Position of the previous extent change. */
};
@@ -341,9 +344,10 @@
#define SYNTAX_FROM_CACHE(cache, c) \
SYNTAX_FROM_CODE (SYNTAX_CODE_FROM_CACHE (cache, c))
-#define SYNTAX_CODE_FROM_CACHE(cache, c) \
- ((cache)->use_code ? (cache)->syntax_code \
-: SYNTAX_CODE ((cache)->mirror_table, c))
+#define SYNTAX_CODE_FROM_CACHE(cache, c) \
+ (SOURCE_IS_TABLE ((cache)->source) \
+ ? SYNTAX_CODE ((cache)->mirror_table, c) \
+: (cache)->syntax_code)
#ifdef NOT_WORTH_THE_EFFORT
/* If we really cared about the theoretical performance hit of the dirty
@@ -356,9 +360,10 @@
functions and could execute arbitrary Lisp very easily), etc. The QUIT
problem is the biggest one, probably, and one of the main reasons it's
probably just not worth it. */
-#define SYNTAX_CODE_FROM_CACHE(cache, c) \
- ((cache)->use_code ? (cache)->syntax_code \
-: SYNTAX_CODE_1 ((cache)->mirror_table, c))
+#define SYNTAX_CODE_FROM_CACHE(cache, c) \
+ (SOURCE_IS_TABLE ((cache)->source) \
+ ? SYNTAX_CODE_1 ((cache)->mirror_table, c) \
+: (cache)->syntax_code)
#endif
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
commit: Reflect change of location of packages to share/
13 years, 4 months
Michael Sperber
changeset: 5551:40a52efbf3a3
tag: tip
user: Mike Sperber <sperber(a)deinprogramm.de>
date: Sun Aug 14 13:51:14 2011 +0200
files: man/ChangeLog man/xemacs-faq.texi man/xemacs/packages.texi
description:
Reflect change of location of packages to share/
2011-08-14 Mike Sperber <mike(a)xemacs.org>
* xemacs-faq.texi:
* xemacs/packages.texi: Reflect change of location of packages
from lib/ to share/.
diff -r b908c7265a2b -r 40a52efbf3a3 man/ChangeLog
--- a/man/ChangeLog Fri Aug 12 16:02:30 2011 +0100
+++ b/man/ChangeLog Sun Aug 14 13:51:14 2011 +0200
@@ -1,3 +1,9 @@
+2011-08-14 Mike Sperber <mike(a)xemacs.org>
+
+ * xemacs-faq.texi:
+ * xemacs/packages.texi: Reflect change of location of packages
+ from lib/ to share/.
+
2011-08-09 Aidan Kehoe <kehoea(a)parhasard.net>
* cl.texi (Argument Lists):
diff -r b908c7265a2b -r 40a52efbf3a3 man/xemacs-faq.texi
--- a/man/xemacs-faq.texi Fri Aug 12 16:02:30 2011 +0100
+++ b/man/xemacs-faq.texi Sun Aug 14 13:51:14 2011 +0200
@@ -168,7 +168,7 @@
If you do not have makeinfo installed, you may @uref{xemacs-faq.info,
download the faq} in info format, and install it in @file{<XEmacs
library directory>/info/}. For example in
-(a)file{/usr/local/lib/xemacs-21.4/info/}.
+(a)file{/usr/local/lib/xemacs-21.5/info/}.
@end itemize
@@ -3285,14 +3285,14 @@
Install them on Unix and Mac OS X using the shell/Terminal command
-@code{cd $prefix/lib/xemacs ; gunzip -c <tarballname> | tar xf -}
+@code{cd $prefix/share/xemacs ; gunzip -c <tarballname> | tar xf -}
Where @samp{$prefix} is what you gave to the @samp{--prefix} flag to
@file{configure}, and defaults to @file{/usr/local}.
If you have GNU tar you can use:
-@code{cd $prefix/lib/xemacs ; tar zxvf <tarballname>}
+@code{cd $prefix/share/xemacs ; tar zxvf <tarballname>}
If you have the packages somewhere nonstandard and don't want to bother
with @samp{$prefix} (for example, you're a developer and are compiling
@@ -3347,8 +3347,8 @@
package (version 1.48):
@example
- mkdir $prefix/lib/xemacs/xemacs-packages RET # if it does not exist yet
- cd $prefix/lib/xemacs/xemacs-packages RET
+ mkdir $prefix/share/xemacs/xemacs-packages RET # if it does not exist yet
+ cd $prefix/share/xemacs/xemacs-packages RET
gunzip -c /path/to/xemacs-base-1.48-pkg.tar.gz | tar xvf - RET
@end example
@@ -3362,8 +3362,8 @@
hierarchy, i.e. for the @samp{mule-base} package, version 1.37:
@example
- mkdir $prefix/lib/xemacs/mule-packages RET # if it does not exist yet
- cd $prefix/lib/xemacs/mule-packages RET
+ mkdir $prefix/share/xemacs/mule-packages RET # if it does not exist yet
+ cd $prefix/share/xemacs/mule-packages RET
gunzip -c /path/to/mule-base-1.37-pkg.tar.gz | tar xvf - RET
@end example
@@ -3509,18 +3509,18 @@
Normally, there are three system wide hierarchies, like this:
@example
-$prefix/lib/xemacs/xemacs-packages/
+$prefix/sahre/xemacs/xemacs-packages/
Normal packages go here.
-$prefix/lib/xemacs/mule-packages/
+$prefix/share/xemacs/mule-packages/
Mule packages go here and are only searched by MULE-enabled XEmacsen.
-$prefix/lib/xemacs/site-packages/
+$prefix/share/xemacs/site-packages/
Local and 3rd party packages go here.
@end example
This is what you get when you untar the SUMO tarballs under
-@file{$prefix/lib/xemacs}.
+@file{$prefix/share/xemacs}.
@file{$prefix} is specified using the @samp{--prefix} parameter to
@file{configure}, and defaults to @file{usr/local}.
@@ -3533,7 +3533,7 @@
@file{lib/xemacs}. The XEmacs executable (under Unix at least) is
installed by default in @file{/usr/local/bin}; this explains why
XEmacs in its default installation will find packages that you put
-under @file{/usr/local/lib/xemacs}.
+under @file{/usr/local/share/xemacs}.
You can specify where exactly XEmacs looks for packages by using the
@samp{--with-user-packages} (an alias for @samp{--with-early-packages})
@@ -3557,7 +3557,7 @@
The site-packages hierarchy replaces the old @file{site-lisp}
directory. XEmacs no longer looks into a @file{site-lisp} directly by
default. A good place to put @file{site-start.el} would be in
-@file{$prefix/lib/xemacs/site-packages/lisp/}.
+@file{$prefix/share/xemacs/site-packages/lisp/}.
@node Q2.1.7, Q2.2.1, Q2.1.6, Installation
@unnumberedsubsec Q2.1.7: EFS fails with "500 AUTH not understood" (NEW)
@@ -6576,7 +6576,7 @@
The package @code{ps-print}, which is now included with XEmacs, provides
the ability to do this. The source code contains complete instructions
on its use, in
-(a)file{$prefix/lib/xemacs/xemacs-packages/lisp/ps-print/ps-print.el},
+@file{$prefix/share/xemacs/xemacs-packages/lisp/ps-print/ps-print.el},
being the default location of an installed ps-print package.
@node Q5.2.3, Q5.2.4, Q5.2.2, External Subsystems
diff -r b908c7265a2b -r 40a52efbf3a3 man/xemacs/packages.texi
--- a/man/xemacs/packages.texi Fri Aug 12 16:02:30 2011 +0100
+++ b/man/xemacs/packages.texi Sun Aug 14 13:51:14 2011 +0200
@@ -311,8 +311,8 @@
package (version 1.48):
@example
- mkdir $prefix/lib/xemacs/xemacs-packages RET # if it does not exist yet
- cd $prefix/lib/xemacs/xemacs-packages RET
+ mkdir $prefix/share/xemacs/xemacs-packages RET # if it does not exist yet
+ cd $prefix/share/xemacs/xemacs-packages RET
gunzip -c /path/to/xemacs-base-1.48-pkg.tar.gz | tar xvf - RET
Or if you have GNU tar, the last step can be:
@@ -324,8 +324,8 @@
hierarchy, i.e. for the @file{mule-base} package, version 1.37:
@example
- mkdir $prefix/lib/xemacs/mule-packages RET # if it does not exist yet
- cd $prefix/lib/xemacs/mule-packages RET
+ mkdir $prefix/share/xemacs/mule-packages RET # if it does not exist yet
+ cd $prefix/share/xemacs/mule-packages RET
gunzip -c /path/to/mule-base-1.37-pkg.tar.gz | tar xvf - RET
Or if you have GNU tar, the last step can be:
@@ -351,11 +351,11 @@
Install them by:
-@code{cd $prefix/lib/xemacs ; gunzip -c <tarballname> | tar xvf - RET}
+@code{cd $prefix/share/xemacs ; gunzip -c <tarballname> | tar xvf - RET}
Or, if you have GNU tar:
-@code{cd $prefix/lib/xemacs ; tar zxvf /path/to/<tarballname> RET}
+@code{cd $prefix/share/xemacs ; tar zxvf /path/to/<tarballname> RET}
As the Sumo tarballs are not regenerated as often as the individual
packages, it is recommended that you use the automatic package tools
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
[C] Reflect change in location of packages to share/
13 years, 4 months
Michael Sperber
2011-08-14 Mike Sperber <mike(a)xemacs.org>
* xemacs-faq.texi:
* xemacs/packages.texi: Reflect change of location of packages
from lib/ to share/.
--
Cheers =8-} Mike
Friede, Völkerverständigung und überhaupt blabla
diff --git a/man/xemacs-faq.texi b/man/xemacs-faq.texi
--- a/man/xemacs-faq.texi
+++ b/man/xemacs-faq.texi
@@ -168,7 +168,7 @@
If you do not have makeinfo installed, you may @uref{xemacs-faq.info,
download the faq} in info format, and install it in @file{<XEmacs
library directory>/info/}. For example in
-(a)file{/usr/local/lib/xemacs-21.4/info/}.
+(a)file{/usr/local/lib/xemacs-21.5/info/}.
@end itemize
@@ -3285,14 +3285,14 @@
Install them on Unix and Mac OS X using the shell/Terminal command
-@code{cd $prefix/lib/xemacs ; gunzip -c <tarballname> | tar xf -}
+@code{cd $prefix/share/xemacs ; gunzip -c <tarballname> | tar xf -}
Where @samp{$prefix} is what you gave to the @samp{--prefix} flag to
@file{configure}, and defaults to @file{/usr/local}.
If you have GNU tar you can use:
-@code{cd $prefix/lib/xemacs ; tar zxvf <tarballname>}
+@code{cd $prefix/share/xemacs ; tar zxvf <tarballname>}
If you have the packages somewhere nonstandard and don't want to bother
with @samp{$prefix} (for example, you're a developer and are compiling
@@ -3347,8 +3347,8 @@
package (version 1.48):
@example
- mkdir $prefix/lib/xemacs/xemacs-packages RET # if it does not exist yet
- cd $prefix/lib/xemacs/xemacs-packages RET
+ mkdir $prefix/share/xemacs/xemacs-packages RET # if it does not exist yet
+ cd $prefix/share/xemacs/xemacs-packages RET
gunzip -c /path/to/xemacs-base-1.48-pkg.tar.gz | tar xvf - RET
@end example
@@ -3362,8 +3362,8 @@
hierarchy, i.e. for the @samp{mule-base} package, version 1.37:
@example
- mkdir $prefix/lib/xemacs/mule-packages RET # if it does not exist yet
- cd $prefix/lib/xemacs/mule-packages RET
+ mkdir $prefix/share/xemacs/mule-packages RET # if it does not exist yet
+ cd $prefix/share/xemacs/mule-packages RET
gunzip -c /path/to/mule-base-1.37-pkg.tar.gz | tar xvf - RET
@end example
@@ -3509,18 +3509,18 @@
Normally, there are three system wide hierarchies, like this:
@example
-$prefix/lib/xemacs/xemacs-packages/
+$prefix/sahre/xemacs/xemacs-packages/
Normal packages go here.
-$prefix/lib/xemacs/mule-packages/
+$prefix/share/xemacs/mule-packages/
Mule packages go here and are only searched by MULE-enabled XEmacsen.
-$prefix/lib/xemacs/site-packages/
+$prefix/share/xemacs/site-packages/
Local and 3rd party packages go here.
@end example
This is what you get when you untar the SUMO tarballs under
-@file{$prefix/lib/xemacs}.
+@file{$prefix/share/xemacs}.
@file{$prefix} is specified using the @samp{--prefix} parameter to
@file{configure}, and defaults to @file{usr/local}.
@@ -3533,7 +3533,7 @@
@file{lib/xemacs}. The XEmacs executable (under Unix at least) is
installed by default in @file{/usr/local/bin}; this explains why
XEmacs in its default installation will find packages that you put
-under @file{/usr/local/lib/xemacs}.
+under @file{/usr/local/share/xemacs}.
You can specify where exactly XEmacs looks for packages by using the
@samp{--with-user-packages} (an alias for @samp{--with-early-packages})
@@ -3557,7 +3557,7 @@
The site-packages hierarchy replaces the old @file{site-lisp}
directory. XEmacs no longer looks into a @file{site-lisp} directly by
default. A good place to put @file{site-start.el} would be in
-@file{$prefix/lib/xemacs/site-packages/lisp/}.
+@file{$prefix/share/xemacs/site-packages/lisp/}.
@node Q2.1.7, Q2.2.1, Q2.1.6, Installation
@unnumberedsubsec Q2.1.7: EFS fails with "500 AUTH not understood" (NEW)
@@ -6576,7 +6576,7 @@
The package @code{ps-print}, which is now included with XEmacs, provides
the ability to do this. The source code contains complete instructions
on its use, in
-(a)file{$prefix/lib/xemacs/xemacs-packages/lisp/ps-print/ps-print.el},
+@file{$prefix/share/xemacs/xemacs-packages/lisp/ps-print/ps-print.el},
being the default location of an installed ps-print package.
@node Q5.2.3, Q5.2.4, Q5.2.2, External Subsystems
diff --git a/man/xemacs/packages.texi b/man/xemacs/packages.texi
--- a/man/xemacs/packages.texi
+++ b/man/xemacs/packages.texi
@@ -311,8 +311,8 @@
package (version 1.48):
@example
- mkdir $prefix/lib/xemacs/xemacs-packages RET # if it does not exist yet
- cd $prefix/lib/xemacs/xemacs-packages RET
+ mkdir $prefix/share/xemacs/xemacs-packages RET # if it does not exist yet
+ cd $prefix/share/xemacs/xemacs-packages RET
gunzip -c /path/to/xemacs-base-1.48-pkg.tar.gz | tar xvf - RET
Or if you have GNU tar, the last step can be:
@@ -324,8 +324,8 @@
hierarchy, i.e. for the @file{mule-base} package, version 1.37:
@example
- mkdir $prefix/lib/xemacs/mule-packages RET # if it does not exist yet
- cd $prefix/lib/xemacs/mule-packages RET
+ mkdir $prefix/share/xemacs/mule-packages RET # if it does not exist yet
+ cd $prefix/share/xemacs/mule-packages RET
gunzip -c /path/to/mule-base-1.37-pkg.tar.gz | tar xvf - RET
Or if you have GNU tar, the last step can be:
@@ -351,11 +351,11 @@
Install them by:
-@code{cd $prefix/lib/xemacs ; gunzip -c <tarballname> | tar xvf - RET}
+@code{cd $prefix/share/xemacs ; gunzip -c <tarballname> | tar xvf - RET}
Or, if you have GNU tar:
-@code{cd $prefix/lib/xemacs ; tar zxvf /path/to/<tarballname> RET}
+@code{cd $prefix/share/xemacs ; tar zxvf /path/to/<tarballname> RET}
As the Sumo tarballs are not regenerated as often as the individual
packages, it is recommended that you use the automatic package tools
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
[COMMIT] Add the #'apply-partially API, as used by GNU.
13 years, 4 months
Aidan Kehoe
APPROVE COMMIT
NOTE: This patch has been committed.
# HG changeset patch
# User Aidan Kehoe <kehoea(a)parhasard.net>
# Date 1313161350 -3600
# Node ID b908c7265a2b98c3dcb5bbc4edecd5c9a158fc02
# Parent 493c487cbc3f1fc4f14855181174eca2c717f119
Add the #'apply-partially API, as used by GNU.
lisp/ChangeLog addition:
2011-08-12 Aidan Kehoe <kehoea(a)parhasard.net>
* cl-macs.el:
* cl-macs.el (apply-partially): New compiler macro.
* subr.el:
* subr.el (apply-partially): New.
Sync this function's API and docstring from GNU. The
implementation is mine and trivial; the compiler macro in
cl-macs.el ensures that partially-applied functions in compiled
code are also compiled.
tests/ChangeLog addition:
2011-08-12 Aidan Kehoe <kehoea(a)parhasard.net>
* automated/lisp-tests.el:
Trivial tests of #'apply-partially, just added to subr.el.
diff -r 493c487cbc3f -r b908c7265a2b lisp/ChangeLog
--- a/lisp/ChangeLog Wed Aug 10 16:50:37 2011 +0100
+++ b/lisp/ChangeLog Fri Aug 12 16:02:30 2011 +0100
@@ -1,3 +1,14 @@
+2011-08-12 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * cl-macs.el:
+ * cl-macs.el (apply-partially): New compiler macro.
+ * subr.el:
+ * subr.el (apply-partially): New.
+ Sync this function's API and docstring from GNU. The
+ implementation is mine and trivial; the compiler macro in
+ cl-macs.el ensures that partially-applied functions in compiled
+ code are also compiled.
+
2011-08-10 Aidan Kehoe <kehoea(a)parhasard.net>
* keymap.el:
diff -r 493c487cbc3f -r b908c7265a2b lisp/cl-macs.el
--- a/lisp/cl-macs.el Wed Aug 10 16:50:37 2011 +0100
+++ b/lisp/cl-macs.el Fri Aug 12 16:02:30 2011 +0100
@@ -3510,6 +3510,24 @@
(list 'let (list (list temp val)) (subst temp val res)))))
form))
+(define-compiler-macro apply-partially (&whole form &rest args)
+ "Generate a #'make-byte-code call for #'apply-partially, if appropriate."
+ (if (< (length args) 1)
+ form
+ (if (cl-const-exprs-p args)
+ `#'(lambda (&rest args) (apply ,@args args))
+ (let* ((placeholders (mapcar 'quote-maybe (mapcar 'gensym args)))
+ (compiled (byte-compile-sexp
+ `#'(lambda (&rest args) (apply ,@placeholders args)))))
+ `(make-byte-code
+ ',(compiled-function-arglist compiled)
+ ,(compiled-function-instructions compiled)
+ (vector ,@(sublis (pairlis placeholders args)
+ (mapcar 'quote-maybe
+ (compiled-function-constants compiled))
+:test 'equal))
+ ,(compiled-function-stack-depth compiled))))))
+
(define-compiler-macro delete-dups (list)
`(delete-duplicates (the list ,list) :test #'equal :from-end t))
diff -r 493c487cbc3f -r b908c7265a2b lisp/subr.el
--- a/lisp/subr.el Wed Aug 10 16:50:37 2011 +0100
+++ b/lisp/subr.el Fri Aug 12 16:02:30 2011 +0100
@@ -85,6 +85,19 @@
quote lambda expressions appropriately."
`(function (lambda ,@cdr)))
+;; Partial application of functions (related to currying). XEmacs; closures
+;; aren't yet available to us as a language type, but they're not necessary
+;; for this function (nor indeed is CL's #'lexical-let). See also the
+;; compiler macro in cl-macs.el, which generates a call to #'make-byte-code
+;; at runtime, ensuring that partially applied functions are byte-compiled.
+(defun apply-partially (function &rest args)
+ "Return a function that is a partial application of FUNCTION to ARGS.
+ARGS is a list of the first N arguments to pass to FUNCTION.
+The result is a new function which does the same as FUNCTION, except that
+the first N arguments are fixed at the values with which this function
+was called."
+ `(lambda (&rest args) (apply ',function ,@(mapcar 'quote-maybe args) args)))
+
;; FSF 21.2 has various basic macros here. We don't because they're either
;; in cl*.el (which we dump and hence is always available) or built-in.
diff -r 493c487cbc3f -r b908c7265a2b tests/ChangeLog
--- a/tests/ChangeLog Wed Aug 10 16:50:37 2011 +0100
+++ b/tests/ChangeLog Fri Aug 12 16:02:30 2011 +0100
@@ -1,3 +1,8 @@
+2011-08-12 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * automated/lisp-tests.el:
+ Trivial tests of #'apply-partially, just added to subr.el.
+
2011-08-08 Stephen J. Turnbull <stephen(a)xemacs.org>
* automated/syntax-tests.el:
diff -r 493c487cbc3f -r b908c7265a2b tests/automated/lisp-tests.el
--- a/tests/automated/lisp-tests.el Wed Aug 10 16:50:37 2011 +0100
+++ b/tests/automated/lisp-tests.el Fri Aug 12 16:02:30 2011 +0100
@@ -2926,4 +2926,13 @@
(Assert (equal '([symbol expansion] [copy expansion] [third expansion])
(test-symbol-macrolet))))
+;; Basic tests of #'apply-partially.
+(let* ((four 4)
+ (times-four (apply-partially '* four))
+ (plus-twelve (apply-partially '+ 6 (* 3 2))))
+ (Assert (eql (funcall times-four 6) 24))
+ (Assert (eql (funcall times-four 4 4) 64))
+ (Assert (eql (funcall plus-twelve (funcall times-four 4) 4 4) 36))
+ (Check-Error wrong-number-of-arguments (apply-partially)))
+
;;; end of lisp-tests.el
--
‘Iodine deficiency was endemic in parts of the UK until, through what has been
described as “an unplanned and accidental public health triumph”, iodine was
added to cattle feed to improve milk production in the 1930s.’
(EN Pearce, Lancet, June 2011)
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
commit: Add the #'apply-partially API, as used by GNU.
13 years, 4 months
Aidan Kehoe
changeset: 5550:b908c7265a2b
tag: tip
user: Aidan Kehoe <kehoea(a)parhasard.net>
date: Fri Aug 12 16:02:30 2011 +0100
files: lisp/ChangeLog lisp/cl-macs.el lisp/subr.el tests/ChangeLog tests/automated/lisp-tests.el
description:
Add the #'apply-partially API, as used by GNU.
lisp/ChangeLog addition:
2011-08-12 Aidan Kehoe <kehoea(a)parhasard.net>
* cl-macs.el:
* cl-macs.el (apply-partially): New compiler macro.
* subr.el:
* subr.el (apply-partially): New.
Sync this function's API and docstring from GNU. The
implementation is mine and trivial; the compiler macro in
cl-macs.el ensures that partially-applied functions in compiled
code are also compiled.
tests/ChangeLog addition:
2011-08-12 Aidan Kehoe <kehoea(a)parhasard.net>
* automated/lisp-tests.el:
Trivial tests of #'apply-partially, just added to subr.el.
diff -r 493c487cbc3f -r b908c7265a2b lisp/ChangeLog
--- a/lisp/ChangeLog Wed Aug 10 16:50:37 2011 +0100
+++ b/lisp/ChangeLog Fri Aug 12 16:02:30 2011 +0100
@@ -1,3 +1,14 @@
+2011-08-12 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * cl-macs.el:
+ * cl-macs.el (apply-partially): New compiler macro.
+ * subr.el:
+ * subr.el (apply-partially): New.
+ Sync this function's API and docstring from GNU. The
+ implementation is mine and trivial; the compiler macro in
+ cl-macs.el ensures that partially-applied functions in compiled
+ code are also compiled.
+
2011-08-10 Aidan Kehoe <kehoea(a)parhasard.net>
* keymap.el:
diff -r 493c487cbc3f -r b908c7265a2b lisp/cl-macs.el
--- a/lisp/cl-macs.el Wed Aug 10 16:50:37 2011 +0100
+++ b/lisp/cl-macs.el Fri Aug 12 16:02:30 2011 +0100
@@ -3510,6 +3510,24 @@
(list 'let (list (list temp val)) (subst temp val res)))))
form))
+(define-compiler-macro apply-partially (&whole form &rest args)
+ "Generate a #'make-byte-code call for #'apply-partially, if appropriate."
+ (if (< (length args) 1)
+ form
+ (if (cl-const-exprs-p args)
+ `#'(lambda (&rest args) (apply ,@args args))
+ (let* ((placeholders (mapcar 'quote-maybe (mapcar 'gensym args)))
+ (compiled (byte-compile-sexp
+ `#'(lambda (&rest args) (apply ,@placeholders args)))))
+ `(make-byte-code
+ ',(compiled-function-arglist compiled)
+ ,(compiled-function-instructions compiled)
+ (vector ,@(sublis (pairlis placeholders args)
+ (mapcar 'quote-maybe
+ (compiled-function-constants compiled))
+:test 'equal))
+ ,(compiled-function-stack-depth compiled))))))
+
(define-compiler-macro delete-dups (list)
`(delete-duplicates (the list ,list) :test #'equal :from-end t))
diff -r 493c487cbc3f -r b908c7265a2b lisp/subr.el
--- a/lisp/subr.el Wed Aug 10 16:50:37 2011 +0100
+++ b/lisp/subr.el Fri Aug 12 16:02:30 2011 +0100
@@ -85,6 +85,19 @@
quote lambda expressions appropriately."
`(function (lambda ,@cdr)))
+;; Partial application of functions (related to currying). XEmacs; closures
+;; aren't yet available to us as a language type, but they're not necessary
+;; for this function (nor indeed is CL's #'lexical-let). See also the
+;; compiler macro in cl-macs.el, which generates a call to #'make-byte-code
+;; at runtime, ensuring that partially applied functions are byte-compiled.
+(defun apply-partially (function &rest args)
+ "Return a function that is a partial application of FUNCTION to ARGS.
+ARGS is a list of the first N arguments to pass to FUNCTION.
+The result is a new function which does the same as FUNCTION, except that
+the first N arguments are fixed at the values with which this function
+was called."
+ `(lambda (&rest args) (apply ',function ,@(mapcar 'quote-maybe args) args)))
+
;; FSF 21.2 has various basic macros here. We don't because they're either
;; in cl*.el (which we dump and hence is always available) or built-in.
diff -r 493c487cbc3f -r b908c7265a2b tests/ChangeLog
--- a/tests/ChangeLog Wed Aug 10 16:50:37 2011 +0100
+++ b/tests/ChangeLog Fri Aug 12 16:02:30 2011 +0100
@@ -1,3 +1,8 @@
+2011-08-12 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * automated/lisp-tests.el:
+ Trivial tests of #'apply-partially, just added to subr.el.
+
2011-08-08 Stephen J. Turnbull <stephen(a)xemacs.org>
* automated/syntax-tests.el:
diff -r 493c487cbc3f -r b908c7265a2b tests/automated/lisp-tests.el
--- a/tests/automated/lisp-tests.el Wed Aug 10 16:50:37 2011 +0100
+++ b/tests/automated/lisp-tests.el Fri Aug 12 16:02:30 2011 +0100
@@ -2926,4 +2926,13 @@
(Assert (equal '([symbol expansion] [copy expansion] [third expansion])
(test-symbol-macrolet))))
+;; Basic tests of #'apply-partially.
+(let* ((four 4)
+ (times-four (apply-partially '* four))
+ (plus-twelve (apply-partially '+ 6 (* 3 2))))
+ (Assert (eql (funcall times-four 6) 24))
+ (Assert (eql (funcall times-four 4 4) 64))
+ (Assert (eql (funcall plus-twelve (funcall times-four 4) 4 4) 36))
+ (Check-Error wrong-number-of-arguments (apply-partially)))
+
;;; end of lisp-tests.el
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
Re: [PATCH] Implement print-circle, use it in the byte compiler.
13 years, 4 months
Aidan Kehoe
Ar an dara lá déag de mí Lúnasa, scríobh Stephen J. Turnbull:
> Aidan Kehoe writes:
>
> > GNU has had this for a while. Their implementation isn’t particularly
> > object-oriented, and I wrote the bulk of the below before we moved to
> > GPLv3, so it’s very different code. If anyone’s interested in writing
> > tests, I can commit this, but I won’t get to writing tests myself for
> > a while, and I’m not in a rush to commit the change without them.
>
> Haven't we had a feature of numbering self-referential objects, and
> printing references to those objects in subobjects as numerical reference
> since the turn of the millennium or so?
We have, yes, but that syntax throws an error on read. Try it:
(let ((vector [1 2 3 4 5]))
(aset vector 4 vector)
vector)
=> [1 2 3 4 #0]
[1 2 3 4 #0]
=> Invalid read syntax: #
(setq print-circle t)
=> t
(let ((vector [1 2 3 4 5]))
(aset vector 4 vector)
vector)
=> #1=[1 2 3 4 #1#]
#1=[1 2 3 4 #1#]
=> #1=[1 2 3 4 #1#]
(aref #1=[1 2 3 4 #1#] 4)
=> #1=[1 2 3 4 #1#]
Not to mention that <circular list> is not readable:
(setq print-circle nil)
=> nil
(let ((list (list 1 2 3 4)))
(nconc list list))
=> (1 2 3 4 1 2 3 ... <circular list>)
(1 2 3 4 1 2 3 ... <circular list>)
=> Invalid read syntax: .
(setq print-circle t)
=> t
(let ((list (list 1 2 3 4)))
(nconc list list))
=> #1=(1 2 3 4 . #1#)
But reading this in *scratch* fails, while it succeeds in other contexts;
lisp-interaction-mode doesn’t yet know enough about this.
--
‘Iodine deficiency was endemic in parts of the UK until, through what has been
described as “an unplanned and accidental public health triumph”, iodine was
added to cattle feed to improve milk production in the 1930s.’
(EN Pearce, Lancet, June 2011)
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches