Add 2012 to FSF copyright years for Emacs files
[bpt/emacs.git] / src / buffer.h
index 65c7168..3df4a95 100644 (file)
@@ -1,6 +1,6 @@
 /* Header file for the buffer manipulation primitives.
 
-Copyright (C) 1985-1986, 1993-1995, 1997-2011
+Copyright (C) 1985-1986, 1993-1995, 1997-2012
                  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -18,6 +18,7 @@ GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#include <sys/types.h> /* for off_t, time_t */
 
 /* Accessing the parameters of the current buffer.  */
 
@@ -107,27 +108,46 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #define BUF_BEG(buf) (BEG)
 #define BUF_BEG_BYTE(buf) (BEG_BYTE)
 
-/* !!!FIXME:  all the BUF_BEGV/BUF_ZV/BUF_PT macros are flawed:
-   on indirect (or base) buffers, that value is only correct if that buffer
-   is the current_buffer, or if the buffer's text hasn't been modified (via
-   an indirect buffer) since it was last current.  */
+/* The BUF_BEGV[_BYTE], BUF_ZV[_BYTE], and BUF_PT[_BYTE] macros cannot
+   be used for assignment; use SET_BUF_* macros below for that.  */
 
 /* Position of beginning of accessible range of buffer.  */
-#define BUF_BEGV(buf) ((buf)->begv)
-#define BUF_BEGV_BYTE(buf) ((buf)->begv_byte)
+#define BUF_BEGV(buf)                                  \
+   (buf == current_buffer ? BEGV                       \
+    : NILP (BVAR (buf, begv_marker)) ? buf->begv       \
+    : marker_position (BVAR (buf, begv_marker)))
+
+#define BUF_BEGV_BYTE(buf)                             \
+   (buf == current_buffer ? BEGV_BYTE                  \
+    : NILP (BVAR (buf, begv_marker)) ? buf->begv_byte  \
+    : marker_byte_position (BVAR (buf, begv_marker)))
 
 /* Position of point in buffer.  */
-#define BUF_PT(buf) ((buf)->pt)
-#define BUF_PT_BYTE(buf) ((buf)->pt_byte)
+#define BUF_PT(buf)                                    \
+   (buf == current_buffer ? PT                         \
+    : NILP (BVAR (buf, pt_marker)) ? buf->pt           \
+    : marker_position (BVAR (buf, pt_marker)))
+
+#define BUF_PT_BYTE(buf)                               \
+   (buf == current_buffer ? PT_BYTE                    \
+    : NILP (BVAR (buf, pt_marker)) ? buf->pt_byte      \
+    : marker_byte_position (BVAR (buf, pt_marker)))
+
+/* Position of end of accessible range of buffer.  */
+#define BUF_ZV(buf)                                    \
+   (buf == current_buffer ? ZV                         \
+    : NILP (BVAR (buf, zv_marker)) ? buf->zv           \
+    : marker_position (BVAR (buf, zv_marker)))
+
+#define BUF_ZV_BYTE(buf)                               \
+   (buf == current_buffer ? ZV_BYTE                    \
+    : NILP (BVAR (buf, zv_marker)) ? buf->zv_byte      \
+    : marker_byte_position (BVAR (buf, zv_marker)))
 
 /* Position of gap in buffer.  */
 #define BUF_GPT(buf) ((buf)->text->gpt)
 #define BUF_GPT_BYTE(buf) ((buf)->text->gpt_byte)
 
-/* Position of end of accessible range of buffer.  */
-#define BUF_ZV(buf) ((buf)->zv)
-#define BUF_ZV_BYTE(buf) ((buf)->zv_byte)
-
 /* Position of end of buffer.  */
 #define BUF_Z(buf) ((buf)->text->z)
 #define BUF_Z_BYTE(buf) ((buf)->text->z_byte)
@@ -235,8 +255,6 @@ extern void enlarge_buffer_text (struct buffer *, EMACS_INT);
 \f
 /* Macros for setting the BEGV, ZV or PT of a given buffer.
 
-   SET_BUF_PT* seet to be redundant.  Get rid of them?
-
    The ..._BOTH macros take both a charpos and a bytepos,
    which must correspond to each other.
 
@@ -289,6 +307,13 @@ do                                                         \
   }                                                            \
 while (0)
 
+/* Maximum number of bytes in a buffer.
+   A buffer cannot contain more bytes than a 1-origin fixnum can represent,
+   nor can it be so large that C pointer arithmetic stops working.
+   The ptrdiff_t cast ensures that this is signed, not unsigned.  */
+#define BUF_BYTES_MAX \
+  (ptrdiff_t) min (MOST_POSITIVE_FIXNUM - 1, min (SIZE_MAX, PTRDIFF_MAX))
+
 /* Return the address of byte position N in current buffer.  */
 
 #define BYTE_POS_ADDR(n) \
@@ -315,7 +340,7 @@ while (0)
 
 #define PTR_BYTE_POS(ptr) \
 ((ptr) - (current_buffer)->text->beg                                       \
- - (ptr - (current_buffer)->text->beg <= (unsigned) (GPT_BYTE - BEG_BYTE) ? 0 : GAP_SIZE) \
+ - (ptr - (current_buffer)->text->beg <= GPT_BYTE - BEG_BYTE ? 0 : GAP_SIZE) \
  + BEG_BYTE)
 
 /* Return character at byte position POS.  */
@@ -374,7 +399,7 @@ extern unsigned char *_fetch_multibyte_char_p;
 
 #define BUF_PTR_BYTE_POS(buf, ptr)                             \
 ((ptr) - (buf)->text->beg                                      \
- - (ptr - (buf)->text->beg <= (unsigned) (BUF_GPT_BYTE ((buf)) - BEG_BYTE)\
+ - (ptr - (buf)->text->beg <= BUF_GPT_BYTE (buf) - BEG_BYTE    \
     ? 0 : BUF_GAP_SIZE ((buf)))                                        \
  + BEG_BYTE)
 
@@ -482,14 +507,13 @@ struct buffer
 
      Check out mark_buffer (alloc.c) to see why.  */
 
-  EMACS_UINT size;
-
-  /* Next buffer, in chain of all buffers including killed buffers.
+  /* HEADER.NEXT is the next buffer, in chain of all buffers,
+     including killed buffers.
      This chain is used only for garbage collection, in order to
      collect killed buffers properly.
      Note that vectors and most pseudovectors are all on one chain,
      but buffers are on a separate chain of their own.  */
-  struct buffer *next;
+  struct vectorlike_header header;
 
   /* This structure holds the coordinates of the buffer contents
      in ordinary buffers.  In indirect buffers, this is not used.  */
@@ -529,21 +553,21 @@ struct buffer
      -1 means visited file was nonexistent.
      0 means visited file modtime unknown; in no case complain
      about any mismatch on next save attempt.  */
-  int modtime;
+  time_t modtime;
   /* Size of the file when modtime was set.  This is used to detect the
      case where the file grew while we were reading it, so the modtime
      is still the same (since it's rounded up to seconds) but we're actually
      not up-to-date.  -1 means the size is unknown.  Only meaningful if
      modtime is actually set.  */
-  EMACS_INT modtime_size;
+  off_t modtime_size;
   /* The value of text->modiff at the last auto-save.  */
   int auto_save_modified;
   /* The value of text->modiff at the last display error.
      Redisplay of this buffer is inhibited until it changes again.  */
   int display_error_modiff;
   /* The time at which we detected a failure to auto-save,
-     Or -1 if we didn't have a failure.  */
-  int auto_save_failure_time;
+     Or 0 if we didn't have a failure.  */
+  time_t auto_save_failure_time;
   /* Position in buffer at which display started
      the last time this buffer was displayed.  */
   EMACS_INT last_window_start;
@@ -588,6 +612,7 @@ struct buffer
   /* Everything from here down must be a Lisp_Object.  */
   /* buffer-local Lisp variables start at `undo_list',
      tho only the ones from `name' on are GC'd normally.  */
+  #define FIRST_FIELD_PER_BUFFER undo_list
 
   /* Changes in the buffer are recorded here for undo.
      t means don't record anything.
@@ -822,6 +847,9 @@ struct buffer
      t means to use hollow box cursor.
      See `cursor-type' for other values.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (cursor_in_non_selected_windows);
+
+  /* This must be the last field in the above list.  */
+  #define LAST_FIELD_PER_BUFFER cursor_in_non_selected_windows
 };
 
 \f
@@ -863,10 +891,10 @@ extern struct buffer buffer_local_symbols;
 extern void delete_all_overlays (struct buffer *);
 extern void reset_buffer (struct buffer *);
 extern void evaporate_overlays (EMACS_INT);
-extern int overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr,
-                        int *len_ptr, EMACS_INT *next_ptr,
-                        EMACS_INT *prev_ptr, int change_req);
-extern int sort_overlays (Lisp_Object *, int, struct window *);
+extern ptrdiff_t overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr,
+                             ptrdiff_t *len_ptr, EMACS_INT *next_ptr,
+                             EMACS_INT *prev_ptr, int change_req);
+extern ptrdiff_t sort_overlays (Lisp_Object *, ptrdiff_t, struct window *);
 extern void recenter_overlay_lists (struct buffer *, EMACS_INT);
 extern EMACS_INT overlay_strings (EMACS_INT, struct window *, unsigned char **);
 extern void validate_region (Lisp_Object *, Lisp_Object *);
@@ -884,7 +912,7 @@ extern void mmap_set_vars (int);
 
 #define GET_OVERLAYS_AT(posn, overlays, noverlays, nextp, chrq)                \
   do {                                                                 \
-    int maxlen = 40;                                                   \
+    ptrdiff_t maxlen = 40;                                                     \
     overlays = (Lisp_Object *) alloca (maxlen * sizeof (Lisp_Object)); \
     noverlays = overlays_at (posn, 0, &overlays, &maxlen,              \
                             nextp, NULL, chrq);                                \
@@ -900,7 +928,6 @@ extern void mmap_set_vars (int);
 EXFUN (Fbuffer_live_p, 1);
 EXFUN (Fbuffer_name, 1);
 EXFUN (Fnext_overlay_change, 1);
-EXFUN (Fdelete_overlay, 1);
 EXFUN (Fbuffer_local_value, 2);
 
 extern Lisp_Object Qbefore_change_functions;
@@ -951,7 +978,7 @@ extern int last_per_buffer_idx;
    variable has an index > 0 associated with it, except when it always
    has buffer-local values, in which case the index is -1.  If this is
    0, this is a bug and means that the slot of VAR in
-   buffer_local_flags wasn't intiialized.  */
+   buffer_local_flags wasn't initialized.  */
 
 #define PER_BUFFER_VAR_IDX(VAR) \
     PER_BUFFER_IDX (PER_BUFFER_VAR_OFFSET (VAR))
@@ -1009,4 +1036,31 @@ extern int last_per_buffer_idx;
 
 #define PER_BUFFER_VALUE(BUFFER, OFFSET) \
       (*(Lisp_Object *)((OFFSET) + (char *) (BUFFER)))
+\f
+/* Downcase a character C, or make no change if that cannot be done.  */
+static inline int
+downcase (int c)
+{
+  Lisp_Object downcase_table = BVAR (current_buffer, downcase_table);
+  Lisp_Object down = CHAR_TABLE_REF (downcase_table, c);
+  return NATNUMP (down) ? XFASTINT (down) : c;
+}
+
+/* 1 if C is upper case.  */
+static inline int uppercasep (int c) { return downcase (c) != c; }
+
+/* Upcase a character C known to be not upper case.  */
+static inline int
+upcase1 (int c)
+{
+  Lisp_Object upcase_table = BVAR (current_buffer, upcase_table);
+  Lisp_Object up = CHAR_TABLE_REF (upcase_table, c);
+  return NATNUMP (up) ? XFASTINT (up) : c;
+}
+
+/* 1 if C is lower case.  */
+static inline int lowercasep (int c)
+{ return !uppercasep (c) && upcase1 (c) != c; }
 
+/* Upcase a character C, or make no change if that cannot be done.  */
+static inline int upcase (int c) { return uppercasep (c) ? c : upcase1 (c); }