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)