[PATCH] Implement print-circle, use it in the byte compiler.
13 years, 4 months
Aidan Kehoe
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.
lisp/ChangeLog addition:
2011-08-11 Aidan Kehoe <kehoea(a)parhasard.net>
* bytecomp.el (byte-compile-output-file-form):
* bytecomp.el (byte-compile-output-docform):
Bind print-circle, print-continuous-numbering in these functions,
now those variables are available.
src/ChangeLog addition:
2011-08-11 Aidan Kehoe <kehoea(a)parhasard.net>
* alloc.c:
* alloc.c (cons_print_preprocess):
* alloc.c (vector_print_preprocess):
* alloc.c (vector_nsubst_structures_descend):
* alloc.c (reinit_alloc_objects_early):
* alloc.c (reinit_alloc_early):
* bytecode.c:
* bytecode.c (compiled_function_print_preprocess):
* bytecode.c (compiled_function_nsubst_structures_descend):
* bytecode.c (set_compiled_function_arglist):
* bytecode.c (set_compiled_function_interactive):
* bytecode.c (bytecode_objects_create):
* chartab.c:
* chartab.c (print_preprocess_mapper):
* chartab.c (nsubst_structures_mapper):
* chartab.c (char_table_nsubst_structures_descend):
* chartab.c (chartab_objects_create):
* elhash.c:
* elhash.c (nsubst_structures_map_hash_table):
* elhash.c (hash_table_nsubst_structures_descend):
* elhash.c (print_preprocess_mapper):
* elhash.c (hash_table_print_preprocess):
* elhash.c (inchash_eq):
* elhash.c (hash_table_objects_create):
* elhash.c (syms_of_elhash):
* elhash.h:
* emacs.c (main_1):
* fns.c:
* fns.c (check_eq_nokey):
* fns.c (Fnsubst):
* fns.c (syms_of_fns):
* lisp.h:
* lisp.h (struct):
* lisp.h (PRINT_PREPROCESS):
* lread.c (read1):
* lrecord.h (struct lrecord_implementation):
* print.c:
* print.c (PRINT_CIRCLE_LIMIT):
* print.c (print_continuous_numbering_changed):
* print.c (print_prepare):
* print.c (print_finish):
* print.c (Fprin1_to_string):
* print.c (print_cons):
* print.c (print_preprocess_inchash_eq):
* print.c (print_preprocess):
* print.c (print_sort_get_numbers):
* print.c (print_sort_compare_ordinals):
* print.c (print_gensym_or_circle):
* print.c (nsubst_structures_descend):
* print.c (nsubst_structures):
* print.c (print_internal):
* print.c (print_symbol):
* print.c (vars_of_print):
* rangetab.c:
* rangetab.c (range_table_print_preprocess):
* rangetab.c (range_table_nsubst_structures_descend):
* rangetab.c (rangetab_objects_create):
* rangetab.c (syms_of_rangetab):
* symbols.c:
* symbols.c (symbol_print_preprocess):
* symbols.c (reinit_symbol_objects_early):
* symsinit.h:
Implement print-circle, printing circular structures in a readable
fashion, and treating them appropriately on read. This is by means
of two new object methods, print_preprocess (detecting
circularities), and nsubst_structures_descend (replacing
placeholders with the read objects).
Expose the substitution to Lisp via #'nsubst and its new
:descend-structures keyword.
diff -r 493c487cbc3f lisp/bytecomp.el
--- a/lisp/bytecomp.el Wed Aug 10 16:50:37 2011 +0100
+++ b/lisp/bytecomp.el Thu Aug 11 17:01:22 2011 +0100
@@ -1935,12 +1935,13 @@
(byte-compile-output-docform nil nil '("\n(" 3 ")") form nil
(memq (car form)
'(autoload custom-declare-variable)))
- (let ((print-escape-newlines t)
- (print-length nil)
- (print-level nil)
- (print-readably t) ; print #[] for bytecode, 'x for (quote x)
- (print-gensym (if byte-compile-print-gensym '(t) nil))
- print-gensym-alist)
+ (let* ((print-escape-newlines t)
+ (print-length nil)
+ (print-level nil)
+ (print-readably t) ; print #[] for bytecode, 'x for (quote x)
+ (print-gensym byte-compile-print-gensym)
+ (print-continuous-numbering print-gensym)
+ (print-circle t))
(when byte-compile-output-preface
(princ "\n(progn " byte-compile-outbuffer)
(prin1 byte-compile-output-preface byte-compile-outbuffer))
@@ -1984,18 +1985,16 @@
(> (length (nth (nth 1 info) form)) 0)
(char= (aref (nth (nth 1 info) form) 0) ?*))
(setq position (- position)))))
- (let ((print-escape-newlines t)
- (print-readably t) ; print #[] for bytecode, 'x for (quote x)
- ;; Use a cons cell to say that we want
- ;; print-gensym-alist not to be cleared between calls
- ;; to print functions.
- (print-gensym (if byte-compile-print-gensym '(t) nil))
- print-gensym-alist
- (index 0))
+ (byte-compile-flush-pending)
+ (let* ((print-escape-newlines t)
+ (print-readably t) ; print #[] for bytecode, 'x for (quote x)
+ (print-gensym byte-compile-print-gensym)
+ (print-continuous-numbering print-gensym)
+ (print-circle t)
+ (index 0))
(when byte-compile-output-preface
(princ "\n(progn " byte-compile-outbuffer)
(prin1 byte-compile-output-preface byte-compile-outbuffer))
- (byte-compile-flush-pending)
(if preface
(progn
(insert preface)
diff -r 493c487cbc3f src/alloc.c
--- a/src/alloc.c Wed Aug 10 16:50:37 2011 +0100
+++ b/src/alloc.c Thu Aug 11 17:01:22 2011 +0100
@@ -1326,6 +1326,43 @@
return 0;
}
+static void
+cons_print_preprocess (Lisp_Object object, Lisp_Object print_number_table,
+ Elemcount *seen_object_count)
+{
+ PRINT_PREPROCESS (XCAR (object), print_number_table, seen_object_count);
+ PRINT_PREPROCESS (XCDR (object), print_number_table, seen_object_count);
+}
+
+static void
+cons_nsubst_structures_descend (Lisp_Object new_, Lisp_Object old,
+ Lisp_Object object,
+ Lisp_Object number_table,
+ Boolint test_not_unboundp)
+{
+ if (EQ (old, XCAR (object)) == test_not_unboundp)
+ {
+ XSETCAR (object, new_);
+ }
+ else if (LRECORDP (XCAR (object)) &&
+ HAS_OBJECT_METH_P (XCAR (object), nsubst_structures_descend))
+ {
+ nsubst_structures_descend (new_, old, XCAR (object), number_table,
+ test_not_unboundp);
+ }
+
+ if (EQ (old, XCDR (object)))
+ {
+ XSETCDR (object, new_);
+ }
+ else if (LRECORDP (XCDR (object)) &&
+ HAS_OBJECT_METH_P (XCDR (object), nsubst_structures_descend))
+ {
+ nsubst_structures_descend (new_, old, XCDR (object), number_table,
+ test_not_unboundp);
+ }
+}
+
static const struct memory_description cons_description[] = {
{ XD_LISP_OBJECT, offsetof (Lisp_Cons, car_) },
{ XD_LISP_OBJECT, offsetof (Lisp_Cons, cdr_) },
@@ -1713,6 +1750,44 @@
depth + 1, equalp));
}
+static void
+vector_print_preprocess (Lisp_Object object, Lisp_Object print_number_table,
+ Elemcount *seen_object_count)
+{
+ Elemcount ii, len;
+
+ for (ii = 0, len = XVECTOR_LENGTH (object); ii < len; ii++)
+ {
+ PRINT_PREPROCESS (XVECTOR_DATA (object)[ii], print_number_table,
+ seen_object_count);
+ }
+}
+
+static void
+vector_nsubst_structures_descend (Lisp_Object new_, Lisp_Object old,
+ Lisp_Object object, Lisp_Object number_table,
+ Boolint test_not_unboundp)
+{
+ Elemcount ii = XVECTOR_LENGTH (object);
+ Lisp_Object *vdata = XVECTOR_DATA (object);
+
+ while (ii > 0)
+ {
+ --ii;
+
+ if (EQ (vdata[ii], old) == test_not_unboundp)
+ {
+ vdata[ii] = new_;
+ }
+ else if (LRECORDP (vdata[ii]) &&
+ HAS_OBJECT_METH_P (vdata[ii], nsubst_structures_descend))
+ {
+ nsubst_structures_descend (new_, old, vdata[ii], number_table,
+ test_not_unboundp);
+ }
+ }
+}
+
static const struct memory_description vector_description[] = {
{ XD_LONG, offsetof (Lisp_Vector, size) },
{ XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Vector, contents), XD_INDIRECT(0, 0) },
@@ -5631,6 +5706,11 @@
OBJECT_HAS_METHOD (string, putprop);
OBJECT_HAS_METHOD (string, remprop);
OBJECT_HAS_METHOD (string, plist);
+
+ OBJECT_HAS_METHOD (cons, print_preprocess);
+ OBJECT_HAS_METHOD (cons, nsubst_structures_descend);
+ OBJECT_HAS_METHOD (vector, print_preprocess);
+ OBJECT_HAS_METHOD (vector, nsubst_structures_descend);
}
void
diff -r 493c487cbc3f src/bytecode.c
--- a/src/bytecode.c Wed Aug 10 16:50:37 2011 +0100
+++ b/src/bytecode.c Thu Aug 11 17:01:22 2011 +0100
@@ -95,6 +95,13 @@
Lisp_Compiled_Function_Args);
#endif /* NEW_GC */
+static void set_compiled_function_arglist (Lisp_Compiled_Function *,
+ Lisp_Object);
+static void set_compiled_function_constants (Lisp_Compiled_Function *,
+ Lisp_Object);
+static void set_compiled_function_interactive (Lisp_Compiled_Function *,
+ Lisp_Object);
+
EXFUN (Ffetch_bytecode, 1);
Lisp_Object Qbyte_code, Qcompiled_functionp, Qinvalid_byte_code;
@@ -2360,6 +2367,76 @@
f2->doc_and_interactive, depth + 1));
}
+static void
+compiled_function_print_preprocess (Lisp_Object object,
+ Lisp_Object print_number_table,
+ Elemcount *seen_object_count)
+{
+ Lisp_Compiled_Function *cf = XCOMPILED_FUNCTION (object);
+
+ PRINT_PREPROCESS (compiled_function_arglist (cf), print_number_table,
+ seen_object_count);
+
+ PRINT_PREPROCESS (compiled_function_constants (cf), print_number_table,
+ seen_object_count);
+
+ if (cf->flags.interactivep)
+ {
+ PRINT_PREPROCESS (compiled_function_interactive (cf),
+ print_number_table, seen_object_count);
+ }
+}
+
+static void
+compiled_function_nsubst_structures_descend (Lisp_Object new_, Lisp_Object old,
+ Lisp_Object object,
+ Lisp_Object number_table,
+ Boolint test_not_unboundp)
+{
+ Lisp_Compiled_Function *cf = XCOMPILED_FUNCTION (object);
+ Lisp_Object arglist = compiled_function_arglist (cf);
+ Lisp_Object constants = compiled_function_constants (cf);
+
+ if (EQ (arglist, old) == test_not_unboundp)
+ {
+ set_compiled_function_arglist (cf, new_);
+ }
+ else if (CONSP (arglist))
+ {
+ nsubst_structures_descend (new_, old, arglist, number_table,
+ test_not_unboundp);
+ }
+
+ if (EQ (constants, old) == test_not_unboundp)
+ {
+ set_compiled_function_constants (cf, new_);
+ }
+ else
+ {
+ nsubst_structures_descend (new_, old, constants, number_table,
+ test_not_unboundp);
+ }
+
+ /* We're not descending into the instructions here, because this function
+ is initially for use in the Lisp reader, where it only makes sense to
+ use the #%d= syntax for lrecords. */
+
+ if (cf->flags.interactivep)
+ {
+ Lisp_Object interactive = compiled_function_interactive (cf);
+ if (EQ (interactive, old) == test_not_unboundp)
+ {
+ set_compiled_function_interactive (cf, new_);
+ }
+ else if (LRECORDP (interactive) &&
+ HAS_OBJECT_METH_P (interactive, nsubst_structures_descend))
+ {
+ nsubst_structures_descend (new_, old, interactive, number_table,
+ test_not_unboundp);
+ }
+ }
+}
+
static Hashcode
compiled_function_hash (Lisp_Object obj, int depth, Boolint UNUSED (equalp))
{
@@ -2607,6 +2684,47 @@
}
}
+static void
+set_compiled_function_arglist (Lisp_Compiled_Function *f, Lisp_Object new_)
+{
+ CHECK_LIST (new_);
+ f->arglist = new_;
+
+ /* Recalculate the optimized version of the function, since this depends
+ on the arglist. */
+ f->instructions = compiled_function_instructions (f);
+ optimize_compiled_function (wrap_compiled_function (f));
+}
+
+static void
+set_compiled_function_constants (Lisp_Compiled_Function *f, Lisp_Object new_)
+{
+ CHECK_VECTOR (new_);
+ f->constants = new_;
+}
+
+static void
+set_compiled_function_interactive (Lisp_Compiled_Function *f, Lisp_Object new_)
+{
+ assert (f->flags.interactivep);
+
+ if (f->flags.documentationp && f->flags.domainp)
+ {
+ XSETCAR (XCDR (f->doc_and_interactive), new_);
+ }
+ else if (f->flags.documentationp)
+ {
+ XSETCDR (f->doc_and_interactive, new_);
+ }
+ else if (f->flags.domainp)
+ {
+ XSETCAR (f->doc_and_interactive, new_);
+ }
+ else
+ {
+ f->doc_and_interactive = new_;
+ }
+}
DEFUN ("compiled-function-arglist", Fcompiled_function_arglist, 1, 1, 0, /*
Return the argument list of the compiled-function object FUNCTION.
@@ -2782,6 +2900,13 @@
void
+bytecode_objects_create (void)
+{
+ OBJECT_HAS_METHOD (compiled_function, print_preprocess);
+ OBJECT_HAS_METHOD (compiled_function, nsubst_structures_descend);
+}
+
+void
syms_of_bytecode (void)
{
INIT_LISP_OBJECT (compiled_function);
diff -r 493c487cbc3f src/chartab.c
--- a/src/chartab.c Wed Aug 10 16:50:37 2011 +0100
+++ b/src/chartab.c Thu Aug 11 17:01:22 2011 +0100
@@ -94,6 +94,122 @@
/* Char Table object */
/************************************************************************/
+static int
+print_preprocess_mapper (struct chartab_range * UNUSED (range),
+ Lisp_Object UNUSED (table), Lisp_Object val,
+ void *extra_arg)
+{
+ print_preprocess (val, ((preprocess_info_t *) extra_arg)->table,
+ ((preprocess_info_t *) extra_arg)->count);
+ return 0;
+}
+
+static void
+char_table_print_preprocess (Lisp_Object object, Lisp_Object print_number_table,
+ Elemcount *seen_object_count)
+{
+ struct chartab_range ctr = { CHARTAB_RANGE_ALL, 0, Qnil, 0 };
+ preprocess_info_t preprocess_info = { print_number_table, seen_object_count };
+ map_char_table (object, &ctr, print_preprocess_mapper, &preprocess_info);
+}
+
+static void decode_char_table_range (Lisp_Object range,
+ struct chartab_range *outrange);
+
+static int
+nsubst_structures_mapper (struct chartab_range * range, Lisp_Object table,
+ Lisp_Object value, void *extra_arg)
+{
+ Lisp_Object number_table
+ = ((nsubst_structures_info_t *) extra_arg)->number_table;
+ Lisp_Object new_ = ((nsubst_structures_info_t *) extra_arg)->new_;
+ Lisp_Object old = ((nsubst_structures_info_t *) extra_arg)->old;
+ Boolint test_not_unboundp
+ = ((nsubst_structures_info_t *) extra_arg)->test_not_unboundp;
+ struct chartab_range changed = { range->type, range->ch, range->charset,
+ range->row };
+
+ switch (range->type)
+ {
+ case CHARTAB_RANGE_ALL:
+ {
+ if (EQ (old, Qt) == test_not_unboundp)
+ {
+ decode_char_table_range (new_, &changed);
+
+ put_char_table (table, range, Qunbound);
+ put_char_table (table, &changed, value);
+ }
+ break;
+ }
+ case CHARTAB_RANGE_CHARSET:
+ {
+ if (EQ (old, range->charset) == test_not_unboundp)
+ {
+ CHECK_CHARSET (new_);
+ changed.charset = new_;
+
+ put_char_table (table, range, Qunbound);
+ put_char_table (table, &changed, value);
+ }
+ else assert (!HAS_OBJECT_METH_P (range->charset,
+ nsubst_structures_descend));
+ break;
+ }
+ case CHARTAB_RANGE_ROW:
+ {
+ if (EQ (old, make_int (range->row)) == test_not_unboundp)
+ {
+ CHECK_INT (new_);
+ changed.row = XINT (new_);
+
+ put_char_table (table, range, Qunbound);
+ put_char_table (table, &changed, value);
+ }
+ break;
+ }
+ case CHARTAB_RANGE_CHAR:
+ {
+ if (EQ (old, make_char (range->ch)) == test_not_unboundp)
+ {
+ CHECK_CHAR (new_);
+ changed.ch = XCHAR (new_);
+
+ put_char_table (table, range, Qunbound);
+ put_char_table (table, &changed, value);
+ }
+ break;
+ }
+ }
+
+ if (EQ (old, value) == test_not_unboundp)
+ {
+ put_char_table (table, &changed, new_);
+ }
+ else if (LRECORDP (value) &&
+ HAS_OBJECT_METH_P (value, nsubst_structures_descend))
+ {
+ nsubst_structures_descend (new_, old, value, number_table,
+ test_not_unboundp);
+ }
+
+ return 0;
+}
+
+static void
+char_table_nsubst_structures_descend (Lisp_Object new_, Lisp_Object old,
+ Lisp_Object object,
+ Lisp_Object number_table,
+ Boolint test_not_unboundp)
+{
+ struct chartab_range ctr = { CHARTAB_RANGE_ALL, 0, Qnil, 0 };
+ nsubst_structures_info_t nsubst_structures_info
+ = { number_table, new_, old, object, test_not_unboundp };
+
+ map_char_table (object, &ctr, nsubst_structures_mapper,
+ &nsubst_structures_info);
+}
+
#ifdef MULE
static Lisp_Object
@@ -1890,6 +2006,13 @@
void
+chartab_objects_create (void)
+{
+ OBJECT_HAS_METHOD (char_table, print_preprocess);
+ OBJECT_HAS_METHOD (char_table, nsubst_structures_descend);
+}
+
+void
syms_of_chartab (void)
{
INIT_LISP_OBJECT (char_table);
diff -r 493c487cbc3f src/elhash.c
--- a/src/elhash.c Wed Aug 10 16:50:37 2011 +0100
+++ b/src/elhash.c Thu Aug 11 17:01:22 2011 +0100
@@ -350,6 +350,89 @@
return Qnil;
}
+static int
+nsubst_structures_map_hash_table (Lisp_Object key, Lisp_Object value,
+ void *extra_arg)
+{
+ Lisp_Object number_table
+ = ((nsubst_structures_info_t *) extra_arg)->number_table;
+ Lisp_Object new_ = ((nsubst_structures_info_t *) extra_arg)->new_;
+ Lisp_Object old = ((nsubst_structures_info_t *) extra_arg)->old;
+ Lisp_Object hash_table
+ = ((nsubst_structures_info_t *) extra_arg)->current_object;
+ Boolint test_not_unboundp
+ = ((nsubst_structures_info_t *) extra_arg)->test_not_unboundp;
+
+ if (EQ (old, key) == test_not_unboundp)
+ {
+ Fremhash (key, hash_table);
+ Fputhash (new_, value, hash_table);
+ }
+ else if (LRECORDP (key) &&
+ HAS_OBJECT_METH_P (key, nsubst_structures_descend))
+ {
+ nsubst_structures_descend (new_, old, key, number_table,
+ test_not_unboundp);
+ }
+
+ if (EQ (old, value) == test_not_unboundp)
+ {
+ Fputhash (key, new_, hash_table);
+ }
+ else if (LRECORDP (value) &&
+ HAS_OBJECT_METH_P (value, nsubst_structures_descend))
+ {
+ nsubst_structures_descend (new_, old, value, number_table,
+ test_not_unboundp);
+ }
+
+ return 0;
+}
+
+static void
+hash_table_nsubst_structures_descend (Lisp_Object new_, Lisp_Object old,
+ Lisp_Object object,
+ Lisp_Object number_table,
+ Boolint test_not_unboundp)
+{
+ nsubst_structures_info_t nsubst_structures_info
+ = { number_table, new_, old, object, test_not_unboundp };
+
+ /* If we're happy with limiting nsubst_structures to use in the Lisp
+ reader, we don't have to worry about the hash table test here, because
+ the only point where NEW_ can be the test will be forms like so:
+ #%d=#:SOME-GENSYM, in which case OLD will most definitively not include
+ a hash table anywhere in its structure. */
+
+ elisp_maphash (nsubst_structures_map_hash_table, object,
+ &nsubst_structures_info);
+}
+
+static int
+print_preprocess_mapper (Lisp_Object key, Lisp_Object value, void *extra_arg)
+{
+ Lisp_Object print_number_table = ((preprocess_info_t *) extra_arg)->table;
+ Elemcount *seen_number_count = ((preprocess_info_t *) extra_arg)->count;
+
+ PRINT_PREPROCESS (key, print_number_table, seen_number_count);
+ PRINT_PREPROCESS (value, print_number_table, seen_number_count);
+
+ return 0;
+}
+
+static void
+hash_table_print_preprocess (Lisp_Object obj, Lisp_Object number_table,
+ Elemcount *seen_object_count)
+{
+ preprocess_info_t preprocess_info = { number_table,
+ seen_object_count };
+
+ print_preprocess (XHASH_TABLE_TEST (XHASH_TABLE (obj)->test)->name,
+ number_table, seen_object_count);
+
+ elisp_maphash_unsafe (print_preprocess_mapper, obj, &preprocess_info);
+}
+
/* Equality of hash tables. Two hash tables are equal when they are of
the same weakness and test function, they have the same number of
elements, and for each key in the hash table, the values are `equal'.
@@ -1277,7 +1360,7 @@
overhead -- profiling overhead was being recorded at up to 15% of the
total time. */
-void
+htentry *
inchash_eq (Lisp_Object key, Lisp_Object table, EMACS_INT offset)
{
Lisp_Hash_Table *ht = XHASH_TABLE (table);
@@ -1297,8 +1380,13 @@
probe->value = make_int (offset);
if (++ht->count >= ht->rehash_count)
- enlarge_hash_table (ht);
+ {
+ enlarge_hash_table (ht);
+ return NULL;
+ }
}
+
+ return probe;
}
DEFUN ("gethash", Fgethash, 2, 3, 0, /*
@@ -2241,6 +2329,8 @@
#ifdef MEMORY_USAGE_STATS
OBJECT_HAS_METHOD (hash_table, memory_usage);
#endif
+ OBJECT_HAS_METHOD (hash_table, print_preprocess);
+ OBJECT_HAS_METHOD (hash_table, nsubst_structures_descend);
}
void
diff -r 493c487cbc3f src/elhash.h
--- a/src/elhash.h Wed Aug 10 16:50:37 2011 +0100
+++ b/src/elhash.h Thu Aug 11 17:01:22 2011 +0100
@@ -128,7 +128,7 @@
void pdump_reorganize_hash_table (Lisp_Object);
-void inchash_eq (Lisp_Object key, Lisp_Object table, EMACS_INT offset);
+htentry *inchash_eq (Lisp_Object key, Lisp_Object table, EMACS_INT offset);
htentry *find_htentry (Lisp_Object key, const Lisp_Hash_Table *ht);
diff -r 493c487cbc3f src/emacs.c
--- a/src/emacs.c Wed Aug 10 16:50:37 2011 +0100
+++ b/src/emacs.c Thu Aug 11 17:01:22 2011 +0100
@@ -1757,7 +1757,9 @@
)
{
buffer_objects_create ();
+ bytecode_objects_create ();
casetab_objects_create ();
+ chartab_objects_create ();
extent_objects_create ();
face_objects_create ();
frame_objects_create ();
@@ -1767,6 +1769,7 @@
#ifdef MULE
mule_charset_objects_create ();
#endif
+ rangetab_objects_create ();
#ifdef HAVE_SCROLLBARS
scrollbar_objects_create ();
#endif
diff -r 493c487cbc3f src/fns.c
--- a/src/fns.c Wed Aug 10 16:50:37 2011 +0100
+++ b/src/fns.c Thu Aug 11 17:01:22 2011 +0100
@@ -59,6 +59,7 @@
Lisp_Object Qsome, Qevery, Qmaplist, Qmapl, Qmapcon, Qreduce, Qsubstitute;
Lisp_Object Q_start1, Q_start2, Q_end1, Q_end2, Q_if_, Q_if_not, Q_stable;
Lisp_Object Q_test_not, Q_count, Qnsubstitute, Qdelete_duplicates, Qmismatch;
+Lisp_Object Q_descend_structures;
Lisp_Object Qintersection, Qset_difference, Qnset_difference;
Lisp_Object Qnunion, Qnintersection, Qsubsetp, Qcar_less_than_car;
@@ -207,7 +208,7 @@
/* Various test functions for #'member*, #'assoc* and the other functions
that take both TEST and KEY arguments. */
-static Boolint
+Boolint
check_eq_nokey (Lisp_Object UNUSED (test), Lisp_Object UNUSED (key),
Lisp_Object item, Lisp_Object elt)
{
@@ -9303,14 +9304,32 @@
Any element of TREE which is `eql' to OLD is changed to NEW (via a call to
`setcar').
-See `member*' for the meaning of the keywords.
-
-arguments: (NEW OLD TREE &key (TEST #'eql) (KEY #'identity) TEST-NOT)
-*/
- (int nargs, Lisp_Object *args))
-{
- Lisp_Object result, alist = noseeum_cons (noseeum_cons (args[1], args[0]),
- Qnil);
+See `member*' for the meaning of the keywords. The keyword
+:descend-structures, not specified by Common Lisp, allows callers to specify
+that non-cons objects (vectors and range tables, among others) should also
+undergo substitution. Currently this implementation is incomplete.
+
+arguments: (NEW OLD TREE &key (TEST #'eql) (KEY #'identity) TEST-NOT DESCEND-STRUCTURES)
+*/
+ (int nargs, Lisp_Object *args))
+{
+ Lisp_Object new_ = args[0], old = args[1], tree = args[2], result, alist;
+ Boolint test_not_unboundp = 1;
+ check_test_func_t check_test = NULL;
+
+ PARSE_KEYWORDS (Fnsubst, nargs, args, 6, (test, if_, test_not, if_not, key,
+ descend_structures), NULL);
+ if (!NILP (descend_structures))
+ {
+ check_test = get_check_test_function (old, &test, test_not, if_, if_not,
+ key, &test_not_unboundp);
+
+ return nsubst_structures (new_, old, tree, check_test, test_not_unboundp,
+ test, key);
+
+ }
+
+ alist = noseeum_cons (noseeum_cons (old, new_), Qnil);
args[1] = alist;
result = Fnsublis (nargs - 1, args + 1);
free_cons (XCAR (alist));
@@ -11707,6 +11726,7 @@
DEFKEYWORD (Q_test_not);
DEFKEYWORD (Q_count);
DEFKEYWORD (Q_stable);
+ DEFKEYWORD (Q_descend_structures);
DEFSYMBOL (Qyes_or_no_p);
diff -r 493c487cbc3f src/lisp.h
--- a/src/lisp.h Wed Aug 10 16:50:37 2011 +0100
+++ b/src/lisp.h Thu Aug 11 17:01:22 2011 +0100
@@ -5267,6 +5267,8 @@
EXFUN (Fsubseq, 3);
EXFUN (Fvalid_plist_p, 1);
+extern Boolint check_eq_nokey (Lisp_Object, Lisp_Object, Lisp_Object,
+ Lisp_Object);
extern Boolint check_lss_key_car (Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object);
extern Boolint check_string_lessp_nokey (Lisp_Object, Lisp_Object,
@@ -5275,6 +5277,20 @@
typedef Boolint (*check_test_func_t) (Lisp_Object test, Lisp_Object key,
Lisp_Object item, Lisp_Object elt);
+typedef struct
+{
+ Lisp_Object number_table;
+ Lisp_Object new_;
+ Lisp_Object old;
+ Lisp_Object current_object;
+ Boolint test_not_unboundp;
+} nsubst_structures_info_t;
+
+Lisp_Object nsubst_structures (Lisp_Object new_, Lisp_Object old,
+ Lisp_Object tree, check_test_func_t check_test,
+ Boolint test_not_unboundp,
+ Lisp_Object test, Lisp_Object key);
+
Lisp_Object list_merge (Lisp_Object org_l1, Lisp_Object org_l2,
check_test_func_t check_merge,
Lisp_Object predicate, Lisp_Object key_func);
@@ -5617,6 +5633,31 @@
DECLARE_DOESNT_RETURN (printing_unreadable_lisp_object (Lisp_Object obj,
const Ibyte *name));
+#define PRINT_PREPROCESS(obj, print_number_table, seen_object_count) \
+ do if (LRECORDP (obj) \
+ && XRECORD_LHEADER_IMPLEMENTATION (obj)->print_preprocess) \
+ { \
+ print_preprocess (obj, print_number_table, seen_object_count); \
+ } while (0)
+
+typedef struct { Lisp_Object table; Elemcount *count; } preprocess_info_t;
+
+void print_preprocess (Lisp_Object obj, Lisp_Object print_number_table,
+ Elemcount *seen_object_count);
+
+/* These is in print.c because they use the print_preprocess
+ infrastructure. */
+Lisp_Object nsubst_structures_descend (Lisp_Object new_, Lisp_Object old,
+ Lisp_Object object,
+ Lisp_Object number_table,
+ Boolint test_not_unboundp);
+
+Lisp_Object nsubst_structures (Lisp_Object new_, Lisp_Object old,
+ Lisp_Object tree,
+ check_test_func_t check_test,
+ Boolint test_not_unboundp,
+ Lisp_Object test, Lisp_Object key);
+
extern Lisp_Object Qexternal_debugging_output;
extern Lisp_Object Qprint_length;
extern Lisp_Object Qprint_string_length;
@@ -5746,6 +5787,18 @@
extern MODULE_API Lisp_Object Qt, Qunbound;
extern Lisp_Object Vobarray;
+DECLARE_INLINE_HEADER (
+int
+uninternedp (Lisp_Object object)
+)
+{
+ Lisp_Object name = symbol_name (XSYMBOL (object)),
+ lookedup = oblookup (Vobarray, XSTRING_DATA (name), XSTRING_LENGTH (name));
+ return !EQ (object, lookedup);
+}
+
+#define UNINTERNEDP(obj) uninternedp (obj)
+
/* Defined in syntax.c */
Charbpos scan_words (struct buffer *, Charbpos, int);
EXFUN (Fchar_syntax, 2);
diff -r 493c487cbc3f src/lread.c
--- a/src/lread.c Wed Aug 10 16:50:37 2011 +0100
+++ b/src/lread.c Thu Aug 11 17:01:22 2011 +0100
@@ -2715,16 +2715,32 @@
{
/* #n=object returns object, but associates it with
n for #n#. */
- Lisp_Object obj;
if (CONSP (found))
- return Fsignal (Qinvalid_read_syntax,
- list2 (build_msg_string
- ("Multiply defined symbol label"),
- make_int (n)));
- obj = read0 (readcharfun);
- Vread_objects = Fcons (Fcons (make_int (n), obj),
- Vread_objects);
- return obj;
+ {
+ return Fsignal (Qinvalid_read_syntax,
+ list2 (build_msg_string
+ ("Multiply defined object label"),
+ make_int (n)));
+ }
+ else
+ {
+ Lisp_Object object;
+
+ found = Fcons (make_int (n), Qnil);
+ /* Make FOUND a placeholder for the object that will
+ be read. (We've just consed it, and it's not
+ visible from Lisp, so there's no possibility of
+ confusing it with something else in the read
+ structure.) */
+ XSETCDR (found, found);
+ Vread_objects = Fcons (found, Vread_objects);
+ object = read0 (readcharfun);
+ XSETCDR (found, object);
+
+ nsubst_structures (object, XCDR (found), object,
+ check_eq_nokey, 1, Qeq, Qnil);
+ return object;
+ }
}
else if (c == '#')
{
diff -r 493c487cbc3f src/lrecord.h
--- a/src/lrecord.h Wed Aug 10 16:50:37 2011 +0100
+++ b/src/lrecord.h Thu Aug 11 17:01:22 2011 +0100
@@ -540,6 +540,14 @@
be NULL. */
void (*disksave) (Lisp_Object);
+ void (*print_preprocess) (Lisp_Object obj, Lisp_Object number_table,
+ Elemcount *seen_object_count);
+
+ void (*nsubst_structures_descend) (Lisp_Object new_, Lisp_Object old,
+ Lisp_Object object,
+ Lisp_Object number_table,
+ Boolint test_not_unboundp);
+
#ifdef MEMORY_USAGE_STATS
/* Return memory-usage information about the object in question, stored
into STATS.
diff -r 493c487cbc3f src/print.c
--- a/src/print.c Wed Aug 10 16:50:37 2011 +0100
+++ b/src/print.c Thu Aug 11 17:01:22 2011 +0100
@@ -50,6 +50,7 @@
#endif
#include "sysfile.h"
+#include "elhash.h"
#include <float.h>
/* Define if not in float.h */
@@ -71,8 +72,8 @@
static int print_depth;
/* Detect most circularities to print finite output. */
-#define PRINT_CIRCLE 200
-static Lisp_Object being_printed[PRINT_CIRCLE];
+#define PRINT_CIRCLE_LIMIT 200
+static Lisp_Object being_printed[PRINT_CIRCLE_LIMIT];
/* Maximum length of list or vector to print in full; noninteger means
effectively infinity */
@@ -96,15 +97,48 @@
Lisp_Object Vprint_message_label;
/* Nonzero means print newlines in strings as \n. */
+Boolint print_escape_newlines;
-int print_escape_newlines;
-int print_readably;
+Boolint print_readably;
-/* Non-nil means print #: before uninterned symbols.
- Neither t nor nil means so that and don't clear Vprint_gensym_alist
- on entry to and exit from print functions. */
-Lisp_Object Vprint_gensym;
-Lisp_Object Vprint_gensym_alist;
+/* Non-zero means print #: before uninterned symbols, and use the #n= and
+ #n# syntax for them. */
+Boolint print_gensym;
+
+/* Non-zero means print recursive structures using #n= and #n# syntax. */
+Boolint print_circle;
+
+/* Non-zero means keep continuous numbers for #n= and #n# syntax between
+ several print functions. Setting or binding the corresponding Lisp
+ variable to a non-nil value silently *clears* Vprint_number_table. */
+Boolint print_continuous_numbering;
+
+/* Vprint_number_table is a hash table mapping objects to their statuses for
+ this print operation. The statuses are represented by integers. */
+Lisp_Object Vprint_number_table;
+
+/* These describe the bit fields of the integers in Vprint_number_table. */
+enum PRINT_NUMBER_FIELDS {
+ /* Lowest four bits describe the number of times a given object has
+ been seen, allowing entries to be manipulated cheaply by
+ inchash_eq() when encountered. */
+ PRINT_NUMBER_SEEN_MASK = 0xF,
+
+ /* The next twenty-five bits give the sequence number for the object,
+ corresponding to the order in which print_preprocess encountered the
+ objects; as such, it's related to print_number_index. */
+ PRINT_NUMBER_ORDINAL_MASK = 0x1FFFFFF0,
+ PRINT_NUMBER_ORDINAL_SHIFT = 4,
+
+ /* And the next bit describes whether the object has already been printed
+ in this print operation (or in these print operations, if
+ print-continuous-numbering is relevant). */
+ PRINT_NUMBER_PRINTED_MASK = 0x20000000,
+};
+
+/* Reflects the number of repeated or possibly-repeated objects encountered
+ by print_preprocess(); reset whenever Vprint_number_table is cleared. */
+Elemcount print_number_index;
Lisp_Object Qdisplay_error;
Lisp_Object Qprint_message_label;
@@ -540,11 +574,29 @@
UNGCPRO;
}
-#define RESET_PRINT_GENSYM do { \
- if (!CONSP (Vprint_gensym)) \
- Vprint_gensym_alist = Qnil; \
-} while (0)
+static int
+print_continuous_numbering_changed (Lisp_Object UNUSED (sym),
+ Lisp_Object *val,
+ Lisp_Object UNUSED (in_object),
+ int UNUSED (flags))
+{
+ if (!NILP (*val) && !print_continuous_numbering)
+ {
+ Fclrhash (Vprint_number_table);
+ print_number_index = 0;
+ }
+ return 0;
+}
+
+#define RESET_PRINT_NUMBER_TABLE do { \
+ if (!print_continuous_numbering) \
+ { \
+ Fclrhash (Vprint_number_table); \
+ print_number_index = 0; \
+ } \
+ } while (0)
+
Lisp_Object
canonicalize_printcharfun (Lisp_Object printcharfun)
{
@@ -565,8 +617,8 @@
if (gc_in_progress)
return Qnil;
#endif
-
- RESET_PRINT_GENSYM;
+
+ RESET_PRINT_NUMBER_TABLE;
printcharfun = canonicalize_printcharfun (printcharfun);
@@ -612,8 +664,8 @@
if (gc_in_progress)
return;
#endif
-
- RESET_PRINT_GENSYM;
+
+ RESET_PRINT_NUMBER_TABLE;
/* See the comment in print_prepare(). */
if (FRAMEP (frame_kludge))
@@ -935,9 +987,9 @@
/* This function can GC */
Lisp_Object result = Qnil;
- RESET_PRINT_GENSYM;
+ RESET_PRINT_NUMBER_TABLE;
result = prin1_to_string (object, !(EQ(noescape, Qnil)));
- RESET_PRINT_GENSYM;
+ RESET_PRINT_NUMBER_TABLE;
return result;
}
@@ -1415,30 +1467,56 @@
obj = XCDR (obj), len++)
{
if (len > 0)
- write_ascstring (printcharfun, " ");
- if (EQ (obj, tortoise) && len > 0)
- {
- if (print_readably)
- printing_unreadable_object_fmt ("circular list");
- else
- write_ascstring (printcharfun, "... <circular list>");
- break;
- }
- if (len & 1)
- tortoise = XCDR (tortoise);
- if (len > max)
- {
- write_ascstring (printcharfun, "...");
- break;
- }
+ {
+ write_ascstring (printcharfun, " ");
+
+ /* Note that print_cons is the only object method that does any
+ circularity checking itself, because a cons that is the cdr
+ of OBJ is not handed to print_internal in the ordinary course
+ of events. All the other possibly-repeated structures always
+ hand sub-objects to print_internal(). */
+ if (print_circle &&
+ INTP (Fgethash (obj, Vprint_number_table, Qnil)))
+ {
+ write_ascstring (printcharfun, ". ");
+ print_internal (obj, printcharfun, escapeflag);
+ /* We have printed the list's tail, print_cons() is done. */
+ break;
+ }
+
+ if (EQ (obj, tortoise))
+ {
+ if (print_readably)
+ {
+ printing_unreadable_object_fmt ("circular list");
+ }
+
+ write_ascstring (printcharfun, "... <circular list>");
+ break;
+ }
+
+ if (len & 1)
+ {
+ tortoise = XCDR (tortoise);
+ }
+
+ if (len > max)
+ {
+ write_ascstring (printcharfun, "...");
+ break;
+ }
+ }
+
print_internal (XCAR (obj), printcharfun, escapeflag);
}
}
+
if (!LISTP (obj))
{
write_ascstring (printcharfun, " . ");
print_internal (obj, printcharfun, escapeflag);
}
+
UNGCPRO;
write_ascstring (printcharfun, ")");
@@ -1638,13 +1716,320 @@
"#<SERIOUS XEMACS BUG: %s Save your buffers immediately "
"and please report this bug>", buf);
}
+
+static Elemcount
+print_preprocess_inchash_eq (Lisp_Object obj, Lisp_Object table,
+ Elemcount *seen_object_count)
+{
+ htentry *hte = inchash_eq (obj, table, 1);
+ Elemcount extracted;
+ /* If the hash table had to be resized, hte is NULL. */
+ if (hte == NULL)
+ {
+ hte = find_htentry (obj, XHASH_TABLE (table));
+ }
+
+ extracted = XINT (hte->value);
+ if (1 == extracted)
+ {
+ *seen_object_count += 1;
+ hte->value
+ = make_int (1 | (*seen_object_count << PRINT_NUMBER_ORDINAL_SHIFT));
+ }
+ else if ((extracted & PRINT_NUMBER_SEEN_MASK) == PRINT_NUMBER_SEEN_MASK)
+ {
+ /* Avoid the number overflowing the bit field. */
+ extracted = (extracted & ~PRINT_NUMBER_SEEN_MASK) | 2;
+ hte->value = make_int (extracted);
+ }
+
+ return extracted & PRINT_NUMBER_SEEN_MASK;
+}
+/* Fill in Vprint_number_table according to the structure of OBJ. OBJ itself
+ and all its elements will be added to Vprint_number_table recursively if
+ its type has the print_preprocess method implemented. Objects with the
+ print_preprocess method implemented include cons, vector, compiled
+ function, hash table, char table, range table, and symbol. Symbol is an
+ exceptional type in that it is impossible to construct a recursive symbol
+ structure, but is here for the print-gensym feature. */
+
+void
+print_preprocess (Lisp_Object object, Lisp_Object print_number_table,
+ Elemcount *seen_object_count)
+{
+ if (!LRECORDP (object) || !HAS_OBJECT_METH_P (object, print_preprocess))
+ {
+ return;
+ }
+
+ if (SYMBOLP (object) && !UNINTERNEDP (object))
+ {
+ /* Handle symbols specially. We do this here rather than in symbols.c
+ because we don't want to have all the other print_preprocess methods
+ worry about print_preprocess_inchash_eq. */
+ return;
+ }
+
+ if (print_preprocess_inchash_eq (object, print_number_table,
+ seen_object_count) > 1)
+ {
+ return;
+ }
+
+ OBJECT_METH (object, print_preprocess, (object, print_number_table,
+ seen_object_count));
+}
+
+typedef struct { Lisp_Object key; Elemcount count; } preprocess_sort_t;
+
+static int
+print_seen_once (Lisp_Object UNUSED (key), Lisp_Object value,
+ void * UNUSED (extra_arg))
+{
+ return 1 == ((XINT (value) & PRINT_NUMBER_SEEN_MASK));
+}
+
+static int
+print_nonsymbol_seen_once (Lisp_Object key, Lisp_Object value,
+ void * UNUSED (extra_arg))
+{
+ /* print_continuous_numbering is used for symbols, so we don't delete them
+ from the print info hash table. It's less useful for other objects at
+ the moment, though. */
+ return !SYMBOLP (key) && (1 == ((XINT (value) & PRINT_NUMBER_SEEN_MASK)));
+}
+
+static int
+print_sort_get_numbers (Lisp_Object key, Lisp_Object value, void *extra_arg)
+{
+ preprocess_sort_t **preprocess_sort_ptr = (preprocess_sort_t **) extra_arg;
+ preprocess_sort_t *preprocess_sort = *preprocess_sort_ptr;
+
+ *preprocess_sort_ptr += 1;
+ preprocess_sort->key = key;
+ preprocess_sort->count = XINT (value);
+
+ return 0;
+}
+
+static int
+print_sort_compare_ordinals (const void *object1, const void *object2)
+{
+ Elemcount a = ((preprocess_sort_t *) object1)->count
+ & PRINT_NUMBER_ORDINAL_MASK;
+ Elemcount b = ((preprocess_sort_t *) object2)->count
+ & PRINT_NUMBER_ORDINAL_MASK;
+
+ return a - b;
+}
+
+enum print_gensym_status
+ {
+ PRINT_GENSYM_DONE,
+ PRINT_GENSYM_PRINT,
+ PRINT_GENSYM_PRINT_AND_CLEANUP_TABLE,
+ };
+
+/* Check for any circular objects or repeated uninterned symbols.
+
+ If OBJ is a repeated structure (or symbol) and it has been printed
+ already, print it now in the #%d# format, and return 1, to indicate
+ print_internal is done.
+
+ If OBJ is a repeated structure and it has not yet been printed, print
+ #%d= before the object, mark it as printed, and return zero, to indicate
+ print_internal should continue as usual.
+
+ If OBJ is not a repeated structure, do nothing, and return zero, to
+ indicate print_internal should continue as usual. */
+static enum print_gensym_status
+print_gensym_or_circle (Lisp_Object obj, Lisp_Object printcharfun)
+{
+ Lisp_Object seen = Fgethash (obj, Vprint_number_table, Qnil);
+ if (NILP (seen))
+ {
+ Elemcount old_print_number_index = print_number_index;
+
+ print_preprocess (obj, Vprint_number_table, &print_number_index);
+
+ if (old_print_number_index != print_number_index)
+ {
+ Elemcount new_print_number_index, ii;
+
+ /* We support up to 25 bits' worth of repeated objects, which is
+ 33 million or so, far more than we support in, say, a
+ compiled-function constants vector. */
+ assert (print_number_index <=
+ (PRINT_NUMBER_ORDINAL_MASK >> PRINT_NUMBER_ORDINAL_SHIFT));
+
+ /* If any objects have been seen once and once only, remove them
+ from Vprint_number_table. This is a bit of an arbitrary
+ decision; we could keep them around for the sake of
+ print_continuous_numbering, but there's the reasonable worry
+ about Vprint_number_table getting awkwardly large. */
+ elisp_map_remhash (print_continuous_numbering ?
+ print_nonsymbol_seen_once : print_seen_once,
+ Vprint_number_table, NULL);
+
+ new_print_number_index
+ = XINT (Fhash_table_count (Vprint_number_table));
+
+ if (new_print_number_index != print_number_index
+ && new_print_number_index != old_print_number_index)
+ {
+ preprocess_sort_t *preprocess_sort
+ = alloca_array (preprocess_sort_t, new_print_number_index);
+ preprocess_sort_t *preprocess_sort_ptr = preprocess_sort;
+
+ /* There are new objects in Vprint_number_table, but their
+ ordinal values don't necessarily represent the order they
+ were seen in, there will be gaps corresponding to the
+ non-symbols that were seen only once. Correct this. */
+ elisp_maphash_unsafe (print_sort_get_numbers, Vprint_number_table,
+ &preprocess_sort_ptr);
+
+ qsort (preprocess_sort, new_print_number_index,
+ sizeof (preprocess_sort_t), print_sort_compare_ordinals);
+
+ for (ii = old_print_number_index;
+ ii < new_print_number_index;
+ ii++)
+ {
+ Fputhash (preprocess_sort[ii].key,
+ make_int ((preprocess_sort[ii].count
+ & ~PRINT_NUMBER_ORDINAL_MASK)
+ | ((ii + 1)
+ << PRINT_NUMBER_ORDINAL_SHIFT)),
+ Vprint_number_table);
+ }
+ }
+
+ print_number_index = new_print_number_index;
+
+ /* The new objects may include OBJ; update SEEN to reflect
+ this. */
+ seen = Fgethash (obj, Vprint_number_table, Qnil);
+ if (INTP (seen))
+ {
+ goto prefix_this;
+ }
+ }
+ }
+ else
+ {
+ prefix_this:
+ if ((XINT (seen) & PRINT_NUMBER_SEEN_MASK) == 1
+ && !(print_continuous_numbering && SYMBOLP (obj)))
+ {
+ return PRINT_GENSYM_PRINT_AND_CLEANUP_TABLE;
+ }
+ else if (XINT (seen) & PRINT_NUMBER_PRINTED_MASK)
+ {
+ write_fmt_string (printcharfun, "#%d#",
+ (XINT (seen) & PRINT_NUMBER_ORDINAL_MASK)
+ >> PRINT_NUMBER_ORDINAL_SHIFT);
+
+ /* We're finished printing this object. */
+ return PRINT_GENSYM_DONE;
+ }
+ else
+ {
+ write_fmt_string (printcharfun, "#%d=",
+ (XINT (seen) & PRINT_NUMBER_ORDINAL_MASK)
+ >> PRINT_NUMBER_ORDINAL_SHIFT);
+
+ /* We set PRINT_NUMBER_PRINTED_MASK immediately here, so the
+ object itself is written as #%d# when printing its contents. */
+ Fputhash (obj, make_int (XINT (seen) | PRINT_NUMBER_PRINTED_MASK),
+ Vprint_number_table);
+
+ /* This is the first time the object has been seen while
+ printing the recursive object; we still have to go ahead
+ and do the actual print. */
+ }
+ }
+
+ return PRINT_GENSYM_PRINT;
+}
+
+Lisp_Object
+nsubst_structures_descend (Lisp_Object new_, Lisp_Object old,
+ Lisp_Object tree,
+ Lisp_Object number_table, Boolint test_not_unboundp)
+{
+ Lisp_Object seen;
+
+ if (!LRECORDP (tree) || !HAS_OBJECT_METH_P (tree, nsubst_structures_descend))
+ {
+ return tree;
+ }
+
+ seen = Fgethash (tree, number_table, Qnil);
+
+ if (INTP (seen))
+ {
+ if (XINT (seen) & PRINT_NUMBER_PRINTED_MASK)
+ {
+ return tree;
+ }
+
+ Fputhash (tree, make_int (XINT (seen) | PRINT_NUMBER_PRINTED_MASK),
+ number_table);
+ }
+
+ OBJECT_METH (tree, nsubst_structures_descend,
+ (new_, old, tree, number_table, test_not_unboundp));
+
+ return tree;
+}
+
+/* Descend TREE, replacing the Lisp object OLD each time it is encountered
+ with the Lisp object NEW_. TREE can be recursive or circular, and this is
+ handled correctly. */
+Lisp_Object
+nsubst_structures (Lisp_Object new_, Lisp_Object old, Lisp_Object tree,
+ check_test_func_t check_test, Boolint test_not_unboundp,
+ Lisp_Object UNUSED (test), Lisp_Object UNUSED (key))
+{
+ Lisp_Object number_table, result;
+ Elemcount ordinal = 0;
+ struct gcpro gcpro1;
+
+ if (check_test != check_eq_nokey || !LRECORDP (old))
+ {
+ signal_error (Qunimplemented,
+ ":descend-structures not yet finished, nsubst",
+ Qunbound);
+ }
+
+ if (!LRECORDP (tree) || !HAS_OBJECT_METH_P (tree, nsubst_structures_descend))
+ {
+ return tree;
+ }
+
+ number_table = make_lisp_hash_table (16, HASH_TABLE_NON_WEAK, Qeq);
+ GCPRO1 (number_table);
+
+ print_preprocess (tree, number_table, &ordinal);
+
+ /* This function can GC by means of the hash table test functions, when
+ replacing hash table entries. */
+ result = nsubst_structures_descend (new_, old, tree, number_table,
+ test_not_unboundp);
+ Fclrhash (number_table);
+
+ RETURN_UNGCPRO (result);
+}
+
void
print_internal (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
{
/* This function can GC */
int specdepth = 0;
struct gcpro gcpro1, gcpro2;
+ Boolint cleanup_table = 0;
QUIT;
@@ -1683,9 +2068,12 @@
{
specdepth = internal_bind_int (&print_depth, print_depth + 1);
- if (print_depth > PRINT_CIRCLE)
- signal_error (Qstack_overflow,
- "Apparently circular structure being printed", Qunbound);
+ if (print_depth > PRINT_CIRCLE_LIMIT)
+ {
+ signal_error (Qstack_overflow,
+ "Apparently circular structure being printed",
+ Qunbound);
+ }
}
switch (XTYPE (obj))
@@ -1888,10 +2276,25 @@
}
}
- /* Detect circularities and truncate them.
- No need to offer any alternative--this is better than an error. */
- if (CONSP (obj) || VECTORP (obj) || COMPILED_FUNCTIONP (obj))
- {
+ if (LRECORDP (obj) &&
+ ((print_circle && HAS_OBJECT_METH_P (obj, print_preprocess)) ||
+ (print_gensym && SYMBOLP (obj) && UNINTERNEDP (obj))))
+ {
+ enum print_gensym_status status
+ = print_gensym_or_circle (obj, printcharfun);
+
+ cleanup_table = (PRINT_GENSYM_PRINT_AND_CLEANUP_TABLE == status);
+
+ if (PRINT_GENSYM_DONE == status)
+ {
+ break;
+ }
+ }
+ else if (!print_circle &&
+ /* Could this structure be recursive? */
+ LRECORDP (obj)
+ && HAS_OBJECT_METH_P (obj, nsubst_structures_descend))
+ {
int i;
for (i = 0; i < print_depth - 1; i++)
if (EQ (obj, being_printed[i]))
@@ -1937,6 +2340,19 @@
}
}
+ if (cleanup_table)
+ {
+ /* If any objects have been seen once and once only, remove them from
+ Vprint_number_table. This is a bit of an arbitrary decision; we
+ could keep them around for the sake of print_continuous_numbering,
+ but there's the reasonable worry about Vprint_number_table getting
+ awkwardly large. */
+ elisp_map_remhash (print_continuous_numbering ?
+ print_nonsymbol_seen_once : print_seen_once,
+ Vprint_number_table, NULL);
+
+ }
+
if (!inhibit_non_essential_conversion_operations)
unbind_to (specdepth);
UNGCPRO;
@@ -1968,49 +2384,15 @@
output_string (printcharfun, 0, name, 0, size);
return;
}
+
GCPRO2 (obj, printcharfun);
- /* If we print an uninterned symbol as part of a complex object and
- the flag print-gensym is non-nil, prefix it with #n= to read the
- object back with the #n# reader syntax later if needed. */
- if (!NILP (Vprint_gensym)
- /* #### Test whether this produces a noticeable slow-down for
- printing when print-gensym is non-nil. */
- && !EQ (obj, oblookup (Vobarray,
- XSTRING_DATA (symbol_name (XSYMBOL (obj))),
- XSTRING_LENGTH (symbol_name (XSYMBOL (obj))))))
+ if (print_gensym)
{
- if (print_depth > 1)
- {
- Lisp_Object tem = Fassq (obj, Vprint_gensym_alist);
- if (CONSP (tem))
- {
- write_ascstring (printcharfun, "#");
- print_internal (XCDR (tem), printcharfun, escapeflag);
- write_ascstring (printcharfun, "#");
- UNGCPRO;
- return;
- }
- else
- {
- if (CONSP (Vprint_gensym_alist))
- {
- /* Vprint_gensym_alist is exposed to Lisp, so we
- have to be careful. */
- CHECK_CONS (XCAR (Vprint_gensym_alist));
- CHECK_INT (XCDR (XCAR (Vprint_gensym_alist)));
- tem = make_int (XINT (XCDR (XCAR (Vprint_gensym_alist))) + 1);
- }
- else
- tem = make_int (1);
- Vprint_gensym_alist = Fcons (Fcons (obj, tem), Vprint_gensym_alist);
-
- write_ascstring (printcharfun, "#");
- print_internal (tem, printcharfun, escapeflag);
- write_ascstring (printcharfun, "=");
- }
- }
- write_ascstring (printcharfun, "#:");
+ if (UNINTERNEDP (obj))
+ {
+ write_ascstring (printcharfun, "#:");
+ }
}
/* Does it look like an integer or a float? */
@@ -2690,7 +3072,7 @@
/* #### I think this should default to t. But we'd better wait
until we see that it works out. */
- DEFVAR_LISP ("print-gensym", &Vprint_gensym /*
+ DEFVAR_BOOL ("print-gensym", &print_gensym /*
If non-nil, then uninterned symbols will be printed specially.
Uninterned symbols are those which are not present in `obarray', that is,
those which were made with `make-symbol' or by calling `intern' with a
@@ -2703,19 +3085,43 @@
two pointers to the same uninterned symbol, `read' will not duplicate
that structure.
-If the value of `print-gensym' is a cons cell, then in addition
-refrain from clearing `print-gensym-alist' on entry to and exit from
-printing functions, so that the use of #...# and #...= can carry over
-for several separately printed objects.
+If the value of `print-continuous-numbering' is non-nil, the table used by
+`print-gensym' and `print-circle' (which see) will not be reset on entry to
+and exit from printing functions, so that the use of #...# and #...= can
+carry over for several separately printed objects.
*/ );
- Vprint_gensym = Qnil;
+ print_gensym = 0;
- DEFVAR_LISP ("print-gensym-alist", &Vprint_gensym_alist /*
-Association list of elements (GENSYM . N) to guide use of #N# and #N=.
-In each element, GENSYM is an uninterned symbol that has been associated
-with #N= for the specified value of N.
-*/ );
- Vprint_gensym_alist = Qnil;
+ DEFVAR_BOOL ("print-circle", &print_circle /*
+Non-nil means print recursive structures using #N= and #N# syntax.
+
+If nil, XEmacs detects recursive structures and truncates them in an
+unreadable fashion.
+
+If non-nil, shared substructures anywhere in the structure are printed
+with `#N=' before the first occurrence (in the order of the print
+representation) and `#N#' in place of each subsequent occurrence,
+where N is a positive decimal integer.
+
+If the value of `print-continuous-numbering' is non-nil, the table used by
+`print-gensym' (which see) and `print-circle' will not be reset on entry to
+and exit from printing functions, so that the use of #...# and #...= can
+carry over for several separately printed objects.
+*/);
+ print_circle = 0;
+
+ DEFVAR_BOOL_MAGIC ("print-continuous-numbering",
+ &print_continuous_numbering /*
+Non-nil means number continuously across print calls, mostly for symbols.
+This affects the numbers printed for #N= labels and #M# references.
+See also `print-circle' and `print-gensym'.
+This variable should not be set with `setq'; bind it with a `let' instead.
+*/ ,
+ print_continuous_numbering_changed);
+ print_continuous_numbering = 0;
+
+ staticpro (&Vprint_number_table);
+ Vprint_number_table = make_lisp_hash_table (16, HASH_TABLE_KEY_WEAK, Qeq);
DEFVAR_LISP ("print-message-label", &Vprint_message_label /*
Label for minibuffer messages created with `print'. This should
diff -r 493c487cbc3f src/rangetab.c
--- a/src/rangetab.c Wed Aug 10 16:50:37 2011 +0100
+++ b/src/rangetab.c Thu Aug 11 17:01:22 2011 +0100
@@ -134,6 +134,52 @@
write_fmt_string (printcharfun, " 0x%x>", LISP_OBJECT_UID (obj));
}
+static void
+range_table_print_preprocess (Lisp_Object object,
+ Lisp_Object print_number_table,
+ Elemcount *seen_object_count)
+{
+ Lisp_Range_Table *rt = XRANGE_TABLE (object);
+ Elemcount ii;
+
+ for (ii = 0; ii < gap_array_length (rt->entries); ii++)
+ {
+ struct range_table_entry *entry
+ = gap_array_atp (rt->entries, ii, struct range_table_entry);
+ PRINT_PREPROCESS (entry->val, print_number_table, seen_object_count);
+ }
+}
+
+static void
+range_table_nsubst_structures_descend (Lisp_Object new_, Lisp_Object old,
+ Lisp_Object object,
+ Lisp_Object number_table,
+ Boolint test_not_unboundp)
+{
+ Lisp_Range_Table *rt = XRANGE_TABLE (object);
+ Elemcount ii;
+
+ /* We don't have to worry about the range table START and END values if
+ we're limiting nsubst_descend to the Lisp reader; it's a similar case
+ to the hash table test. */
+ for (ii = 0; ii < gap_array_length (rt->entries); ii++)
+ {
+ struct range_table_entry *entry
+ = gap_array_atp (rt->entries, ii, struct range_table_entry);
+
+ if (EQ (old, entry->val) == test_not_unboundp)
+ {
+ entry->val = new_;
+ }
+ else if (LRECORDP (entry->val) &&
+ HAS_OBJECT_METH_P (entry->val, nsubst_structures_descend))
+ {
+ nsubst_structures_descend (new_, old, entry->val, number_table,
+ test_not_unboundp);
+ }
+ }
+}
+
static int
range_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth, int foldcase)
{
@@ -1033,6 +1079,12 @@
/************************************************************************/
/* Initialization */
/************************************************************************/
+void
+rangetab_objects_create (void)
+{
+ OBJECT_HAS_METHOD (range_table, print_preprocess);
+ OBJECT_HAS_METHOD (range_table, nsubst_structures_descend);
+}
void
syms_of_rangetab (void)
diff -r 493c487cbc3f src/symbols.c
--- a/src/symbols.c Wed Aug 10 16:50:37 2011 +0100
+++ b/src/symbols.c Thu Aug 11 17:01:22 2011 +0100
@@ -139,6 +139,16 @@
return external_remprop (&XSYMBOL (symbol)->plist, property, 0, ERROR_ME);
}
+static void
+symbol_print_preprocess (Lisp_Object UNUSED (symbol),
+ Lisp_Object UNUSED (print_number_table),
+ Elemcount * UNUSED (seen_object_count))
+{
+ /* This method is empty; symbols are handled specially in
+ print_preprocess, because print_preprocess_inchash_eq() is conditional
+ for them, rather than a given. */
+}
+
DEFINE_DUMPABLE_FROB_BLOCK_LISP_OBJECT ("symbol", symbol,
mark_symbol, print_symbol,
0, 0, 0, symbol_description,
@@ -3536,6 +3546,7 @@
OBJECT_HAS_METHOD (symbol, getprop);
OBJECT_HAS_METHOD (symbol, putprop);
OBJECT_HAS_METHOD (symbol, remprop);
+ OBJECT_HAS_METHOD (symbol, print_preprocess);
OBJECT_HAS_NAMED_METHOD (symbol, plist, Fsymbol_plist);
OBJECT_HAS_NAMED_METHOD (symbol, setplist, Fsetplist);
}
diff -r 493c487cbc3f src/symsinit.h
--- a/src/symsinit.h Wed Aug 10 16:50:37 2011 +0100
+++ b/src/symsinit.h Thu Aug 11 17:01:22 2011 +0100
@@ -208,7 +208,9 @@
Dump time and post-pdump-load-time. */
void buffer_objects_create (void);
+void bytecode_objects_create (void);
void casetab_objects_create (void);
+void chartab_objects_create (void);
void extent_objects_create (void);
void face_objects_create (void);
void frame_objects_create (void);
@@ -216,6 +218,7 @@
void hash_table_objects_create (void);
void lstream_objects_create (void);
void mule_charset_objects_create (void);
+void rangetab_objects_create (void);
void scrollbar_objects_create (void);
void specifier_objects_create (void);
void ui_gtk_objects_create (void);
--
‘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 #'event-apply-modifiers, implement #'event-apply-modifiers in terms of it.
13 years, 4 months
Aidan Kehoe
Alan, this may help a little with what you’re doing, though it’s not
available on 21.4.
APPROVE COMMIT
NOTE: This patch has been committed.
# HG changeset patch
# User Aidan Kehoe <kehoea(a)parhasard.net>
# Date 1312991437 -3600
# Node ID 493c487cbc3f1fc4f14855181174eca2c717f119
# Parent b90c153730c78ba2829bb9f6c972532bcbdd6687
Add #'event-apply-modifiers, implement #'event-apply-modifiers in terms of it.
2011-08-10 Aidan Kehoe <kehoea(a)parhasard.net>
* keymap.el:
* keymap.el (event-apply-alt-modifier):
* keymap.el (event-apply-super-modifier):
* keymap.el (event-apply-hyper-modifier):
* keymap.el (event-apply-shift-modifier):
* keymap.el (event-apply-control-modifier):
* keymap.el (event-apply-meta-modifier):
* keymap.el (event-apply-modifiers): New.
* keymap.el (event-apply-modifier): Implement in terms of
#'event-apply-modifier.
Rework #'event-apply-modifier to take a list of modifiers, and
change its name appropriately. Keep the old name around, too.
diff -r b90c153730c7 -r 493c487cbc3f lisp/ChangeLog
--- a/lisp/ChangeLog Wed Aug 10 15:55:53 2011 +0100
+++ b/lisp/ChangeLog Wed Aug 10 16:50:37 2011 +0100
@@ -1,3 +1,19 @@
+2011-08-10 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * keymap.el:
+ * keymap.el (event-apply-alt-modifier):
+ * keymap.el (event-apply-super-modifier):
+ * keymap.el (event-apply-hyper-modifier):
+ * keymap.el (event-apply-shift-modifier):
+ * keymap.el (event-apply-control-modifier):
+ * keymap.el (event-apply-meta-modifier):
+ * keymap.el (event-apply-modifiers): New.
+ * keymap.el (event-apply-modifier): Implement in terms of
+ #'event-apply-modifier.
+
+ Rework #'event-apply-modifier to take a list of modifiers, and
+ change its name appropriately. Keep the old name around, too.
+
2011-08-10 Aidan Kehoe <kehoea(a)parhasard.net>
* bytecomp.el (byte-compile-normal-call):
diff -r b90c153730c7 -r 493c487cbc3f lisp/keymap.el
--- a/lisp/keymap.el Wed Aug 10 15:55:53 2011 +0100
+++ b/lisp/keymap.el Wed Aug 10 16:50:37 2011 +0100
@@ -443,22 +443,22 @@
;;; to the following event.
(defun event-apply-alt-modifier (ignore-prompt)
- (event-apply-modifier 'alt))
+ (event-apply-modifiers '(alt)))
(defun event-apply-super-modifier (ignore-prompt)
- (event-apply-modifier 'super))
+ (event-apply-modifiers '(super)))
(defun event-apply-hyper-modifier (ignore-prompt)
- (event-apply-modifier 'hyper))
+ (event-apply-modifiers '(hyper)))
(defun event-apply-shift-modifier (ignore-prompt)
- (event-apply-modifier 'shift))
+ (event-apply-modifiers '(shift)))
(defun event-apply-control-modifier (ignore-prompt)
- (event-apply-modifier 'control))
+ (event-apply-modifiers '(control)))
(defun event-apply-meta-modifier (ignore-prompt)
- (event-apply-modifier 'meta))
+ (event-apply-modifiers '(meta)))
;;; #### `key-translate-map' is ignored for now.
-(defun event-apply-modifier (symbol)
- "Return the next key event, with a modifier flag applied.
-SYMBOL is the name of this modifier, as a symbol.
+(defun event-apply-modifiers (list)
+ "Return the next key event, with a list of modifiers applied.
+LIST describes the names of these modifier, a list of symbols.
`function-key-map' is scanned for prefix bindings."
(let (events binding)
;; read keystrokes scanning `function-key-map'
@@ -479,11 +479,17 @@
(setq unread-command-events
(mapcar 'character-to-event (cdr events))))
(setq unread-command-events (cdr events)))
- ;; add a modifier SYMBOL to the first keystroke or event
+ ;; add modifiers LIST to the first keystroke or event
(vector
- (append (list symbol)
- (delq symbol
- (aref (key-sequence-list-description (car events)) 0))))))
+ (append list
+ (set-difference (aref (key-sequence-list-description (car events))
+ 0)
+ list :stable t)))))
+
+(defun event-apply-modifier (symbol)
+ "Return the next key event, with a single modifier applied.
+See `event-apply-modifiers'."
+ (event-apply-modifiers (list symbol)))
(defun synthesize-keysym (ignore-prompt)
"Read a sequence of keys, and returned the corresponding key symbol.
--
‘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 #'event-apply-modifiers, implement #'event-apply-modifiers in terms of it.
13 years, 4 months
Aidan Kehoe
changeset: 5549:493c487cbc3f
tag: tip
user: Aidan Kehoe <kehoea(a)parhasard.net>
date: Wed Aug 10 16:50:37 2011 +0100
files: lisp/ChangeLog lisp/keymap.el
description:
Add #'event-apply-modifiers, implement #'event-apply-modifiers in terms of it.
2011-08-10 Aidan Kehoe <kehoea(a)parhasard.net>
* keymap.el:
* keymap.el (event-apply-alt-modifier):
* keymap.el (event-apply-super-modifier):
* keymap.el (event-apply-hyper-modifier):
* keymap.el (event-apply-shift-modifier):
* keymap.el (event-apply-control-modifier):
* keymap.el (event-apply-meta-modifier):
* keymap.el (event-apply-modifiers): New.
* keymap.el (event-apply-modifier): Implement in terms of
#'event-apply-modifier.
Rework #'event-apply-modifier to take a list of modifiers, and
change its name appropriately. Keep the old name around, too.
diff -r b90c153730c7 -r 493c487cbc3f lisp/ChangeLog
--- a/lisp/ChangeLog Wed Aug 10 15:55:53 2011 +0100
+++ b/lisp/ChangeLog Wed Aug 10 16:50:37 2011 +0100
@@ -1,3 +1,19 @@
+2011-08-10 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * keymap.el:
+ * keymap.el (event-apply-alt-modifier):
+ * keymap.el (event-apply-super-modifier):
+ * keymap.el (event-apply-hyper-modifier):
+ * keymap.el (event-apply-shift-modifier):
+ * keymap.el (event-apply-control-modifier):
+ * keymap.el (event-apply-meta-modifier):
+ * keymap.el (event-apply-modifiers): New.
+ * keymap.el (event-apply-modifier): Implement in terms of
+ #'event-apply-modifier.
+
+ Rework #'event-apply-modifier to take a list of modifiers, and
+ change its name appropriately. Keep the old name around, too.
+
2011-08-10 Aidan Kehoe <kehoea(a)parhasard.net>
* bytecomp.el (byte-compile-normal-call):
diff -r b90c153730c7 -r 493c487cbc3f lisp/keymap.el
--- a/lisp/keymap.el Wed Aug 10 15:55:53 2011 +0100
+++ b/lisp/keymap.el Wed Aug 10 16:50:37 2011 +0100
@@ -443,22 +443,22 @@
;;; to the following event.
(defun event-apply-alt-modifier (ignore-prompt)
- (event-apply-modifier 'alt))
+ (event-apply-modifiers '(alt)))
(defun event-apply-super-modifier (ignore-prompt)
- (event-apply-modifier 'super))
+ (event-apply-modifiers '(super)))
(defun event-apply-hyper-modifier (ignore-prompt)
- (event-apply-modifier 'hyper))
+ (event-apply-modifiers '(hyper)))
(defun event-apply-shift-modifier (ignore-prompt)
- (event-apply-modifier 'shift))
+ (event-apply-modifiers '(shift)))
(defun event-apply-control-modifier (ignore-prompt)
- (event-apply-modifier 'control))
+ (event-apply-modifiers '(control)))
(defun event-apply-meta-modifier (ignore-prompt)
- (event-apply-modifier 'meta))
+ (event-apply-modifiers '(meta)))
;;; #### `key-translate-map' is ignored for now.
-(defun event-apply-modifier (symbol)
- "Return the next key event, with a modifier flag applied.
-SYMBOL is the name of this modifier, as a symbol.
+(defun event-apply-modifiers (list)
+ "Return the next key event, with a list of modifiers applied.
+LIST describes the names of these modifier, a list of symbols.
`function-key-map' is scanned for prefix bindings."
(let (events binding)
;; read keystrokes scanning `function-key-map'
@@ -479,11 +479,17 @@
(setq unread-command-events
(mapcar 'character-to-event (cdr events))))
(setq unread-command-events (cdr events)))
- ;; add a modifier SYMBOL to the first keystroke or event
+ ;; add modifiers LIST to the first keystroke or event
(vector
- (append (list symbol)
- (delq symbol
- (aref (key-sequence-list-description (car events)) 0))))))
+ (append list
+ (set-difference (aref (key-sequence-list-description (car events))
+ 0)
+ list :stable t)))))
+
+(defun event-apply-modifier (symbol)
+ "Return the next key event, with a single modifier applied.
+See `event-apply-modifiers'."
+ (event-apply-modifiers (list symbol)))
(defun synthesize-keysym (ignore-prompt)
"Read a sequence of keys, and returned the corresponding key symbol.
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
[COMMIT] Do the quoted-lambda check when functions take :if, :test, :key arguments, too.
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 1312988153 -3600
# Node ID b90c153730c78ba2829bb9f6c972532bcbdd6687
# Parent a46c5c8d65648803e334ca73b5a306092557334b
Do the quoted-lambda check when functions take :if, :test, :key arguments, too.
lisp/ChangeLog addition:
2011-08-10 Aidan Kehoe <kehoea(a)parhasard.net>
* bytecomp.el (byte-compile-normal-call):
When a function takes :if, :if-not, :test, :test-not or :key
arguments, do the quoted-lambda check there too.
diff -r a46c5c8d6564 -r b90c153730c7 lisp/ChangeLog
--- a/lisp/ChangeLog Tue Aug 09 17:17:44 2011 +0100
+++ b/lisp/ChangeLog Wed Aug 10 15:55:53 2011 +0100
@@ -1,3 +1,9 @@
+2011-08-10 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * bytecomp.el (byte-compile-normal-call):
+ When a function takes :if, :if-not, :test, :test-not or :key
+ arguments, do the quoted-lambda check there too.
+
2011-08-04 Stephen J. Turnbull <stephen(a)xemacs.org>
* test-harness.el (test-harness-bug-expected):
diff -r a46c5c8d6564 -r b90c153730c7 lisp/bytecomp.el
--- a/lisp/bytecomp.el Tue Aug 09 17:17:44 2011 +0100
+++ b/lisp/bytecomp.el Wed Aug 10 15:55:53 2011 +0100
@@ -2880,20 +2880,28 @@
(map nil
(function*
(lambda ((function . nargs))
- (and (setq function (plist-get plist function
- not-present))
- (not (eq function not-present))
- (byte-compile-constp function)
- (byte-compile-callargs-warn
- (cons (eval function)
- (member*
- nargs
- ;; Dummy arguments. There's no need for
- ;; it to be longer than even 2, now, but
- ;; very little harm in it.
- '(9 8 7 6 5 4 3 2 1)))))))
- '((:key . 1) (:test . 2) (:test-not . 2)
- (:if . 1) (:if-not . 1))))))))
+ (let ((value (plist-get plist function not-present)))
+ (when (and (not (eq value not-present))
+ (byte-compile-constp value))
+ (byte-compile-callargs-warn
+ (cons (eval value)
+ (member*
+ nargs
+ ;; Dummy arguments. There's no need for
+ ;; it to be longer than even 2, now, but
+ ;; very little harm in it.
+ '(9 8 7 6 5 4 3 2 1))))
+ (when (and (eq (car-safe value) 'quote)
+ (eq (car-safe (nth 1 value)) 'lambda)
+ (or
+ (null (memq 'quoted-lambda
+ byte-compile-warnings))
+ (byte-compile-warn
+ "Passing a quoted lambda to #'%s, \
+keyword %s, forcing function quoting" (car form) function)))
+ (setcar value 'function))))))
+ '((:key . 1) (:test . 2) (:test-not . 2) (:if . 1)
+ (:if-not . 1))))))))
(if byte-compile-generate-call-tree
(byte-compile-annotate-call-tree form))
(byte-compile-push-constant (car form))
--
‘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: Do the quoted-lambda check when functions take :if, :test, :key arguments, too.
13 years, 4 months
Aidan Kehoe
changeset: 5548:b90c153730c7
tag: tip
user: Aidan Kehoe <kehoea(a)parhasard.net>
date: Wed Aug 10 15:55:53 2011 +0100
files: lisp/ChangeLog lisp/bytecomp.el
description:
Do the quoted-lambda check when functions take :if, :test, :key arguments, too.
lisp/ChangeLog addition:
2011-08-10 Aidan Kehoe <kehoea(a)parhasard.net>
* bytecomp.el (byte-compile-normal-call):
When a function takes :if, :if-not, :test, :test-not or :key
arguments, do the quoted-lambda check there too.
diff -r a46c5c8d6564 -r b90c153730c7 lisp/ChangeLog
--- a/lisp/ChangeLog Tue Aug 09 17:17:44 2011 +0100
+++ b/lisp/ChangeLog Wed Aug 10 15:55:53 2011 +0100
@@ -1,3 +1,9 @@
+2011-08-10 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * bytecomp.el (byte-compile-normal-call):
+ When a function takes :if, :if-not, :test, :test-not or :key
+ arguments, do the quoted-lambda check there too.
+
2011-08-04 Stephen J. Turnbull <stephen(a)xemacs.org>
* test-harness.el (test-harness-bug-expected):
diff -r a46c5c8d6564 -r b90c153730c7 lisp/bytecomp.el
--- a/lisp/bytecomp.el Tue Aug 09 17:17:44 2011 +0100
+++ b/lisp/bytecomp.el Wed Aug 10 15:55:53 2011 +0100
@@ -2880,20 +2880,28 @@
(map nil
(function*
(lambda ((function . nargs))
- (and (setq function (plist-get plist function
- not-present))
- (not (eq function not-present))
- (byte-compile-constp function)
- (byte-compile-callargs-warn
- (cons (eval function)
- (member*
- nargs
- ;; Dummy arguments. There's no need for
- ;; it to be longer than even 2, now, but
- ;; very little harm in it.
- '(9 8 7 6 5 4 3 2 1)))))))
- '((:key . 1) (:test . 2) (:test-not . 2)
- (:if . 1) (:if-not . 1))))))))
+ (let ((value (plist-get plist function not-present)))
+ (when (and (not (eq value not-present))
+ (byte-compile-constp value))
+ (byte-compile-callargs-warn
+ (cons (eval value)
+ (member*
+ nargs
+ ;; Dummy arguments. There's no need for
+ ;; it to be longer than even 2, now, but
+ ;; very little harm in it.
+ '(9 8 7 6 5 4 3 2 1))))
+ (when (and (eq (car-safe value) 'quote)
+ (eq (car-safe (nth 1 value)) 'lambda)
+ (or
+ (null (memq 'quoted-lambda
+ byte-compile-warnings))
+ (byte-compile-warn
+ "Passing a quoted lambda to #'%s, \
+keyword %s, forcing function quoting" (car form) function)))
+ (setcar value 'function))))))
+ '((:key . 1) (:test . 2) (:test-not . 2) (:if . 1)
+ (:if-not . 1))))))))
(if byte-compile-generate-call-tree
(byte-compile-annotate-call-tree form))
(byte-compile-push-constant (car form))
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
[AC xemacs-base] an old patch to advice to use called-interactively-p
13 years, 4 months
Stephen J. Turnbull
APPROVE COMMIT xemacs-base
This patch is needed if you use keyboard macros with advised functions.
Index: xemacs-packages/xemacs-base/ChangeLog
===================================================================
RCS file: /cvs/xemacs/XEmacs/packages/xemacs-packages/xemacs-base/ChangeLog,v
retrieving revision 1.243
diff -u -U 0 -r1.243 ChangeLog
--- xemacs-packages/xemacs-base/ChangeLog 10 Jan 2011 07:38:39 -0000 1.243
+++ xemacs-packages/xemacs-base/ChangeLog 9 Aug 2011 16:30:14 -0000
@@ -0,0 +1,11 @@
+2009-08-19 Stephen J. Turnbull <stephen(a)xemacs.org>
+
+ Conditionally define and use `called-interactively-p'.
+
+ * advice.el (called-interactively-p): defun if not fboundp.
+ (car): Use it in example.
+ (ad-enable-regexp):
+ (ad-disable-regexp):
+ (ad-make-advised-definition):
+ Use it instead of `interactive-p'.
+
Index: xemacs-packages/xemacs-base/advice.el
===================================================================
RCS file: /cvs/xemacs/XEmacs/packages/xemacs-packages/xemacs-base/advice.el,v
retrieving revision 1.4
diff -u -u -r1.4 advice.el
--- xemacs-packages/xemacs-base/advice.el 21 Jul 2010 15:01:12 -0000 1.4
+++ xemacs-packages/xemacs-base/advice.el 9 Aug 2011 16:30:21 -0000
@@ -218,7 +218,7 @@
;; "Make `car' an interactive function."
;; (interactive "xCar of list: ")
;; ad-do-it
-;; (if (interactive-p)
+;; (if (called-interactively-p)
;; (message "%s" ad-return-value)))
@@ -1821,6 +1821,22 @@
;; During a normal load this is a noop:
(require 'advice-preload "advice.el")
+(defmacro ad-xemacs-p ()
+ ;;Expands into Non-nil constant if we run XEmacs.
+ ;;Unselected conditional code will be optimized away during compilation.
+ (or (featurep 'xemacs) (string-match "XEmacs" emacs-version)))
+
+;; #### This compatibility kludge should be moved into a `future' package.
+(unless (fboundp 'called-interactively-p)
+ (defsubst called-interactively-p ()
+ "Non-nil if this function was invoked with `call-interactively'.
+`call-interactively' is implicitly applied when a function is invoked as a
+command, as well as the occasional explicit use by commands which delegate
+argument gathering to other functions.
+ This implementation is a kludge; semantics are different in batch-mode,
+and may subtly differ in an interactive session."
+ (or (interactive-p) executing-kbd-macro)))
+
;; We need this; it's not available on 21.4 or early 21.5.
(defun-when-void special-operator-p (object)
"Return whether OBJECT is a special operator.
@@ -2323,7 +2339,7 @@
(interactive
(list (ad-read-regexp "Enable advices via regexp: ")))
(let ((matched-advices (ad-enable-regexp-internal regexp 'any t)))
- (if (interactive-p)
+ (if (called-interactively-p)
(message "%d matching advices enabled" matched-advices))
matched-advices))
@@ -2333,7 +2349,7 @@
(interactive
(list (ad-read-regexp "Disable advices via regexp: ")))
(let ((matched-advices (ad-enable-regexp-internal regexp 'any nil)))
- (if (interactive-p)
+ (if (called-interactively-p)
(message "%d matching advices disabled" matched-advices))
matched-advices))
@@ -3038,7 +3054,7 @@
(not advised-interactive-form))
;; Check whether we were called interactively
;; in order to do proper prompting:
- (` (if (interactive-p)
+ (` (if (called-interactively-p)
(call-interactively '(, origname))
(, (ad-make-mapped-call
orig-arglist advised-arglist origname)))))
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
[COMMIT] Avoid calling various macros "special operators" in the manuals.
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 1312906664 -3600
# Node ID a46c5c8d65648803e334ca73b5a306092557334b
# Parent d54278e74d71b8fbd47829e91cb129376fc709ea
Avoid calling various macros "special operators" in the manuals.
2011-08-09 Aidan Kehoe <kehoea(a)parhasard.net>
* cl.texi (Argument Lists):
* cl.texi (Time of Evaluation):
* cl.texi (Type Predicates):
* cl.texi (Assignment):
* cl.texi (Basic Setf):
* cl.texi (Modify Macros):
* cl.texi (Customizing Setf):
* cl.texi (Dynamic Bindings):
* cl.texi (Lexical Bindings):
* cl.texi (Function Bindings):
* cl.texi (Macro Bindings):
* cl.texi (Conditionals):
* cl.texi (Blocks and Exits):
* cl.texi (Iteration):
* cl.texi (Loop Basics):
* cl.texi (Macros):
* cl.texi (Declarations):
* cl.texi (Property Lists):
* cl.texi (Structures):
* cl.texi (Assertions):
* cl.texi (Efficiency Concerns):
* lispref/compile.texi (Eval During Compile):
* lispref/compile.texi (Compiled-Function Objects):
* lispref/eval.texi (Multiple values):
* lispref/frames.texi (Input Focus):
* lispref/internationalization.texi (Level 3 Primitives):
* lispref/positions.texi (Excursions):
* lispref/positions.texi (Narrowing):
* lispref/searching.texi (Saving Match Data):
* lispref/specifiers.texi (Adding Specifications):
* lispref/windows.texi:
Correct the manuals to avoid using the term "special operator" when
#'special-operator-p would give nil.
diff -r d54278e74d71 -r a46c5c8d6564 man/ChangeLog
--- a/man/ChangeLog Mon Aug 08 23:10:47 2011 +0900
+++ b/man/ChangeLog Tue Aug 09 17:17:44 2011 +0100
@@ -1,3 +1,39 @@
+2011-08-09 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * cl.texi (Argument Lists):
+ * cl.texi (Time of Evaluation):
+ * cl.texi (Type Predicates):
+ * cl.texi (Assignment):
+ * cl.texi (Basic Setf):
+ * cl.texi (Modify Macros):
+ * cl.texi (Customizing Setf):
+ * cl.texi (Dynamic Bindings):
+ * cl.texi (Lexical Bindings):
+ * cl.texi (Function Bindings):
+ * cl.texi (Macro Bindings):
+ * cl.texi (Conditionals):
+ * cl.texi (Blocks and Exits):
+ * cl.texi (Iteration):
+ * cl.texi (Loop Basics):
+ * cl.texi (Macros):
+ * cl.texi (Declarations):
+ * cl.texi (Property Lists):
+ * cl.texi (Structures):
+ * cl.texi (Assertions):
+ * cl.texi (Efficiency Concerns):
+ * lispref/compile.texi (Eval During Compile):
+ * lispref/compile.texi (Compiled-Function Objects):
+ * lispref/eval.texi (Multiple values):
+ * lispref/frames.texi (Input Focus):
+ * lispref/internationalization.texi (Level 3 Primitives):
+ * lispref/positions.texi (Excursions):
+ * lispref/positions.texi (Narrowing):
+ * lispref/searching.texi (Saving Match Data):
+ * lispref/specifiers.texi (Adding Specifications):
+ * lispref/windows.texi:
+ Correct the manuals to avoid using the term "special operator" when
+ #'special-operator-p would give nil.
+
2011-08-08 Stephen J. Turnbull <stephen(a)xemacs.org>
* internals/internals.texi (Mercurial Techniques): New.
diff -r d54278e74d71 -r a46c5c8d6564 man/cl.texi
--- a/man/cl.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/cl.texi Tue Aug 09 17:17:44 2011 +0100
@@ -381,14 +381,14 @@
Instead, this package defines alternates for several Lisp forms
which you must use if you need Common Lisp argument lists.
-@deffn {Special Operator} defun* name arglist body...
+@defmac defun* name arglist body...
This form is identical to the regular @code{defun} form, except
that @var{arglist} is allowed to be a full Common Lisp argument
list. Also, the function body is enclosed in an implicit block
called @var{name}; @pxref{Blocks and Exits}.
-@end deffn
-
-@deffn {Special Operator} defsubst* name arglist body...
+@end defmac
+
+@defmac defsubst* name arglist body...
This is just like @code{defun*}, except that the function that
is defined is automatically proclaimed @code{inline}, i.e.,
calls to it may be expanded into in-line code by the byte compiler.
@@ -398,9 +398,9 @@
efficient inline expansions. In particular, @code{defsubst*}
arranges for the processing of keyword arguments, default values,
etc., to be done at compile-time whenever possible.
-@end deffn
-
-@deffn {Special Operator} defmacro* name arglist body...
+@end defmac
+
+@defmac defmacro* name arglist body...
This is identical to the regular @code{defmacro} form,
except that @var{arglist} is allowed to be a full Common Lisp
argument list. The @code{&environment} keyword is supported as
@@ -409,13 +409,13 @@
cannot be implemented with the current Emacs Lisp interpreter.
The macro expander body is enclosed in an implicit block called
@var{name}.
-@end deffn
-
-@deffn {Special Operator} function* symbol-or-lambda
+@end defmac
+
+@defmac function* symbol-or-lambda
This is identical to the regular @code{function} form,
except that if the argument is a @code{lambda} form then that
form may use a full Common Lisp argument list.
-@end deffn
+@end defmac
Also, all forms (such as @code{defsetf} and @code{flet}) defined
in this package that include @var{arglist}s in their syntax allow
@@ -606,7 +606,7 @@
at compile-time so that later parts of the file can refer to the
macros that are defined.
-@deffn {Special Operator} eval-when (situations...) forms...
+@defmac eval-when (situations...) forms...
This form controls when the body @var{forms} are evaluated.
The @var{situations} list may contain any set of the symbols
@code{compile}, @code{load}, and @code{eval} (or their long-winded
@@ -678,7 +678,7 @@
certain top-level forms, like @code{defmacro} (sort-of) and
@code{require}, as if they were wrapped in @code{(eval-when
(compile load eval) @dots{})}.
-@end deffn
+@end defmac
Emacs 19 includes two special operators related to @code{eval-when}.
One of these, @code{eval-when-compile}, is not quite equivalent to
@@ -690,7 +690,7 @@
equivalent to @samp{(eval-when (compile load eval) @dots{})} and
so is not itself defined by this package.
-@deffn {Special Operator} eval-when-compile forms...
+@defmac eval-when-compile forms...
The @var{forms} are evaluated at compile-time; at execution time,
this form acts like a quoted constant of the resulting value. Used
at top-level, @code{eval-when-compile} is just like @samp{eval-when
@@ -699,9 +699,9 @@
or other reasons.
This form is similar to the @samp{#.} syntax of true Common Lisp.
-@end deffn
-
-@deffn {Special Operator} load-time-value form
+@end defmac
+
+@defmac load-time-value form
The @var{form} is evaluated at load-time; at execution time,
this form acts like a quoted constant of the resulting value.
@@ -742,7 +742,7 @@
", and loaded on: "
--temp--))
@end example
-@end deffn
+@end defmac
@node Function Aliases, , Time of Evaluation, Program Structure
@section Function Aliases
@@ -869,7 +869,7 @@
error.
@end defun
-@deffn {Special Operator} deftype name arglist forms...
+@defmac deftype name arglist forms...
This macro defines a new type called @var{name}. It is similar
to @code{defmacro} in many ways; when @var{name} is encountered
as a type name, the body @var{forms} are evaluated and should
@@ -897,7 +897,7 @@
The last example shows how the Common Lisp @code{unsigned-byte}
type specifier could be implemented if desired; this package does
not implement @code{unsigned-byte} by default.
-@end deffn
+@end defmac
The @code{typecase} and @code{check-type} macros also use type
names. @xref{Conditionals}. @xref{Assertions}. The @code{map},
@@ -989,7 +989,7 @@
The @code{psetq} form is just like @code{setq}, except that multiple
assignments are done in parallel rather than sequentially.
-@deffn {Special Operator} psetq [symbol form]@dots{}
+@defmac psetq [symbol form]@dots{}
This macro is used to assign to several
variables simultaneously. Given only one @var{symbol} and @var{form},
it has the same effect as @code{setq}. Given several @var{symbol}
@@ -1017,7 +1017,7 @@
@pxref{Modify Macros}.)
@code{psetq} always returns @code{nil}.
-@end deffn
+@end defmac
@node Generalized Variables, Variable Bindings, Assignment, Control Structure
@section Generalized Variables
@@ -1055,7 +1055,7 @@
The @code{setf} macro is the most basic way to operate on generalized
variables.
-@deffn {Special Operator} setf [place form]@dots{}
+@defmac setf [place form]@dots{}
This macro evaluates @var{form} and stores it in @var{place}, which
must be a valid generalized variable form. If there are several
@var{place} and @var{form} pairs, the assignments are done sequentially
@@ -1218,7 +1218,7 @@
the form @code{(setf (wrong-order @var{a} @var{b}) 17)} will
evaluate @var{b} first, then @var{a}, just as in an actual call
to @code{wrong-order}.
-@end deffn
+@end defmac
@node Modify Macros, Customizing Setf, Basic Setf, Generalized Variables
@subsection Modify Macros
@@ -1228,15 +1228,15 @@
that operate on generalized variables. Many are interesting and
useful even when the @var{place} is just a variable name.
-@deffn {Special Operator} psetf [place form]@dots{}
+@defmac psetf [place form]@dots{}
This macro is to @code{setf} what @code{psetq} is to @code{setq}:
When several @var{place}s and @var{form}s are involved, the
assignments take place in parallel rather than sequentially.
Specifically, all subforms are evaluated from left to right, then
all the assignments are done (in an undefined order).
-@end deffn
-
-@deffn {Special Operator} incf place &optional x
+@end defmac
+
+@defmac incf place &optional x
This macro increments the number stored in @var{place} by one, or
by @var{x} if specified. The incremented value is returned. For
example, @code{(incf i)} is equivalent to @code{(setq i (1+ i))}, and
@@ -1274,35 +1274,35 @@
As a more Emacs-specific example of @code{incf}, the expression
@code{(incf (point) @var{n})} is essentially equivalent to
@code{(forward-char @var{n})}.
-@end deffn
-
-@deffn {Special Operator} decf place &optional x
+@end defmac
+
+@defmac decf place &optional x
This macro decrements the number stored in @var{place} by one, or
by @var{x} if specified.
-@end deffn
-
-@deffn {Special Operator} pop place
+@end defmac
+
+@defmac pop place
This macro removes and returns the first element of the list stored
in @var{place}. It is analogous to @code{(prog1 (car @var{place})
(setf @var{place} (cdr @var{place})))}, except that it takes care
to evaluate all subforms only once.
-@end deffn
-
-@deffn {Special Operator} push x place
+@end defmac
+
+@defmac push x place
This macro inserts @var{x} at the front of the list stored in
@var{place}. It is analogous to @code{(setf @var{place} (cons
@var{x} @var{place}))}, except for evaluation of the subforms.
-@end deffn
-
-@deffn {Special Operator} pushnew x place @t{&key :test :test-not :key}
+@end defmac
+
+@defmac pushnew x place @t{&key :test :test-not :key}
This macro inserts @var{x} at the front of the list stored in
@var{place}, but only if @var{x} was not @code{eql} to any
existing element of the list. The optional keyword arguments
are interpreted in the same way as for @code{adjoin}.
@xref{Lists as Sets}.
-@end deffn
-
-@deffn {Special Operator} shiftf place@dots{} newvalue
+@end defmac
+
+@defmac shiftf place@dots{} newvalue
This macro shifts the @var{place}s left by one, shifting in the
value of @var{newvalue} (which may be any Lisp expression, not just
a generalized variable), and returning the value shifted out of
@@ -1320,9 +1320,9 @@
@noindent
except that the subforms of @var{a}, @var{b}, and @var{c} are actually
evaluated only once each and in the apparent order.
-@end deffn
-
-@deffn {Special Operator} rotatef place@dots{}
+@end defmac
+
+@defmac rotatef place@dots{}
This macro rotates the @var{place}s left by one in circular fashion.
Thus, @code{(rotatef @var{a} @var{b} @var{c} @var{d})} is equivalent to
@@ -1337,12 +1337,12 @@
except for the evaluation of subforms. @code{rotatef} always
returns @code{nil}. Note that @code{(rotatef @var{a} @var{b})}
conveniently exchanges @var{a} and @var{b}.
-@end deffn
+@end defmac
The following macros were invented for this package; they have no
analogues in Common Lisp.
-@deffn {Special Operator} letf (bindings@dots{}) forms@dots{}
+@defmac letf (bindings@dots{}) forms@dots{}
This macro is analogous to @code{let}, but for generalized variables
rather than just symbols. Each @var{binding} should be of the form
@code{(@var{place} @var{value})}; the original contents of the
@@ -1392,14 +1392,14 @@
variables and calls to @code{symbol-value} and @code{symbol-function}.
If the symbol is not bound on entry, it is simply made unbound by
@code{makunbound} or @code{fmakunbound} on exit.
-@end deffn
-
-@deffn {Special Operator} letf* (bindings@dots{}) forms@dots{}
+@end defmac
+
+@defmac letf* (bindings@dots{}) forms@dots{}
This macro is to @code{letf} what @code{let*} is to @code{let}:
It does the bindings in sequential rather than parallel order.
-@end deffn
-
-@deffn {Special Operator} callf @var{function} @var{place} @var{args}@dots{}
+@end defmac
+
+@defmac callf @var{function} @var{place} @var{args}@dots{}
This is the ``generic'' modify macro. It calls @var{function},
which should be an unquoted function name, macro name, or lambda.
It passes @var{place} and @var{args} as arguments, and assigns the
@@ -1416,14 +1416,14 @@
@xref{Customizing Setf}, for @code{define-modify-macro}, a way
to create even more concise notations for modify macros. Note
again that @code{callf} is an extension to standard Common Lisp.
-@end deffn
-
-@deffn {Special Operator} callf2 @var{function} @var{arg1} @var{place} @var{args}@dots{}
+@end defmac
+
+@defmac callf2 @var{function} @var{arg1} @var{place} @var{args}@dots{}
This macro is like @code{callf}, except that @var{place} is
the @emph{second} argument of @var{function} rather than the
first. For example, @code{(push @var{x} @var{place})} is
equivalent to @code{(callf2 cons @var{x} @var{place})}.
-@end deffn
+@end defmac
The @code{callf} and @code{callf2} macros serve as building
blocks for other macros like @code{incf}, @code{pushnew}, and
@@ -1439,7 +1439,7 @@
@code{defsetf}, and @code{define-setf-method}, that allow the
user to extend generalized variables in various ways.
-@deffn {Special Operator} define-modify-macro name arglist function [doc-string]
+@defmac define-modify-macro name arglist function [doc-string]
This macro defines a ``read-modify-write'' macro similar to
@code{incf} and @code{decf}. The macro @var{name} is defined
to take a @var{place} argument followed by additional arguments
@@ -1480,9 +1480,9 @@
using @code{get-setf-method}, or consult the source file
@file{cl-macs.el} to see how to use the internal @code{setf}
building blocks.
-@end deffn
-
-@deffn {Special Operator} defsetf access-fn update-fn
+@end defmac
+
+@defmac defsetf access-fn update-fn
This is the simpler of two @code{defsetf} forms. Where
@var{access-fn} is the name of a function which accesses a place,
this declares @var{update-fn} to be the corresponding store
@@ -1525,9 +1525,9 @@
(defsetf symbol-value set)
(defsetf buffer-name rename-buffer t)
@end example
-@end deffn
-
-@deffn {Special Operator} defsetf access-fn arglist (store-var) forms@dots{}
+@end defmac
+
+@defmac defsetf access-fn arglist (store-var) forms@dots{}
This is the second, more complex, form of @code{defsetf}. It is
rather like @code{defmacro} except for the additional @var{store-var}
argument. The @var{forms} should return a Lisp form which stores
@@ -1556,9 +1556,9 @@
(defsetf nth (n x) (store)
(list 'setcar (list 'nthcdr n x) store))
@end example
-@end deffn
-
-@deffn {Special Operator} define-setf-method access-fn arglist forms@dots{}
+@end defmac
+
+@defmac define-setf-method access-fn arglist forms@dots{}
This is the most general way to create new place forms. When
a @code{setf} to @var{access-fn} with arguments described by
@var{arglist} is expanded, the @var{forms} are evaluated and
@@ -1603,7 +1603,7 @@
use this setf-method will optimize away most temporaries that
turn out to be unnecessary, so there is little reason for the
setf-method itself to optimize.
-@end deffn
+@end defmac
@defun get-setf-method place &optional env
This function returns the setf-method for @var{place}, by
@@ -1669,7 +1669,7 @@
at compile-time. The @code{progv} form provides an easy way to
bind variables whose names are computed at run-time.
-@deffn {Special Operator} progv symbols values forms@dots{}
+@defmac progv symbols values forms@dots{}
This form establishes @code{let}-style variable bindings on a
set of variables computed at run-time. The expressions
@var{symbols} and @var{values} are evaluated, and must return lists
@@ -1679,7 +1679,7 @@
are made unbound (as if by @code{makunbound}) inside the body.
If @var{symbols} is shorter than @var{values}, the excess values
are ignored.
-@end deffn
+@end defmac
@node Lexical Bindings, Function Bindings, Dynamic Bindings, Variable Bindings
@subsection Lexical Bindings
@@ -1688,7 +1688,7 @@
The @dfn{CL} package defines the following macro which
more closely follows the Common Lisp @code{let} form:
-@deffn {Special Operator} lexical-let (bindings@dots{}) forms@dots{}
+@defmac lexical-let (bindings@dots{}) forms@dots{}
This form is exactly like @code{let} except that the bindings it
establishes are purely lexical. Lexical bindings are similar to
local variables in a language like C: Only the code physically
@@ -1788,12 +1788,12 @@
The @code{lexical-let} form is an extension to Common Lisp. In
true Common Lisp, all bindings are lexical unless declared otherwise.
-@end deffn
-
-@deffn {Special Operator} lexical-let* (bindings@dots{}) forms@dots{}
+@end defmac
+
+@defmac lexical-let* (bindings@dots{}) forms@dots{}
This form is just like @code{lexical-let}, except that the bindings
are made sequentially in the manner of @code{let*}.
-@end deffn
+@end defmac
@node Function Bindings, Macro Bindings, Lexical Bindings, Variable Bindings
@subsection Function Bindings
@@ -1802,7 +1802,7 @@
These forms make @code{let}-like bindings to functions instead
of variables.
-@deffn {Special Operator} flet (bindings@dots{}) forms@dots{}
+@defmac flet (bindings@dots{}) forms@dots{}
This form establishes @code{let}-style bindings on the function
cells of symbols rather than on the value cells. Each @var{binding}
must be a list of the form @samp{(@var{name} @var{arglist}
@@ -1841,14 +1841,14 @@
argument notation supported by @code{defun*}; also, the function
body is enclosed in an implicit block as if by @code{defun*}.
@xref{Program Structure}.
-@end deffn
-
-@deffn {Special Operator} labels (bindings@dots{}) forms@dots{}
+@end defmac
+
+@defmac labels (bindings@dots{}) forms@dots{}
The @code{labels} form is a synonym for @code{flet}. (In Common
Lisp, @code{labels} and @code{flet} differ in ways that depend on
their lexical scoping; these distinctions vanish in dynamically
scoped Emacs Lisp.)
-@end deffn
+@end defmac
@node Macro Bindings, , Function Bindings, Variable Bindings
@subsection Macro Bindings
@@ -1856,7 +1856,7 @@
@noindent
These forms create local macros and ``symbol macros.''
-@deffn {Special Operator} macrolet (bindings@dots{}) forms@dots{}
+@defmac macrolet (bindings@dots{}) forms@dots{}
This form is analogous to @code{flet}, but for macros instead of
functions. Each @var{binding} is a list of the same form as the
arguments to @code{defmacro*} (i.e., a macro name, argument list,
@@ -1868,9 +1868,9 @@
affect only calls that appear physically within the body
@var{forms}, possibly after expansion of other macros in the
body.
-@end deffn
-
-@deffn {Special Operator} symbol-macrolet (bindings@dots{}) forms@dots{}
+@end defmac
+
+@defmac symbol-macrolet (bindings@dots{}) forms@dots{}
This form creates @dfn{symbol macros}, which are macros that look
like variable references rather than function calls. Each
@var{binding} is a list @samp{(@var{var} @var{expansion})};
@@ -1935,7 +1935,7 @@
@xref{Loop Facility}, for a description of the @code{loop} macro.
This package defines a nonstandard @code{in-ref} loop clause that
works much like @code{my-dolist}.
-@end deffn
+@end defmac
@node Conditionals, Blocks and Exits, Variable Bindings, Control Structure
@section Conditionals
@@ -1944,7 +1944,7 @@
These conditional forms augment Emacs Lisp's simple @code{if},
@code{and}, @code{or}, and @code{cond} forms.
-@deffn {Special Operator} when test forms@dots{}
+@defmac when test forms@dots{}
This is a variant of @code{if} where there are no ``else'' forms,
and possibly several ``then'' forms. In particular,
@@ -1958,9 +1958,9 @@
@example
(if @var{test} (progn @var{a} @var{b} @var{c}) nil)
@end example
-@end deffn
-
-@deffn {Special Operator} unless test forms@dots{}
+@end defmac
+
+@defmac unless test forms@dots{}
This is a variant of @code{if} where there are no ``then'' forms,
and possibly several ``else'' forms:
@@ -1974,9 +1974,9 @@
@example
(when (not @var{test}) @var{a} @var{b} @var{c})
@end example
-@end deffn
-
-@deffn {Special Operator} case keyform clause@dots{}
+@end defmac
+
+@defmac case keyform clause@dots{}
This macro evaluates @var{keyform}, then compares it with the key
values listed in the various @var{clause}s. Whichever clause matches
the key is executed; comparison is done by @code{eql}. If no clause
@@ -2010,15 +2010,15 @@
((?\r ?\n) (do-ret-thing))
(t (do-other-thing)))
@end example
-@end deffn
-
-@deffn {Special Operator} ecase keyform clause@dots{}
+@end defmac
+
+@defmac ecase keyform clause@dots{}
This macro is just like @code{case}, except that if the key does
not match any of the clauses, an error is signalled rather than
simply returning @code{nil}.
-@end deffn
-
-@deffn {Special Operator} typecase keyform clause@dots{}
+@end defmac
+
+@defmac typecase keyform clause@dots{}
This macro is a version of @code{case} that checks for types
rather than values. Each @var{clause} is of the form
@samp{(@var{type} @var{body}...)}. @xref{Type Predicates},
@@ -2035,13 +2035,13 @@
The type specifier @code{t} matches any type of object; the word
@code{otherwise} is also allowed. To make one clause match any of
several types, use an @code{(or ...)} type specifier.
-@end deffn
-
-@deffn {Special Operator} etypecase keyform clause@dots{}
+@end defmac
+
+@defmac etypecase keyform clause@dots{}
This macro is just like @code{typecase}, except that if the key does
not match any of the clauses, an error is signalled rather than
simply returning @code{nil}.
-@end deffn
+@end defmac
@node Blocks and Exits, Iteration, Conditionals, Control Structure
@section Blocks and Exits
@@ -2054,7 +2054,7 @@
optimizing byte-compiler to omit the costly @code{catch} step if the
body of the block does not actually @code{return-from} the block.
-@deffn {Special Operator} block name forms@dots{}
+@defmac block name forms@dots{}
The @var{forms} are evaluated as if by a @code{progn}. However,
if any of the @var{forms} execute @code{(return-from @var{name})},
they will jump out and return directly from the @code{block} form.
@@ -2093,20 +2093,20 @@
that jump to it. This means that @code{do} loops and @code{defun*}
functions which don't use @code{return} don't pay the overhead to
support it.
-@end deffn
-
-@deffn {Special Operator} return-from name [result]
+@end defmac
+
+@defmac return-from name [result]
This macro returns from the block named @var{name}, which must be
an (unevaluated) symbol. If a @var{result} form is specified, it
is evaluated to produce the result returned from the @code{block}.
Otherwise, @code{nil} is returned.
-@end deffn
-
-@deffn {Special Operator} return [result]
+@end defmac
+
+@defmac return [result]
This macro is exactly like @code{(return-from nil @var{result})}.
Common Lisp loops like @code{do} and @code{dolist} implicitly enclose
themselves in @code{nil} blocks.
-@end deffn
+@end defmac
@node Iteration, Loop Facility, Blocks and Exits, Control Structure
@section Iteration
@@ -2116,7 +2116,7 @@
looping constructs to complement Emacs Lisp's basic @code{while}
loop.
-@deffn {Special Operator} loop forms@dots{}
+@defmac loop forms@dots{}
The @dfn{CL} package supports both the simple, old-style meaning of
@code{loop} and the extremely powerful and flexible feature known as
the @dfn{Loop Facility} or @dfn{Loop Macro}. This more advanced
@@ -2144,9 +2144,9 @@
(This is not a restriction in practice, since a plain symbol
in the above notation would simply access and throw away the
value of a variable.)
-@end deffn
-
-@deffn {Special Operator} do (spec@dots{}) (end-test [result@dots{}]) forms@dots{}
+@end defmac
+
+@defmac do (spec@dots{}) (end-test [result@dots{}]) forms@dots{}
This macro creates a general iterative loop. Each @var{spec} is
of the form
@@ -2192,9 +2192,9 @@
((or (null x) (null y))
(nreverse z)))
@end example
-@end deffn
-
-@deffn {Special Operator} do* (spec@dots{}) (end-test [result@dots{}]) forms@dots{}
+@end defmac
+
+@defmac do* (spec@dots{}) (end-test [result@dots{}]) forms@dots{}
This is to @code{do} what @code{let*} is to @code{let}. In
particular, the initial values are bound as if by @code{let*}
rather than @code{let}, and the steps are assigned as if by
@@ -2212,18 +2212,18 @@
(nreverse z))
(push (f x y) z))
@end example
-@end deffn
-
-@deffn {Special Operator} dolist (var list [result]) forms@dots{}
+@end defmac
+
+@defmac dolist (var list [result]) forms@dots{}
This is a more specialized loop which iterates across the elements
of a list. @var{list} should evaluate to a list; the body @var{forms}
are executed with @var{var} bound to each element of the list in
turn. Finally, the @var{result} form (or @code{nil}) is evaluated
with @var{var} bound to @code{nil} to produce the result returned by
the loop. The loop is surrounded by an implicit @code{nil} block.
-@end deffn
-
-@deffn {Special Operator} dotimes (var count [result]) forms@dots{}
+@end defmac
+
+@defmac dotimes (var count [result]) forms@dots{}
This is a more specialized loop which iterates a specified number
of times. The body is executed with @var{var} bound to the integers
from zero (inclusive) to @var{count} (exclusive), in turn. Then
@@ -2231,9 +2231,9 @@
number of iterations that were done (i.e., @code{(max 0 @var{count})})
to get the return value for the loop form. The loop is surrounded
by an implicit @code{nil} block.
-@end deffn
-
-@deffn {Special Operator} do-symbols (var [obarray [result]]) forms@dots{}
+@end defmac
+
+@defmac do-symbols (var [obarray [result]]) forms@dots{}
This loop iterates over all interned symbols. If @var{obarray}
is specified and is not @code{nil}, it loops over all symbols in
that obarray. For each symbol, the body @var{forms} are evaluated
@@ -2241,12 +2241,12 @@
an unspecified order. Afterward the @var{result} form, if any,
is evaluated (with @var{var} bound to @code{nil}) to get the return
value. The loop is surrounded by an implicit @code{nil} block.
-@end deffn
-
-@deffn {Special Operator} do-all-symbols (var [result]) forms@dots{}
+@end defmac
+
+@defmac do-all-symbols (var [result]) forms@dots{}
This is identical to @code{do-symbols} except that the @var{obarray}
argument is omitted; it always iterates over the default obarray.
-@end deffn
+@end defmac
@xref{Mapping over Sequences}, for some more functions for
iterating over vectors or lists.
@@ -2286,7 +2286,7 @@
takes place at byte-compile time; compiled @code{loop}s are just
as efficient as the equivalent @code{while} loops written longhand.
-@deffn {Special Operator} loop clauses@dots{}
+@defmac loop clauses@dots{}
A loop construct consists of a series of @var{clause}s, each
introduced by a symbol like @code{for} or @code{do}. Clauses
are simply strung together in the argument list of @code{loop},
@@ -2325,7 +2325,7 @@
(Because the loop body is enclosed in an implicit block, you can
also use regular Lisp @code{return} or @code{return-from} to
break out of the loop.)
-@end deffn
+@end defmac
The following sections give some examples of the Loop Macro in
action, and describe the particular loop clauses in great detail.
@@ -3003,7 +3003,7 @@
Destructuring is made available to the user by way of the
following macro:
-@deffn {Special Operator} destructuring-bind arglist expr forms@dots{}
+@defmac destructuring-bind arglist expr forms@dots{}
This macro expands to code which executes @var{forms}, with
the variables in @var{arglist} bound to the list of values
returned by @var{expr}. The @var{arglist} can include all
@@ -3012,13 +3012,13 @@
is not allowed.) The macro expansion will signal an error
if @var{expr} returns a list of the wrong number of arguments
or with incorrect keyword arguments.
-@end deffn
+@end defmac
This package also includes the Common Lisp @code{define-compiler-macro}
facility, which allows you to define compile-time expansions and
optimizations for your functions.
-@deffn {Special Operator} define-compiler-macro name arglist forms@dots{}
+@defmac define-compiler-macro name arglist forms@dots{}
This form is similar to @code{defmacro}, except that it only expands
calls to @var{name} at compile-time; calls processed by the Lisp
interpreter are not expanded, nor are they expanded by the
@@ -3052,7 +3052,7 @@
@code{member*} call is left intact. (The actual compiler macro
for @code{member*} optimizes a number of other cases, including
common @code{:test} predicates.)
-@end deffn
+@end defmac
@defun compiler-macroexpand form
This function is analogous to @code{macroexpand}, except that it
@@ -3094,7 +3094,7 @@
is evaluated and thus should normally be quoted.
@end defun
-@deffn {Special Operator} declaim decl-specs@dots{}
+@defmac declaim decl-specs@dots{}
This macro is like @code{proclaim}, except that it takes any number
of @var{decl-spec} arguments, and the arguments are unevaluated and
unquoted. The @code{declaim} macro also puts an @code{(eval-when
@@ -3103,22 +3103,22 @@
since normally the declarations are meant to influence the way the
compiler treats the rest of the file that contains the @code{declaim}
form.)
-@end deffn
-
-@deffn {Special Operator} declare decl-specs@dots{}
+@end defmac
+
+@defmac declare decl-specs@dots{}
This macro is used to make declarations within functions and other
code. Common Lisp allows declarations in various locations, generally
at the beginning of any of the many ``implicit @code{progn}s''
throughout Lisp syntax, such as function bodies, @code{let} bodies,
etc. Currently the only declaration understood by @code{declare}
is @code{special}.
-@end deffn
-
-@deffn {Special Operator} locally declarations@dots{} forms@dots{}
+@end defmac
+
+@defmac locally declarations@dots{} forms@dots{}
In this package, @code{locally} is no different from @code{progn}.
-@end deffn
-
-@deffn {Special Operator} the type form
+@end defmac
+
+@defmac the type form
Type information provided by @code{the} is ignored in this package;
in other words, @code{(the @var{type} @var{form})} is equivalent
to @var{form}. Future versions of the optimizing byte-compiler may
@@ -3131,7 +3131,7 @@
compiler would have enough information to expand the loop in-line.
For now, Emacs Lisp will treat the above code as exactly equivalent
to @code{(mapcar 'car foo)}.
-@end deffn
+@end defmac
Each @var{decl-spec} in a @code{proclaim}, @code{declaim}, or
@code{declare} should be a list beginning with a symbol that says
@@ -3313,7 +3313,7 @@
expression.
@end defun
-@deffn {Special Operator} remf place property
+@defmac remf place property
This macro removes the property-value pair for @var{property} from
the property list stored at @var{place}, which is any @code{setf}-able
place expression. It returns true if the property was found. Note
@@ -3321,7 +3321,7 @@
effectively do a @code{(setf @var{place} (cddr @var{place}))},
whereas if it occurs later, this simply uses @code{setcdr} to splice
out the property and value cells.
-@end deffn
+@end defmac
@iftex
@secno=2
@@ -4677,7 +4677,7 @@
implements structures as vectors (or lists upon request) with a
special ``tag'' symbol to identify them.
-@deffn {Special Operator} defstruct name slots@dots{}
+@defmac defstruct name slots@dots{}
The @code{defstruct} form defines a new structure type called
@var{name}, with the specified @var{slots}. (The @var{slots}
may begin with a string which documents the structure type.)
@@ -4984,7 +4984,7 @@
specifies a number of slots to be skipped between the last slot
of the included type and the first new slot.
@end table
-@end deffn
+@end defmac
Except as noted, the @code{defstruct} facility of this package is
entirely compatible with that of Common Lisp.
@@ -5007,7 +5007,7 @@
away the following assertions. Because assertions might be optimized
away, it is a bad idea for them to include side-effects.
-@deffn {Special Operator} assert test-form [show-args string args@dots{}]
+@defmac assert test-form [show-args string args@dots{}]
This form verifies that @var{test-form} is true (i.e., evaluates to
a non-@code{nil} value). If so, it returns @code{nil}. If the test
is not satisfied, @code{assert} signals an error.
@@ -5030,9 +5030,9 @@
true Common Lisp, the second argument gives a list of @var{places}
which can be @code{setf}'d by the user before continuing from the
error.
-@end deffn
-
-@deffn {Special Operator} check-type place type &optional string
+@end defmac
+
+@defmac check-type place type &optional string
This form verifies that @var{place} evaluates to a value of type
@var{type}. If so, it returns @code{nil}. If not, @code{check-type}
signals a continuable @code{wrong-type-argument} error. The default
@@ -5051,18 +5051,18 @@
should be a @var{place} suitable for use by @code{setf}, because
@code{check-type} signals a continuable error that allows the user to
modify @var{place}, most simply by returning a value from the debugger.
-@end deffn
+@end defmac
The following error-related macro is also defined:
-@deffn {Special Operator} ignore-errors forms@dots{}
+@defmac ignore-errors forms@dots{}
This executes @var{forms} exactly like a @code{progn}, except that
errors are ignored during the @var{forms}. More precisely, if
an error is signalled then @code{ignore-errors} immediately
aborts execution of the @var{forms} and returns @code{nil}.
If the @var{forms} complete successfully, @code{ignore-errors}
returns the result of the last @var{form}.
-@end deffn
+@end defmac
@node Efficiency Concerns, Common Lisp Compatibility, Assertions, Top
@appendix Efficiency Concerns
diff -r d54278e74d71 -r a46c5c8d6564 man/lispref/compile.texi
--- a/man/lispref/compile.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/lispref/compile.texi Tue Aug 09 17:17:44 2011 +0100
@@ -691,7 +691,7 @@
These features permit you to write code to be evaluated during
compilation of a program.
-@deffn {Special Operator} eval-and-compile body
+@defmac eval-and-compile body
This form marks @var{body} to be evaluated both when you compile the
containing code and when you run it (whether compiled or not).
@@ -699,9 +699,9 @@
and referring to that file with @code{require}. Using @code{require} is
preferable if there is a substantial amount of code to be executed in
this way.
-@end deffn
+@end defmac
-@deffn {Special Operator} eval-when-compile body
+@defmac eval-when-compile body
This form marks @var{body} to be evaluated at compile time and not when
the compiled program is loaded. The result of evaluation by the
compiler becomes a constant which appears in the compiled program. When
@@ -712,7 +712,7 @@
@code{(eval-when (compile eval) @dots{})}. Elsewhere, the Common Lisp
@samp{#.} reader macro (but not when interpreting) is closer to what
@code{eval-when-compile} does.
-@end deffn
+@end defmac
@node Compiled-Function Objects
@section Compiled-Function Objects
diff -r d54278e74d71 -r a46c5c8d6564 man/lispref/eval.texi
--- a/man/lispref/eval.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/lispref/eval.texi Tue Aug 09 17:17:44 2011 +0100
@@ -743,21 +743,21 @@
values.
@end defun
-@deffn {Special Operator} multiple-value-bind (var@dots{}) values-form forms@dots{}
-This special operator evaluates @var{values-form}, which may return
+@defmac multiple-value-bind (var@dots{}) values-form forms@dots{}
+This macro evaluates @var{values-form}, which may return
multiple values. It then binds the @var{var}s to these respective values,
as if by @code{let}, and then executes the body @var{forms}.
If there are more @var{var}s than values, the extra @var{var}s
are bound to @code{nil}. If there are fewer @var{var}s than
values, the excess values are ignored.
-@end deffn
+@end defmac
-@deffn {Special Operator} multiple-value-setq (var@dots{}) form
-This special operator evaluates @var{form}, which may return multiple
+@defmac multiple-value-setq (var@dots{}) form
+This macro evaluates @var{form}, which may return multiple
values. It then sets the @var{var}s to these respective values, as if by
@code{setq}. Extra @var{var}s or values are treated the same as
in @code{multiple-value-bind}.
-@end deffn
+@end defmac
@deffn {Special Operator} multiple-value-call function forms@dots{}
This special operator evaluates function, discarding any multiple
@@ -767,10 +767,10 @@
infrastructure, treating multiple values as intercalated lists.
@end deffn
-@deffn {Special Operator} multiple-value-list form
-This special operator evaluates @var{form} and returns a list of the
+@defmac multiple-value-list form
+This macro evaluates @var{form} and returns a list of the
multiple values given by it.
-@end deffn
+@end defmac
@deffn {Special Operator} multiple-value-prog1 first body@dots{}
This special operator evaluates the form @var{first}, then the
@@ -779,12 +779,12 @@
@code{prog1} always discards multiple values.
@end deffn
-@deffn {Special Operator} nth-value n form
-This special operator evaluates @var{form} and returns the @var{n}th
+@defmac nth-value n form
+This macro evaluates @var{form} and returns the @var{n}th
value it gave. @var{n} must be an integer of value zero or more.
If @var{form} gave insufficient multiple values, @code{nth-value}
returns @code{nil}.
-@end deffn
+@end defmac
@defvar multiple-values-limit
This constant describes the exclusive upper bound on the number of
diff -r d54278e74d71 -r a46c5c8d6564 man/lispref/frames.texi
--- a/man/lispref/frames.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/lispref/frames.texi Tue Aug 09 17:17:44 2011 +0100
@@ -785,18 +785,18 @@
@code{focus-follows-mouse}.
@end defun
-@deffn {Special Operator} save-selected-frame forms@dots{}
-This special operator records the selected frame, executes @var{forms} in
+@defmac save-selected-frame forms@dots{}
+This macro records the selected frame, executes @var{forms} in
sequence, then restores the earlier selected frame. The value returned
is the value of the last form.
-@end deffn
+@end defmac
-@deffn {Special Operator} with-selected-frame frame forms@dots{}
-This special operator records the selected frame, then selects @var{frame}
+@defmac with-selected-frame frame forms@dots{}
+This macro records the selected frame, then selects @var{frame}
and executes @var{forms} in sequence. After the last form is finished,
the earlier selected frame is restored. The value returned is the value
of the last form.
-@end deffn
+@end defmac
@ignore (FSF Emacs, continued from defun select-frame)
XEmacs cooperates with the X server and the window managers by arranging
diff -r d54278e74d71 -r a46c5c8d6564 man/lispref/internationalization.texi
--- a/man/lispref/internationalization.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/lispref/internationalization.texi Tue Aug 09 17:17:44 2011 +0100
@@ -83,8 +83,8 @@
nothing.
@end defun
-@deffn {Special Operator} domain string
-This function specifies the text domain used for translating documentation
+@defmac domain string
+This macro specifies the text domain used for translating documentation
strings and interactive prompts of a function. For example, write:
@example
@@ -94,7 +94,7 @@
to specify @code{emacs-foo} as the text domain of the function @code{foo}.
The ``call'' to @code{domain} is actually a declaration rather than a
function; when actually called, @code{domain} just returns @code{nil}.
-@end deffn
+@end defmac
@defun domain-of function
This function returns the text domain of @var{function}; it returns
diff -r d54278e74d71 -r a46c5c8d6564 man/lispref/positions.texi
--- a/man/lispref/positions.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/lispref/positions.texi Tue Aug 09 17:17:44 2011 +0100
@@ -818,21 +818,21 @@
@code{save-current-buffer} is a primitive.
@end deffn
-@deffn {Special Operator} with-current-buffer buffer forms@dots{}
+@defmac with-current-buffer buffer forms@dots{}
This macro evaluates @var{forms} with @var{buffer} as the current
buffer. It returns the value of the last form.
-@end deffn
+@end defmac
-@deffn {Special Operator} with-temp-file filename forms@dots{}
+@defmac with-temp-file filename forms@dots{}
This macro creates a new buffer, evaluates @var{forms} there, and
writes the buffer to @var{filename}. It returns the value of the last form
evaluated.
-@end deffn
+@end defmac
-@deffn {Special Operator} save-selected-window forms@dots{}
+@defmac save-selected-window forms@dots{}
This macro is similar to @code{save-excursion} but it saves and
restores the selected window and nothing else.
-@end deffn
+@end defmac
@node Narrowing
@section Narrowing
diff -r d54278e74d71 -r a46c5c8d6564 man/lispref/searching.texi
--- a/man/lispref/searching.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/lispref/searching.texi Tue Aug 09 17:17:44 2011 +0100
@@ -1458,10 +1458,10 @@
You can save and restore the match data with @code{save-match-data}:
-@deffn {Special Operator} save-match-data body@dots{}
-This special operator executes @var{body}, saving and restoring the match
+@defmac save-match-data body@dots{}
+This macro executes @var{body}, saving and restoring the match
data around it.
-@end deffn
+@end defmac
Emacs automatically saves and restores the match data when it runs
process filter functions (@pxref{Filter Functions}) and process
diff -r d54278e74d71 -r a46c5c8d6564 man/lispref/specifiers.texi
--- a/man/lispref/specifiers.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/lispref/specifiers.texi Tue Aug 09 17:17:44 2011 +0100
@@ -875,7 +875,7 @@
@code{add-spec-list-to-specifier}.
@end defun
-@deffn {Special Operator} let-specifier specifier-list &rest body
+@defmac let-specifier specifier-list &rest body
This macro temporarily adds specifications to specifiers,
evaluates forms in @var{body} and restores the specifiers to their
previous states. The specifiers and their temporary specifications are
@@ -912,7 +912,7 @@
(let-specifier ((modeline-shadow-thickness 0 (selected-window)))
(sit-for 1))
@end example
-@end deffn
+@end defmac
@defun set-specifier specifier value &optional locale tag-set how-to-add
This function adds some specifications to @var{specifier}. @var{value}
diff -r d54278e74d71 -r a46c5c8d6564 man/lispref/windows.texi
--- a/man/lispref/windows.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/lispref/windows.texi Tue Aug 09 17:17:44 2011 +0100
@@ -442,12 +442,12 @@
@end example
@end defun
-@deffn {Special Operator} save-selected-window forms@dots{}
+@defmac save-selected-window forms@dots{}
This macro records the selected window, executes @var{forms} in
sequence, then restores the earlier selected window. It does not save
or restore anything about the sizes, arrangement or contents of windows;
therefore, if the @var{forms} change them, the changes are permanent.
-@end deffn
+@end defmac
@cindex finding windows
The following functions choose one of the windows on the screen,
@@ -1969,7 +1969,7 @@
@end example
@end defun
-@deffn {Special Operator} save-window-excursion forms@dots{}
+@defmac save-window-excursion forms@dots{}
This macro records the window configuration, executes @var{forms}
in sequence, then restores the earlier window configuration. The window
configuration includes the value of point and the portion of the buffer
@@ -2005,7 +2005,7 @@
;; @r{The frame is now split again.}
@end group
@end example
-@end deffn
+@end defmac
@defun window-configuration-p object
This function returns @code{t} if @var{object} is a window configuration.
--
‘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: Avoid calling various macros "special operators" in the manuals.
13 years, 4 months
Aidan Kehoe
changeset: 5547:a46c5c8d6564
tag: tip
user: Aidan Kehoe <kehoea(a)parhasard.net>
date: Tue Aug 09 17:17:44 2011 +0100
files: man/ChangeLog man/cl.texi man/lispref/compile.texi man/lispref/eval.texi man/lispref/frames.texi man/lispref/internationalization.texi man/lispref/positions.texi man/lispref/searching.texi man/lispref/specifiers.texi man/lispref/windows.texi
description:
Avoid calling various macros "special operators" in the manuals.
2011-08-09 Aidan Kehoe <kehoea(a)parhasard.net>
* cl.texi (Argument Lists):
* cl.texi (Time of Evaluation):
* cl.texi (Type Predicates):
* cl.texi (Assignment):
* cl.texi (Basic Setf):
* cl.texi (Modify Macros):
* cl.texi (Customizing Setf):
* cl.texi (Dynamic Bindings):
* cl.texi (Lexical Bindings):
* cl.texi (Function Bindings):
* cl.texi (Macro Bindings):
* cl.texi (Conditionals):
* cl.texi (Blocks and Exits):
* cl.texi (Iteration):
* cl.texi (Loop Basics):
* cl.texi (Macros):
* cl.texi (Declarations):
* cl.texi (Property Lists):
* cl.texi (Structures):
* cl.texi (Assertions):
* cl.texi (Efficiency Concerns):
* lispref/compile.texi (Eval During Compile):
* lispref/compile.texi (Compiled-Function Objects):
* lispref/eval.texi (Multiple values):
* lispref/frames.texi (Input Focus):
* lispref/internationalization.texi (Level 3 Primitives):
* lispref/positions.texi (Excursions):
* lispref/positions.texi (Narrowing):
* lispref/searching.texi (Saving Match Data):
* lispref/specifiers.texi (Adding Specifications):
* lispref/windows.texi:
Correct the manuals to avoid using the term "special operator" when
#'special-operator-p would give nil.
diff -r d54278e74d71 -r a46c5c8d6564 man/ChangeLog
--- a/man/ChangeLog Mon Aug 08 23:10:47 2011 +0900
+++ b/man/ChangeLog Tue Aug 09 17:17:44 2011 +0100
@@ -1,3 +1,39 @@
+2011-08-09 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * cl.texi (Argument Lists):
+ * cl.texi (Time of Evaluation):
+ * cl.texi (Type Predicates):
+ * cl.texi (Assignment):
+ * cl.texi (Basic Setf):
+ * cl.texi (Modify Macros):
+ * cl.texi (Customizing Setf):
+ * cl.texi (Dynamic Bindings):
+ * cl.texi (Lexical Bindings):
+ * cl.texi (Function Bindings):
+ * cl.texi (Macro Bindings):
+ * cl.texi (Conditionals):
+ * cl.texi (Blocks and Exits):
+ * cl.texi (Iteration):
+ * cl.texi (Loop Basics):
+ * cl.texi (Macros):
+ * cl.texi (Declarations):
+ * cl.texi (Property Lists):
+ * cl.texi (Structures):
+ * cl.texi (Assertions):
+ * cl.texi (Efficiency Concerns):
+ * lispref/compile.texi (Eval During Compile):
+ * lispref/compile.texi (Compiled-Function Objects):
+ * lispref/eval.texi (Multiple values):
+ * lispref/frames.texi (Input Focus):
+ * lispref/internationalization.texi (Level 3 Primitives):
+ * lispref/positions.texi (Excursions):
+ * lispref/positions.texi (Narrowing):
+ * lispref/searching.texi (Saving Match Data):
+ * lispref/specifiers.texi (Adding Specifications):
+ * lispref/windows.texi:
+ Correct the manuals to avoid using the term "special operator" when
+ #'special-operator-p would give nil.
+
2011-08-08 Stephen J. Turnbull <stephen(a)xemacs.org>
* internals/internals.texi (Mercurial Techniques): New.
diff -r d54278e74d71 -r a46c5c8d6564 man/cl.texi
--- a/man/cl.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/cl.texi Tue Aug 09 17:17:44 2011 +0100
@@ -381,14 +381,14 @@
Instead, this package defines alternates for several Lisp forms
which you must use if you need Common Lisp argument lists.
-@deffn {Special Operator} defun* name arglist body...
+@defmac defun* name arglist body...
This form is identical to the regular @code{defun} form, except
that @var{arglist} is allowed to be a full Common Lisp argument
list. Also, the function body is enclosed in an implicit block
called @var{name}; @pxref{Blocks and Exits}.
-@end deffn
-
-@deffn {Special Operator} defsubst* name arglist body...
+@end defmac
+
+@defmac defsubst* name arglist body...
This is just like @code{defun*}, except that the function that
is defined is automatically proclaimed @code{inline}, i.e.,
calls to it may be expanded into in-line code by the byte compiler.
@@ -398,9 +398,9 @@
efficient inline expansions. In particular, @code{defsubst*}
arranges for the processing of keyword arguments, default values,
etc., to be done at compile-time whenever possible.
-@end deffn
-
-@deffn {Special Operator} defmacro* name arglist body...
+@end defmac
+
+@defmac defmacro* name arglist body...
This is identical to the regular @code{defmacro} form,
except that @var{arglist} is allowed to be a full Common Lisp
argument list. The @code{&environment} keyword is supported as
@@ -409,13 +409,13 @@
cannot be implemented with the current Emacs Lisp interpreter.
The macro expander body is enclosed in an implicit block called
@var{name}.
-@end deffn
-
-@deffn {Special Operator} function* symbol-or-lambda
+@end defmac
+
+@defmac function* symbol-or-lambda
This is identical to the regular @code{function} form,
except that if the argument is a @code{lambda} form then that
form may use a full Common Lisp argument list.
-@end deffn
+@end defmac
Also, all forms (such as @code{defsetf} and @code{flet}) defined
in this package that include @var{arglist}s in their syntax allow
@@ -606,7 +606,7 @@
at compile-time so that later parts of the file can refer to the
macros that are defined.
-@deffn {Special Operator} eval-when (situations...) forms...
+@defmac eval-when (situations...) forms...
This form controls when the body @var{forms} are evaluated.
The @var{situations} list may contain any set of the symbols
@code{compile}, @code{load}, and @code{eval} (or their long-winded
@@ -678,7 +678,7 @@
certain top-level forms, like @code{defmacro} (sort-of) and
@code{require}, as if they were wrapped in @code{(eval-when
(compile load eval) @dots{})}.
-@end deffn
+@end defmac
Emacs 19 includes two special operators related to @code{eval-when}.
One of these, @code{eval-when-compile}, is not quite equivalent to
@@ -690,7 +690,7 @@
equivalent to @samp{(eval-when (compile load eval) @dots{})} and
so is not itself defined by this package.
-@deffn {Special Operator} eval-when-compile forms...
+@defmac eval-when-compile forms...
The @var{forms} are evaluated at compile-time; at execution time,
this form acts like a quoted constant of the resulting value. Used
at top-level, @code{eval-when-compile} is just like @samp{eval-when
@@ -699,9 +699,9 @@
or other reasons.
This form is similar to the @samp{#.} syntax of true Common Lisp.
-@end deffn
-
-@deffn {Special Operator} load-time-value form
+@end defmac
+
+@defmac load-time-value form
The @var{form} is evaluated at load-time; at execution time,
this form acts like a quoted constant of the resulting value.
@@ -742,7 +742,7 @@
", and loaded on: "
--temp--))
@end example
-@end deffn
+@end defmac
@node Function Aliases, , Time of Evaluation, Program Structure
@section Function Aliases
@@ -869,7 +869,7 @@
error.
@end defun
-@deffn {Special Operator} deftype name arglist forms...
+@defmac deftype name arglist forms...
This macro defines a new type called @var{name}. It is similar
to @code{defmacro} in many ways; when @var{name} is encountered
as a type name, the body @var{forms} are evaluated and should
@@ -897,7 +897,7 @@
The last example shows how the Common Lisp @code{unsigned-byte}
type specifier could be implemented if desired; this package does
not implement @code{unsigned-byte} by default.
-@end deffn
+@end defmac
The @code{typecase} and @code{check-type} macros also use type
names. @xref{Conditionals}. @xref{Assertions}. The @code{map},
@@ -989,7 +989,7 @@
The @code{psetq} form is just like @code{setq}, except that multiple
assignments are done in parallel rather than sequentially.
-@deffn {Special Operator} psetq [symbol form]@dots{}
+@defmac psetq [symbol form]@dots{}
This macro is used to assign to several
variables simultaneously. Given only one @var{symbol} and @var{form},
it has the same effect as @code{setq}. Given several @var{symbol}
@@ -1017,7 +1017,7 @@
@pxref{Modify Macros}.)
@code{psetq} always returns @code{nil}.
-@end deffn
+@end defmac
@node Generalized Variables, Variable Bindings, Assignment, Control Structure
@section Generalized Variables
@@ -1055,7 +1055,7 @@
The @code{setf} macro is the most basic way to operate on generalized
variables.
-@deffn {Special Operator} setf [place form]@dots{}
+@defmac setf [place form]@dots{}
This macro evaluates @var{form} and stores it in @var{place}, which
must be a valid generalized variable form. If there are several
@var{place} and @var{form} pairs, the assignments are done sequentially
@@ -1218,7 +1218,7 @@
the form @code{(setf (wrong-order @var{a} @var{b}) 17)} will
evaluate @var{b} first, then @var{a}, just as in an actual call
to @code{wrong-order}.
-@end deffn
+@end defmac
@node Modify Macros, Customizing Setf, Basic Setf, Generalized Variables
@subsection Modify Macros
@@ -1228,15 +1228,15 @@
that operate on generalized variables. Many are interesting and
useful even when the @var{place} is just a variable name.
-@deffn {Special Operator} psetf [place form]@dots{}
+@defmac psetf [place form]@dots{}
This macro is to @code{setf} what @code{psetq} is to @code{setq}:
When several @var{place}s and @var{form}s are involved, the
assignments take place in parallel rather than sequentially.
Specifically, all subforms are evaluated from left to right, then
all the assignments are done (in an undefined order).
-@end deffn
-
-@deffn {Special Operator} incf place &optional x
+@end defmac
+
+@defmac incf place &optional x
This macro increments the number stored in @var{place} by one, or
by @var{x} if specified. The incremented value is returned. For
example, @code{(incf i)} is equivalent to @code{(setq i (1+ i))}, and
@@ -1274,35 +1274,35 @@
As a more Emacs-specific example of @code{incf}, the expression
@code{(incf (point) @var{n})} is essentially equivalent to
@code{(forward-char @var{n})}.
-@end deffn
-
-@deffn {Special Operator} decf place &optional x
+@end defmac
+
+@defmac decf place &optional x
This macro decrements the number stored in @var{place} by one, or
by @var{x} if specified.
-@end deffn
-
-@deffn {Special Operator} pop place
+@end defmac
+
+@defmac pop place
This macro removes and returns the first element of the list stored
in @var{place}. It is analogous to @code{(prog1 (car @var{place})
(setf @var{place} (cdr @var{place})))}, except that it takes care
to evaluate all subforms only once.
-@end deffn
-
-@deffn {Special Operator} push x place
+@end defmac
+
+@defmac push x place
This macro inserts @var{x} at the front of the list stored in
@var{place}. It is analogous to @code{(setf @var{place} (cons
@var{x} @var{place}))}, except for evaluation of the subforms.
-@end deffn
-
-@deffn {Special Operator} pushnew x place @t{&key :test :test-not :key}
+@end defmac
+
+@defmac pushnew x place @t{&key :test :test-not :key}
This macro inserts @var{x} at the front of the list stored in
@var{place}, but only if @var{x} was not @code{eql} to any
existing element of the list. The optional keyword arguments
are interpreted in the same way as for @code{adjoin}.
@xref{Lists as Sets}.
-@end deffn
-
-@deffn {Special Operator} shiftf place@dots{} newvalue
+@end defmac
+
+@defmac shiftf place@dots{} newvalue
This macro shifts the @var{place}s left by one, shifting in the
value of @var{newvalue} (which may be any Lisp expression, not just
a generalized variable), and returning the value shifted out of
@@ -1320,9 +1320,9 @@
@noindent
except that the subforms of @var{a}, @var{b}, and @var{c} are actually
evaluated only once each and in the apparent order.
-@end deffn
-
-@deffn {Special Operator} rotatef place@dots{}
+@end defmac
+
+@defmac rotatef place@dots{}
This macro rotates the @var{place}s left by one in circular fashion.
Thus, @code{(rotatef @var{a} @var{b} @var{c} @var{d})} is equivalent to
@@ -1337,12 +1337,12 @@
except for the evaluation of subforms. @code{rotatef} always
returns @code{nil}. Note that @code{(rotatef @var{a} @var{b})}
conveniently exchanges @var{a} and @var{b}.
-@end deffn
+@end defmac
The following macros were invented for this package; they have no
analogues in Common Lisp.
-@deffn {Special Operator} letf (bindings@dots{}) forms@dots{}
+@defmac letf (bindings@dots{}) forms@dots{}
This macro is analogous to @code{let}, but for generalized variables
rather than just symbols. Each @var{binding} should be of the form
@code{(@var{place} @var{value})}; the original contents of the
@@ -1392,14 +1392,14 @@
variables and calls to @code{symbol-value} and @code{symbol-function}.
If the symbol is not bound on entry, it is simply made unbound by
@code{makunbound} or @code{fmakunbound} on exit.
-@end deffn
-
-@deffn {Special Operator} letf* (bindings@dots{}) forms@dots{}
+@end defmac
+
+@defmac letf* (bindings@dots{}) forms@dots{}
This macro is to @code{letf} what @code{let*} is to @code{let}:
It does the bindings in sequential rather than parallel order.
-@end deffn
-
-@deffn {Special Operator} callf @var{function} @var{place} @var{args}@dots{}
+@end defmac
+
+@defmac callf @var{function} @var{place} @var{args}@dots{}
This is the ``generic'' modify macro. It calls @var{function},
which should be an unquoted function name, macro name, or lambda.
It passes @var{place} and @var{args} as arguments, and assigns the
@@ -1416,14 +1416,14 @@
@xref{Customizing Setf}, for @code{define-modify-macro}, a way
to create even more concise notations for modify macros. Note
again that @code{callf} is an extension to standard Common Lisp.
-@end deffn
-
-@deffn {Special Operator} callf2 @var{function} @var{arg1} @var{place} @var{args}@dots{}
+@end defmac
+
+@defmac callf2 @var{function} @var{arg1} @var{place} @var{args}@dots{}
This macro is like @code{callf}, except that @var{place} is
the @emph{second} argument of @var{function} rather than the
first. For example, @code{(push @var{x} @var{place})} is
equivalent to @code{(callf2 cons @var{x} @var{place})}.
-@end deffn
+@end defmac
The @code{callf} and @code{callf2} macros serve as building
blocks for other macros like @code{incf}, @code{pushnew}, and
@@ -1439,7 +1439,7 @@
@code{defsetf}, and @code{define-setf-method}, that allow the
user to extend generalized variables in various ways.
-@deffn {Special Operator} define-modify-macro name arglist function [doc-string]
+@defmac define-modify-macro name arglist function [doc-string]
This macro defines a ``read-modify-write'' macro similar to
@code{incf} and @code{decf}. The macro @var{name} is defined
to take a @var{place} argument followed by additional arguments
@@ -1480,9 +1480,9 @@
using @code{get-setf-method}, or consult the source file
@file{cl-macs.el} to see how to use the internal @code{setf}
building blocks.
-@end deffn
-
-@deffn {Special Operator} defsetf access-fn update-fn
+@end defmac
+
+@defmac defsetf access-fn update-fn
This is the simpler of two @code{defsetf} forms. Where
@var{access-fn} is the name of a function which accesses a place,
this declares @var{update-fn} to be the corresponding store
@@ -1525,9 +1525,9 @@
(defsetf symbol-value set)
(defsetf buffer-name rename-buffer t)
@end example
-@end deffn
-
-@deffn {Special Operator} defsetf access-fn arglist (store-var) forms@dots{}
+@end defmac
+
+@defmac defsetf access-fn arglist (store-var) forms@dots{}
This is the second, more complex, form of @code{defsetf}. It is
rather like @code{defmacro} except for the additional @var{store-var}
argument. The @var{forms} should return a Lisp form which stores
@@ -1556,9 +1556,9 @@
(defsetf nth (n x) (store)
(list 'setcar (list 'nthcdr n x) store))
@end example
-@end deffn
-
-@deffn {Special Operator} define-setf-method access-fn arglist forms@dots{}
+@end defmac
+
+@defmac define-setf-method access-fn arglist forms@dots{}
This is the most general way to create new place forms. When
a @code{setf} to @var{access-fn} with arguments described by
@var{arglist} is expanded, the @var{forms} are evaluated and
@@ -1603,7 +1603,7 @@
use this setf-method will optimize away most temporaries that
turn out to be unnecessary, so there is little reason for the
setf-method itself to optimize.
-@end deffn
+@end defmac
@defun get-setf-method place &optional env
This function returns the setf-method for @var{place}, by
@@ -1669,7 +1669,7 @@
at compile-time. The @code{progv} form provides an easy way to
bind variables whose names are computed at run-time.
-@deffn {Special Operator} progv symbols values forms@dots{}
+@defmac progv symbols values forms@dots{}
This form establishes @code{let}-style variable bindings on a
set of variables computed at run-time. The expressions
@var{symbols} and @var{values} are evaluated, and must return lists
@@ -1679,7 +1679,7 @@
are made unbound (as if by @code{makunbound}) inside the body.
If @var{symbols} is shorter than @var{values}, the excess values
are ignored.
-@end deffn
+@end defmac
@node Lexical Bindings, Function Bindings, Dynamic Bindings, Variable Bindings
@subsection Lexical Bindings
@@ -1688,7 +1688,7 @@
The @dfn{CL} package defines the following macro which
more closely follows the Common Lisp @code{let} form:
-@deffn {Special Operator} lexical-let (bindings@dots{}) forms@dots{}
+@defmac lexical-let (bindings@dots{}) forms@dots{}
This form is exactly like @code{let} except that the bindings it
establishes are purely lexical. Lexical bindings are similar to
local variables in a language like C: Only the code physically
@@ -1788,12 +1788,12 @@
The @code{lexical-let} form is an extension to Common Lisp. In
true Common Lisp, all bindings are lexical unless declared otherwise.
-@end deffn
-
-@deffn {Special Operator} lexical-let* (bindings@dots{}) forms@dots{}
+@end defmac
+
+@defmac lexical-let* (bindings@dots{}) forms@dots{}
This form is just like @code{lexical-let}, except that the bindings
are made sequentially in the manner of @code{let*}.
-@end deffn
+@end defmac
@node Function Bindings, Macro Bindings, Lexical Bindings, Variable Bindings
@subsection Function Bindings
@@ -1802,7 +1802,7 @@
These forms make @code{let}-like bindings to functions instead
of variables.
-@deffn {Special Operator} flet (bindings@dots{}) forms@dots{}
+@defmac flet (bindings@dots{}) forms@dots{}
This form establishes @code{let}-style bindings on the function
cells of symbols rather than on the value cells. Each @var{binding}
must be a list of the form @samp{(@var{name} @var{arglist}
@@ -1841,14 +1841,14 @@
argument notation supported by @code{defun*}; also, the function
body is enclosed in an implicit block as if by @code{defun*}.
@xref{Program Structure}.
-@end deffn
-
-@deffn {Special Operator} labels (bindings@dots{}) forms@dots{}
+@end defmac
+
+@defmac labels (bindings@dots{}) forms@dots{}
The @code{labels} form is a synonym for @code{flet}. (In Common
Lisp, @code{labels} and @code{flet} differ in ways that depend on
their lexical scoping; these distinctions vanish in dynamically
scoped Emacs Lisp.)
-@end deffn
+@end defmac
@node Macro Bindings, , Function Bindings, Variable Bindings
@subsection Macro Bindings
@@ -1856,7 +1856,7 @@
@noindent
These forms create local macros and ``symbol macros.''
-@deffn {Special Operator} macrolet (bindings@dots{}) forms@dots{}
+@defmac macrolet (bindings@dots{}) forms@dots{}
This form is analogous to @code{flet}, but for macros instead of
functions. Each @var{binding} is a list of the same form as the
arguments to @code{defmacro*} (i.e., a macro name, argument list,
@@ -1868,9 +1868,9 @@
affect only calls that appear physically within the body
@var{forms}, possibly after expansion of other macros in the
body.
-@end deffn
-
-@deffn {Special Operator} symbol-macrolet (bindings@dots{}) forms@dots{}
+@end defmac
+
+@defmac symbol-macrolet (bindings@dots{}) forms@dots{}
This form creates @dfn{symbol macros}, which are macros that look
like variable references rather than function calls. Each
@var{binding} is a list @samp{(@var{var} @var{expansion})};
@@ -1935,7 +1935,7 @@
@xref{Loop Facility}, for a description of the @code{loop} macro.
This package defines a nonstandard @code{in-ref} loop clause that
works much like @code{my-dolist}.
-@end deffn
+@end defmac
@node Conditionals, Blocks and Exits, Variable Bindings, Control Structure
@section Conditionals
@@ -1944,7 +1944,7 @@
These conditional forms augment Emacs Lisp's simple @code{if},
@code{and}, @code{or}, and @code{cond} forms.
-@deffn {Special Operator} when test forms@dots{}
+@defmac when test forms@dots{}
This is a variant of @code{if} where there are no ``else'' forms,
and possibly several ``then'' forms. In particular,
@@ -1958,9 +1958,9 @@
@example
(if @var{test} (progn @var{a} @var{b} @var{c}) nil)
@end example
-@end deffn
-
-@deffn {Special Operator} unless test forms@dots{}
+@end defmac
+
+@defmac unless test forms@dots{}
This is a variant of @code{if} where there are no ``then'' forms,
and possibly several ``else'' forms:
@@ -1974,9 +1974,9 @@
@example
(when (not @var{test}) @var{a} @var{b} @var{c})
@end example
-@end deffn
-
-@deffn {Special Operator} case keyform clause@dots{}
+@end defmac
+
+@defmac case keyform clause@dots{}
This macro evaluates @var{keyform}, then compares it with the key
values listed in the various @var{clause}s. Whichever clause matches
the key is executed; comparison is done by @code{eql}. If no clause
@@ -2010,15 +2010,15 @@
((?\r ?\n) (do-ret-thing))
(t (do-other-thing)))
@end example
-@end deffn
-
-@deffn {Special Operator} ecase keyform clause@dots{}
+@end defmac
+
+@defmac ecase keyform clause@dots{}
This macro is just like @code{case}, except that if the key does
not match any of the clauses, an error is signalled rather than
simply returning @code{nil}.
-@end deffn
-
-@deffn {Special Operator} typecase keyform clause@dots{}
+@end defmac
+
+@defmac typecase keyform clause@dots{}
This macro is a version of @code{case} that checks for types
rather than values. Each @var{clause} is of the form
@samp{(@var{type} @var{body}...)}. @xref{Type Predicates},
@@ -2035,13 +2035,13 @@
The type specifier @code{t} matches any type of object; the word
@code{otherwise} is also allowed. To make one clause match any of
several types, use an @code{(or ...)} type specifier.
-@end deffn
-
-@deffn {Special Operator} etypecase keyform clause@dots{}
+@end defmac
+
+@defmac etypecase keyform clause@dots{}
This macro is just like @code{typecase}, except that if the key does
not match any of the clauses, an error is signalled rather than
simply returning @code{nil}.
-@end deffn
+@end defmac
@node Blocks and Exits, Iteration, Conditionals, Control Structure
@section Blocks and Exits
@@ -2054,7 +2054,7 @@
optimizing byte-compiler to omit the costly @code{catch} step if the
body of the block does not actually @code{return-from} the block.
-@deffn {Special Operator} block name forms@dots{}
+@defmac block name forms@dots{}
The @var{forms} are evaluated as if by a @code{progn}. However,
if any of the @var{forms} execute @code{(return-from @var{name})},
they will jump out and return directly from the @code{block} form.
@@ -2093,20 +2093,20 @@
that jump to it. This means that @code{do} loops and @code{defun*}
functions which don't use @code{return} don't pay the overhead to
support it.
-@end deffn
-
-@deffn {Special Operator} return-from name [result]
+@end defmac
+
+@defmac return-from name [result]
This macro returns from the block named @var{name}, which must be
an (unevaluated) symbol. If a @var{result} form is specified, it
is evaluated to produce the result returned from the @code{block}.
Otherwise, @code{nil} is returned.
-@end deffn
-
-@deffn {Special Operator} return [result]
+@end defmac
+
+@defmac return [result]
This macro is exactly like @code{(return-from nil @var{result})}.
Common Lisp loops like @code{do} and @code{dolist} implicitly enclose
themselves in @code{nil} blocks.
-@end deffn
+@end defmac
@node Iteration, Loop Facility, Blocks and Exits, Control Structure
@section Iteration
@@ -2116,7 +2116,7 @@
looping constructs to complement Emacs Lisp's basic @code{while}
loop.
-@deffn {Special Operator} loop forms@dots{}
+@defmac loop forms@dots{}
The @dfn{CL} package supports both the simple, old-style meaning of
@code{loop} and the extremely powerful and flexible feature known as
the @dfn{Loop Facility} or @dfn{Loop Macro}. This more advanced
@@ -2144,9 +2144,9 @@
(This is not a restriction in practice, since a plain symbol
in the above notation would simply access and throw away the
value of a variable.)
-@end deffn
-
-@deffn {Special Operator} do (spec@dots{}) (end-test [result@dots{}]) forms@dots{}
+@end defmac
+
+@defmac do (spec@dots{}) (end-test [result@dots{}]) forms@dots{}
This macro creates a general iterative loop. Each @var{spec} is
of the form
@@ -2192,9 +2192,9 @@
((or (null x) (null y))
(nreverse z)))
@end example
-@end deffn
-
-@deffn {Special Operator} do* (spec@dots{}) (end-test [result@dots{}]) forms@dots{}
+@end defmac
+
+@defmac do* (spec@dots{}) (end-test [result@dots{}]) forms@dots{}
This is to @code{do} what @code{let*} is to @code{let}. In
particular, the initial values are bound as if by @code{let*}
rather than @code{let}, and the steps are assigned as if by
@@ -2212,18 +2212,18 @@
(nreverse z))
(push (f x y) z))
@end example
-@end deffn
-
-@deffn {Special Operator} dolist (var list [result]) forms@dots{}
+@end defmac
+
+@defmac dolist (var list [result]) forms@dots{}
This is a more specialized loop which iterates across the elements
of a list. @var{list} should evaluate to a list; the body @var{forms}
are executed with @var{var} bound to each element of the list in
turn. Finally, the @var{result} form (or @code{nil}) is evaluated
with @var{var} bound to @code{nil} to produce the result returned by
the loop. The loop is surrounded by an implicit @code{nil} block.
-@end deffn
-
-@deffn {Special Operator} dotimes (var count [result]) forms@dots{}
+@end defmac
+
+@defmac dotimes (var count [result]) forms@dots{}
This is a more specialized loop which iterates a specified number
of times. The body is executed with @var{var} bound to the integers
from zero (inclusive) to @var{count} (exclusive), in turn. Then
@@ -2231,9 +2231,9 @@
number of iterations that were done (i.e., @code{(max 0 @var{count})})
to get the return value for the loop form. The loop is surrounded
by an implicit @code{nil} block.
-@end deffn
-
-@deffn {Special Operator} do-symbols (var [obarray [result]]) forms@dots{}
+@end defmac
+
+@defmac do-symbols (var [obarray [result]]) forms@dots{}
This loop iterates over all interned symbols. If @var{obarray}
is specified and is not @code{nil}, it loops over all symbols in
that obarray. For each symbol, the body @var{forms} are evaluated
@@ -2241,12 +2241,12 @@
an unspecified order. Afterward the @var{result} form, if any,
is evaluated (with @var{var} bound to @code{nil}) to get the return
value. The loop is surrounded by an implicit @code{nil} block.
-@end deffn
-
-@deffn {Special Operator} do-all-symbols (var [result]) forms@dots{}
+@end defmac
+
+@defmac do-all-symbols (var [result]) forms@dots{}
This is identical to @code{do-symbols} except that the @var{obarray}
argument is omitted; it always iterates over the default obarray.
-@end deffn
+@end defmac
@xref{Mapping over Sequences}, for some more functions for
iterating over vectors or lists.
@@ -2286,7 +2286,7 @@
takes place at byte-compile time; compiled @code{loop}s are just
as efficient as the equivalent @code{while} loops written longhand.
-@deffn {Special Operator} loop clauses@dots{}
+@defmac loop clauses@dots{}
A loop construct consists of a series of @var{clause}s, each
introduced by a symbol like @code{for} or @code{do}. Clauses
are simply strung together in the argument list of @code{loop},
@@ -2325,7 +2325,7 @@
(Because the loop body is enclosed in an implicit block, you can
also use regular Lisp @code{return} or @code{return-from} to
break out of the loop.)
-@end deffn
+@end defmac
The following sections give some examples of the Loop Macro in
action, and describe the particular loop clauses in great detail.
@@ -3003,7 +3003,7 @@
Destructuring is made available to the user by way of the
following macro:
-@deffn {Special Operator} destructuring-bind arglist expr forms@dots{}
+@defmac destructuring-bind arglist expr forms@dots{}
This macro expands to code which executes @var{forms}, with
the variables in @var{arglist} bound to the list of values
returned by @var{expr}. The @var{arglist} can include all
@@ -3012,13 +3012,13 @@
is not allowed.) The macro expansion will signal an error
if @var{expr} returns a list of the wrong number of arguments
or with incorrect keyword arguments.
-@end deffn
+@end defmac
This package also includes the Common Lisp @code{define-compiler-macro}
facility, which allows you to define compile-time expansions and
optimizations for your functions.
-@deffn {Special Operator} define-compiler-macro name arglist forms@dots{}
+@defmac define-compiler-macro name arglist forms@dots{}
This form is similar to @code{defmacro}, except that it only expands
calls to @var{name} at compile-time; calls processed by the Lisp
interpreter are not expanded, nor are they expanded by the
@@ -3052,7 +3052,7 @@
@code{member*} call is left intact. (The actual compiler macro
for @code{member*} optimizes a number of other cases, including
common @code{:test} predicates.)
-@end deffn
+@end defmac
@defun compiler-macroexpand form
This function is analogous to @code{macroexpand}, except that it
@@ -3094,7 +3094,7 @@
is evaluated and thus should normally be quoted.
@end defun
-@deffn {Special Operator} declaim decl-specs@dots{}
+@defmac declaim decl-specs@dots{}
This macro is like @code{proclaim}, except that it takes any number
of @var{decl-spec} arguments, and the arguments are unevaluated and
unquoted. The @code{declaim} macro also puts an @code{(eval-when
@@ -3103,22 +3103,22 @@
since normally the declarations are meant to influence the way the
compiler treats the rest of the file that contains the @code{declaim}
form.)
-@end deffn
-
-@deffn {Special Operator} declare decl-specs@dots{}
+@end defmac
+
+@defmac declare decl-specs@dots{}
This macro is used to make declarations within functions and other
code. Common Lisp allows declarations in various locations, generally
at the beginning of any of the many ``implicit @code{progn}s''
throughout Lisp syntax, such as function bodies, @code{let} bodies,
etc. Currently the only declaration understood by @code{declare}
is @code{special}.
-@end deffn
-
-@deffn {Special Operator} locally declarations@dots{} forms@dots{}
+@end defmac
+
+@defmac locally declarations@dots{} forms@dots{}
In this package, @code{locally} is no different from @code{progn}.
-@end deffn
-
-@deffn {Special Operator} the type form
+@end defmac
+
+@defmac the type form
Type information provided by @code{the} is ignored in this package;
in other words, @code{(the @var{type} @var{form})} is equivalent
to @var{form}. Future versions of the optimizing byte-compiler may
@@ -3131,7 +3131,7 @@
compiler would have enough information to expand the loop in-line.
For now, Emacs Lisp will treat the above code as exactly equivalent
to @code{(mapcar 'car foo)}.
-@end deffn
+@end defmac
Each @var{decl-spec} in a @code{proclaim}, @code{declaim}, or
@code{declare} should be a list beginning with a symbol that says
@@ -3313,7 +3313,7 @@
expression.
@end defun
-@deffn {Special Operator} remf place property
+@defmac remf place property
This macro removes the property-value pair for @var{property} from
the property list stored at @var{place}, which is any @code{setf}-able
place expression. It returns true if the property was found. Note
@@ -3321,7 +3321,7 @@
effectively do a @code{(setf @var{place} (cddr @var{place}))},
whereas if it occurs later, this simply uses @code{setcdr} to splice
out the property and value cells.
-@end deffn
+@end defmac
@iftex
@secno=2
@@ -4677,7 +4677,7 @@
implements structures as vectors (or lists upon request) with a
special ``tag'' symbol to identify them.
-@deffn {Special Operator} defstruct name slots@dots{}
+@defmac defstruct name slots@dots{}
The @code{defstruct} form defines a new structure type called
@var{name}, with the specified @var{slots}. (The @var{slots}
may begin with a string which documents the structure type.)
@@ -4984,7 +4984,7 @@
specifies a number of slots to be skipped between the last slot
of the included type and the first new slot.
@end table
-@end deffn
+@end defmac
Except as noted, the @code{defstruct} facility of this package is
entirely compatible with that of Common Lisp.
@@ -5007,7 +5007,7 @@
away the following assertions. Because assertions might be optimized
away, it is a bad idea for them to include side-effects.
-@deffn {Special Operator} assert test-form [show-args string args@dots{}]
+@defmac assert test-form [show-args string args@dots{}]
This form verifies that @var{test-form} is true (i.e., evaluates to
a non-@code{nil} value). If so, it returns @code{nil}. If the test
is not satisfied, @code{assert} signals an error.
@@ -5030,9 +5030,9 @@
true Common Lisp, the second argument gives a list of @var{places}
which can be @code{setf}'d by the user before continuing from the
error.
-@end deffn
-
-@deffn {Special Operator} check-type place type &optional string
+@end defmac
+
+@defmac check-type place type &optional string
This form verifies that @var{place} evaluates to a value of type
@var{type}. If so, it returns @code{nil}. If not, @code{check-type}
signals a continuable @code{wrong-type-argument} error. The default
@@ -5051,18 +5051,18 @@
should be a @var{place} suitable for use by @code{setf}, because
@code{check-type} signals a continuable error that allows the user to
modify @var{place}, most simply by returning a value from the debugger.
-@end deffn
+@end defmac
The following error-related macro is also defined:
-@deffn {Special Operator} ignore-errors forms@dots{}
+@defmac ignore-errors forms@dots{}
This executes @var{forms} exactly like a @code{progn}, except that
errors are ignored during the @var{forms}. More precisely, if
an error is signalled then @code{ignore-errors} immediately
aborts execution of the @var{forms} and returns @code{nil}.
If the @var{forms} complete successfully, @code{ignore-errors}
returns the result of the last @var{form}.
-@end deffn
+@end defmac
@node Efficiency Concerns, Common Lisp Compatibility, Assertions, Top
@appendix Efficiency Concerns
diff -r d54278e74d71 -r a46c5c8d6564 man/lispref/compile.texi
--- a/man/lispref/compile.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/lispref/compile.texi Tue Aug 09 17:17:44 2011 +0100
@@ -691,7 +691,7 @@
These features permit you to write code to be evaluated during
compilation of a program.
-@deffn {Special Operator} eval-and-compile body
+@defmac eval-and-compile body
This form marks @var{body} to be evaluated both when you compile the
containing code and when you run it (whether compiled or not).
@@ -699,9 +699,9 @@
and referring to that file with @code{require}. Using @code{require} is
preferable if there is a substantial amount of code to be executed in
this way.
-@end deffn
+@end defmac
-@deffn {Special Operator} eval-when-compile body
+@defmac eval-when-compile body
This form marks @var{body} to be evaluated at compile time and not when
the compiled program is loaded. The result of evaluation by the
compiler becomes a constant which appears in the compiled program. When
@@ -712,7 +712,7 @@
@code{(eval-when (compile eval) @dots{})}. Elsewhere, the Common Lisp
@samp{#.} reader macro (but not when interpreting) is closer to what
@code{eval-when-compile} does.
-@end deffn
+@end defmac
@node Compiled-Function Objects
@section Compiled-Function Objects
diff -r d54278e74d71 -r a46c5c8d6564 man/lispref/eval.texi
--- a/man/lispref/eval.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/lispref/eval.texi Tue Aug 09 17:17:44 2011 +0100
@@ -743,21 +743,21 @@
values.
@end defun
-@deffn {Special Operator} multiple-value-bind (var@dots{}) values-form forms@dots{}
-This special operator evaluates @var{values-form}, which may return
+@defmac multiple-value-bind (var@dots{}) values-form forms@dots{}
+This macro evaluates @var{values-form}, which may return
multiple values. It then binds the @var{var}s to these respective values,
as if by @code{let}, and then executes the body @var{forms}.
If there are more @var{var}s than values, the extra @var{var}s
are bound to @code{nil}. If there are fewer @var{var}s than
values, the excess values are ignored.
-@end deffn
+@end defmac
-@deffn {Special Operator} multiple-value-setq (var@dots{}) form
-This special operator evaluates @var{form}, which may return multiple
+@defmac multiple-value-setq (var@dots{}) form
+This macro evaluates @var{form}, which may return multiple
values. It then sets the @var{var}s to these respective values, as if by
@code{setq}. Extra @var{var}s or values are treated the same as
in @code{multiple-value-bind}.
-@end deffn
+@end defmac
@deffn {Special Operator} multiple-value-call function forms@dots{}
This special operator evaluates function, discarding any multiple
@@ -767,10 +767,10 @@
infrastructure, treating multiple values as intercalated lists.
@end deffn
-@deffn {Special Operator} multiple-value-list form
-This special operator evaluates @var{form} and returns a list of the
+@defmac multiple-value-list form
+This macro evaluates @var{form} and returns a list of the
multiple values given by it.
-@end deffn
+@end defmac
@deffn {Special Operator} multiple-value-prog1 first body@dots{}
This special operator evaluates the form @var{first}, then the
@@ -779,12 +779,12 @@
@code{prog1} always discards multiple values.
@end deffn
-@deffn {Special Operator} nth-value n form
-This special operator evaluates @var{form} and returns the @var{n}th
+@defmac nth-value n form
+This macro evaluates @var{form} and returns the @var{n}th
value it gave. @var{n} must be an integer of value zero or more.
If @var{form} gave insufficient multiple values, @code{nth-value}
returns @code{nil}.
-@end deffn
+@end defmac
@defvar multiple-values-limit
This constant describes the exclusive upper bound on the number of
diff -r d54278e74d71 -r a46c5c8d6564 man/lispref/frames.texi
--- a/man/lispref/frames.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/lispref/frames.texi Tue Aug 09 17:17:44 2011 +0100
@@ -785,18 +785,18 @@
@code{focus-follows-mouse}.
@end defun
-@deffn {Special Operator} save-selected-frame forms@dots{}
-This special operator records the selected frame, executes @var{forms} in
+@defmac save-selected-frame forms@dots{}
+This macro records the selected frame, executes @var{forms} in
sequence, then restores the earlier selected frame. The value returned
is the value of the last form.
-@end deffn
+@end defmac
-@deffn {Special Operator} with-selected-frame frame forms@dots{}
-This special operator records the selected frame, then selects @var{frame}
+@defmac with-selected-frame frame forms@dots{}
+This macro records the selected frame, then selects @var{frame}
and executes @var{forms} in sequence. After the last form is finished,
the earlier selected frame is restored. The value returned is the value
of the last form.
-@end deffn
+@end defmac
@ignore (FSF Emacs, continued from defun select-frame)
XEmacs cooperates with the X server and the window managers by arranging
diff -r d54278e74d71 -r a46c5c8d6564 man/lispref/internationalization.texi
--- a/man/lispref/internationalization.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/lispref/internationalization.texi Tue Aug 09 17:17:44 2011 +0100
@@ -83,8 +83,8 @@
nothing.
@end defun
-@deffn {Special Operator} domain string
-This function specifies the text domain used for translating documentation
+@defmac domain string
+This macro specifies the text domain used for translating documentation
strings and interactive prompts of a function. For example, write:
@example
@@ -94,7 +94,7 @@
to specify @code{emacs-foo} as the text domain of the function @code{foo}.
The ``call'' to @code{domain} is actually a declaration rather than a
function; when actually called, @code{domain} just returns @code{nil}.
-@end deffn
+@end defmac
@defun domain-of function
This function returns the text domain of @var{function}; it returns
diff -r d54278e74d71 -r a46c5c8d6564 man/lispref/positions.texi
--- a/man/lispref/positions.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/lispref/positions.texi Tue Aug 09 17:17:44 2011 +0100
@@ -818,21 +818,21 @@
@code{save-current-buffer} is a primitive.
@end deffn
-@deffn {Special Operator} with-current-buffer buffer forms@dots{}
+@defmac with-current-buffer buffer forms@dots{}
This macro evaluates @var{forms} with @var{buffer} as the current
buffer. It returns the value of the last form.
-@end deffn
+@end defmac
-@deffn {Special Operator} with-temp-file filename forms@dots{}
+@defmac with-temp-file filename forms@dots{}
This macro creates a new buffer, evaluates @var{forms} there, and
writes the buffer to @var{filename}. It returns the value of the last form
evaluated.
-@end deffn
+@end defmac
-@deffn {Special Operator} save-selected-window forms@dots{}
+@defmac save-selected-window forms@dots{}
This macro is similar to @code{save-excursion} but it saves and
restores the selected window and nothing else.
-@end deffn
+@end defmac
@node Narrowing
@section Narrowing
diff -r d54278e74d71 -r a46c5c8d6564 man/lispref/searching.texi
--- a/man/lispref/searching.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/lispref/searching.texi Tue Aug 09 17:17:44 2011 +0100
@@ -1458,10 +1458,10 @@
You can save and restore the match data with @code{save-match-data}:
-@deffn {Special Operator} save-match-data body@dots{}
-This special operator executes @var{body}, saving and restoring the match
+@defmac save-match-data body@dots{}
+This macro executes @var{body}, saving and restoring the match
data around it.
-@end deffn
+@end defmac
Emacs automatically saves and restores the match data when it runs
process filter functions (@pxref{Filter Functions}) and process
diff -r d54278e74d71 -r a46c5c8d6564 man/lispref/specifiers.texi
--- a/man/lispref/specifiers.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/lispref/specifiers.texi Tue Aug 09 17:17:44 2011 +0100
@@ -875,7 +875,7 @@
@code{add-spec-list-to-specifier}.
@end defun
-@deffn {Special Operator} let-specifier specifier-list &rest body
+@defmac let-specifier specifier-list &rest body
This macro temporarily adds specifications to specifiers,
evaluates forms in @var{body} and restores the specifiers to their
previous states. The specifiers and their temporary specifications are
@@ -912,7 +912,7 @@
(let-specifier ((modeline-shadow-thickness 0 (selected-window)))
(sit-for 1))
@end example
-@end deffn
+@end defmac
@defun set-specifier specifier value &optional locale tag-set how-to-add
This function adds some specifications to @var{specifier}. @var{value}
diff -r d54278e74d71 -r a46c5c8d6564 man/lispref/windows.texi
--- a/man/lispref/windows.texi Mon Aug 08 23:10:47 2011 +0900
+++ b/man/lispref/windows.texi Tue Aug 09 17:17:44 2011 +0100
@@ -442,12 +442,12 @@
@end example
@end defun
-@deffn {Special Operator} save-selected-window forms@dots{}
+@defmac save-selected-window forms@dots{}
This macro records the selected window, executes @var{forms} in
sequence, then restores the earlier selected window. It does not save
or restore anything about the sizes, arrangement or contents of windows;
therefore, if the @var{forms} change them, the changes are permanent.
-@end deffn
+@end defmac
@cindex finding windows
The following functions choose one of the windows on the screen,
@@ -1969,7 +1969,7 @@
@end example
@end defun
-@deffn {Special Operator} save-window-excursion forms@dots{}
+@defmac save-window-excursion forms@dots{}
This macro records the window configuration, executes @var{forms}
in sequence, then restores the earlier window configuration. The window
configuration includes the value of point and the portion of the buffer
@@ -2005,7 +2005,7 @@
;; @r{The frame is now split again.}
@end group
@end example
-@end deffn
+@end defmac
@defun window-configuration-p object
This function returns @code{t} if @var{object} is a window configuration.
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
commit: Add some working with Mercurial stuff.
13 years, 4 months
Stephen J. Turnbull
changeset: 5546:d54278e74d71
tag: tip
user: Stephen J. Turnbull <stephen(a)xemacs.org>
date: Mon Aug 08 23:10:47 2011 +0900
files: man/ChangeLog man/internals/internals.texi
description:
Add some working with Mercurial stuff.
diff -r 69de75c48efa -r d54278e74d71 man/ChangeLog
--- a/man/ChangeLog Mon Aug 08 13:57:20 2011 +0900
+++ b/man/ChangeLog Mon Aug 08 23:10:47 2011 +0900
@@ -1,3 +1,13 @@
+2011-08-08 Stephen J. Turnbull <stephen(a)xemacs.org>
+
+ * internals/internals.texi (Mercurial Techniques): New.
+ (Mercurial Basics): New.
+ (Preserving Existing Changes with Mercurial Queues): New.
+ (Top): Update menus.
+ (Regression Testing XEmacs): Update node pointers.
+ (CVS Techniques): Update node pointers. Note obsolescence of CVS.
+ Add @ref to Mercurial Techniques.
+
2011-06-25 Aidan Kehoe <kehoea(a)parhasard.net>
* lispref/os.texi (Translating Input):
diff -r 69de75c48efa -r d54278e74d71 man/internals/internals.texi
--- a/man/internals/internals.texi Mon Aug 08 13:57:20 2011 +0900
+++ b/man/internals/internals.texi Mon Aug 08 23:10:47 2011 +0900
@@ -349,6 +349,7 @@
* The Build Configuration System::
* Rules When Writing New C Code::
* Regression Testing XEmacs::
+* Mercurial Techniques::
* CVS Techniques::
* XEmacs from the Inside::
* Basic Types::
@@ -442,6 +443,11 @@
* How to Regression-Test::
* Modules for Regression Testing::
+Mercurial Techniques
+
+* Mercurial Basics::
+* Preserving Existing Changes with Mercurial Queues::
+
CVS Techniques
* Creating a Branch::
@@ -6356,7 +6362,7 @@
configure --with-mule --use-union-type --error-checking=all
@end example
-@node Regression Testing XEmacs, CVS Techniques, Rules When Writing New C Code, Top
+@node Regression Testing XEmacs, Mercurial Techniques, Rules When Writing New C Code, Top
@chapter Regression Testing XEmacs
@cindex testing, regression
@@ -6621,10 +6627,246 @@
@code{Check-Message}. The other files are test files, testing various
XEmacs facilities. @xref{Regression Testing XEmacs}.
-@node CVS Techniques, XEmacs from the Inside, Regression Testing XEmacs, Top
+@node Mercurial Techniques, CVS Techniques, Regression Testing XEmacs, Top
+@chapter Mercurial Techniques
+@cindex Mercurial techniques
+
+@dfn{Mercurial} is the @emph{distributed version control system} used to
+manage the XEmacs core code. We plan to migrate the packages as well in
+the near future. The command used is @code{hg}; the entire system is
+implemented as subcommands of the @code{hg} command.
+
+@menu
+* Mercurial Basics::
+* Preserving Existing Changes with Mercurial Queues::
+@end menu
+
+@node Mercurial Basics, Preserving Existing Changes with Mercurial Queues, Mercurial Techniques, Mercurial Techniques
+
+@subheading Installing Mercurial
+
+Most people have some kind of package manager to help install free
+software. Invariably a reasonably fresh version of Mercurial is
+available. XEmacs doesn't do anything particularly tricky in its
+repositories, so unless you're one of those folks who likes to spend
+more time fiddling with your infrastructure than developing, the
+packaged Mercurial should be more than sufficient. Somewhat fresher
+versions may be available in prepackaged form from
+@uref{http://mercurial.selenic.com, the Mercurial Project}, if you like
+to stay on the leading edge.
+
+@subheading Documentation
+
+The primary online command for getting help on Mercurial is @code{hg
+help}.
+
+@subheading What is the XEmacs repository URL?
+
+For up-to-date information about this, other information about accessing
+the repository @strong{including making your first clone of the
+repository}, and availability of branches, please refer to our website,
+@uref{http://www.xemacs.org/Develop/hgaccess.html}.
+
+@subheading What's so special about ``distributed'' version control systems?
+
+Very little, for occasional contributors. So don't worry about it; the
+commands are you used to with CVS or Subversion will work pretty much as
+is. There are two important differences:
+
+@table @strong
+@item update
+In version control, @dfn{update} means to refresh the versions of files
+in your workspace. In a distributed system, however, there are two
+possible sources: the @dfn{project repository}, and your own @dfn{clone}
+(local repository) which is a more or less up-to-date copy of the
+project repository, including all the history information and historical
+revisions.
+
+@dfn{update} is taken to mean @emph{refresh from the clone}, and a new
+command @dfn{pull} is defined to mean @emph{copy history from the
+project repository to the clone}. Thus, to get new work from other
+contributors applied to your repository, you need to pull, then update.
+Normally the source for pull defaults to the project repository you
+cloned from, and the version to update to defaults to the @dfn{tip}
+(latest version in the clone), so in principle you can abbreviate to
+
+@example
+hg pull
+hg update
+@end example
+
+@noindent
+In fact, Mercurial allows a further abbreviation, to @code{hg pull -u}.
+
+@item commit
+The other direction is similar. The @dfn{commit} command refers to the
+@emph{clone}. A new command, @dfn{push} is used to copy local history
+to the project repository. Unlike the @code{pull} command, however,
+there is no very short way to say ``command @emph{and} push.''
+@end table
+
+@subheading Mercurial Extensions and .hgrc
+
+Third parties provide many extensions to Mercurial. (In fact, the
+Mercurial Project often distributes new functionality as extensions,
+until the UI has stabilized.) Extensions are just as easy to use as
+core commands, and well-written extensions provide their documentation
+via @code{hg help} just like the core. The main difference is that core
+commands are always available, but extensions must be enabled. This is
+done in the extensions section of @file{~/.hgrc}. Here's one of mine:
+
+@example
+[ui]
+username = Stephen J. Turnbull <stephen@(a)xemacs.org>
+ignore = ~/.hgglobalignore
+
+[extensions]
+hgext.hgk =
+hgext.mq =
+hgext.rebase =
+@end example
+
+All of the extensions mentioned above are distributed with Mercurial
+itself, so enabing them is particularly simple. A locally written or
+third-party extension would have a path-to-module after the equal sign.
+The first two extensions above are recommended for all contributors.
+Some contributors may like to use the rebase extension as well, and
+sometimes it's a good way to dig yourself out of a hole. Others hate
+it; if you are thinking about using it, you should be careful, and you
+should never @code{push} a rebased branch without coordinating with the
+project.
+
+@table @code
+@item hgk
+A browser for the history graph, showing relationships among versions.
+Provides the @code{view} command.
+
+@item mq
+@emph{Mercurial queues} are a way of managing sequences of patches,
+similar to the ``quilt'' program made famous by some Linux maintainers.
+It allows you to distinguish between your local changes and ``official''
+ones. Provides many commands beginning with the letter ``q''.
+
+@item rebase
+Rebasing is an alternative technique for managing sequences of patches.
+However, it uses branches rather than patches, and can produce a very
+confusing public history if used indiscriminately. Provides the
+@code{rebase} command.
+@end table
+
+
+@node Preserving Existing Changes with Mercurial Queues, , Mercurial Basics, Mercurial Techniques
+@section Preserving Existing Changes with Mercurial Queues
+@cindex preserving existing changes with mercurial queues
+@cindex mercurial queues, preserving existing changes with
+
+When first working with a distributed VCS, you may find yourself
+creating a series of unrelated changes in the workspace. Now you feel
+stuck: you worry that you if you commit now, you'll pull in unrelated
+changes. But Mercurial won't let you merge until you have committed?
+Here's how to use Mercurial queues to push ``just this fix'' without
+also pushing unrelated, uncommited changes also present in the
+workspace. This will also set you up for more effective workflow in the
+future.
+
+First, @emph{mq} is an extension, which must be enabled before use. Edit
+(a)file{$HOME/.hgrc} and add these two lines:
+
+@example
+[extensions]
+ hgext.mq =
+@end example
+
+@noindent
+If you already have an [extensions] section, omit the first line.
+
+Suppose the change that you are ready to push is a check for a valid
+drive letter on the Windows platform. It affects @file{src/nt.c}, and
+of course @file{src/ChangeLog}. Assume you have no other changes to these
+files. It is important to do this step now, before handling other
+changes! (In general, it's a good idea to create your @i{mq} patches in
+approximately the order you will submit them. There are ways to
+override that order, using ``guards,'' but that's a little tedious.
+Recent versions of Mercurial queues have an option to reorder patches
+when applying them: @samp{hg qpush --move @var{patch-name}}.)
+
+Initialize an @emph{mq} patch for this change:
+
+@example
+hg qnew -f -m "Check first whether drive is valid." valid-drive \
+ src/ChangeLog src/nt.c
+@end example
+
+@noindent
+View @file{.hg/patches/valid-drive} and make sure it is the patch you
+want to push.
+
+Now make patches for other changes. For a change to @file{foo.el},
+(a)file{foo-msw.el}, and @file{lisp/ChangeLog} it would look like
+
+@example
+hg qnew -f -m "Frob foo." frob-foo lisp/foo.el lisp/foo-msw.el \
+ lisp/ChangeLog
+@end example
+
+@noindent
+Do this until there are @emph{no} changes left (@kbd{hg status} reports
+no modified files).
+
+I strongly recommend that you do this @emph{now}. This is probably the
+best way to organize your work when you make many small changes.
+However, if you have overlapping changes that you can't easily sort out,
+or just don't feel like doing that, you can just
+
+@example
+hg qnew -f -m "DON'T COMMIT ME!" big-ball-of-mud
+@end example
+
+@noindent
+instead.
+
+Now let's commit the patch you want to push. If you feel paranoid, you
+can view all the patches in @file{.hg/patches} to make sure they look
+OK.
+
+@example
+hg qpop --all # unapply --all patches
+hg status # should report no modified files
+hg qpush # note, no argument needed
+hg qapplied # will report "valid-drive" because that was
+ # the first patch you created (it's a queue!!)
+hg qfinish --applied # convert valid-drive from a patch to a commit
+# Make sure it's OK.
+hg log -r tip # message you gave in 'qnew -m' is the
+ # log message
+@end example
+
+@noindent
+Update and push.
+
+@example
+hg pull -u # should work without complaint since you
+ # don't say you have any commits
+hg push # Yay!
+@end example
+
+That looks like a lot of work, but it's actually not too inconvenient.
+
+After this, whenever you have something that could turn into a
+commitable change, do "@kbd{hg qnew ...}". Make the @file{ChangeLog}
+right away (it can even just be a placeholder to fill in later). That
+allows you to isolate this change from other changes, even if they touch
+the same files.
+
+
+@node CVS Techniques, XEmacs from the Inside, Mercurial Techniques, Top
@chapter CVS Techniques
@cindex CVS techniques
+This section is obsolete for core XEmacs; we now use Mercurial
+@ref{Mercurial Techniques}. However these may be of some use for the
+packages, which are still in CVS for the moment.
+
@menu
* Creating a Branch::
* Merging a Branch into the Trunk::
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
[AC21.5] Some (basic) information on Mercurial for contributors
13 years, 4 months
Stephen J. Turnbull
APPROVE COMMIT 21.5
Here's some stuff I worked up quite a long time ago but never
committed. I'm not sure this stuff belongs in Internals, but better
there than nowhere.
Probably most people likely to contribute to XEmacs already know a bit
about Mercurial, but I've left the node "Mercurial Basics" in anyway.
Of more interest is the node "Preserving Existing Changes with
Mercurial Queues", which seems likely to be of use to new contributors
with multiple changes in their trees.
Suggestions for better organization welcome.
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches