Mercurial > hg > xemacs-beta
comparison src/text.h @ 851:e7ee5f8bde58
[xemacs-hg @ 2002-05-23 11:46:08 by ben]
fix for raymond toy's crash, alloca crashes, some recover-session improvements
files.el: Recover-session improvements: Only show session files where some
files can actually be recovered, and show in chronological order.
subr.el, menubar-items.el: As promised to rms, the functionality in
truncate-string-with-continuation-dots has been merged into
truncate-string-to-width. Change callers in menubar-items.el.
select.el: Document some of these funs better. Fix problem where we were
doing own-clipboard twice.
Makefile.in.in: Add alloca.o. Ensure that alloca.s doesn't compile into alloca.o,
but allocax.o (not that it's currently used or anything.)
EmacsFrame.c, abbrev.c, alloc.c, alloca.c, callint.c, callproc.c, config.h.in, device-msw.c, device-x.c, dired.c, doc.c, editfns.c, emacs.c, emodules.c, eval.c, event-Xt.c, event-msw.c, event-stream.c, file-coding.c, fileio.c, filelock.c, fns.c, glyphs-gtk.c, glyphs-msw.c, glyphs-x.c, gui-x.c, input-method-xlib.c, intl-win32.c, lisp.h, lread.c, menubar-gtk.c, menubar-msw.c, menubar.c, mule-wnnfns.c, nt.c, objects-msw.c, process-nt.c, realpath.c, redisplay-gtk.c, redisplay-output.c, redisplay-x.c, redisplay.c, search.c, select-msw.c, sysdep.c, syswindows.h, text.c, text.h, ui-byhand.c: Fix Raymond Toy's crash. Repeat to self: 2^21 - 1 is NOT the
same as (2 << 21) - 1.
Fix crashes due to excessive alloca(). replace alloca() with
ALLOCA(), which calls the C alloca() [which uses xmalloc()]
when the size is too big. Insert in various places calls to
try to flush the C alloca() stored info if there is any.
Add MALLOC_OR_ALLOCA(), for places that expect to be alloca()ing
large blocks. This xmalloc()s when too large and records an
unwind-protect to free -- relying on the caller to unbind_to()
elsewhere in the function. Use it in concat().
Use MALLOC instead of ALLOCA in select-msw.c.
xemacs.mak: Add alloca.o.
author | ben |
---|---|
date | Thu, 23 May 2002 11:46:46 +0000 |
parents | 5d09ddada9ae |
children | 804517e16990 |
comparison
equal
deleted
inserted
replaced
850:f915ad7befaf | 851:e7ee5f8bde58 |
---|---|
1094 const Intbyte *_bsta_2 = (p); \ | 1094 const Intbyte *_bsta_2 = (p); \ |
1095 Bytecount _bsta_3 = qxestrlen (_bsta_2); \ | 1095 Bytecount _bsta_3 = qxestrlen (_bsta_2); \ |
1096 *_bsta_ = alloca_array (Intbyte, 1 + _bsta_3); \ | 1096 *_bsta_ = alloca_array (Intbyte, 1 + _bsta_3); \ |
1097 memcpy (*_bsta_, _bsta_2, 1 + _bsta_3); \ | 1097 memcpy (*_bsta_, _bsta_2, 1 + _bsta_3); \ |
1098 } while (0) | 1098 } while (0) |
1099 | |
1099 | 1100 |
1100 #define alloca_intbytes(num) alloca_array (Intbyte, num) | 1101 #define alloca_intbytes(num) alloca_array (Intbyte, num) |
1101 #define alloca_extbytes(num) alloca_array (Extbyte, num) | 1102 #define alloca_extbytes(num) alloca_array (Extbyte, num) |
1102 | 1103 |
1103 void resize_string (Lisp_Object s, Bytecount pos, Bytecount delta); | 1104 void resize_string (Lisp_Object s, Bytecount pos, Bytecount delta); |
1270 in feel to the standard strcpy(), strcat(), strlen(), etc., but | 1271 in feel to the standard strcpy(), strcat(), strlen(), etc., but |
1271 | 1272 |
1272 (a) it is Mule-correct | 1273 (a) it is Mule-correct |
1273 (b) it does dynamic allocation so you never have to worry about size | 1274 (b) it does dynamic allocation so you never have to worry about size |
1274 restrictions | 1275 restrictions |
1275 (c) it comes in an alloca() variety (all allocation is stack-local, | 1276 (c) it comes in an ALLOCA() variety (all allocation is stack-local, |
1276 so there is no need to explicitly clean up) as well as a malloc() | 1277 so there is no need to explicitly clean up) as well as a malloc() |
1277 variety | 1278 variety |
1278 (d) it knows its own length, so it does not suffer from standard null | 1279 (d) it knows its own length, so it does not suffer from standard null |
1279 byte brain-damage -- but it null-terminates the data anyway, so | 1280 byte brain-damage -- but it null-terminates the data anyway, so |
1280 it can be passed to standard routines | 1281 it can be passed to standard routines |
1314 Declare a new Eistring. This is a standard local variable declaration | 1315 Declare a new Eistring. This is a standard local variable declaration |
1315 and can go anywhere in the variable declaration section. NAME itself | 1316 and can go anywhere in the variable declaration section. NAME itself |
1316 is declared as an Eistring *, and its storage declared on the stack. | 1317 is declared as an Eistring *, and its storage declared on the stack. |
1317 | 1318 |
1318 DECLARE_EISTRING_MALLOC (name); | 1319 DECLARE_EISTRING_MALLOC (name); |
1319 Declare a new Eistring, which uses malloc()ed instead of alloca()ed | 1320 Declare a new Eistring, which uses malloc()ed instead of ALLOCA()ed |
1320 data. This is a standard local variable declaration and can go | 1321 data. This is a standard local variable declaration and can go |
1321 anywhere in the variable declaration section. Once you initialize | 1322 anywhere in the variable declaration section. Once you initialize |
1322 the Eistring, you will have to free it using eifree() to avoid | 1323 the Eistring, you will have to free it using eifree() to avoid |
1323 memory leaks. You will need to use this form if you are passing | 1324 memory leaks. You will need to use this form if you are passing |
1324 an Eistring to any function that modifies it (otherwise, the | 1325 an Eistring to any function that modifies it (otherwise, the |
1425 Bytecount len, Charcount charlen); | 1426 Bytecount len, Charcount charlen); |
1426 Make a Lisp string out of a section of the Eistring. | 1427 Make a Lisp string out of a section of the Eistring. |
1427 | 1428 |
1428 void eicpyout_alloca (Eistring *eistr, LVALUE: Intbyte *ptr_out, | 1429 void eicpyout_alloca (Eistring *eistr, LVALUE: Intbyte *ptr_out, |
1429 LVALUE: Bytecount len_out); | 1430 LVALUE: Bytecount len_out); |
1430 Make an alloca() copy of the data in the Eistring, using the | 1431 Make an ALLOCA() copy of the data in the Eistring, using the |
1431 default internal format. Due to the nature of alloca(), this | 1432 default internal format. Due to the nature of ALLOCA(), this |
1432 must be a macro, with all lvalues passed in as parameters. | 1433 must be a macro, with all lvalues passed in as parameters. |
1433 (More specifically, not all compilers correctly handle using | 1434 (More specifically, not all compilers correctly handle using |
1434 alloca() as the argument to a function call -- GCC on x86 | 1435 ALLOCA() as the argument to a function call -- GCC on x86 |
1435 didn't used to, for example.) A pointer to the alloca()ed data | 1436 didn't used to, for example.) A pointer to the ALLOCA()ed data |
1436 is stored in PTR_OUT, and the length of the data (not including | 1437 is stored in PTR_OUT, and the length of the data (not including |
1437 the terminating zero) is stored in LEN_OUT. | 1438 the terminating zero) is stored in LEN_OUT. |
1438 | 1439 |
1439 void eicpyout_alloca_fmt (Eistring *eistr, LVALUE: Intbyte *ptr_out, | 1440 void eicpyout_alloca_fmt (Eistring *eistr, LVALUE: Intbyte *ptr_out, |
1440 LVALUE: Bytecount len_out, | 1441 LVALUE: Bytecount len_out, |
1708 | 1709 |
1709 | 1710 |
1710 /* Principles for writing Eistring functions: | 1711 /* Principles for writing Eistring functions: |
1711 | 1712 |
1712 (1) Unfortunately, we have to write most of the Eistring functions | 1713 (1) Unfortunately, we have to write most of the Eistring functions |
1713 as macros, because of the use of alloca(). The principle used | 1714 as macros, because of the use of ALLOCA(). The principle used |
1714 below to assure no conflict in local variables is to prefix all | 1715 below to assure no conflict in local variables is to prefix all |
1715 local variables with "ei" plus a number, which should be unique | 1716 local variables with "ei" plus a number, which should be unique |
1716 among macros. In practice, when finding a new number, find the | 1717 among macros. In practice, when finding a new number, find the |
1717 highest so far used, and add 1. | 1718 highest so far used, and add 1. |
1718 | 1719 |
1765 needs protection against multi-evaluation. (Take the address of | 1766 needs protection against multi-evaluation. (Take the address of |
1766 the Eistring structure, store in a temporary variable, and use | 1767 the Eistring structure, store in a temporary variable, and use |
1767 temporary variable for all access to the Eistring. | 1768 temporary variable for all access to the Eistring. |
1768 Essentially, we want it to appear as if these Eistring macros | 1769 Essentially, we want it to appear as if these Eistring macros |
1769 are functions -- we would like to declare them as functions but | 1770 are functions -- we would like to declare them as functions but |
1770 they use alloca(), so we can't (and we can't make them inline | 1771 they use ALLOCA(), so we can't (and we can't make them inline |
1771 functions either -- alloca() is explicitly disallowed in inline | 1772 functions either -- ALLOCA() is explicitly disallowed in inline |
1772 functions.) | 1773 functions.) |
1773 | 1774 |
1774 (7) Note that our rules regarding multiple evaluation are *more* | 1775 (7) Note that our rules regarding multiple evaluation are *more* |
1775 strict than the rules listed above under the heading "working | 1776 strict than the rules listed above under the heading "working |
1776 with raw internal-format data". | 1777 with raw internal-format data". |
1870 if ((ei)->mallocp_) \ | 1871 if ((ei)->mallocp_) \ |
1871 /* xrealloc always preserves existing data as much as possible */ \ | 1872 /* xrealloc always preserves existing data as much as possible */ \ |
1872 (ei)->data_ = (Intbyte *) xrealloc ((ei)->data_, ei1newsize); \ | 1873 (ei)->data_ = (Intbyte *) xrealloc ((ei)->data_, ei1newsize); \ |
1873 else \ | 1874 else \ |
1874 { \ | 1875 { \ |
1875 /* We don't have realloc, so alloca() more space and copy the \ | 1876 /* We don't have realloc, so ALLOCA() more space and copy the \ |
1876 data into it. */ \ | 1877 data into it. */ \ |
1877 Intbyte *ei1oldeidata = (ei)->data_; \ | 1878 Intbyte *ei1oldeidata = (ei)->data_; \ |
1878 (ei)->data_ = (Intbyte *) alloca (ei1newsize); \ | 1879 (ei)->data_ = (Intbyte *) ALLOCA (ei1newsize); \ |
1879 if (ei1oldeidata) \ | 1880 if (ei1oldeidata) \ |
1880 memcpy ((ei)->data_, ei1oldeidata, ei1oldeibytelen + 1); \ | 1881 memcpy ((ei)->data_, ei1oldeidata, ei1oldeibytelen + 1); \ |
1881 } \ | 1882 } \ |
1882 (ei)->max_size_allocated_ = ei1newsize; \ | 1883 (ei)->max_size_allocated_ = ei1newsize; \ |
1883 } \ | 1884 } \ |
2089 { \ | 2090 { \ |
2090 Intbyte *ei13newdata; \ | 2091 Intbyte *ei13newdata; \ |
2091 \ | 2092 \ |
2092 (ei)->max_size_allocated_ = \ | 2093 (ei)->max_size_allocated_ = \ |
2093 eifind_large_enough_buffer (0, (ei)->bytelen_ + 1); \ | 2094 eifind_large_enough_buffer (0, (ei)->bytelen_ + 1); \ |
2094 ei13newdata = (Intbyte *) alloca ((ei)->max_size_allocated_); \ | 2095 ei13newdata = (Intbyte *) ALLOCA ((ei)->max_size_allocated_); \ |
2095 memcpy (ei13newdata, (ei)->data_, (ei)->bytelen_ + 1); \ | 2096 memcpy (ei13newdata, (ei)->data_, (ei)->bytelen_ + 1); \ |
2096 xfree ((ei)->data_); \ | 2097 xfree ((ei)->data_); \ |
2097 (ei)->data_ = ei13newdata; \ | 2098 (ei)->data_ = ei13newdata; \ |
2098 } \ | 2099 } \ |
2099 \ | 2100 \ |
2100 if ((ei)->extdata_) \ | 2101 if ((ei)->extdata_) \ |
2101 { \ | 2102 { \ |
2102 Extbyte *ei13newdata = (Extbyte *) alloca ((ei)->extlen_ + 2); \ | 2103 Extbyte *ei13newdata = (Extbyte *) ALLOCA ((ei)->extlen_ + 2); \ |
2103 \ | 2104 \ |
2104 memcpy (ei13newdata, (ei)->extdata_, (ei)->extlen_); \ | 2105 memcpy (ei13newdata, (ei)->extdata_, (ei)->extlen_); \ |
2105 /* Double null-terminate in case of Unicode data */ \ | 2106 /* Double null-terminate in case of Unicode data */ \ |
2106 ei13newdata[(ei)->extlen_] = '\0'; \ | 2107 ei13newdata[(ei)->extlen_] = '\0'; \ |
2107 ei13newdata[(ei)->extlen_ + 1] = '\0'; \ | 2108 ei13newdata[(ei)->extlen_ + 1] = '\0'; \ |
2420 int downp); | 2421 int downp); |
2421 | 2422 |
2422 #define EI_CASECHANGE(ei, downp) \ | 2423 #define EI_CASECHANGE(ei, downp) \ |
2423 do { \ | 2424 do { \ |
2424 int ei11new_allocmax = (ei)->charlen_ * MAX_EMCHAR_LEN + 1; \ | 2425 int ei11new_allocmax = (ei)->charlen_ * MAX_EMCHAR_LEN + 1; \ |
2425 Intbyte *ei11storage = (Intbyte *) alloca_array (Intbyte, \ | 2426 Intbyte *ei11storage = \ |
2426 ei11new_allocmax); \ | 2427 (Intbyte *) alloca_array (Intbyte, ei11new_allocmax); \ |
2427 int ei11newlen = eistr_casefiddle_1 ((ei)->data_, (ei)->bytelen_, \ | 2428 int ei11newlen = eistr_casefiddle_1 ((ei)->data_, (ei)->bytelen_, \ |
2428 ei11storage, downp); \ | 2429 ei11storage, downp); \ |
2429 \ | 2430 \ |
2430 if (ei11newlen) \ | 2431 if (ei11newlen) \ |
2431 { \ | 2432 { \ |
2464 alloca-copying of strings and other annoying stuff. | 2465 alloca-copying of strings and other annoying stuff. |
2465 | 2466 |
2466 The source or sink can be specified in one of these ways: | 2467 The source or sink can be specified in one of these ways: |
2467 | 2468 |
2468 DATA, (ptr, len), // input data is a fixed buffer of size len | 2469 DATA, (ptr, len), // input data is a fixed buffer of size len |
2469 ALLOCA, (ptr, len), // output data is in a alloca()ed buffer of size len | 2470 ALLOCA, (ptr, len), // output data is in a ALLOCA()ed buffer of size len |
2470 MALLOC, (ptr, len), // output data is in a malloc()ed buffer of size len | 2471 MALLOC, (ptr, len), // output data is in a malloc()ed buffer of size len |
2471 C_STRING_ALLOCA, ptr, // equivalent to ALLOCA (ptr, len_ignored) on output | 2472 C_STRING_ALLOCA, ptr, // equivalent to ALLOCA (ptr, len_ignored) on output |
2472 C_STRING_MALLOC, ptr, // equivalent to MALLOC (ptr, len_ignored) on output | 2473 C_STRING_MALLOC, ptr, // equivalent to MALLOC (ptr, len_ignored) on output |
2473 C_STRING, ptr, // equivalent to DATA, (ptr, strlen/wcslen (ptr)) | 2474 C_STRING, ptr, // equivalent to DATA, (ptr, strlen/wcslen (ptr)) |
2474 // on input (the Unicode version is used when correct) | 2475 // on input (the Unicode version is used when correct) |
2724 | 2725 |
2725 /* Assign to the `sink' lvalue(s) using the converted data. */ | 2726 /* Assign to the `sink' lvalue(s) using the converted data. */ |
2726 /* + 2 because we double zero-extended to account for Unicode conversion */ | 2727 /* + 2 because we double zero-extended to account for Unicode conversion */ |
2727 typedef union { char c; void *p; } *dfc_aliasing_voidpp; | 2728 typedef union { char c; void *p; } *dfc_aliasing_voidpp; |
2728 #define DFC_ALLOCA_USE_CONVERTED_DATA(sink) do { \ | 2729 #define DFC_ALLOCA_USE_CONVERTED_DATA(sink) do { \ |
2729 void * dfc_sink_ret = alloca (dfc_sink.data.len + 2); \ | 2730 void * dfc_sink_ret = ALLOCA (dfc_sink.data.len + 2); \ |
2730 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 2); \ | 2731 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 2); \ |
2731 ((dfc_aliasing_voidpp) &(DFC_CPP_CAR sink))->p = dfc_sink_ret; \ | 2732 ((dfc_aliasing_voidpp) &(DFC_CPP_CAR sink))->p = dfc_sink_ret; \ |
2732 (DFC_CPP_CDR sink) = dfc_sink.data.len; \ | 2733 (DFC_CPP_CDR sink) = dfc_sink.data.len; \ |
2733 } while (0) | 2734 } while (0) |
2734 #define DFC_MALLOC_USE_CONVERTED_DATA(sink) do { \ | 2735 #define DFC_MALLOC_USE_CONVERTED_DATA(sink) do { \ |
2736 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 2); \ | 2737 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 2); \ |
2737 ((dfc_aliasing_voidpp) &(DFC_CPP_CAR sink))->p = dfc_sink_ret; \ | 2738 ((dfc_aliasing_voidpp) &(DFC_CPP_CAR sink))->p = dfc_sink_ret; \ |
2738 (DFC_CPP_CDR sink) = dfc_sink.data.len; \ | 2739 (DFC_CPP_CDR sink) = dfc_sink.data.len; \ |
2739 } while (0) | 2740 } while (0) |
2740 #define DFC_C_STRING_ALLOCA_USE_CONVERTED_DATA(sink) do { \ | 2741 #define DFC_C_STRING_ALLOCA_USE_CONVERTED_DATA(sink) do { \ |
2741 void * dfc_sink_ret = alloca (dfc_sink.data.len + 2); \ | 2742 void * dfc_sink_ret = ALLOCA (dfc_sink.data.len + 2); \ |
2742 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 2); \ | 2743 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 2); \ |
2743 ((dfc_aliasing_voidpp) &(sink))->p = dfc_sink_ret; \ | 2744 ((dfc_aliasing_voidpp) &(sink))->p = dfc_sink_ret; \ |
2744 } while (0) | 2745 } while (0) |
2745 #define DFC_C_STRING_MALLOC_USE_CONVERTED_DATA(sink) do { \ | 2746 #define DFC_C_STRING_MALLOC_USE_CONVERTED_DATA(sink) do { \ |
2746 void * dfc_sink_ret = xmalloc (dfc_sink.data.len + 2); \ | 2747 void * dfc_sink_ret = xmalloc (dfc_sink.data.len + 2); \ |
2801 int __gsnum__ = (num); \ | 2802 int __gsnum__ = (num); \ |
2802 Extbyte * __gserr__ = strerror (__gsnum__); \ | 2803 Extbyte * __gserr__ = strerror (__gsnum__); \ |
2803 \ | 2804 \ |
2804 if (!__gserr__) \ | 2805 if (!__gserr__) \ |
2805 { \ | 2806 { \ |
2806 var = alloca_intbytes (99); \ | 2807 var = alloca_intbytes (99); \ |
2807 qxesprintf (var, "Unknown error %d", __gsnum__); \ | 2808 qxesprintf (var, "Unknown error %d", __gsnum__); \ |
2808 } \ | 2809 } \ |
2809 else \ | 2810 else \ |
2810 EXTERNAL_TO_C_STRING (__gserr__, var, Qstrerror_encoding); \ | 2811 EXTERNAL_TO_C_STRING (__gserr__, var, Qstrerror_encoding); \ |
2811 } while (0) | 2812 } while (0) |