with lisp system changes.
+2001-10-16 Ken Raeburn <raeburn@gnu.org>
+
+ Avoid the assumption that car and cdr slots of cons cells are
+ addressable lvalues; this allows for easier experimentation with
+ other lisp implementations that may not permit such accesses for
+ various reasons. Not quite complete -- buffer.c still needs some
+ work, and w32/mac files need rechecking -- so compile-time
+ enforcement is left disabled for now.
+
+ * lisp.h (LISP_MAKE_RVALUE): New macro, or function in the case of
+ gcc with a union-based Lisp object rep. Redefine as no-op for
+ now.
+ (XCAR_AS_LVALUE, XCDR_AS_LVALUE): Rename from old XCAR, XCDR.
+ (XCAR, XCDR): Apply LISP_MAKE_RVALUE to the _AS_LVALUE versions.
+ (XSETCAR, XSETCDR): New macros.
+ (XSETCARFASTINT, XSETCDRFASTINT): New macros.
+ (CHECK_NUMBER_CAR, CHECK_NUMBER_CDR): New macros.
+ * keyboard.h (POSN_BUFFER_SET_POSN): New macro.
+ * alloc.c (Fcons, pure_cons, Fgarbage_collect): Use XSETCAR and
+ XSETCDR.
+ (mark_buffer): Use XCAR_AS_LVALUE, XCDR_AS_LVALUE.
+ * buffer.c (record_buffer, Fbury_buffer,
+ swap_out_buffer_local_variables, recenter_overlay_lists,
+ Foverlay_put): Use XSETCAR and XSETCDR to set the car and cdr
+ fields of a cons cell respectively.
+ * callint.c (quotify_args, Fcall_interactively): Likewise.
+ * ccl.c (Fregister_code_conversion_map): Likewise.
+ * coding.c (detect_coding_system): Likewise.
+ * composite.c (get_composition_id, make_composition_value_copy):
+ Likewise.
+ * data.c (Fsetcar, Fsetcdr, swap_in_global_binding,
+ swap_in_symval_forwarding, set_internal, Fset_default,
+ Fmake_variable_buffer_local, Fmake_local_variable,
+ Fmake_variable_frame_local): Likewise.
+ * fns.c (concat, Fcopy_alist, Fwidget_put): Likewise.
+ * keymap.c (Fset_keymap_parent, store_in_keymap,
+ accessible_keymaps_1, where_is_internal_2, Fcopy_keymap):
+ Likewise.
+ * minibuf.c (get_minibuffer): Likewise.
+ * search.c (Fmatch_data): Likewise.
+ * textprop.c (extend_property_ranges): Likewise.
+ * undo.c (record_insert, Fundo_boundary, truncate_undo_list):
+ Likewise.
+ * w32fns.c (w32_msg_pump, Fw32_register_hot_key, w32_list_fonts):
+ Likewise.
+ * w32term.c (x_delete_display): Likewise.
+ * xfaces.c (remove_duplicates, Finternal_set_lisp_face_attribute):
+ Likewise.
+ * xterm.c (x_list_fonts, x_load_font, x_delete_display):
+ Likewise.
+ * doc.c (store_function_docstring): Use XSETCARFASTINT.
+ * fileio.c (Fdo_auto_save): Use XSETCARFASTINT and
+ XSETCDRFASTINT.
+ (Fread_file_name): Use XSETCAR.
+ * fontset.c (Fset_fontset_font): Use CHECK_NUMBER_CAR and
+ CHECK_NUMBER_CDR.
+ (accumulate_font_info, Ffontset_info): Use XSETCAR and XSETCDR.
+ * frame.c (Fmake_terminal_frame): Use XSETCDR.
+ * indent.c (Fcompute_motion): Use CHECK_NUMBER_CAR and
+ CHECK_NUMBER_CDR.
+ * keyboard.c (read_char): Alter list traversal to avoid taking the
+ address of cons cell slots. Use POSN_BUFFER_SET_POSN.
+ (parse_menu_item): Use XSETCAR and XSETCDR.
+ (reach_char_x_menu_prompt): Use XSETCAR.
+ (read_key_sequence): Use POSN_BUFFER_SET_POSN.
+ (Fcommand_execute): Use XSETCDR.
+ * lread.c (Fload): Use XSETCARFASTINT and XSETCDRFASTINT.
+ (openp): Change list traversal to avoid using XCAR as lvalue.
+ (read_list): Use XSETCDR.
+ * process.c (wait_reading_process_input): Change wait_for_cell
+ handling to avoid taking addresses of cons cell slots.
+ * xselect.c (x_own_selection, x_handle_selection_clear,
+ x_clear_frame_selections): Use XSETCDR.
+ (wait_for_property_change): Use XSETCARFASTINT and
+ XSETCDRFASTINT.
+ (x_handle_property_notify, x_get_foreign_selection,
+ x_handle_selection_notify): Use XSETCAR.
+
2001-10-15 Pavel Jan\e,Bm\e(Bk <Pavel@Janik.cz>
* buffer.c: Put doc strings in comments.
XSETCONS (val, &cons_block->conses[cons_block_index++]);
}
- XCAR (val) = car;
- XCDR (val) = cdr;
+ XSETCAR (val, car);
+ XSETCDR (val, cdr);
consing_since_gc += sizeof (struct Lisp_Cons);
cons_cells_consed++;
return val;
p = (struct Lisp_Cons *) pure_alloc (sizeof *p, Lisp_Cons);
XSETCONS (new, p);
- XCAR (new) = Fpurecopy (car);
- XCDR (new) = Fpurecopy (cdr);
+ XSETCAR (new, Fpurecopy (car));
+ XSETCDR (new, Fpurecopy (cdr));
return new;
}
if (NILP (prev))
nextb->undo_list = tail = XCDR (tail);
else
- tail = XCDR (prev) = XCDR (tail);
+ {
+ tail = XCDR (tail);
+ XSETCDR (prev, tail);
+ }
}
else
{
&& ! XMARKBIT (XCAR (ptr->car))
&& GC_MARKERP (XCAR (ptr->car)))
{
- XMARK (XCAR (ptr->car));
- mark_object (&XCDR (ptr->car));
+ XMARK (XCAR_AS_LVALUE (ptr->car));
+ mark_object (&XCDR_AS_LVALUE (ptr->car));
}
else
mark_object (&ptr->car);
break;
}
- mark_object (&XCDR (tail));
+ mark_object (&XCDR_AS_LVALUE (tail));
}
else
mark_object (&buffer->undo_list);
if (NILP (prev))
Vbuffer_alist = XCDR (Vbuffer_alist);
else
- XCDR (prev) = XCDR (XCDR (prev));
+ XSETCDR (prev, XCDR (XCDR (prev)));
- XCDR (link) = Vbuffer_alist;
+ XSETCDR (link, Vbuffer_alist);
Vbuffer_alist = link;
/* Now move this buffer to the front of frame_buffer_list also. */
set_frame_buffer_list (frame,
XCDR (frame_buffer_list (frame)));
else
- XCDR (prev) = XCDR (XCDR (prev));
+ XSETCDR (prev, XCDR (XCDR (prev)));
- XCDR (link) = frame_buffer_list (frame);
+ XSETCDR (link, frame_buffer_list (frame));
set_frame_buffer_list (frame, link);
}
else
aelt = Frassq (buffer, Vbuffer_alist);
link = Fmemq (aelt, Vbuffer_alist);
Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
- XCDR (link) = Qnil;
+ XSETCDR (link, Qnil);
Vbuffer_alist = nconc2 (Vbuffer_alist, link);
frames_bury_buffer (buffer);
it is currently set up for. This is so that, if the
local is marked permanent, and we make it local again
later in Fkill_all_local_variables, we don't lose the value. */
- XCDR (XCAR (tem))
- = do_symval_forwarding (XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->realvalue);
+ XSETCDR (XCAR (tem),
+ do_symval_forwarding (XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->realvalue));
/* Switch to the symbol's default-value alist entry. */
- XCAR (tem) = tem;
+ XSETCAR (tem, tem);
/* Mark it as current for buffer B. */
XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->buffer = buffer;
/* Store the current value into any forwarding in the symbol. */
/* Splice the cons cell TAIL out of overlays_before. */
if (!NILP (prev))
- XCDR (prev) = next;
+ XSETCDR (prev, next);
else
buf->overlays_before = next;
}
/* Add TAIL to overlays_after before OTHER. */
- XCDR (tail) = other;
+ XSETCDR (tail, other);
if (!NILP (other_prev))
- XCDR (other_prev) = tail;
+ XSETCDR (other_prev, tail);
else
buf->overlays_after = tail;
tail = prev;
/* Splice the cons cell TAIL out of overlays_after. */
if (!NILP (prev))
- XCDR (prev) = next;
+ XSETCDR (prev, next);
else
buf->overlays_after = next;
}
/* Add TAIL to overlays_before before OTHER. */
- XCDR (tail) = other;
+ XSETCDR (tail, other);
if (!NILP (other_prev))
- XCDR (other_prev) = tail;
+ XSETCDR (other_prev, tail);
else
buf->overlays_before = tail;
tail = prev;
if (EQ (XCAR (tail), prop))
{
changed = !EQ (XCAR (XCDR (tail)), value);
- XCAR (XCDR (tail)) = value;
+ XSETCAR (XCDR (tail), value);
goto found;
}
/* It wasn't in the list, so add it to the front. */
for (tail = exp; CONSP (tail); tail = next)
{
next = XCDR (tail);
- XCAR (tail) = quotify_arg (XCAR (tail));
+ XSETCAR (tail, quotify_arg (XCAR (tail)));
}
return exp;
}
{
teml = Fnthcdr (Vhistory_length, Vcommand_history);
if (CONSP (teml))
- XCDR (teml) = Qnil;
+ XSETCDR (teml, Qnil);
}
}
single_kboard_state ();
{
teml = Fnthcdr (Vhistory_length, Vcommand_history);
if (CONSP (teml))
- XCDR (teml) = Qnil;
+ XSETCDR (teml, Qnil);
}
}
if (EQ (symbol, XCAR (slot)))
{
index = make_number (i);
- XCDR (slot) = map;
+ XSETCDR (slot, map);
Fput (symbol, Qcode_conversion_map, map);
Fput (symbol, Qcode_conversion_map_id, index);
return index;
Lisp_Object eol;
eol = Fget (XCAR (tmp), Qeol_type);
if (VECTORP (eol))
- XCAR (tmp) = XVECTOR (eol)->contents[eol_type];
+ XSETCAR (tmp, XVECTOR (eol)->contents[eol_type]);
}
}
return (highest ? XCAR (val) : val);
modify the cons cell of PROP because it is not shared. */
key = HASH_KEY (hash_table, hash_index);
id = HASH_VALUE (hash_table, hash_index);
- XCAR (prop) = id;
- XCDR (prop) = Fcons (make_number (nchars), Fcons (key, XCDR (prop)));
+ XSETCAR (prop, id);
+ XSETCDR (prop, Fcons (make_number (nchars), Fcons (key, XCDR (prop))));
return XINT (id);
}
/* Change PROP from Form-A above to Form-B. We can directly modify
the cons cell of PROP because it is not shared. */
XSETFASTINT (id, n_compositions);
- XCAR (prop) = id;
- XCDR (prop) = Fcons (make_number (nchars), Fcons (key, XCDR (prop)));
+ XSETCAR (prop, id);
+ XSETCDR (prop, Fcons (make_number (nchars), Fcons (key, XCDR (prop))));
/* Register the composition in composition_hash_table. */
hash_index = hash_put (hash_table, key, id, hash_code);
{
if (EQ (XCAR (plist), Qcomposition)
&& (val = XCAR (XCDR (plist)), CONSP (val)))
- XCAR (XCDR (plist)) = Fcons (XCAR (val), XCDR (val));
+ XSETCAR (XCDR (plist), Fcons (XCAR (val), XCDR (val)));
plist = XCDR (XCDR (plist));
}
}
cell = wrong_type_argument (Qconsp, cell);
CHECK_IMPURE (cell);
- XCAR (cell) = newcar;
+ XSETCAR (cell, newcar);
return newcar;
}
cell = wrong_type_argument (Qconsp, cell);
CHECK_IMPURE (cell);
- XCDR (cell) = newcdr;
+ XSETCDR (cell, newcdr);
return newcdr;
}
\f
do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue));
/* Select the global binding in the symbol. */
- XCAR (cdr) = cdr;
+ XSETCAR (cdr, cdr);
store_symval_forwarding (symbol, valcontents, XCDR (cdr), NULL);
/* Indicate that the global binding is set up now. */
XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 1;
/* Load the new binding. */
- XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr) = tem1;
+ XSETCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr, tem1);
XSETBUFFER (XBUFFER_LOCAL_VALUE (valcontents)->buffer, current_buffer);
XBUFFER_LOCAL_VALUE (valcontents)->frame = selected_frame;
store_symval_forwarding (symbol,
}
/* Record which binding is now loaded. */
- XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr)
- = tem1;
+ XSETCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr,
+ tem1);
/* Set `buffer' and `frame' slots for thebinding now loaded. */
XSETBUFFER (XBUFFER_LOCAL_VALUE (valcontents)->buffer, buf);
the default binding is loaded, the loaded binding may be the
wrong one. */
if (XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame)
- XCDR (current_alist_element) = newval;
+ XSETCDR (current_alist_element, newval);
}
return newval;
return Fset (symbol, value);
/* Store new value into the DEFAULT-VALUE slot. */
- XCDR (XBUFFER_LOCAL_VALUE (valcontents)->cdr) = value;
+ XSETCDR (XBUFFER_LOCAL_VALUE (valcontents)->cdr, value);
/* If the default binding is now loaded, set the REALVALUE slot too. */
current_alist_element
if (EQ (valcontents, Qunbound))
SET_SYMBOL_VALUE (variable, Qnil);
tem = Fcons (Qnil, Fsymbol_value (variable));
- XCAR (tem) = tem;
+ XSETCAR (tem, tem);
newval = allocate_misc ();
XMISCTYPE (newval) = Lisp_Misc_Buffer_Local_Value;
XBUFFER_LOCAL_VALUE (newval)->realvalue = SYMBOL_VALUE (variable);
{
Lisp_Object newval;
tem = Fcons (Qnil, do_symval_forwarding (valcontents));
- XCAR (tem) = tem;
+ XSETCAR (tem, tem);
newval = allocate_misc ();
XMISCTYPE (newval) = Lisp_Misc_Some_Buffer_Local_Value;
XBUFFER_LOCAL_VALUE (newval)->realvalue = SYMBOL_VALUE (variable);
if (EQ (valcontents, Qunbound))
SET_SYMBOL_VALUE (variable, Qnil);
tem = Fcons (Qnil, Fsymbol_value (variable));
- XCAR (tem) = tem;
+ XSETCAR (tem, tem);
newval = allocate_misc ();
XMISCTYPE (newval) = Lisp_Misc_Some_Buffer_Local_Value;
XBUFFER_LOCAL_VALUE (newval)->realvalue = SYMBOL_VALUE (variable);
{
tem = Fcdr (Fcdr (fun));
if (CONSP (tem) && INTEGERP (XCAR (tem)))
- XSETFASTINT (XCAR (tem), offset);
+ XSETCARFASTINT (tem, offset);
}
else if (EQ (tem, Qmacro))
store_function_docstring (XCDR (fun), offset);
/* Arrange to close that file whether or not we get an error.
Also reset auto_saving to 0. */
lispstream = Fcons (Qnil, Qnil);
- XSETFASTINT (XCAR (lispstream), (EMACS_UINT)stream >> 16);
- XSETFASTINT (XCDR (lispstream), (EMACS_UINT)stream & 0xffff);
+ XSETCARFASTINT (lispstream, (EMACS_UINT)stream >> 16);
+ XSETCDRFASTINT (lispstream, (EMACS_UINT)stream & 0xffff);
}
else
lispstream = Qnil;
if (replace_in_history)
/* Replace what Fcompleting_read added to the history
with what we will actually return. */
- XCAR (Fsymbol_value (Qfile_name_history)) = double_dollars (val);
+ XSETCAR (Fsymbol_value (Qfile_name_history), double_dollars (val));
else if (add_to_history)
{
/* Add the value to the history--but not if it matches
/* Store this element into the result. */
if (toindex < 0)
{
- XCAR (tail) = elt;
+ XSETCAR (tail, elt);
prev = tail;
tail = XCDR (tail);
}
}
}
if (!NILP (prev))
- XCDR (prev) = last_tail;
+ XSETCDR (prev, last_tail);
if (num_textprops > 0)
{
car = XCAR (tem);
if (CONSP (car))
- XCAR (tem) = Fcons (XCAR (car), XCDR (car));
+ XSETCAR (tem, Fcons (XCAR (car), XCDR (car)));
}
return alist;
}
Lisp_Object widget, property, value;
{
CHECK_CONS (widget, 1);
- XCDR (widget) = Fplist_put (XCDR (widget), property, value);
+ XSETCDR (widget, Fplist_put (XCDR (widget), property, value));
return value;
}
{
/* CH should be (FROM . TO) where FROM and TO are non-generic
characters. */
- CHECK_NUMBER (XCAR (character), 1);
- CHECK_NUMBER (XCDR (character), 1);
+ CHECK_NUMBER_CAR (character, 1);
+ CHECK_NUMBER_CDR (character, 1);
from = XINT (XCAR (character));
to = XINT (XCDR (character));
if (!char_valid_p (from, 0) || !char_valid_p (to, 0))
{
if (this_charset == CHAR_CHARSET (XINT (XCAR (last_char))))
{
- XCDR (last_char) = character;
+ XSETCDR (last_char, character);
return;
}
}
return;
else if (this_charset == CHAR_CHARSET (XINT (last_char)))
{
- XCAR (XCAR (last)) = Fcons (last_char, character);
+ XSETCAR (XCAR (last), Fcons (last_char, character));
return;
}
}
- XCDR (last) = Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil);
- XCAR (arg) = XCDR (last);
+ XSETCDR (last, Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil));
+ XSETCAR (arg, XCDR (last));
}
c = XINT (XCAR (elt));
SPLIT_CHAR (c, charset, c1, c2);
if (c1 == 0)
- XCAR (elt) = CHARSET_SYMBOL (charset);
+ XSETCAR (elt, CHARSET_SYMBOL (charset));
}
else
c = XINT (XCAR (XCAR (elt)));
{
font = build_string (face->font_name);
if (NILP (Fmember (font, XCDR (XCDR (elt)))))
- XCDR (XCDR (elt)) = Fcons (font, XCDR (XCDR (elt)));
+ XSETCDR (XCDR (elt), Fcons (font, XCDR (XCDR (elt))));
}
}
}
the vectors which are the CDRs of associations in face_alist to
be copied as well. */
for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
- XCDR (XCAR (tem)) = Fcopy_sequence (XCDR (XCAR (tem)));
+ XSETCDR (XCAR (tem), Fcopy_sequence (XCDR (XCAR (tem))));
return frame;
}
CHECK_NUMBER_COERCE_MARKER (from, 0);
CHECK_CONS (frompos, 0);
- CHECK_NUMBER (XCAR (frompos), 0);
- CHECK_NUMBER (XCDR (frompos), 0);
+ CHECK_NUMBER_CAR (frompos, 0);
+ CHECK_NUMBER_CDR (frompos, 0);
CHECK_NUMBER_COERCE_MARKER (to, 0);
CHECK_CONS (topos, 0);
- CHECK_NUMBER (XCAR (topos), 0);
- CHECK_NUMBER (XCDR (topos), 0);
+ CHECK_NUMBER_CAR (topos, 0);
+ CHECK_NUMBER_CDR (topos, 0);
CHECK_NUMBER (width, 0);
if (!NILP (offsets))
{
CHECK_CONS (offsets, 0);
- CHECK_NUMBER (XCAR (offsets), 0);
- CHECK_NUMBER (XCDR (offsets), 0);
+ CHECK_NUMBER_CAR (offsets, 0);
+ CHECK_NUMBER_CDR (offsets, 0);
hscroll = XINT (XCAR (offsets));
tab_offset = XINT (XCDR (offsets));
}
KBOARD *kb = FRAME_KBOARD (XFRAME (selected_frame));
if (kb != current_kboard)
{
- Lisp_Object *tailp = &kb->kbd_queue;
+ Lisp_Object link = kb->kbd_queue;
/* We shouldn't get here if we were in single-kboard mode! */
if (single_kboard)
abort ();
- while (CONSP (*tailp))
- tailp = &XCDR (*tailp);
- if (!NILP (*tailp))
- abort ();
- *tailp = Fcons (c, Qnil);
+ if (CONSP (link))
+ {
+ while (CONSP (XCDR (link)))
+ link = XCDR (link);
+ if (!NILP (XCDR (link)))
+ abort ();
+ }
+ if (!CONSP (link))
+ kb->kbd_queue = Fcons (c, Qnil);
+ else
+ XSETCDR (link, Fcons (c, Qnil));
kb->kbd_queue_has_data = 1;
current_kboard = kb;
/* This is going to exit from read_char
#ifdef MULTI_KBOARD
if (! NILP (c) && (kb != current_kboard))
{
- Lisp_Object *tailp = &kb->kbd_queue;
- while (CONSP (*tailp))
- tailp = &XCDR (*tailp);
- if (!NILP (*tailp))
- abort ();
- *tailp = Fcons (c, Qnil);
+ Lisp_Object link = kb->kbd_queue;
+ if (CONSP (link))
+ {
+ while (CONSP (XCDR (link)))
+ link = XCDR (link);
+ if (!NILP (XCDR (link)))
+ abort ();
+ }
+ if (!CONSP (link))
+ kb->kbd_queue = Fcons (c, Qnil);
+ else
+ XSETCDR (link, Fcons (c, Qnil));
kb->kbd_queue_has_data = 1;
c = Qnil;
if (single_kboard)
if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar))
{
/* Change menu-bar to (menu-bar) as the event "position". */
- POSN_BUFFER_POSN (EVENT_START (c)) = Fcons (posn, Qnil);
+ POSN_BUFFER_SET_POSN (EVENT_START (c), Fcons (posn, Qnil));
also_record = c;
Vunread_command_events = Fcons (c, Vunread_command_events);
{
/* We have to create a cachelist. */
CHECK_IMPURE (start);
- XCDR (start) = Fcons (Fcons (Qnil, Qnil), XCDR (start));
+ XSETCDR (start, Fcons (Fcons (Qnil, Qnil), XCDR (start)));
cachelist = XCAR (XCDR (start));
newcache = 1;
tem = AREF (item_properties, ITEM_PROPERTY_KEYEQ);
if (!NILP (keyhint))
{
- XCAR (cachelist) = XCAR (keyhint);
+ XSETCAR (cachelist, XCAR (keyhint));
newcache = 0;
}
else if (STRINGP (tem))
{
- XCDR (cachelist) = Fsubstitute_command_keys (tem);
- XCAR (cachelist) = Qt;
+ XSETCDR (cachelist, Fsubstitute_command_keys (tem));
+ XSETCAR (cachelist, Qt);
}
}
&& ! NILP (Fget (def, Qmenu_alias)))
def = XSYMBOL (def)->function;
tem = Fwhere_is_internal (def, Qnil, Qt, Qnil);
- XCAR (cachelist) = tem;
+ XSETCAR (cachelist, tem);
if (NILP (tem))
{
- XCDR (cachelist) = Qnil;
+ XSETCDR (cachelist, Qnil);
chkcache = 0;
}
}
if (STRINGP (XCDR (prefix)))
tem = concat2 (tem, XCDR (prefix));
}
- XCDR (cachelist) = tem;
+ XSETCDR (cachelist, tem);
}
}
if (newcache && !NILP (tem))
{
tem = concat3 (build_string (" ("), tem, build_string (")"));
- XCDR (cachelist) = tem;
+ XSETCDR (cachelist, tem);
}
/* If we only want to precompute equivalent key bindings, stop here. */
record_menu_key (XCAR (tem));
if (SYMBOLP (XCAR (tem))
|| INTEGERP (XCAR (tem)))
- XCAR (tem) = Fcons (XCAR (tem), Qdisabled);
+ XSETCAR (tem, Fcons (XCAR (tem), Qdisabled));
}
/* If we got more than one event, put all but the first
/* Zap the position in key, so we know that we've
expanded it, and don't try to do so again. */
- POSN_BUFFER_POSN (EVENT_START (key))
- = Fcons (posn, Qnil);
+ POSN_BUFFER_SET_POSN (EVENT_START (key),
+ Fcons (posn, Qnil));
mock_input = t + 2;
goto replay_sequence;
{
tem = Fnthcdr (Vhistory_length, Vcommand_history);
if (CONSP (tem))
- XCDR (tem) = Qnil;
+ XSETCDR (tem, Qnil);
}
}
/* Extract the fields of a position. */
#define POSN_WINDOW(posn) (XCAR (posn))
#define POSN_BUFFER_POSN(posn) (XCAR (XCDR (posn)))
+#define POSN_BUFFER_SET_POSN(posn,x) (XSETCAR (XCDR (posn), (x)))
#define POSN_WINDOW_POSN(posn) (XCAR (XCDR (XCDR (posn))))
#define POSN_TIMESTAMP(posn) \
(XCAR (XCDR (XCDR (XCDR (posn)))))
if (EQ (XCDR (prev), parent))
RETURN_UNGCPRO (parent);
- XCDR (prev) = parent;
+ XSETCDR (prev, parent);
break;
}
prev = list;
{
if (EQ (idx, XCAR (elt)))
{
- XCDR (elt) = def;
+ XSETCDR (elt, def);
return def;
}
}
keymap_end:
/* We have scanned the entire keymap, and not found a binding for
IDX. Let's add one. */
- XCDR (insertion_point)
- = Fcons (Fcons (idx, def), XCDR (insertion_point));
+ XSETCDR (insertion_point,
+ Fcons (Fcons (idx, def), XCDR (insertion_point)));
}
return def;
Lisp_Object indices[3];
elt = Fcopy_sequence (elt);
- XCAR (tail) = elt;
+ XSETCAR (tail, elt);
map_char_table (copy_keymap_1, Qnil, elt, elt, 0, indices);
}
int i;
elt = Fcopy_sequence (elt);
- XCAR (tail) = elt;
+ XSETCAR (tail, elt);
for (i = 0; i < ASIZE (elt); i++)
if (CONSP (AREF (elt, i)) && EQ (XCAR (AREF (elt, i)), Qkeymap))
if (EQ (XCAR (tem),Qmenu_item))
{
/* Copy cell with menu-item marker. */
- XCDR (elt)
- = Fcons (XCAR (tem), XCDR (tem));
+ XSETCDR (elt,
+ Fcons (XCAR (tem), XCDR (tem)));
elt = XCDR (elt);
tem = XCDR (elt);
if (CONSP (tem))
{
/* Copy cell with menu-item name. */
- XCDR (elt)
- = Fcons (XCAR (tem), XCDR (tem));
+ XSETCDR (elt,
+ Fcons (XCAR (tem), XCDR (tem)));
elt = XCDR (elt);
tem = XCDR (elt);
};
{
/* Copy cell with binding and if the binding is a keymap,
copy that. */
- XCDR (elt)
- = Fcons (XCAR (tem), XCDR (tem));
+ XSETCDR (elt,
+ Fcons (XCAR (tem), XCDR (tem)));
elt = XCDR (elt);
tem = XCAR (elt);
if (CONSP (tem) && EQ (XCAR (tem), Qkeymap))
- XCAR (elt) = Fcopy_keymap (tem);
+ XSETCAR (elt, Fcopy_keymap (tem));
tem = XCDR (elt);
if (CONSP (tem) && CONSP (XCAR (tem)))
/* Delete cache for key equivalences. */
- XCDR (elt) = XCDR (tem);
+ XSETCDR (elt, XCDR (tem));
}
}
else
if (STRINGP (XCAR (tem)))
{
/* Copy the cell, since copy-alist didn't go this deep. */
- XCDR (elt)
- = Fcons (XCAR (tem), XCDR (tem));
+ XSETCDR (elt,
+ Fcons (XCAR (tem), XCDR (tem)));
elt = XCDR (elt);
tem = XCDR (elt);
/* Also skip the optional menu help string. */
if (CONSP (tem) && STRINGP (XCAR (tem)))
{
- XCDR (elt)
- = Fcons (XCAR (tem), XCDR (tem));
+ XSETCDR (elt,
+ Fcons (XCAR (tem), XCDR (tem)));
elt = XCDR (elt);
tem = XCDR (elt);
}
&& CONSP (XCAR (tem))
&& (NILP (XCAR (XCAR (tem)))
|| VECTORP (XCAR (XCAR (tem)))))
- XCDR (elt) = XCDR (tem);
+ XSETCDR (elt, XCDR (tem));
}
if (CONSP (elt)
&& CONSP (XCDR (elt))
&& EQ (XCAR (XCDR (elt)), Qkeymap))
- XCDR (elt) = Fcopy_keymap (XCDR (elt));
+ XSETCDR (elt, Fcopy_keymap (XCDR (elt)));
}
}
/* This new sequence is the same length as
thisseq, so stick it in the list right
after this one. */
- XCDR (tail)
- = Fcons (Fcons (tem, cmd), XCDR (tail));
+ XSETCDR (tail,
+ Fcons (Fcons (tem, cmd), XCDR (tail)));
}
else
{
this, last, nomenus, last_is_meta);
if (!NILP (sequence))
- XCDR (XCAR (args)) = Fcons (sequence, result);
+ XSETCDR (XCAR (args), Fcons (sequence, result));
UNGCPRO;
}
#endif /* WORDS_BIG_ENDIAN */
+#ifdef __GNUC__
+static __inline__ Lisp_Object
+LISP_MAKE_RVALUE (Lisp_Object o)
+{
+ return o;
+}
+#else
+#define LISP_MAKE_RVALUE(o) (o) /* XXX - keeps arg as rvalue. */
+#endif
+
#endif /* NO_UNION_TYPE */
#ifdef NO_UNION_TYPE
#define Lisp_Object EMACS_INT
+#define LISP_MAKE_RVALUE(o) (0+(o))
#endif /* NO_UNION_TYPE */
#ifndef VALMASK
};
/* Take the car or cdr of something known to be a cons cell. */
+/* The _AS_LVALUE macros shouldn't be used outside of the minimal set
+ of code that has to know what a cons cell looks like. Other code not
+ part of the basic lisp implementation should assume that the car and cdr
+ fields are not accessible as lvalues. (What if we want to switch to
+ a copying collector someday? Cached cons cell field addresses may be
+ invalidated at arbitrary points.) */
#ifdef HIDE_LISP_IMPLEMENTATION
-#define XCAR(c) (XCONS ((c))->car_)
-#define XCDR(c) (XCONS ((c))->cdr_)
+#define XCAR_AS_LVALUE(c) (XCONS ((c))->car_)
+#define XCDR_AS_LVALUE(c) (XCONS ((c))->cdr_)
#else
-#define XCAR(c) (XCONS ((c))->car)
-#define XCDR(c) (XCONS ((c))->cdr)
+#define XCAR_AS_LVALUE(c) (XCONS ((c))->car)
+#define XCDR_AS_LVALUE(c) (XCONS ((c))->cdr)
#endif
+/* Okay, we're not quite ready to turn this on yet. A few files still
+ need to be updated and tested. */
+#undef LISP_MAKE_RVALUE
+#define LISP_MAKE_RVALUE(x) (x)
+
+/* Use these from normal code. */
+#define XCAR(c) LISP_MAKE_RVALUE(XCAR_AS_LVALUE(c))
+#define XCDR(c) LISP_MAKE_RVALUE(XCDR_AS_LVALUE(c))
+
+/* Use these to set the fields of a cons cell.
+
+ Note that both arguments may refer to the same object, so 'n'
+ should not be read after 'c' is first modified. Also, neither
+ argument should be evaluated more than once; side effects are
+ especially common in the second argument. */
+#define XSETCAR(c,n) (XCAR_AS_LVALUE(c) = (n))
+#define XSETCDR(c,n) (XCDR_AS_LVALUE(c) = (n))
+
+/* For performance: Fast storage of positive integers into the
+ fields of a cons cell. See above caveats. */
+#define XSETCARFASTINT(c,n) XSETFASTINT(XCAR_AS_LVALUE(c),(n))
+#define XSETCDRFASTINT(c,n) XSETFASTINT(XCDR_AS_LVALUE(c),(n))
+
/* Take the car or cdr of something whose type is not known. */
#define CAR(c) \
(CONSP ((c)) ? XCAR ((c)) \
#define CHECK_OVERLAY(x, i) \
do { if (!OVERLAYP ((x))) x = wrong_type_argument (Qoverlayp, (x));} while (0)
+/* Since we can't assign directly to the CAR or CDR fields of a cons
+ cell, use these when checking that those fields contain numbers. */
+#define CHECK_NUMBER_CAR(x, i) \
+ do { \
+ Lisp_Object tmp = XCAR (x); \
+ CHECK_NUMBER (tmp, (i)); \
+ XSETCAR ((x), tmp); \
+ } while (0)
+
+#define CHECK_NUMBER_CDR(x, i) \
+ do { \
+ Lisp_Object tmp = XCDR (x); \
+ CHECK_NUMBER (tmp, (i)); \
+ XSETCDR ((x), tmp); \
+ } while (0)
+
/* Cast pointers to this type to compare them. Some machines want int. */
#ifndef PNTR_COMPARISON_TYPE
#define PNTR_COMPARISON_TYPE EMACS_UINT
GCPRO1 (file);
lispstream = Fcons (Qnil, Qnil);
- XSETFASTINT (XCAR (lispstream), (EMACS_UINT)stream >> 16);
- XSETFASTINT (XCDR (lispstream), (EMACS_UINT)stream & 0xffff);
+ XSETCARFASTINT (lispstream, (EMACS_UINT)stream >> 16);
+ XSETCDRFASTINT (lispstream, (EMACS_UINT)stream & 0xffff);
record_unwind_protect (load_unwind, lispstream);
record_unwind_protect (load_descriptor_unwind, load_descriptor_list);
specbind (Qload_file_name, found);
Lisp_Object string, tail;
int max_suffix_len = 0;
+ string = filename = Qnil;
+ GCPRO5 (str, string, filename, path, suffixes);
+
for (tail = suffixes; CONSP (tail); tail = XCDR (tail))
{
- CHECK_STRING (XCAR (tail), 0);
+ string = XCAR (tail);
+ CHECK_STRING (string, 0);
+ if (! EQ (string, XCAR (tail)))
+ XSETCAR (tail, string);
max_suffix_len = max (max_suffix_len,
- STRING_BYTES (XSTRING (XCAR (tail))));
+ STRING_BYTES (XSTRING (string)));
}
- string = filename = Qnil;
- GCPRO5 (str, string, filename, path, suffixes);
-
if (storeptr)
*storeptr = Qnil;
{
GCPRO2 (val, tail);
if (!NILP (tail))
- XCDR (tail) = read0 (readcharfun);
+ XSETCDR (tail, read0 (readcharfun));
else
val = read0 (readcharfun);
read1 (readcharfun, &ch, 0);
? pure_cons (elt, Qnil)
: Fcons (elt, Qnil));
if (!NILP (tail))
- XCDR (tail) = tem;
+ XSETCDR (tail, tem);
else
val = tem;
tail = tem;
enabled in it. */
Fbuffer_enable_undo (buf);
- XCAR (tail) = buf;
+ XSETCAR (tail, buf);
}
else
{
int wait_channel = -1;
struct Lisp_Process *wait_proc = 0;
int got_some_input = 0;
- Lisp_Object *wait_for_cell = 0;
+ /* Either nil or a cons cell, the car of which is of interest and
+ may be changed outside of this routine. */
+ Lisp_Object wait_for_cell = Qnil;
FD_ZERO (&Available);
/* If waiting for non-nil in a cell, record where. */
if (CONSP (read_kbd))
{
- wait_for_cell = &XCAR (read_kbd);
+ wait_for_cell = read_kbd;
XSETFASTINT (read_kbd, 0);
}
QUIT;
/* Exit now if the cell we're waiting for became non-nil. */
- if (wait_for_cell && ! NILP (*wait_for_cell))
+ if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
break;
/* Compute time from now till when time limit is up */
But not if wait_for_cell; in those cases,
the wait is supposed to be short,
and those callers cannot handle running arbitrary Lisp code here. */
- if (! wait_for_cell)
+ if (NILP (wait_for_cell))
{
EMACS_TIME timer_delay;
/* Wait till there is something to do */
- if (wait_for_cell)
+ if (!NILP (wait_for_cell))
Available = non_process_wait_mask;
else if (! XINT (read_kbd))
Available = non_keyboard_wait_mask;
}
/* Exit now if the cell we're waiting for became non-nil. */
- if (wait_for_cell && ! NILP (*wait_for_cell))
+ if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
break;
#ifdef SIGIO
/* If checking input just got us a size-change event from X,
obey it now if we should. */
- if (XINT (read_kbd) || wait_for_cell)
+ if (XINT (read_kbd) || ! NILP (wait_for_cell))
do_pending_window_change (0);
/* Check for data from a process. */
EMACS_TIME end_time, timeout;
SELECT_TYPE waitchannels;
int xerrno;
- Lisp_Object *wait_for_cell = 0;
+ /* Either nil or a cons cell, the car of which is of interest and
+ may be changed outside of this routine. */
+ Lisp_Object wait_for_cell = Qnil;
/* If waiting for non-nil in a cell, record where. */
if (CONSP (read_kbd))
{
- wait_for_cell = &XCAR (read_kbd);
+ wait_for_cell = read_kbd;
XSETFASTINT (read_kbd, 0);
}
QUIT;
/* Exit now if the cell we're waiting for became non-nil. */
- if (wait_for_cell && ! NILP (*wait_for_cell))
+ if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
break;
/* Compute time from now till when time limit is up */
run timer events directly.
(Callers that will immediately read keyboard events
call timer_delay on their own.) */
- if (! wait_for_cell)
+ if (NILP (wait_for_cell))
{
EMACS_TIME timer_delay;
/* Wait till there is something to do. */
- if (! XINT (read_kbd) && wait_for_cell == 0)
+ if (! XINT (read_kbd) && NILP (wait_for_cell))
FD_ZERO (&waitchannels);
else
FD_SET (0, &waitchannels);
input at all when wait_for_cell, but the code
has been this way since July 1994.
Try changing this after version 19.31.) */
- if (wait_for_cell
+ if (! NILP (wait_for_cell)
&& detect_input_pending ())
{
swallow_events (do_display);
}
/* Exit now if the cell we're waiting for became non-nil. */
- if (wait_for_cell && ! NILP (*wait_for_cell))
+ if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
break;
}
i++, tail = XCDR (tail))
{
if (i < 2 * len + 2)
- XCAR (tail) = data[i];
+ XSETCAR (tail, data[i]);
else
- XCAR (tail) = Qnil;
+ XSETCAR (tail, Qnil);
prev = tail;
}
/* If we couldn't fit all value elements into REUSE,
cons up the rest of them and add them to the end of REUSE. */
if (i < 2 * len + 2)
- XCDR (prev) = Flist (2 * len + 2 - i, data + i);
+ XSETCDR (prev, Flist (2 * len + 2 - i, data + i));
return reuse;
}
end = XCAR (XCDR (item));
if (EQ (end, old_end))
- XCAR (XCDR (item)) = new_end;
+ XSETCAR (XCDR (item), new_end);
}
}
&& INTEGERP (XCDR (elt))
&& XINT (XCDR (elt)) == beg)
{
- XSETINT (XCDR (elt), beg + length);
+ XSETCDR (elt, make_number (beg + length));
return;
}
}
{
/* If we have preallocated the cons cell to use here,
use that one. */
- XCDR (pending_boundary) = current_buffer->undo_list;
+ XSETCDR (pending_boundary, current_buffer->undo_list);
current_buffer->undo_list = pending_boundary;
pending_boundary = Qnil;
}
/* Truncate at the boundary where we decided to truncate. */
if (!NILP (last_boundary))
{
- XCDR (last_boundary) = Qnil;
+ XSETCDR (last_boundary, Qnil);
return list;
}
else
thread-safe. The next line is okay because the cons
cell is never made into garbage and is not relocated by
GC. */
- XCAR ((Lisp_Object) msg.lParam) = Qnil;
+ XSETCAR ((Lisp_Object) msg.lParam, Qnil);
if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
abort ();
break;
/* Make a list of the fonts we got back.
Store that in the font cache for the display. */
- XCDR (dpyinfo->name_list_element)
- = Fcons (Fcons (tpat, list),
- XCDR (dpyinfo->name_list_element));
+ XSETCDR (dpyinfo->name_list_element,
+ Fcons (Fcons (tpat, list),
+ XCDR (dpyinfo->name_list_element)));
label_cached:
if (NILP (list)) continue; /* Try the remaining alternatives. */
hdc = GetDC (dpyinfo->root_window);
oldobj = SelectObject (hdc, thisinfo.hfont);
if (GetTextMetrics (hdc, &thisinfo.tm))
- XCDR (tem) = make_number (FONT_WIDTH (&thisinfo));
+ XSETCDR (tem, make_number (FONT_WIDTH (&thisinfo)));
else
- XCDR (tem) = make_number (0);
+ XSETCDR (tem, make_number (0));
SelectObject (hdc, oldobj);
ReleaseDC (dpyinfo->root_window, hdc);
DeleteObject(thisinfo.hfont);
if (NILP (item))
w32_grabbed_keys = Fcons (key, w32_grabbed_keys);
else
- XCAR (item) = key;
+ XSETCAR (item, key);
/* Notify input thread about new hot-key definition, so that it
takes effect without needing to switch focus. */
{
if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
{
- XCDR (tail) = XCDR (XCDR (tail));
+ XSETCDR (tail, XCDR (XCDR (tail)));
break;
}
tail = XCDR (tail);
{
Lisp_Object next = XCDR (tail);
if (!NILP (Fequal (XCAR (next), XCAR (tail))))
- XCDR (tail) = XCDR (next);
+ XSETCDR (tail, XCDR (next));
else
tail = XCDR (tail);
}
{
Lisp_Object cons;
cons = XCAR (Vparam_value_alist);
- XCAR (cons) = param;
- XCDR (cons) = value;
+ XSETCAR (cons, param);
+ XSETCDR (cons, value);
Fmodify_frame_parameters (frame, Vparam_value_alist);
}
}
for (rest = Vselection_alist; !NILP (rest); rest = Fcdr (rest))
if (EQ (prev_value, Fcar (XCDR (rest))))
{
- XCDR (rest) = Fcdr (XCDR (rest));
+ XSETCDR (rest, Fcdr (XCDR (rest)));
break;
}
}
for (rest = Vselection_alist; !NILP (rest); rest = Fcdr (rest))
if (EQ (local_selection_data, Fcar (XCDR (rest))))
{
- XCDR (rest) = Fcdr (XCDR (rest));
+ XSETCDR (rest, Fcdr (XCDR (rest)));
break;
}
}
redisplay_preserve_echo_area (22);
#endif
}
- XCDR (rest) = Fcdr (XCDR (rest));
+ XSETCDR (rest, Fcdr (XCDR (rest)));
break;
}
}
Lisp_Object tem;
tem = Fcons (Qnil, Qnil);
- XSETFASTINT (XCAR (tem), (EMACS_UINT)location >> 16);
- XSETFASTINT (XCDR (tem), (EMACS_UINT)location & 0xffff);
+ XSETCARFASTINT (tem, (EMACS_UINT)location >> 16);
+ XSETCDRFASTINT (tem, (EMACS_UINT)location & 0xffff);
/* Make sure to do unexpect_property_change if we quit or err. */
record_unwind_protect (wait_for_property_change_unwind, tem);
- XCAR (property_change_reply) = Qnil;
+ XSETCAR (property_change_reply, Qnil);
property_change_reply_object = location;
/* If the event we are waiting for arrives beyond here, it will set
/* If this is the one wait_for_property_change is waiting for,
tell it to wake up. */
if (rest == property_change_reply_object)
- XCAR (property_change_reply) = Qt;
+ XSETCAR (property_change_reply, Qt);
if (prev)
prev->next = rest->next;
/* Prepare to block until the reply has been read. */
reading_selection_window = requestor_window;
reading_which_selection = selection_atom;
- XCAR (reading_selection_reply) = Qnil;
+ XSETCAR (reading_selection_reply, Qnil);
frame = some_frame_on_display (dpyinfo);
return;
TRACE0 ("Received SelectionNotify");
- XCAR (reading_selection_reply)
- = (event->property != 0 ? Qt : Qlambda);
+ XSETCAR (reading_selection_reply,
+ (event->property != 0 ? Qt : Qlambda));
}
\f
}
/* Now store the result in the cache. */
- XCDR (dpyinfo->name_list_element)
- = Fcons (Fcons (key, list), XCDR (dpyinfo->name_list_element));
+ XSETCDR (dpyinfo->name_list_element,
+ Fcons (Fcons (key, list), XCDR (dpyinfo->name_list_element)));
label_cached:
if (NILP (list)) continue; /* Try the remaining alternatives. */
if (thisinfo)
{
- XCDR (tem)
- = (thisinfo->min_bounds.width == 0
- ? make_number (0)
- : make_number (thisinfo->max_bounds.width));
+ XSETCDR (tem,
+ (thisinfo->min_bounds.width == 0
+ ? make_number (0)
+ : make_number (thisinfo->max_bounds.width)));
BLOCK_INPUT;
XFreeFont (dpy, thisinfo);
UNBLOCK_INPUT;
/* For unknown reason, the previous call of XListFont had
returned a font which can't be opened. Record the size
as 0 not to try to open it again. */
- XCDR (tem) = make_number (0);
+ XSETCDR (tem, make_number (0));
}
found_size = XINT (XCDR (tem));
Lisp_Object key = Fcons (Fcons (lispy_name, make_number (256)),
Qnil);
- XCDR (dpyinfo->name_list_element)
- = Fcons (Fcons (key,
- Fcons (Fcons (lispy_full_name,
- make_number (fontp->size)),
- Qnil)),
- XCDR (dpyinfo->name_list_element));
+ XSETCDR (dpyinfo->name_list_element,
+ Fcons (Fcons (key,
+ Fcons (Fcons (lispy_full_name,
+ make_number (fontp->size)),
+ Qnil)),
+ XCDR (dpyinfo->name_list_element)));
if (full_name)
{
key = Fcons (Fcons (lispy_full_name, make_number (256)),
Qnil);
- XCDR (dpyinfo->name_list_element)
- = Fcons (Fcons (key,
- Fcons (Fcons (lispy_full_name,
- make_number (fontp->size)),
- Qnil)),
- XCDR (dpyinfo->name_list_element));
+ XSETCDR (dpyinfo->name_list_element,
+ Fcons (Fcons (key,
+ Fcons (Fcons (lispy_full_name,
+ make_number (fontp->size)),
+ Qnil)),
+ XCDR (dpyinfo->name_list_element)));
}
}
{
if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
{
- XCDR (tail) = XCDR (XCDR (tail));
+ XSETCDR (tail, XCDR (XCDR (tail)));
break;
}
tail = XCDR (tail);