diff options
Diffstat (limited to 'src/buffer.c')
| -rw-r--r-- | src/buffer.c | 205 |
1 files changed, 92 insertions, 113 deletions
diff --git a/src/buffer.c b/src/buffer.c index 0759ce1c43c..9932c649044 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -78,9 +78,6 @@ static Lisp_Object Vbuffer_defaults; | |||
| 78 | be a DEFVAR_PER_BUFFER for the slot, there is no default value for it; | 78 | be a DEFVAR_PER_BUFFER for the slot, there is no default value for it; |
| 79 | and the corresponding slot in buffer_defaults is not used. | 79 | and the corresponding slot in buffer_defaults is not used. |
| 80 | 80 | ||
| 81 | If a slot is -2, then there is no DEFVAR_PER_BUFFER for it, | ||
| 82 | but there is a default value which is copied into each buffer. | ||
| 83 | |||
| 84 | If a slot in this structure corresponding to a DEFVAR_PER_BUFFER is | 81 | If a slot in this structure corresponding to a DEFVAR_PER_BUFFER is |
| 85 | zero, that is a bug */ | 82 | zero, that is a bug */ |
| 86 | 83 | ||
| @@ -94,6 +91,12 @@ DECL_ALIGN (struct buffer, buffer_local_symbols); | |||
| 94 | /* A Lisp_Object pointer to the above, used for staticpro */ | 91 | /* A Lisp_Object pointer to the above, used for staticpro */ |
| 95 | static Lisp_Object Vbuffer_local_symbols; | 92 | static Lisp_Object Vbuffer_local_symbols; |
| 96 | 93 | ||
| 94 | /* Return the symbol of the per-buffer variable at offset OFFSET in | ||
| 95 | the buffer structure. */ | ||
| 96 | |||
| 97 | #define PER_BUFFER_SYMBOL(OFFSET) \ | ||
| 98 | (*(Lisp_Object *)((OFFSET) + (char *) &buffer_local_symbols)) | ||
| 99 | |||
| 97 | /* Flags indicating which built-in buffer-local variables | 100 | /* Flags indicating which built-in buffer-local variables |
| 98 | are permanent locals. */ | 101 | are permanent locals. */ |
| 99 | static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS]; | 102 | static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS]; |
| @@ -507,7 +510,7 @@ clone_per_buffer_values (from, to) | |||
| 507 | continue; | 510 | continue; |
| 508 | 511 | ||
| 509 | obj = PER_BUFFER_VALUE (from, offset); | 512 | obj = PER_BUFFER_VALUE (from, offset); |
| 510 | if (MARKERP (obj)) | 513 | if (MARKERP (obj) && XMARKER (obj)->buffer == from) |
| 511 | { | 514 | { |
| 512 | struct Lisp_Marker *m = XMARKER (obj); | 515 | struct Lisp_Marker *m = XMARKER (obj); |
| 513 | obj = Fmake_marker (); | 516 | obj = Fmake_marker (); |
| @@ -770,9 +773,7 @@ reset_buffer_local_variables (b, permanent_too) | |||
| 770 | { | 773 | { |
| 771 | Lisp_Object tmp, prop, last = Qnil; | 774 | Lisp_Object tmp, prop, last = Qnil; |
| 772 | for (tmp = b->local_var_alist; CONSP (tmp); tmp = XCDR (tmp)) | 775 | for (tmp = b->local_var_alist; CONSP (tmp); tmp = XCDR (tmp)) |
| 773 | if (CONSP (XCAR (tmp)) | 776 | if (!NILP (prop = Fget (XCAR (XCAR (tmp)), Qpermanent_local))) |
| 774 | && SYMBOLP (XCAR (XCAR (tmp))) | ||
| 775 | && !NILP (prop = Fget (XCAR (XCAR (tmp)), Qpermanent_local))) | ||
| 776 | { | 777 | { |
| 777 | /* If permanent-local, keep it. */ | 778 | /* If permanent-local, keep it. */ |
| 778 | last = tmp; | 779 | last = tmp; |
| @@ -822,9 +823,7 @@ reset_buffer_local_variables (b, permanent_too) | |||
| 822 | int idx = PER_BUFFER_IDX (offset); | 823 | int idx = PER_BUFFER_IDX (offset); |
| 823 | if ((idx > 0 | 824 | if ((idx > 0 |
| 824 | && (permanent_too | 825 | && (permanent_too |
| 825 | || buffer_permanent_local_flags[idx] == 0)) | 826 | || buffer_permanent_local_flags[idx] == 0))) |
| 826 | /* Is -2 used anywhere? */ | ||
| 827 | || idx == -2) | ||
| 828 | PER_BUFFER_VALUE (b, offset) = PER_BUFFER_DEFAULT (offset); | 827 | PER_BUFFER_VALUE (b, offset) = PER_BUFFER_DEFAULT (offset); |
| 829 | } | 828 | } |
| 830 | } | 829 | } |
| @@ -938,59 +937,49 @@ is the default binding of the variable. */) | |||
| 938 | CHECK_SYMBOL (variable); | 937 | CHECK_SYMBOL (variable); |
| 939 | CHECK_BUFFER (buffer); | 938 | CHECK_BUFFER (buffer); |
| 940 | buf = XBUFFER (buffer); | 939 | buf = XBUFFER (buffer); |
| 940 | sym = XSYMBOL (variable); | ||
| 941 | 941 | ||
| 942 | sym = indirect_variable (XSYMBOL (variable)); | 942 | start: |
| 943 | XSETSYMBOL (variable, sym); | 943 | switch (sym->redirect) |
| 944 | |||
| 945 | /* Look in local_var_list */ | ||
| 946 | result = Fassoc (variable, buf->local_var_alist); | ||
| 947 | if (NILP (result)) | ||
| 948 | { | ||
| 949 | int offset, idx; | ||
| 950 | int found = 0; | ||
| 951 | |||
| 952 | /* Look in special slots */ | ||
| 953 | /* buffer-local Lisp variables start at `undo_list', | ||
| 954 | tho only the ones from `name' on are GC'd normally. */ | ||
| 955 | for (offset = PER_BUFFER_VAR_OFFSET (undo_list); | ||
| 956 | offset < sizeof (struct buffer); | ||
| 957 | /* sizeof EMACS_INT == sizeof Lisp_Object */ | ||
| 958 | offset += (sizeof (EMACS_INT))) | ||
| 959 | { | ||
| 960 | idx = PER_BUFFER_IDX (offset); | ||
| 961 | if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx)) | ||
| 962 | && SYMBOLP (PER_BUFFER_SYMBOL (offset)) | ||
| 963 | && EQ (PER_BUFFER_SYMBOL (offset), variable)) | ||
| 964 | { | ||
| 965 | result = PER_BUFFER_VALUE (buf, offset); | ||
| 966 | found = 1; | ||
| 967 | break; | ||
| 968 | } | ||
| 969 | } | ||
| 970 | |||
| 971 | if (!found) | ||
| 972 | result = Fdefault_value (variable); | ||
| 973 | } | ||
| 974 | else | ||
| 975 | { | 944 | { |
| 976 | Lisp_Object valcontents; | 945 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; |
| 977 | Lisp_Object current_alist_element; | 946 | case SYMBOL_PLAINVAL: result = SYMBOL_VAL (sym); break; |
| 978 | 947 | case SYMBOL_LOCALIZED: | |
| 979 | /* What binding is loaded right now? */ | 948 | { /* Look in local_var_alist. */ |
| 980 | valcontents = sym->value; | 949 | struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); |
| 981 | current_alist_element | 950 | XSETSYMBOL (variable, sym); /* Update In case of aliasing. */ |
| 982 | = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr); | 951 | result = Fassoc (variable, buf->local_var_alist); |
| 983 | 952 | if (!NILP (result)) | |
| 984 | /* The value of the currently loaded binding is not | 953 | { |
| 985 | stored in it, but rather in the realvalue slot. | 954 | if (blv->fwd) |
| 986 | Store that value into the binding it belongs to | 955 | { /* What binding is loaded right now? */ |
| 987 | in case that is the one we are about to use. */ | 956 | Lisp_Object current_alist_element = blv->valcell; |
| 988 | 957 | ||
| 989 | Fsetcdr (current_alist_element, | 958 | /* The value of the currently loaded binding is not |
| 990 | do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue)); | 959 | stored in it, but rather in the realvalue slot. |
| 960 | Store that value into the binding it belongs to | ||
| 961 | in case that is the one we are about to use. */ | ||
| 991 | 962 | ||
| 992 | /* Now get the (perhaps updated) value out of the binding. */ | 963 | XSETCDR (current_alist_element, |
| 993 | result = XCDR (result); | 964 | do_symval_forwarding (blv->fwd)); |
| 965 | } | ||
| 966 | /* Now get the (perhaps updated) value out of the binding. */ | ||
| 967 | result = XCDR (result); | ||
| 968 | } | ||
| 969 | else | ||
| 970 | result = Fdefault_value (variable); | ||
| 971 | break; | ||
| 972 | } | ||
| 973 | case SYMBOL_FORWARDED: | ||
| 974 | { | ||
| 975 | union Lisp_Fwd *fwd = SYMBOL_FWD (sym); | ||
| 976 | if (BUFFER_OBJFWDP (fwd)) | ||
| 977 | result = PER_BUFFER_VALUE (buf, XBUFFER_OBJFWD (fwd)->offset); | ||
| 978 | else | ||
| 979 | result = Fdefault_value (variable); | ||
| 980 | break; | ||
| 981 | } | ||
| 982 | default: abort (); | ||
| 994 | } | 983 | } |
| 995 | 984 | ||
| 996 | if (!EQ (result, Qunbound)) | 985 | if (!EQ (result, Qunbound)) |
| @@ -1025,12 +1014,7 @@ buffer_lisp_local_variables (buf) | |||
| 1025 | if (buf != current_buffer) | 1014 | if (buf != current_buffer) |
| 1026 | val = XCDR (elt); | 1015 | val = XCDR (elt); |
| 1027 | 1016 | ||
| 1028 | /* If symbol is unbound, put just the symbol in the list. */ | 1017 | result = Fcons (Fcons (XCAR (elt), val), result); |
| 1029 | if (EQ (val, Qunbound)) | ||
| 1030 | result = Fcons (XCAR (elt), result); | ||
| 1031 | /* Otherwise, put (symbol . value) in the list. */ | ||
| 1032 | else | ||
| 1033 | result = Fcons (Fcons (XCAR (elt), val), result); | ||
| 1034 | } | 1018 | } |
| 1035 | 1019 | ||
| 1036 | return result; | 1020 | return result; |
| @@ -1862,8 +1846,7 @@ set_buffer_internal_1 (b) | |||
| 1862 | register struct buffer *b; | 1846 | register struct buffer *b; |
| 1863 | { | 1847 | { |
| 1864 | register struct buffer *old_buf; | 1848 | register struct buffer *old_buf; |
| 1865 | register Lisp_Object tail, valcontents; | 1849 | register Lisp_Object tail; |
| 1866 | Lisp_Object tem; | ||
| 1867 | 1850 | ||
| 1868 | #ifdef USE_MMAP_FOR_BUFFERS | 1851 | #ifdef USE_MMAP_FOR_BUFFERS |
| 1869 | if (b->text->beg == NULL) | 1852 | if (b->text->beg == NULL) |
| @@ -1935,34 +1918,21 @@ set_buffer_internal_1 (b) | |||
| 1935 | /* Look down buffer's list of local Lisp variables | 1918 | /* Look down buffer's list of local Lisp variables |
| 1936 | to find and update any that forward into C variables. */ | 1919 | to find and update any that forward into C variables. */ |
| 1937 | 1920 | ||
| 1938 | for (tail = b->local_var_alist; CONSP (tail); tail = XCDR (tail)) | 1921 | do |
| 1939 | { | 1922 | { |
| 1940 | if (CONSP (XCAR (tail)) | 1923 | for (tail = b->local_var_alist; CONSP (tail); tail = XCDR (tail)) |
| 1941 | && SYMBOLP (XCAR (XCAR (tail))) | 1924 | { |
| 1942 | && (valcontents = SYMBOL_VALUE (XCAR (XCAR (tail))), | 1925 | Lisp_Object var = XCAR (XCAR (tail)); |
| 1943 | (BUFFER_LOCAL_VALUEP (valcontents))) | 1926 | struct Lisp_Symbol *sym = XSYMBOL (var); |
| 1944 | && (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue, | 1927 | if (sym->redirect == SYMBOL_LOCALIZED /* Just to be sure. */ |
| 1945 | (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem)))) | 1928 | && SYMBOL_BLV (sym)->fwd) |
| 1946 | /* Just reference the variable to cause it to become set for | 1929 | /* Just reference the variable |
| 1947 | this buffer. */ | 1930 | to cause it to become set for this buffer. */ |
| 1948 | Fsymbol_value (XCAR (XCAR (tail))); | 1931 | Fsymbol_value (var); |
| 1932 | } | ||
| 1949 | } | 1933 | } |
| 1950 | |||
| 1951 | /* Do the same with any others that were local to the previous buffer */ | 1934 | /* Do the same with any others that were local to the previous buffer */ |
| 1952 | 1935 | while (b != old_buf && (b = old_buf, b)); | |
| 1953 | if (old_buf) | ||
| 1954 | for (tail = old_buf->local_var_alist; CONSP (tail); tail = XCDR (tail)) | ||
| 1955 | { | ||
| 1956 | if (CONSP (tail) | ||
| 1957 | && SYMBOLP (XCAR (XCAR (tail))) | ||
| 1958 | && (valcontents = SYMBOL_VALUE (XCAR (XCAR (tail))), | ||
| 1959 | (BUFFER_LOCAL_VALUEP (valcontents))) | ||
| 1960 | && (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue, | ||
| 1961 | (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem)))) | ||
| 1962 | /* Just reference the variable to cause it to become set for | ||
| 1963 | this buffer. */ | ||
| 1964 | Fsymbol_value (XCAR (XCAR (tail))); | ||
| 1965 | } | ||
| 1966 | } | 1936 | } |
| 1967 | 1937 | ||
| 1968 | /* Switch to buffer B temporarily for redisplay purposes. | 1938 | /* Switch to buffer B temporarily for redisplay purposes. |
| @@ -2677,23 +2647,22 @@ static void | |||
| 2677 | swap_out_buffer_local_variables (b) | 2647 | swap_out_buffer_local_variables (b) |
| 2678 | struct buffer *b; | 2648 | struct buffer *b; |
| 2679 | { | 2649 | { |
| 2680 | Lisp_Object oalist, alist, sym, buffer; | 2650 | Lisp_Object oalist, alist, buffer; |
| 2681 | 2651 | ||
| 2682 | XSETBUFFER (buffer, b); | 2652 | XSETBUFFER (buffer, b); |
| 2683 | oalist = b->local_var_alist; | 2653 | oalist = b->local_var_alist; |
| 2684 | 2654 | ||
| 2685 | for (alist = oalist; CONSP (alist); alist = XCDR (alist)) | 2655 | for (alist = oalist; CONSP (alist); alist = XCDR (alist)) |
| 2686 | { | 2656 | { |
| 2687 | if (CONSP (XCAR (alist)) | 2657 | Lisp_Object sym = XCAR (XCAR (alist)); |
| 2688 | && (sym = XCAR (XCAR (alist)), SYMBOLP (sym)) | 2658 | eassert (XSYMBOL (sym)->redirect == SYMBOL_LOCALIZED); |
| 2689 | /* Need not do anything if some other buffer's binding is | 2659 | /* Need not do anything if some other buffer's binding is |
| 2690 | now encached. */ | 2660 | now encached. */ |
| 2691 | && EQ (XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->buffer, | 2661 | if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer)) |
| 2692 | buffer)) | ||
| 2693 | { | 2662 | { |
| 2694 | /* Symbol is set up for this buffer's old local value: | 2663 | /* Symbol is set up for this buffer's old local value: |
| 2695 | swap it out! */ | 2664 | swap it out! */ |
| 2696 | swap_in_global_binding (sym); | 2665 | swap_in_global_binding (XSYMBOL (sym)); |
| 2697 | } | 2666 | } |
| 2698 | } | 2667 | } |
| 2699 | } | 2668 | } |
| @@ -5162,7 +5131,9 @@ init_buffer_once () | |||
| 5162 | /* Make sure all markable slots in buffer_defaults | 5131 | /* Make sure all markable slots in buffer_defaults |
| 5163 | are initialized reasonably, so mark_buffer won't choke. */ | 5132 | are initialized reasonably, so mark_buffer won't choke. */ |
| 5164 | reset_buffer (&buffer_defaults); | 5133 | reset_buffer (&buffer_defaults); |
| 5134 | eassert (EQ (buffer_defaults.name, make_number (0))); | ||
| 5165 | reset_buffer_local_variables (&buffer_defaults, 1); | 5135 | reset_buffer_local_variables (&buffer_defaults, 1); |
| 5136 | eassert (EQ (buffer_local_symbols.name, make_number (0))); | ||
| 5166 | reset_buffer (&buffer_local_symbols); | 5137 | reset_buffer (&buffer_local_symbols); |
| 5167 | reset_buffer_local_variables (&buffer_local_symbols, 1); | 5138 | reset_buffer_local_variables (&buffer_local_symbols, 1); |
| 5168 | /* Prevent GC from getting confused. */ | 5139 | /* Prevent GC from getting confused. */ |
| @@ -5421,33 +5392,41 @@ init_buffer () | |||
| 5421 | in the buffer that is current now. */ | 5392 | in the buffer that is current now. */ |
| 5422 | 5393 | ||
| 5423 | /* TYPE is nil for a general Lisp variable. | 5394 | /* TYPE is nil for a general Lisp variable. |
| 5424 | An integer specifies a type; then only LIsp values | 5395 | An integer specifies a type; then only Lisp values |
| 5425 | with that type code are allowed (except that nil is allowed too). | 5396 | with that type code are allowed (except that nil is allowed too). |
| 5426 | LNAME is the LIsp-level variable name. | 5397 | LNAME is the Lisp-level variable name. |
| 5427 | VNAME is the name of the buffer slot. | 5398 | VNAME is the name of the buffer slot. |
| 5428 | DOC is a dummy where you write the doc string as a comment. */ | 5399 | DOC is a dummy where you write the doc string as a comment. */ |
| 5429 | #define DEFVAR_PER_BUFFER(lname, vname, type, doc) \ | 5400 | #define DEFVAR_PER_BUFFER(lname, vname, type, doc) \ |
| 5430 | defvar_per_buffer (lname, vname, type, 0) | 5401 | do { \ |
| 5402 | static struct Lisp_Buffer_Objfwd bo_fwd; \ | ||
| 5403 | defvar_per_buffer (&bo_fwd, lname, vname, type, 0); \ | ||
| 5404 | } while (0) | ||
| 5431 | 5405 | ||
| 5432 | static void | 5406 | static void |
| 5433 | defvar_per_buffer (namestring, address, type, doc) | 5407 | defvar_per_buffer (bo_fwd, namestring, address, type, doc) |
| 5408 | struct Lisp_Buffer_Objfwd *bo_fwd; | ||
| 5434 | char *namestring; | 5409 | char *namestring; |
| 5435 | Lisp_Object *address; | 5410 | Lisp_Object *address; |
| 5436 | Lisp_Object type; | 5411 | Lisp_Object type; |
| 5437 | char *doc; | 5412 | char *doc; |
| 5438 | { | 5413 | { |
| 5439 | Lisp_Object sym, val; | 5414 | struct Lisp_Symbol *sym; |
| 5440 | int offset; | 5415 | int offset; |
| 5441 | 5416 | ||
| 5442 | sym = intern (namestring); | 5417 | sym = XSYMBOL (intern (namestring)); |
| 5443 | val = allocate_misc (); | ||
| 5444 | offset = (char *)address - (char *)current_buffer; | 5418 | offset = (char *)address - (char *)current_buffer; |
| 5445 | 5419 | ||
| 5446 | XMISCTYPE (val) = Lisp_Misc_Buffer_Objfwd; | 5420 | bo_fwd->type = Lisp_Fwd_Buffer_Obj; |
| 5447 | XBUFFER_OBJFWD (val)->offset = offset; | 5421 | bo_fwd->offset = offset; |
| 5448 | XBUFFER_OBJFWD (val)->slottype = type; | 5422 | bo_fwd->slottype = type; |
| 5449 | SET_SYMBOL_VALUE (sym, val); | 5423 | sym->redirect = SYMBOL_FORWARDED; |
| 5450 | PER_BUFFER_SYMBOL (offset) = sym; | 5424 | { |
| 5425 | /* I tried to do the job without a cast, but it seems impossible. | ||
| 5426 | union Lisp_Fwd *fwd; &(fwd->u_buffer_objfwd) = bo_fwd; */ | ||
| 5427 | SET_SYMBOL_FWD (sym, (union Lisp_Fwd *)bo_fwd); | ||
| 5428 | } | ||
| 5429 | XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym); | ||
| 5451 | 5430 | ||
| 5452 | if (PER_BUFFER_IDX (offset) == 0) | 5431 | if (PER_BUFFER_IDX (offset) == 0) |
| 5453 | /* Did a DEFVAR_PER_BUFFER without initializing the corresponding | 5432 | /* Did a DEFVAR_PER_BUFFER without initializing the corresponding |