diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/buffer.c | 234 |
1 files changed, 86 insertions, 148 deletions
diff --git a/src/buffer.c b/src/buffer.c index c5a58429ef3..129fee7c095 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -1954,6 +1954,24 @@ struct sortstr | |||
| 1954 | int priority; | 1954 | int priority; |
| 1955 | }; | 1955 | }; |
| 1956 | 1956 | ||
| 1957 | struct sortstrlist | ||
| 1958 | { | ||
| 1959 | struct sortstr *buf; /* An array that expands as needed; never freed. */ | ||
| 1960 | int size; /* Allocated length of that array. */ | ||
| 1961 | int used; /* How much of the array is currently in use. */ | ||
| 1962 | int bytes; /* Total length of the strings in buf. */ | ||
| 1963 | }; | ||
| 1964 | |||
| 1965 | /* Buffers for storing information about the overlays touching a given | ||
| 1966 | position. These could be automatic variables in overlay_strings, but | ||
| 1967 | it's more efficient to hold onto the memory instead of repeatedly | ||
| 1968 | allocating and freeing it. */ | ||
| 1969 | static struct sortstrlist overlay_heads, overlay_tails; | ||
| 1970 | static char *overlay_str_buf; | ||
| 1971 | |||
| 1972 | /* Allocated length of overlay_str_buf. */ | ||
| 1973 | static int overlay_str_len; | ||
| 1974 | |||
| 1957 | /* A comparison function suitable for passing to qsort. */ | 1975 | /* A comparison function suitable for passing to qsort. */ |
| 1958 | static int | 1976 | static int |
| 1959 | cmp_for_strings (as1, as2) | 1977 | cmp_for_strings (as1, as2) |
| @@ -1968,13 +1986,28 @@ cmp_for_strings (as1, as2) | |||
| 1968 | return 0; | 1986 | return 0; |
| 1969 | } | 1987 | } |
| 1970 | 1988 | ||
| 1971 | /* Buffers for storing the overlays touching a given position. | 1989 | static void |
| 1972 | These are expanded as needed, but never freed. */ | 1990 | record_overlay_string (ssl, str, pri, size) |
| 1973 | static struct sortstr *overlay_heads, *overlay_tails; | 1991 | struct sortstrlist *ssl; |
| 1974 | static char *overlay_str_buf; | 1992 | Lisp_Object str; |
| 1975 | 1993 | Lisp_Object pri; | |
| 1976 | /* Allocated length of those buffers. */ | 1994 | int size; |
| 1977 | static int overlay_heads_len, overlay_tails_len, overlay_str_len; | 1995 | { |
| 1996 | if (ssl->used == ssl->size) | ||
| 1997 | { | ||
| 1998 | if (ssl->buf) | ||
| 1999 | ssl->size *= 2; | ||
| 2000 | else | ||
| 2001 | ssl->size = 5; | ||
| 2002 | ssl->buf = ((struct sortstr *) | ||
| 2003 | xrealloc (ssl->buf, ssl->size * sizeof (struct sortstr))); | ||
| 2004 | } | ||
| 2005 | ssl->buf[ssl->used].string = str; | ||
| 2006 | ssl->buf[ssl->used].size = size; | ||
| 2007 | ssl->buf[ssl->used].priority = (INTEGERP (pri) ? XINT (pri) : 0); | ||
| 2008 | ssl->used++; | ||
| 2009 | ssl->bytes += XSTRING (str)->size; | ||
| 2010 | } | ||
| 1978 | 2011 | ||
| 1979 | /* Return the concatenation of the strings associated with overlays that | 2012 | /* Return the concatenation of the strings associated with overlays that |
| 1980 | begin or end at POS, ignoring overlays that are specific to a window | 2013 | begin or end at POS, ignoring overlays that are specific to a window |
| @@ -1989,11 +2022,11 @@ overlay_strings (pos, w, pstr) | |||
| 1989 | struct window *w; | 2022 | struct window *w; |
| 1990 | char **pstr; | 2023 | char **pstr; |
| 1991 | { | 2024 | { |
| 1992 | Lisp_Object ov, overlay, window, str, tem; | 2025 | Lisp_Object ov, overlay, window, str; |
| 1993 | int ntail = 0, nhead = 0; | ||
| 1994 | int total = 0; | ||
| 1995 | int startpos, endpos; | 2026 | int startpos, endpos; |
| 1996 | 2027 | ||
| 2028 | overlay_heads.used = overlay_heads.bytes = 0; | ||
| 2029 | overlay_tails.used = overlay_tails.bytes = 0; | ||
| 1997 | for (ov = current_buffer->overlays_before; CONSP (ov); ov = XCONS (ov)->cdr) | 2030 | for (ov = current_buffer->overlays_before; CONSP (ov); ov = XCONS (ov)->cdr) |
| 1998 | { | 2031 | { |
| 1999 | overlay = XCONS (ov)->car; | 2032 | overlay = XCONS (ov)->car; |
| @@ -2009,66 +2042,16 @@ overlay_strings (pos, w, pstr) | |||
| 2009 | window = Foverlay_get (overlay, Qwindow); | 2042 | window = Foverlay_get (overlay, Qwindow); |
| 2010 | if (WINDOWP (window) && XWINDOW (window) != w) | 2043 | if (WINDOWP (window) && XWINDOW (window) != w) |
| 2011 | continue; | 2044 | continue; |
| 2012 | if (endpos == pos) | 2045 | if (endpos == pos |
| 2013 | { | 2046 | && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))) |
| 2014 | str = Foverlay_get (overlay, Qafter_string); | 2047 | record_overlay_string (&overlay_tails, str, |
| 2015 | if (STRINGP (str)) | 2048 | Foverlay_get (overlay, Qpriority), |
| 2016 | { | 2049 | endpos - startpos); |
| 2017 | if (ntail == overlay_tails_len) | 2050 | if (startpos == pos |
| 2018 | { | 2051 | && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) |
| 2019 | if (! overlay_tails) | 2052 | record_overlay_string (&overlay_heads, str, |
| 2020 | { | 2053 | Foverlay_get (overlay, Qpriority), |
| 2021 | overlay_tails_len = 5; | 2054 | endpos - startpos); |
| 2022 | overlay_tails = ((struct sortstr *) | ||
| 2023 | xmalloc (5 * sizeof (struct sortstr))); | ||
| 2024 | } | ||
| 2025 | else | ||
| 2026 | { | ||
| 2027 | overlay_tails_len *= 2; | ||
| 2028 | overlay_tails = ((struct sortstr *) | ||
| 2029 | xrealloc (overlay_tails, | ||
| 2030 | (overlay_tails_len | ||
| 2031 | * sizeof (struct sortstr)))); | ||
| 2032 | } | ||
| 2033 | } | ||
| 2034 | overlay_tails[ntail].string = str; | ||
| 2035 | overlay_tails[ntail].size = endpos - startpos; | ||
| 2036 | tem = Foverlay_get (overlay, Qpriority); | ||
| 2037 | overlay_tails[ntail].priority = (INTEGERP (tem) ? XINT (tem) : 0); | ||
| 2038 | ntail++; | ||
| 2039 | total += XSTRING (str)->size; | ||
| 2040 | } | ||
| 2041 | } | ||
| 2042 | if (startpos == pos) | ||
| 2043 | { | ||
| 2044 | str = Foverlay_get (overlay, Qbefore_string); | ||
| 2045 | if (STRINGP (str)) | ||
| 2046 | { | ||
| 2047 | if (nhead == overlay_heads_len) | ||
| 2048 | { | ||
| 2049 | if (! overlay_heads) | ||
| 2050 | { | ||
| 2051 | overlay_heads_len = 5; | ||
| 2052 | overlay_heads = ((struct sortstr *) | ||
| 2053 | xmalloc (5 * sizeof (struct sortstr))); | ||
| 2054 | } | ||
| 2055 | else | ||
| 2056 | { | ||
| 2057 | overlay_heads_len *= 2; | ||
| 2058 | overlay_heads = ((struct sortstr *) | ||
| 2059 | xrealloc (overlay_heads, | ||
| 2060 | (overlay_heads_len | ||
| 2061 | * sizeof (struct sortstr)))); | ||
| 2062 | } | ||
| 2063 | } | ||
| 2064 | overlay_heads[nhead].string = str; | ||
| 2065 | overlay_heads[nhead].size = endpos - startpos; | ||
| 2066 | tem = Foverlay_get (overlay, Qpriority); | ||
| 2067 | overlay_heads[nhead].priority = (INTEGERP (tem) ? XINT (tem) : 0); | ||
| 2068 | nhead++; | ||
| 2069 | total += XSTRING (str)->size; | ||
| 2070 | } | ||
| 2071 | } | ||
| 2072 | } | 2055 | } |
| 2073 | for (ov = current_buffer->overlays_after; CONSP (ov); ov = XCONS (ov)->cdr) | 2056 | for (ov = current_buffer->overlays_after; CONSP (ov); ov = XCONS (ov)->cdr) |
| 2074 | { | 2057 | { |
| @@ -2080,101 +2063,56 @@ overlay_strings (pos, w, pstr) | |||
| 2080 | endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); | 2063 | endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); |
| 2081 | if (startpos > pos) | 2064 | if (startpos > pos) |
| 2082 | break; | 2065 | break; |
| 2083 | if (endpos == pos) | 2066 | if (endpos != pos && startpos != pos) |
| 2084 | { | 2067 | continue; |
| 2085 | str = Foverlay_get (overlay, Qafter_string); | 2068 | window = Foverlay_get (overlay, Qwindow); |
| 2086 | if (STRINGP (str)) | 2069 | if (WINDOWP (window) && XWINDOW (window) != w) |
| 2087 | { | 2070 | continue; |
| 2088 | if (ntail == overlay_tails_len) | 2071 | if (endpos == pos |
| 2089 | { | 2072 | && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))) |
| 2090 | if (! overlay_tails) | 2073 | record_overlay_string (&overlay_tails, str, |
| 2091 | { | 2074 | Foverlay_get (overlay, Qpriority), |
| 2092 | overlay_tails_len = 5; | 2075 | endpos - startpos); |
| 2093 | overlay_tails = ((struct sortstr *) | 2076 | if (startpos == pos |
| 2094 | xmalloc (5 * sizeof (struct sortstr))); | 2077 | && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) |
| 2095 | } | 2078 | record_overlay_string (&overlay_heads, str, |
| 2096 | else | 2079 | Foverlay_get (overlay, Qpriority), |
| 2097 | { | 2080 | endpos - startpos); |
| 2098 | overlay_tails_len *= 2; | 2081 | } |
| 2099 | overlay_tails = ((struct sortstr *) | 2082 | if (overlay_tails.used > 1) |
| 2100 | xrealloc (overlay_tails, | 2083 | qsort (overlay_tails.buf, overlay_tails.used, sizeof (struct sortstr), |
| 2101 | (overlay_tails_len | 2084 | cmp_for_strings); |
| 2102 | * sizeof (struct sortstr)))); | 2085 | if (overlay_heads.used > 1) |
| 2103 | } | 2086 | qsort (overlay_heads.buf, overlay_heads.used, sizeof (struct sortstr), |
| 2104 | } | 2087 | cmp_for_strings); |
| 2105 | overlay_tails[ntail].string = str; | 2088 | if (overlay_heads.bytes || overlay_tails.bytes) |
| 2106 | overlay_tails[ntail].size = endpos - startpos; | ||
| 2107 | tem = Foverlay_get (overlay, Qpriority); | ||
| 2108 | overlay_tails[ntail].priority = (INTEGERP (tem) ? XINT (tem) : 0); | ||
| 2109 | ntail++; | ||
| 2110 | total += XSTRING (str)->size; | ||
| 2111 | } | ||
| 2112 | } | ||
| 2113 | if (startpos == pos) | ||
| 2114 | { | ||
| 2115 | str = Foverlay_get (overlay, Qbefore_string); | ||
| 2116 | if (STRINGP (str)) | ||
| 2117 | { | ||
| 2118 | if (nhead == overlay_heads_len) | ||
| 2119 | { | ||
| 2120 | if (! overlay_heads) | ||
| 2121 | { | ||
| 2122 | overlay_heads_len = 5; | ||
| 2123 | overlay_heads = ((struct sortstr *) | ||
| 2124 | xmalloc (5 * sizeof (struct sortstr))); | ||
| 2125 | } | ||
| 2126 | else | ||
| 2127 | { | ||
| 2128 | overlay_heads_len *= 2; | ||
| 2129 | overlay_heads = ((struct sortstr *) | ||
| 2130 | xrealloc (overlay_heads, | ||
| 2131 | (overlay_heads_len | ||
| 2132 | * sizeof (struct sortstr)))); | ||
| 2133 | } | ||
| 2134 | } | ||
| 2135 | overlay_heads[nhead].string = str; | ||
| 2136 | overlay_heads[nhead].size = endpos - startpos; | ||
| 2137 | tem = Foverlay_get (overlay, Qpriority); | ||
| 2138 | overlay_heads[nhead].priority = (INTEGERP (tem) ? XINT (tem) : 0); | ||
| 2139 | nhead++; | ||
| 2140 | total += XSTRING (str)->size; | ||
| 2141 | } | ||
| 2142 | } | ||
| 2143 | } | ||
| 2144 | if (ntail > 1) | ||
| 2145 | qsort (overlay_tails, ntail, sizeof (struct sortstr), cmp_for_strings); | ||
| 2146 | if (nhead > 1) | ||
| 2147 | qsort (overlay_heads, nhead, sizeof (struct sortstr), cmp_for_strings); | ||
| 2148 | if (total) | ||
| 2149 | { | 2089 | { |
| 2090 | Lisp_Object tem; | ||
| 2150 | int i; | 2091 | int i; |
| 2151 | char *p; | 2092 | char *p; |
| 2093 | int total = overlay_heads.bytes + overlay_tails.bytes; | ||
| 2152 | 2094 | ||
| 2153 | if (total > overlay_str_len) | 2095 | if (total > overlay_str_len) |
| 2154 | { | 2096 | overlay_str_buf = (char *)xrealloc (overlay_str_buf, |
| 2155 | if (! overlay_str_buf) | 2097 | overlay_str_len = total); |
| 2156 | overlay_str_buf = (char *)xmalloc (total); | ||
| 2157 | else | ||
| 2158 | overlay_str_buf = (char *)xrealloc (overlay_str_buf, total); | ||
| 2159 | overlay_str_len = total; | ||
| 2160 | } | ||
| 2161 | p = overlay_str_buf; | 2098 | p = overlay_str_buf; |
| 2162 | for (i = ntail; --i >= 0;) | 2099 | for (i = overlay_tails.used; --i >= 0;) |
| 2163 | { | 2100 | { |
| 2164 | tem = overlay_tails[i].string; | 2101 | tem = overlay_tails.buf[i].string; |
| 2165 | bcopy (XSTRING (tem)->data, p, XSTRING (tem)->size); | 2102 | bcopy (XSTRING (tem)->data, p, XSTRING (tem)->size); |
| 2166 | p += XSTRING (tem)->size; | 2103 | p += XSTRING (tem)->size; |
| 2167 | } | 2104 | } |
| 2168 | for (i = 0; i < nhead; ++i) | 2105 | for (i = 0; i < overlay_heads.used; ++i) |
| 2169 | { | 2106 | { |
| 2170 | tem = overlay_heads[i].string; | 2107 | tem = overlay_heads.buf[i].string; |
| 2171 | bcopy (XSTRING (tem)->data, p, XSTRING (tem)->size); | 2108 | bcopy (XSTRING (tem)->data, p, XSTRING (tem)->size); |
| 2172 | p += XSTRING (tem)->size; | 2109 | p += XSTRING (tem)->size; |
| 2173 | } | 2110 | } |
| 2174 | if (pstr) | 2111 | if (pstr) |
| 2175 | *pstr = overlay_str_buf; | 2112 | *pstr = overlay_str_buf; |
| 2113 | return total; | ||
| 2176 | } | 2114 | } |
| 2177 | return total; | 2115 | return 0; |
| 2178 | } | 2116 | } |
| 2179 | 2117 | ||
| 2180 | /* Shift overlays in BUF's overlay lists, to center the lists at POS. */ | 2118 | /* Shift overlays in BUF's overlay lists, to center the lists at POS. */ |