comparison src/text.h @ 2367:ecf1ebac70d8

[xemacs-hg @ 2004-11-04 23:05:23 by ben] commit mega-patch configure.in: Turn off -Winline and -Wchar-subscripts. Use the right set of cflags when compiling modules. Rewrite ldap configuration to separate the inclusion of lber (needed in recent Cygwin) from the basic checks for the needed libraries. add a function for MAKE_JUNK_C; initially code was added to generate xemacs.def using this, but it will need to be rewritten. add an rm -f for junk.c to avoid weird Cygwin bug with cp -f onto an existing file. Sort list of auto-detected functions and eliminate unused checks for stpcpy, setlocale and getwd. Add autodetection of Cygwin scanf problems BETA: Rewrite section on configure to indicate what flags are important and what not. digest-doc.c, make-dump-id.c, profile.c, sorted-doc.c: Add proper decls for main(). make-msgfile.c: Document that this is old junk. Move proposal to text.c. make-msgfile.lex: Move proposal to text.c. make-mswin-unicode.pl: Convert error-generating code so that the entire message will be seen as a single unrecognized token. mule/mule-ccl.el: Update docs. lispref/mule.texi: Update CCL docs. ldap/eldap.c: Mule-ize. Use EXTERNAL_LIST_LOOP_2 instead of deleted EXTERNAL_LIST_LOOP. * XEmacs 21.5.18 "chestnut" is released. --------------------------------------------------------------- MULE-RELATED WORK: --------------------------------------------------------------- --------------------------- byte-char conversion --------------------------- buffer.c, buffer.h, insdel.c, text.c: Port FSF algorithm for byte-char conversion, replacing broken previous version. Track the char position of the gap. Add functions to do char-byte conversion downwards as well as upwards. Move comments about algorithm workings to internals manual. --------------------------- work on types --------------------------- alloc.c, console-x-impl.h, dump-data.c, dump-data.h, dumper.c, dialog-msw.c, dired-msw.c, doc.c, editfns.c, esd.c, event-gtk.h, event-msw.c, events.c, file-coding.c, file-coding.h, fns.c, glyphs-eimage.c, glyphs-gtk.c, glyphs-msw.c, glyphs-shared.c, glyphs-x.c, glyphs.c, glyphs.h, gui.c, hpplay.c, imgproc.c, intl-win32.c, lrecord.h, lstream.c, keymap.c, lisp.h, libsst.c, linuxplay.c, miscplay.c, miscplay.h, mule-coding.c, nas.c, nt.c, ntheap.c, ntplay.c, objects-msw.c, objects-tty.c, objects-x.c, print.c, process-nt.c, process.c, redisplay.h, select-common.h, select-gtk.c, select-x.c, sgiplay.c, sound.c, sound.h, sunplay.c, sysfile.h, sysdep.c, syswindows.h, text.c, unexnt.c, win32.c, xgccache.c: Further work on types. This creates a full set of types for all the basic semantics of `char' that I have so far identified, so that its semantics can always be identified for the purposes of proper Mule-safe code, and the raw use of `char' always avoided. (1) More type renaming, for consistency of naming. Char_ASCII -> Ascbyte UChar_ASCII -> UAscbyte Char_Binary -> CBinbyte UChar_Binary -> Binbyte SChar_Binary -> SBinbyte (2) Introduce Rawbyte, CRawbyte, Boolbyte, Chbyte, UChbyte, and Bitbyte and use them. (3) New types Itext, Wexttext and Textcount for separating out the concepts of bytes and textual units (different under UTF-16 and UTF-32, which are potential internal encodings). (4) qxestr*_c -> qxestr*_ascii. lisp.h: New; goes with other qxe() functions. #### Maybe goes in a different section. lisp.h: Group generic int-type defs together with EMACS_INT defs. lisp.h: * lisp.h (WEXTTEXT_IS_WIDE) New defns. lisp.h: New type to replace places where int occurs as a boolean. It's signed because occasionally people may want to use -1 as an error value, and because unsigned ints are viral -- see comments in the internals manual against using them. dynarr.c: int -> Bytecount. --------------------------- Mule-izing --------------------------- device-x.c: Partially Mule-ize. dumper.c, dumper.h: Mule-ize. Use Rawbyte. Use stderr_out not printf. Use wext_*(). sysdep.c, syswindows.h, text.c: New Wexttext API for manipulation of external text that may be Unicode (e.g. startup code under Windows). emacs.c: Mule-ize. Properly deal with argv in external encoding. Use wext_*() and Wexttext. Use Rawbyte. #if 0 some old junk on SCO that is unlikely to be correct. Rewrite allocation code in run-temacs. emacs.c, symsinit.h, win32.c: Rename win32 init function and call it even earlier, to initialize mswindows_9x_p even earlier, for use in startup code (XEUNICODE_P). process.c: Use _wenviron not environ under Windows, to get Unicode environment variables. event-Xt.c: Mule-ize drag-n-drop related stuff. dragdrop.c, dragdrop.h, frame-x.c: Mule-ize. text.h: Add some more stand-in defines for particular kinds of conversion; use in Mule-ization work in frame-x.c etc. --------------------------- Freshening --------------------------- intl-auto-encap-win32.c, intl-auto-encap-win32.h: Regenerate. --------------------------- Unicode-work --------------------------- intl-win32.c, syswindows.h: Factor out common options to MultiByteToWideChar and WideCharToMultiByte. Add convert_unicode_to_multibyte_malloc() and convert_unicode_to_multibyte_dynarr() and use. Add stuff for alloca() conversion of multibyte/unicode. alloc.c: Use dfc_external_data_len() in case of unicode coding system. alloc.c, mule-charset.c: Don't zero out and reinit charset Unicode tables. This fucks up dump-time loading. Anyway, either we load them at dump time or run time, never both. unicode.c: Dump the blank tables as well. --------------------------------------------------------------- DOCUMENTATION, MOSTLY MULE-RELATED: --------------------------------------------------------------- EmacsFrame.c, emodules.c, event-Xt.c, fileio.c, input-method-xlib.c, mule-wnnfns.c, redisplay-gtk.c, redisplay-tty.c, redisplay-x.c, regex.c, sysdep.c: Add comment about Mule work needed. text.h: Add more documentation describing why DFC routines were not written to return their value. Add some other DFC documentation. console-msw.c, console-msw.h: Add pointer to docs in win32.c. emacs.c: Add comments on sources of doc info. text.c, charset.h, unicode.c, intl-win32.c, intl-encap-win32.c, text.h, file-coding.c, mule-coding.c: Collect background comments and related to text matters and internationalization, and proposals for work to be done, in text.c or Internals manual, stuff related to specific textual API's in text.h, and stuff related to internal implementation of Unicode conversion in unicode.c. Put lots of pointers to the comments to make them easier to find. s/mingw32.h, s/win32-common.h, s/win32-native.h, s/windowsnt.h, win32.c: Add bunches of new documentation on the different kinds of builds and environments under Windows and how they work. Collect this info in win32.c. Add pointers to these docs in the relevant s/* files. emacs.c: Document places with long comments. Remove comment about exiting, move to internals manual, put in pointer. event-stream.c: Move docs about event queues and focus to internals manual, put in pointer. events.h: Move docs about event stream callbacks to internals manual, put in pointer. profile.c, redisplay.c, signal.c: Move documentation to the Internals manual. process-nt.c: Add pointer to comment in win32-native.el. lisp.h: Add comments about some comment conventions. lisp.h: Add comment about the second argument. device-msw.c, redisplay-msw.c: @@#### comments are out-of-date. --------------------------------------------------------------- PDUMP WORK (MOTIVATED BY UNICODE CHANGES) --------------------------------------------------------------- alloc.c, buffer.c, bytecode.c, console-impl.h, console.c, device.c, dumper.c, lrecord.h, elhash.c, emodules.h, events.c, extents.c, frame.c, glyphs.c, glyphs.h, mule-charset.c, mule-coding.c, objects.c, profile.c, rangetab.c, redisplay.c, specifier.c, specifier.h, window.c, lstream.c, file-coding.h, file-coding.c: PDUMP: Properly implement dump_add_root_block(), which never worked before, and is necessary for dumping Unicode tables. Pdump name changes for accuracy: XD_STRUCT_PTR -> XD_BLOCK_PTR. XD_STRUCT_ARRAY -> XD_BLOCK_ARRAY. XD_C_STRING -> XD_ASCII_STRING. *_structure_* -> *_block_*. lrecord.h: some comments added about dump_add_root_block() vs dump_add_root_block_ptr(). extents.c: remove incorrect comment about pdump problems with gap array. --------------------------------------------------------------- ALLOCATION --------------------------------------------------------------- abbrev.c, alloc.c, bytecode.c, casefiddle.c, device-msw.c, device-x.c, dired-msw.c, doc.c, doprnt.c, dragdrop.c, editfns.c, emodules.c, file-coding.c, fileio.c, filelock.c, fns.c, glyphs-eimage.c, glyphs-gtk.c, glyphs-msw.c, glyphs-x.c, gui-msw.c, gui-x.c, imgproc.c, intl-win32.c, lread.c, menubar-gtk.c, menubar.c, nt.c, objects-msw.c, objects-x.c, print.c, process-nt.c, process-unix.c, process.c, realpath.c, redisplay.c, search.c, select-common.c, symbols.c, sysdep.c, syswindows.h, text.c, text.h, ui-byhand.c: New macros {alloca,xnew}_{itext,{i,ext,raw,bin,asc}bytes} for more convenient allocation of these commonly requested items. Modify functions to use alloca_ibytes, alloca_array, alloca_extbytes, xnew_ibytes, etc. also XREALLOC_ARRAY, xnew. alloc.c: Rewrite the allocation functions to factor out repeated code. Add assertions for freeing dumped data. lisp.h: Moved down and consolidated with other allocation stuff. lisp.h, dynarr.c: New functions for allocation that's very efficient when mostly in LIFO order. lisp.h, text.c, text.h: Factor out some stuff for general use by alloca()-conversion funs. text.h, lisp.h: Fill out convenience routines for allocating various kinds of bytes and put them in lisp.h. Use them in place of xmalloc(), ALLOCA(). text.h: Fill out the convenience functions so the _MALLOC() kinds match the alloca() kinds. --------------------------------------------------------------- ERROR-CHECKING --------------------------------------------------------------- text.h: Create ASSERT_ASCTEXT_ASCII() and ASSERT_ASCTEXT_ASCII_LEN() from similar Eistring checkers and change the Eistring checkers to use them instead. --------------------------------------------------------------- MACROS IN LISP.H --------------------------------------------------------------- lisp.h: Redo GCPRO declarations. Create a "base" set of functions that can be used to generate any kind of gcpro sets -- regular, ngcpro, nngcpro, private ones used in GC_EXTERNAL_LIST_LOOP_2. buffer.c, callint.c, chartab.c, console-msw.c, device-x.c, dialog-msw.c, dired.c, extents.c, ui-gtk.c, rangetab.c, nt.c, mule-coding.c, minibuf.c, menubar-msw.c, menubar.c, menubar-gtk.c, lread.c, lisp.h, gutter.c, glyphs.c, glyphs-widget.c, fns.c, fileio.c, file-coding.c, specifier.c: Eliminate EXTERNAL_LIST_LOOP, which does not check for circularities. Use EXTERNAL_LIST_LOOP_2 instead or EXTERNAL_LIST_LOOP_3 or EXTERNAL_PROPERTY_LIST_LOOP_3 or GC_EXTERNAL_LIST_LOOP_2 (new macro). Removed/redid comments on EXTERNAL_LIST_LOOP. --------------------------------------------------------------- SPACING FIXES --------------------------------------------------------------- callint.c, hftctl.c, number-gmp.c, process-unix.c: Spacing fixes. --------------------------------------------------------------- FIX FOR GEOMETRY PROBLEM IN FIRST FRAME --------------------------------------------------------------- unicode.c: Add workaround for newlib bug in sscanf() [should be fixed by release 1.5.12 of Cygwin]. toolbar.c: bug fix for problem of initial frame being 77 chars wide on Windows. will be overridden by my other ws. --------------------------------------------------------------- FIX FOR LEAKING PROCESS HANDLES: --------------------------------------------------------------- process-nt.c: Fixes for leaking handles. Inspired by work done by Adrian Aichner <adrian@xemacs.org>. --------------------------------------------------------------- FIX FOR CYGWIN BUG (Unicode-related): --------------------------------------------------------------- unicode.c: Add workaround for newlib bug in sscanf() [should be fixed by release 1.5.12 of Cygwin]. --------------------------------------------------------------- WARNING FIXES: --------------------------------------------------------------- console-stream.c: `reinit' is unused. compiler.h, event-msw.c, frame-msw.c, intl-encap-win32.c, text.h: Add stuff to deal with ANSI-aliasing warnings I got. regex.c: Gather includes together to avoid warning. --------------------------------------------------------------- CHANGES TO INITIALIZATION ROUTINES: --------------------------------------------------------------- buffer.c, emacs.c, console.c, debug.c, device-x.c, device.c, dragdrop.c, emodules.c, eval.c, event-Xt.c, event-gtk.c, event-msw.c, event-stream.c, event-tty.c, events.c, extents.c, faces.c, file-coding.c, fileio.c, font-lock.c, frame-msw.c, glyphs-widget.c, glyphs.c, gui-x.c, insdel.c, lread.c, lstream.c, menubar-gtk.c, menubar-x.c, minibuf.c, mule-wnnfns.c, objects-msw.c, objects.c, print.c, scrollbar-x.c, search.c, select-x.c, text.c, undo.c, unicode.c, window.c, symsinit.h: Call reinit_*() functions directly from emacs.c, for clarity. Factor out some redundant init code. Move disallowed stuff that had crept into vars_of_glyphs() into complex_vars_of_glyphs(). Call init_eval_semi_early() from eval.c not in the middle of vars_of_() in emacs.c since there should be no order dependency in the latter calls. --------------------------------------------------------------- ARMAGEDDON: --------------------------------------------------------------- alloc.c, emacs.c, lisp.h, print.c: Rename inhibit_non_essential_printing_operations to inhibit_non_essential_conversion_operations. text.c: Assert on !inhibit_non_essential_conversion_operations. console-msw.c, print.c: Don't do conversion in SetConsoleTitle or FindWindow to avoid problems during armageddon. Put #errors for NON_ASCII_INTERNAL_FORMAT in places where problems would arise. --------------------------------------------------------------- CHANGES TO THE BUILD PROCEDURE: --------------------------------------------------------------- config.h.in, s/cxux.h, s/usg5-4-2.h, m/powerpc.h: Add comment about correct ordering of this file. Rearrange everything to follow this -- put all #undefs together and before the s&m files. Add undefs for HAVE_ALLOCA, C_ALLOCA, BROKEN_ALLOCA_IN_FUNCTION_CALLS, STACK_DIRECTION. Remove unused HAVE_STPCPY, HAVE_GETWD, HAVE_SETLOCALE. m/gec63.h: Deleted; totally broken, not used at all, not in FSF. m/7300.h, m/acorn.h, m/alliant-2800.h, m/alliant.h, m/altos.h, m/amdahl.h, m/apollo.h, m/att3b.h, m/aviion.h, m/celerity.h, m/clipper.h, m/cnvrgnt.h, m/convex.h, m/cydra5.h, m/delta.h, m/delta88k.h, m/dpx2.h, m/elxsi.h, m/ews4800r.h, m/gould.h, m/hp300bsd.h, m/hp800.h, m/hp9000s300.h, m/i860.h, m/ibmps2-aix.h, m/ibmrs6000.h, m/ibmrt-aix.h, m/ibmrt.h, m/intel386.h, m/iris4d.h, m/iris5d.h, m/iris6d.h, m/irist.h, m/isi-ov.h, m/luna88k.h, m/m68k.h, m/masscomp.h, m/mg1.h, m/mips-nec.h, m/mips-siemens.h, m/mips.h, m/news.h, m/nh3000.h, m/nh4000.h, m/ns32000.h, m/orion105.h, m/pfa50.h, m/plexus.h, m/pmax.h, m/powerpc.h, m/pyrmips.h, m/sequent-ptx.h, m/sequent.h, m/sgi-challenge.h, m/symmetry.h, m/tad68k.h, m/tahoe.h, m/targon31.h, m/tekxd88.h, m/template.h, m/tower32.h, m/tower32v3.h, m/ustation.h, m/vax.h, m/wicat.h, m/xps100.h: Delete C_ALLOCA, HAVE_ALLOCA, STACK_DIRECTION, BROKEN_ALLOCA_IN_FUNCTION_CALLS. All of this is auto-detected. When in doubt, I followed recent FSF sources, which also have these things deleted.
author ben
date Thu, 04 Nov 2004 23:08:28 +0000
parents ba4677f54a05
children ac4ffbd57062
comparison
equal deleted inserted replaced
2366:2a392e0c390a 2367:ecf1ebac70d8
1 /* Header file for text manipulation primitives and macros. 1 /* Header file for text manipulation primitives and macros.
2 Copyright (C) 1985-1995 Free Software Foundation, Inc. 2 Copyright (C) 1985-1995 Free Software Foundation, Inc.
3 Copyright (C) 1995 Sun Microsystems, Inc. 3 Copyright (C) 1995 Sun Microsystems, Inc.
4 Copyright (C) 2000, 2001, 2002, 2003 Ben Wing. 4 Copyright (C) 2000, 2001, 2002, 2003, 2004 Ben Wing.
5 5
6 This file is part of XEmacs. 6 This file is part of XEmacs.
7 7
8 XEmacs is free software; you can redistribute it and/or modify it 8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the 9 under the terms of the GNU General Public License as published by the
164 164
165 #define MAX_ICHAR_LEN 4 165 #define MAX_ICHAR_LEN 4
166 166
167 #endif /* not MULE */ 167 #endif /* not MULE */
168 168
169 /* ---------------- Handling non-default formats ----------------- */ 169 /* For more discussion, see text.c, "handling non-default formats" */
170 170
171 /* We support, at least to some extent, formats other than the default
172 variable-width format, for speed; all of these alternative formats are
173 fixed-width. Currently we only handle these non-default formats in
174 buffers, because access to their text is strictly controlled and thus
175 the details of the format mostly compartmentalized. The only really
176 tricky part is the search code -- the regex, Boyer-Moore, and
177 simple-search algorithms in search.c and regex.c. All other code that
178 knows directly about the buffer representation is the basic code to
179 modify or retrieve the buffer text.
180
181 Supporting fixed-width formats in Lisp strings is harder, but possible
182 -- FSF currently does this, for example. In this case, however,
183 probably only 8-bit-fixed is reasonable for Lisp strings -- getting
184 non-ASCII-compatible fixed-width formats to work is much, much harder
185 because a lot of code assumes that strings are ASCII-compatible
186 (i.e. ASCII + other characters represented exclusively using high-bit
187 bytes) and a lot of code mixes Lisp strings and non-Lisp strings freely.
188
189 The different possible fixed-width formats are 8-bit fixed, 16-bit
190 fixed, and 32-bit fixed. The latter can represent all possible
191 characters, but at a substantial memory penalty. The other two can
192 represent only a subset of the possible characters. How these subsets
193 are defined can be simple or very tricky.
194
195 Currently we support only the default format and the 8-bit fixed format,
196 and in the latter, we only allow these to be the first 256 characters in
197 an Ichar (ASCII and Latin 1).
198
199 One reasonable approach for 8-bit fixed is to allow the upper half to
200 represent any 1-byte charset, which is specified on a per-buffer basis.
201 This should work fairly well in practice since most documents are in
202 only one foreign language (possibly with some English mixed in). I
203 think FSF does something like this; or at least, they have something
204 called nonascii-translation-table and use it when converting from
205 8-bit-fixed text ("unibyte text") to default text ("multibyte text").
206 With 16-bit fixed, you could do something like assign chunks of the 64K
207 worth of characters to charsets as they're encountered in documents.
208 This should work well with most Asian documents.
209
210 If/when we switch to using Unicode internally, we might have formats more
211 like this:
212
213 -- UTF-8 or some extension as the default format. Perl uses an
214 extension that handles 64-bit chars and requires as much as 13 bytes per
215 char, vs. the standard of 31-bit chars and 6 bytes max. UTF-8 has the
216 same basic properties as our own variable-width format (see text.c,
217 Internal String Encoding) and so most code would not need to be changed.
218
219 -- UTF-16 as a "pseudo-fixed" format (i.e. 16-bit fixed plus surrogates
220 for representing characters not in the BMP, aka >= 65536). The vast
221 majority of documents will have no surrogates in them so byte/char
222 conversion will be very fast.
223
224 -- an 8-bit fixed format, like currently.
225
226 -- possibly, UCS-4 as a 32-bit fixed format.
227
228 The fixed-width formats essentially treat the buffer as an array of
229 8-bit, 16-bit or 32-bit integers. This means that how they are stored
230 in memory (in particular, big-endian or little-endian) depends on the
231 native format of the machine's processor. It also means we have to
232 worry a bit about alignment (basically, we just need to keep the gap an
233 integral size of the character size, and get things aligned properly
234 when converting the buffer between formats).
235 */
236 typedef enum internal_format 171 typedef enum internal_format
237 { 172 {
238 FORMAT_DEFAULT, 173 FORMAT_DEFAULT,
239 FORMAT_8_BIT_FIXED, 174 FORMAT_8_BIT_FIXED,
240 FORMAT_16_BIT_FIXED, /* not implemented */ 175 FORMAT_16_BIT_FIXED, /* not implemented */
601 536
602 #define validate_ibyte_string_backward(ptr, n) (n) 537 #define validate_ibyte_string_backward(ptr, n) (n)
603 538
604 #endif /* MULE */ 539 #endif /* MULE */
605 540
541 #ifdef ERROR_CHECK_TEXT
542 #define ASSERT_ASCTEXT_ASCII_LEN(ptr, len) \
543 do { \
544 int aia2; \
545 const Ascbyte *aia2ptr = (ptr); \
546 int aia2len = (len); \
547 \
548 for (aia2 = 0; aia2 < aia2len; aia2++) \
549 assert (aia2ptr[aia2] >= 0x00 && aia2ptr[aia2] < 0x7F); \
550 } while (0)
551 #define ASSERT_ASCTEXT_ASCII(ptr) \
552 do { \
553 const Ascbyte *aiaz2 = (ptr); \
554 ASSERT_ASCTEXT_ASCII_LEN (aiaz2, strlen (aiaz2)); \
555 } while (0)
556 #else
557 #define ASSERT_ASCTEXT_ASCII_LEN(ptr, len)
558 #define ASSERT_ASCTEXT_ASCII(ptr)
559 #endif
560
606 /* -------------------------------------------------------------- */ 561 /* -------------------------------------------------------------- */
607 /* Working with the length (in bytes and characters) of a */ 562 /* Working with the length (in bytes and characters) of a */
608 /* section of internally-formatted text */ 563 /* section of internally-formatted text */
609 /* -------------------------------------------------------------- */ 564 /* -------------------------------------------------------------- */
610 565
668 } 623 }
669 return newptr - ptr; 624 return newptr - ptr;
670 } 625 }
671 else 626 else
672 return charcount_to_bytecount_fun (ptr, len); 627 return charcount_to_bytecount_fun (ptr, len);
628 }
629
630 MODULE_API Bytecount
631 charcount_to_bytecount_down_fun (const Ibyte *ptr, Charcount len);
632
633 /* Given a pointer to a text string and a length in bytes, return
634 the equivalent length in characters of the stretch [PTR - LEN, PTR). */
635
636 DECLARE_INLINE_HEADER (
637 Charcount
638 bytecount_to_charcount_down (const Ibyte *ptr, Bytecount len)
639 )
640 {
641 /* No need to be clever here */
642 return bytecount_to_charcount (ptr - len, len);
643 }
644
645 /* Given a pointer to a text string and a length in characters, return the
646 equivalent length in bytes of the stretch of characters of that length
647 BEFORE the pointer.
648 */
649
650 DECLARE_INLINE_HEADER (
651 Bytecount
652 charcount_to_bytecount_down (const Ibyte *ptr, Charcount len)
653 )
654 {
655 #define SLEDGEHAMMER_CHECK_TEXT
656 #ifdef SLEDGEHAMMER_CHECK_TEXT
657 Charcount len1 = len;
658 Bytecount ret1, ret2;
659
660 /* To test the correctness of the function version, always do the
661 calculation both ways and check that the values are the same. */
662 text_checking_assert (len >= 0);
663 {
664 const Ibyte *newptr = ptr;
665 while (len1 > 0)
666 {
667 DEC_IBYTEPTR (newptr);
668 len1--;
669 }
670 ret1 = ptr - newptr;
671 }
672 ret2 = charcount_to_bytecount_down_fun (ptr, len);
673 text_checking_assert (ret1 == ret2);
674 return ret1;
675 #else
676 text_checking_assert (len >= 0);
677 if (len < 20) /* See above */
678 {
679 const Ibyte *newptr = ptr;
680 while (len > 0)
681 {
682 DEC_IBYTEPTR (newptr);
683 len--;
684 }
685 return ptr - newptr;
686 }
687 else
688 return charcount_to_bytecount_down_fun (ptr, len);
689 #endif /* SLEDGEHAMMER_CHECK_TEXT */
673 } 690 }
674 691
675 /* Given a pointer to a text string in the specified format and a length in 692 /* Given a pointer to a text string in the specified format and a length in
676 bytes, return the equivalent length in characters. 693 bytes, return the equivalent length in characters.
677 */ 694 */
989 #define itext_ichar_n(ptr, offset) \ 1006 #define itext_ichar_n(ptr, offset) \
990 itext_ichar (itext_n_addr (ptr, offset)) 1007 itext_ichar (itext_n_addr (ptr, offset))
991 1008
992 1009
993 /* ---------------------------- */ 1010 /* ---------------------------- */
994 /* Working with Ichars */ 1011 /* Working with Ichars */
995 /* ---------------------------- */ 1012 /* ---------------------------- */
996 1013
997 /* NOTE: There are other functions/macros for working with Ichars in 1014 /* NOTE: There are other functions/macros for working with Ichars in
998 charset.h, for retrieving the charset of an Ichar, the length of an 1015 charset.h, for retrieving the charset of an Ichar, the length of an
999 Ichar when converted to text, etc. 1016 Ichar when converted to text, etc.
1098 /* Make an alloca'd copy of a Lisp string */ 1115 /* Make an alloca'd copy of a Lisp string */
1099 #define LISP_STRING_TO_ALLOCA(s, lval) \ 1116 #define LISP_STRING_TO_ALLOCA(s, lval) \
1100 do { \ 1117 do { \
1101 Ibyte **_lta_ = (Ibyte **) &(lval); \ 1118 Ibyte **_lta_ = (Ibyte **) &(lval); \
1102 Lisp_Object _lta_2 = (s); \ 1119 Lisp_Object _lta_2 = (s); \
1103 *_lta_ = alloca_array (Ibyte, 1 + XSTRING_LENGTH (_lta_2)); \ 1120 *_lta_ = alloca_ibytes (1 + XSTRING_LENGTH (_lta_2)); \
1104 memcpy (*_lta_, XSTRING_DATA (_lta_2), 1 + XSTRING_LENGTH (_lta_2)); \ 1121 memcpy (*_lta_, XSTRING_DATA (_lta_2), 1 + XSTRING_LENGTH (_lta_2)); \
1105 } while (0) 1122 } while (0)
1106
1107 /* Make an alloca'd copy of a Ibyte * */
1108 #define IBYTE_STRING_TO_ALLOCA(p, lval) \
1109 do { \
1110 Ibyte **_bsta_ = (Ibyte **) &(lval); \
1111 const Ibyte *_bsta_2 = (p); \
1112 Bytecount _bsta_3 = qxestrlen (_bsta_2); \
1113 *_bsta_ = alloca_array (Ibyte, 1 + _bsta_3); \
1114 memcpy (*_bsta_, _bsta_2, 1 + _bsta_3); \
1115 } while (0)
1116
1117
1118 #define alloca_ibytes(num) alloca_array (Ibyte, num)
1119 #define alloca_extbytes(num) alloca_array (Extbyte, num)
1120 1123
1121 void resize_string (Lisp_Object s, Bytecount pos, Bytecount delta); 1124 void resize_string (Lisp_Object s, Bytecount pos, Bytecount delta);
1122 1125
1123 /* Convert a byte index into a string into a char index. */ 1126 /* Convert a byte index into a string into a char index. */
1124 DECLARE_INLINE_HEADER ( 1127 DECLARE_INLINE_HEADER (
1333 1336
1334 To declare an Eistring, either put one of the following in the local 1337 To declare an Eistring, either put one of the following in the local
1335 variable section: 1338 variable section:
1336 1339
1337 DECLARE_EISTRING (name); 1340 DECLARE_EISTRING (name);
1338 Declare a new Eistring. This is a standard local variable declaration 1341 Declare a new Eistring and initialize it to the empy string. This
1339 and can go anywhere in the variable declaration section. NAME itself 1342 is a standard local variable declaration and can go anywhere in the
1340 is declared as an Eistring *, and its storage declared on the stack. 1343 variable declaration section. NAME itself is declared as an
1344 Eistring *, and its storage declared on the stack.
1341 1345
1342 DECLARE_EISTRING_MALLOC (name); 1346 DECLARE_EISTRING_MALLOC (name);
1343 Declare a new Eistring, which uses malloc()ed instead of ALLOCA()ed 1347 Declare and initialize a new Eistring, which uses malloc()ed
1344 data. This is a standard local variable declaration and can go 1348 instead of ALLOCA()ed data. This is a standard local variable
1345 anywhere in the variable declaration section. Once you initialize 1349 declaration and can go anywhere in the variable declaration
1346 the Eistring, you will have to free it using eifree() to avoid 1350 section. Once you initialize the Eistring, you will have to free
1347 memory leaks. You will need to use this form if you are passing 1351 it using eifree() to avoid memory leaks. You will need to use this
1348 an Eistring to any function that modifies it (otherwise, the 1352 form if you are passing an Eistring to any function that modifies
1349 modified data may be in stack space and get overwritten when the 1353 it (otherwise, the modified data may be in stack space and get
1350 function returns). 1354 overwritten when the function returns).
1351 1355
1352 or use 1356 or use
1353 1357
1354 Eistring ei; 1358 Eistring ei;
1355 void eiinit (Eistring *ei); 1359 void eiinit (Eistring *ei);
1414 void eicpy_rawz_fmt (Eistring *eistr, const Ibyte *data, 1418 void eicpy_rawz_fmt (Eistring *eistr, const Ibyte *data,
1415 Internal_Format intfmt, Lisp_Object object); 1419 Internal_Format intfmt, Lisp_Object object);
1416 ... from raw internal-format data in the specified format that is 1420 ... from raw internal-format data in the specified format that is
1417 "null-terminated" (the meaning of this depends on the nature of 1421 "null-terminated" (the meaning of this depends on the nature of
1418 the specific format). 1422 the specific format).
1419 void eicpy_c (Eistring *eistr, const Char_ASCII *c_string); 1423 void eicpy_c (Eistring *eistr, const Ascbyte *c_string);
1420 ... from an ASCII null-terminated string. Non-ASCII characters in 1424 ... from an ASCII null-terminated string. Non-ASCII characters in
1421 the string are *ILLEGAL* (read abort() with error-checking defined). 1425 the string are *ILLEGAL* (read abort() with error-checking defined).
1422 void eicpy_c_len (Eistring *eistr, const Char_ASCII *c_string, len); 1426 void eicpy_c_len (Eistring *eistr, const Ascbyte *c_string, len);
1423 ... from an ASCII string, with length specified. Non-ASCII characters 1427 ... from an ASCII string, with length specified. Non-ASCII characters
1424 in the string are *ILLEGAL* (read abort() with error-checking defined). 1428 in the string are *ILLEGAL* (read abort() with error-checking defined).
1425 void eicpy_ext (Eistring *eistr, const Extbyte *extdata, 1429 void eicpy_ext (Eistring *eistr, const Extbyte *extdata,
1426 Lisp_Object codesys); 1430 Lisp_Object codesys);
1427 ... from external null-terminated data, with coding system specified. 1431 ... from external null-terminated data, with coding system specified.
1557 Concatenate onto the end of the Eistring, with data coming from the 1561 Concatenate onto the end of the Eistring, with data coming from the
1558 same places as above: 1562 same places as above:
1559 1563
1560 void eicat_ei (Eistring *eistr, Eistring *eistr2); 1564 void eicat_ei (Eistring *eistr, Eistring *eistr2);
1561 ... from another Eistring. 1565 ... from another Eistring.
1562 void eicat_c (Eistring *eistr, Char_ASCII *c_string); 1566 void eicat_c (Eistring *eistr, Ascbyte *c_string);
1563 ... from an ASCII null-terminated string. Non-ASCII characters in 1567 ... from an ASCII null-terminated string. Non-ASCII characters in
1564 the string are *ILLEGAL* (read abort() with error-checking defined). 1568 the string are *ILLEGAL* (read abort() with error-checking defined).
1565 void eicat_raw (ei, const Ibyte *data, Bytecount len); 1569 void eicat_raw (ei, const Ibyte *data, Bytecount len);
1566 ... from raw internal-format data in the default internal format. 1570 ... from raw internal-format data in the default internal format.
1567 void eicat_rawz (ei, const Ibyte *data); 1571 void eicat_rawz (ei, const Ibyte *data);
1587 1591
1588 void eisub_ei (Eistring *eistr, Bytecount off, Charcount charoff, 1592 void eisub_ei (Eistring *eistr, Bytecount off, Charcount charoff,
1589 Bytecount len, Charcount charlen, Eistring *eistr2); 1593 Bytecount len, Charcount charlen, Eistring *eistr2);
1590 ... with another Eistring. 1594 ... with another Eistring.
1591 void eisub_c (Eistring *eistr, Bytecount off, Charcount charoff, 1595 void eisub_c (Eistring *eistr, Bytecount off, Charcount charoff,
1592 Bytecount len, Charcount charlen, Char_ASCII *c_string); 1596 Bytecount len, Charcount charlen, Ascbyte *c_string);
1593 ... with an ASCII null-terminated string. Non-ASCII characters in 1597 ... with an ASCII null-terminated string. Non-ASCII characters in
1594 the string are *ILLEGAL* (read abort() with error-checking defined). 1598 the string are *ILLEGAL* (read abort() with error-checking defined).
1595 void eisub_ch (Eistring *eistr, Bytecount off, Charcount charoff, 1599 void eisub_ch (Eistring *eistr, Bytecount off, Charcount charoff,
1596 Bytecount len, Charcount charlen, Ichar ch); 1600 Bytecount len, Charcount charlen, Ichar ch);
1597 ... with an Ichar. 1601 ... with an Ichar.
1654 Bytecount eirstr_ei_off (Eistring *eistr, Eistring *eistr2, Bytecount off, 1658 Bytecount eirstr_ei_off (Eistring *eistr, Eistring *eistr2, Bytecount off,
1655 Charcount charoff); 1659 Charcount charoff);
1656 Charcount eirstr_ei_off_char (Eistring *eistr, Eistring *eistr2, 1660 Charcount eirstr_ei_off_char (Eistring *eistr, Eistring *eistr2,
1657 Bytecount off, Charcount charoff); 1661 Bytecount off, Charcount charoff);
1658 1662
1659 Bytecount eistr_c (Eistring *eistr, Char_ASCII *c_string); 1663 Bytecount eistr_c (Eistring *eistr, Ascbyte *c_string);
1660 Charcount eistr_c_char (Eistring *eistr, Char_ASCII *c_string); 1664 Charcount eistr_c_char (Eistring *eistr, Ascbyte *c_string);
1661 Bytecount eistr_c_off (Eistring *eistr, Char_ASCII *c_string, Bytecount off, 1665 Bytecount eistr_c_off (Eistring *eistr, Ascbyte *c_string, Bytecount off,
1662 Charcount charoff); 1666 Charcount charoff);
1663 Charcount eistr_c_off_char (Eistring *eistr, Char_ASCII *c_string, 1667 Charcount eistr_c_off_char (Eistring *eistr, Ascbyte *c_string,
1664 Bytecount off, Charcount charoff); 1668 Bytecount off, Charcount charoff);
1665 Bytecount eirstr_c (Eistring *eistr, Char_ASCII *c_string); 1669 Bytecount eirstr_c (Eistring *eistr, Ascbyte *c_string);
1666 Charcount eirstr_c_char (Eistring *eistr, Char_ASCII *c_string); 1670 Charcount eirstr_c_char (Eistring *eistr, Ascbyte *c_string);
1667 Bytecount eirstr_c_off (Eistring *eistr, Char_ASCII *c_string, 1671 Bytecount eirstr_c_off (Eistring *eistr, Ascbyte *c_string,
1668 Bytecount off, Charcount charoff); 1672 Bytecount off, Charcount charoff);
1669 Charcount eirstr_c_off_char (Eistring *eistr, Char_ASCII *c_string, 1673 Charcount eirstr_c_off_char (Eistring *eistr, Ascbyte *c_string,
1670 Bytecount off, Charcount charoff); 1674 Bytecount off, Charcount charoff);
1671 1675
1672 1676
1673 ********************************************** 1677 **********************************************
1674 * Comparison * 1678 * Comparison *
1705 int eicasecmp_i18n_ei (Eistring *eistr, Eistring *eistr2); 1709 int eicasecmp_i18n_ei (Eistring *eistr, Eistring *eistr2);
1706 int eicasecmp_i18n_off_ei (Eistring *eistr, Bytecount off, 1710 int eicasecmp_i18n_off_ei (Eistring *eistr, Bytecount off,
1707 Charcount charoff, Bytecount len, 1711 Charcount charoff, Bytecount len,
1708 Charcount charlen, Eistring *eistr2); 1712 Charcount charlen, Eistring *eistr2);
1709 1713
1710 int eicmp_c (Eistring *eistr, Char_ASCII *c_string); 1714 int eicmp_c (Eistring *eistr, Ascbyte *c_string);
1711 int eicmp_off_c (Eistring *eistr, Bytecount off, Charcount charoff, 1715 int eicmp_off_c (Eistring *eistr, Bytecount off, Charcount charoff,
1712 Bytecount len, Charcount charlen, Char_ASCII *c_string); 1716 Bytecount len, Charcount charlen, Ascbyte *c_string);
1713 int eicasecmp_c (Eistring *eistr, Char_ASCII *c_string); 1717 int eicasecmp_c (Eistring *eistr, Ascbyte *c_string);
1714 int eicasecmp_off_c (Eistring *eistr, Bytecount off, Charcount charoff, 1718 int eicasecmp_off_c (Eistring *eistr, Bytecount off, Charcount charoff,
1715 Bytecount len, Charcount charlen, 1719 Bytecount len, Charcount charlen,
1716 Char_ASCII *c_string); 1720 Ascbyte *c_string);
1717 int eicasecmp_i18n_c (Eistring *eistr, Char_ASCII *c_string); 1721 int eicasecmp_i18n_c (Eistring *eistr, Ascbyte *c_string);
1718 int eicasecmp_i18n_off_c (Eistring *eistr, Bytecount off, Charcount charoff, 1722 int eicasecmp_i18n_off_c (Eistring *eistr, Bytecount off, Charcount charoff,
1719 Bytecount len, Charcount charlen, 1723 Bytecount len, Charcount charlen,
1720 Char_ASCII *c_string); 1724 Ascbyte *c_string);
1721 1725
1722 1726
1723 ********************************************** 1727 **********************************************
1724 * Case-changing the Eistring * 1728 * Case-changing the Eistring *
1725 ********************************************** 1729 **********************************************
1897 else \ 1901 else \
1898 { \ 1902 { \
1899 /* We don't have realloc, so ALLOCA() more space and copy the \ 1903 /* We don't have realloc, so ALLOCA() more space and copy the \
1900 data into it. */ \ 1904 data into it. */ \
1901 Ibyte *ei1oldeidata = (ei)->data_; \ 1905 Ibyte *ei1oldeidata = (ei)->data_; \
1902 (ei)->data_ = (Ibyte *) ALLOCA (ei1newsize); \ 1906 (ei)->data_ = alloca_ibytes (ei1newsize); \
1903 if (ei1oldeidata) \ 1907 if (ei1oldeidata) \
1904 memcpy ((ei)->data_, ei1oldeidata, ei1oldeibytelen + 1); \ 1908 memcpy ((ei)->data_, ei1oldeidata, ei1oldeibytelen + 1); \
1905 } \ 1909 } \
1906 (ei)->max_size_allocated_ = ei1newsize; \ 1910 (ei)->max_size_allocated_ = ei1newsize; \
1907 } \ 1911 } \
1913 #define EI_ALLOC_AND_COPY(ei, data, bytelen, charlen) \ 1917 #define EI_ALLOC_AND_COPY(ei, data, bytelen, charlen) \
1914 do { \ 1918 do { \
1915 EI_ALLOC (ei, bytelen, charlen, 1); \ 1919 EI_ALLOC (ei, bytelen, charlen, 1); \
1916 memcpy ((ei)->data_, data, (ei)->bytelen_); \ 1920 memcpy ((ei)->data_, data, (ei)->bytelen_); \
1917 } while (0) 1921 } while (0)
1918
1919 #ifdef ERROR_CHECK_TEXT
1920 #define EI_ASSERT_ASCII(ptr, len) \
1921 do { \
1922 int ei5; \
1923 const Char_ASCII *ei5ptr = (ptr); \
1924 int ei5len = (len); \
1925 \
1926 for (ei5 = 0; ei5 < ei5len; ei5++) \
1927 assert (ei5ptr[ei5] >= 0x00 && ei5ptr[ei5] < 0x7F); \
1928 } while (0)
1929 #define EI_ASSERT_ASCIIZ(ptr) \
1930 do { \
1931 const Char_ASCII *ei5p1 = (ptr); \
1932 EI_ASSERT_ASCII (ei5p1, strlen (ei5p1)); \
1933 } while (0)
1934 #else
1935 #define EI_ASSERT_ASCII(ptr, len)
1936 #define EI_ASSERT_ASCIIZ(ptr)
1937 #endif
1938
1939 1922
1940 /* ----- Initialization ----- */ 1923 /* ----- Initialization ----- */
1941 1924
1942 #define eicpy_ei(ei, eicpy) \ 1925 #define eicpy_ei(ei, eicpy) \
1943 do { \ 1926 do { \
1999 EI_ALLOC_AND_COPY (ei, ei12p2, ei12p2len, 1); \ 1982 EI_ALLOC_AND_COPY (ei, ei12p2, ei12p2len, 1); \
2000 } while (0) 1983 } while (0)
2001 1984
2002 #define eicpy_c(ei, c_string) \ 1985 #define eicpy_c(ei, c_string) \
2003 do { \ 1986 do { \
2004 const Char_ASCII *ei4 = (c_string); \ 1987 const Ascbyte *ei4 = (c_string); \
2005 \ 1988 \
2006 EI_ASSERT_ASCIIZ (ei4); \ 1989 ASSERT_ASCTEXT_ASCII (ei4); \
2007 eicpy_ext (ei, ei4, Qbinary); \ 1990 eicpy_ext (ei, ei4, Qbinary); \
2008 } while (0) 1991 } while (0)
2009 1992
2010 #define eicpy_c_len(ei, c_string, c_len) \ 1993 #define eicpy_c_len(ei, c_string, c_len) \
2011 do { \ 1994 do { \
2012 const Char_ASCII *ei6 = (c_string); \ 1995 const Ascbyte *ei6 = (c_string); \
2013 int ei6len = (c_len); \ 1996 int ei6len = (c_len); \
2014 \ 1997 \
2015 EI_ASSERT_ASCII (ei6, ei6len); \ 1998 ASSERT_ASCTEXT_ASCII_LEN (ei6, ei6len); \
2016 eicpy_ext_len (ei, ei6, ei6len, Qbinary); \ 1999 eicpy_ext_len (ei, ei6, ei6len, Qbinary); \
2017 } while (0) 2000 } while (0)
2018 2001
2019 #define eicpy_ext_len(ei, extdata, extlen, codesys) \ 2002 #define eicpy_ext_len(ei, extdata, extlen, codesys) \
2020 do { \ 2003 do { \
2076 Bytecount *ei23lenout = &(lenout); \ 2059 Bytecount *ei23lenout = &(lenout); \
2077 \ 2060 \
2078 assert (ei23fmt == FORMAT_DEFAULT); \ 2061 assert (ei23fmt == FORMAT_DEFAULT); \
2079 \ 2062 \
2080 *ei23lenout = (eistr)->bytelen_; \ 2063 *ei23lenout = (eistr)->bytelen_; \
2081 *ei23ptrout = alloca_array (Ibyte, (eistr)->bytelen_ + 1); \ 2064 *ei23ptrout = alloca_ibytes ((eistr)->bytelen_ + 1); \
2082 memcpy (*ei23ptrout, (eistr)->data_, (eistr)->bytelen_ + 1); \ 2065 memcpy (*ei23ptrout, (eistr)->data_, (eistr)->bytelen_ + 1); \
2083 } while (0) 2066 } while (0)
2084 2067
2085 /* ----- Moving to the heap ----- */ 2068 /* ----- Moving to the heap ----- */
2086 2069
2112 { \ 2095 { \
2113 Ibyte *ei13newdata; \ 2096 Ibyte *ei13newdata; \
2114 \ 2097 \
2115 (ei)->max_size_allocated_ = \ 2098 (ei)->max_size_allocated_ = \
2116 eifind_large_enough_buffer (0, (ei)->bytelen_ + 1); \ 2099 eifind_large_enough_buffer (0, (ei)->bytelen_ + 1); \
2117 ei13newdata = (Ibyte *) ALLOCA ((ei)->max_size_allocated_); \ 2100 ei13newdata = alloca_ibytes ((ei)->max_size_allocated_); \
2118 memcpy (ei13newdata, (ei)->data_, (ei)->bytelen_ + 1); \ 2101 memcpy (ei13newdata, (ei)->data_, (ei)->bytelen_ + 1); \
2119 xfree ((ei)->data_, Ibyte *); \ 2102 xfree ((ei)->data_, Ibyte *); \
2120 (ei)->data_ = ei13newdata; \ 2103 (ei)->data_ = ei13newdata; \
2121 } \ 2104 } \
2122 \ 2105 \
2123 if ((ei)->extdata_) \ 2106 if ((ei)->extdata_) \
2124 { \ 2107 { \
2125 Extbyte *ei13newdata = (Extbyte *) ALLOCA ((ei)->extlen_ + 2); \ 2108 Extbyte *ei13newdata = alloca_extbytes ((ei)->extlen_ + 2); \
2126 \ 2109 \
2127 memcpy (ei13newdata, (ei)->extdata_, (ei)->extlen_); \ 2110 memcpy (ei13newdata, (ei)->extdata_, (ei)->extlen_); \
2128 /* Double null-terminate in case of Unicode data */ \ 2111 /* Double null-terminate in case of Unicode data */ \
2129 ei13newdata[(ei)->extlen_] = '\0'; \ 2112 ei13newdata[(ei)->extlen_] = '\0'; \
2130 ei13newdata[(ei)->extlen_ + 1] = '\0'; \ 2113 ei13newdata[(ei)->extlen_ + 1] = '\0'; \
2224 eicat_1 (ei, ei9->data_, ei9->bytelen_, ei9->charlen_); \ 2207 eicat_1 (ei, ei9->data_, ei9->bytelen_, ei9->charlen_); \
2225 } while (0) 2208 } while (0)
2226 2209
2227 #define eicat_c(ei, c_string) \ 2210 #define eicat_c(ei, c_string) \
2228 do { \ 2211 do { \
2229 const Char_ASCII *ei15 = (c_string); \ 2212 const Ascbyte *ei15 = (c_string); \
2230 int ei15len = strlen (ei15); \ 2213 int ei15len = strlen (ei15); \
2231 \ 2214 \
2232 EI_ASSERT_ASCII (ei15, ei15len); \ 2215 ASSERT_ASCTEXT_ASCII_LEN (ei15, ei15len); \
2233 eicat_1 (ei, ei15, ei15len, \ 2216 eicat_1 (ei, ei15, ei15len, \
2234 bytecount_to_charcount ((Ibyte *) ei15, ei15len)); \ 2217 bytecount_to_charcount ((Ibyte *) ei15, ei15len)); \
2235 } while (0) 2218 } while (0)
2236 2219
2237 #define eicat_raw(ei, data, len) \ 2220 #define eicat_raw(ei, data, len) \
2303 ei19->charlen_); \ 2286 ei19->charlen_); \
2304 } while (0) 2287 } while (0)
2305 2288
2306 #define eisub_c(ei, off, charoff, len, charlen, c_string) \ 2289 #define eisub_c(ei, off, charoff, len, charlen, c_string) \
2307 do { \ 2290 do { \
2308 const Char_ASCII *ei20 = (c_string); \ 2291 const Ascbyte *ei20 = (c_string); \
2309 int ei20len = strlen (ei20); \ 2292 int ei20len = strlen (ei20); \
2310 EI_ASSERT_ASCII (ei20, ei20len); \ 2293 ASSERT_ASCTEXT_ASCII_LEN (ei20, ei20len); \
2311 eisub_1 (ei, off, charoff, len, charlen, ei20, ei20len, -1); \ 2294 eisub_1 (ei, off, charoff, len, charlen, ei20, ei20len, -1); \
2312 } while (0) 2295 } while (0)
2313 2296
2314 #define eisub_ch(ei, off, charoff, len, charlen, ch) \ 2297 #define eisub_ch(ei, off, charoff, len, charlen, ch) \
2315 do { \ 2298 do { \
2444 2427
2445 #define EI_CASECHANGE(ei, downp) \ 2428 #define EI_CASECHANGE(ei, downp) \
2446 do { \ 2429 do { \
2447 int ei11new_allocmax = (ei)->charlen_ * MAX_ICHAR_LEN + 1; \ 2430 int ei11new_allocmax = (ei)->charlen_ * MAX_ICHAR_LEN + 1; \
2448 Ibyte *ei11storage = \ 2431 Ibyte *ei11storage = \
2449 (Ibyte *) alloca_array (Ibyte, ei11new_allocmax); \ 2432 (Ibyte *) alloca_ibytes (ei11new_allocmax); \
2450 int ei11newlen = eistr_casefiddle_1 ((ei)->data_, (ei)->bytelen_, \ 2433 int ei11newlen = eistr_casefiddle_1 ((ei)->data_, (ei)->bytelen_, \
2451 ei11storage, downp); \ 2434 ei11storage, downp); \
2452 \ 2435 \
2453 if (ei11newlen) \ 2436 if (ei11newlen) \
2454 { \ 2437 { \
2523 TO_EXTERNAL_FORMAT (source_type, source, sink_type, sink, codesys) 2506 TO_EXTERNAL_FORMAT (source_type, source, sink_type, sink, codesys)
2524 TO_INTERNAL_FORMAT (source_type, source, sink_type, sink, codesys) 2507 TO_INTERNAL_FORMAT (source_type, source, sink_type, sink, codesys)
2525 2508
2526 Typical use is 2509 Typical use is
2527 2510
2528 TO_EXTERNAL_FORMAT (DATA, (ptr, len), 2511 TO_EXTERNAL_FORMAT (LISP_STRING, str, C_STRING_MALLOC, ptr, Qfile_name);
2529 LISP_BUFFER, buffer, 2512
2530 Qfile_name); 2513 which means that the contents of the lisp string `str' are written
2514 to a malloc'ed memory area which will be pointed to by `ptr', after the
2515 function returns. The conversion will be done using the `file-name'
2516 coding system (which will be controlled by the user indirectly by
2517 setting or binding the variable `file-name-coding-system').
2518
2519 Some sources and sinks require two C variables to specify. We use
2520 some preprocessor magic to allow different source and sink types, and
2521 even different numbers of arguments to specify different types of
2522 sources and sinks.
2523
2524 So we can have a call that looks like
2525
2526 TO_INTERNAL_FORMAT (DATA, (ptr, len),
2527 MALLOC, (ptr, len),
2528 coding_system);
2529
2530 The parenthesized argument pairs are required to make the
2531 preprocessor magic work.
2531 2532
2532 NOTE: GC is inhibited during the entire operation of these macros. This 2533 NOTE: GC is inhibited during the entire operation of these macros. This
2533 is because frequently the data to be converted comes from strings but 2534 is because frequently the data to be converted comes from strings but
2534 gets passed in as just DATA, and GC may move around the string data. If 2535 gets passed in as just DATA, and GC may move around the string data. If
2535 we didn't inhibit GC, there'd have to be a lot of messy recoding, 2536 we didn't inhibit GC, there'd have to be a lot of messy recoding,
2549 LISP_LSTREAM, lstream, // input or output is a Lisp_Object of type lstream 2550 LISP_LSTREAM, lstream, // input or output is a Lisp_Object of type lstream
2550 LISP_OPAQUE, object, // input or output is a Lisp_Object of type opaque 2551 LISP_OPAQUE, object, // input or output is a Lisp_Object of type opaque
2551 2552
2552 When specifying the sink, use lvalues, since the macro will assign to them, 2553 When specifying the sink, use lvalues, since the macro will assign to them,
2553 except when the sink is an lstream or a lisp buffer. 2554 except when the sink is an lstream or a lisp buffer.
2555
2556 For the sink types `ALLOCA' and `C_STRING_ALLOCA', the resulting text is
2557 stored in a stack-allocated buffer, which is automatically freed on
2558 returning from the function. However, the sink types `MALLOC' and
2559 `C_STRING_MALLOC' return `xmalloc()'ed memory. The caller is responsible
2560 for freeing this memory using `xfree()'.
2554 2561
2555 The macros accept the kinds of sources and sinks appropriate for 2562 The macros accept the kinds of sources and sinks appropriate for
2556 internal and external data representation. See the type_checking_assert 2563 internal and external data representation. See the type_checking_assert
2557 macros below for the actual allowed types. 2564 macros below for the actual allowed types.
2558 2565
2605 of whether the conversion is internal or external and regardless of 2612 of whether the conversion is internal or external and regardless of
2606 whether the external coding system is in fact Unicode. This 2613 whether the external coding system is in fact Unicode. This
2607 behavior may change in the future, and you cannot rely on this -- 2614 behavior may change in the future, and you cannot rely on this --
2608 the most you can rely on is that sink data in Unicode format will 2615 the most you can rely on is that sink data in Unicode format will
2609 have two terminating nulls, which combine to form one Unicode null 2616 have two terminating nulls, which combine to form one Unicode null
2610 character. */ 2617 character.
2618
2619 NOTE: You might ask, why are these not written as functions that
2620 *RETURN* the converted string, since that would allow them to be used
2621 much more conveniently, without having to constantly declare temporary
2622 variables? The answer is that in fact I originally did write the
2623 routines that way, but that required either
2624
2625 (a) calling alloca() inside of a function call, or
2626 (b) using expressions separated by commas and a global temporary variable, or
2627 (c) using the GCC extension ({ ... }).
2628
2629 Turned out that all of the above had bugs, all caused by GCC (hence the
2630 comments about "those GCC wankers" and "ream gcc up the ass"). As for
2631 (a), some versions of GCC (especially on Intel platforms), which had
2632 buggy implementations of alloca() that couldn't handle being called
2633 inside of a function call -- they just decremented the stack right in the
2634 middle of pushing args. Oops, crash with stack trashing, very bad. (b)
2635 was an attempt to fix (a), and that led to further GCC crashes, esp. when
2636 you had two such calls in a single subexpression, because GCC couldn't be
2637 counted upon to follow even a minimally reasonable order of execution.
2638 True, you can't count on one argument being evaluated before another, but
2639 GCC would actually interleave them so that the temp var got stomped on by
2640 one while the other was accessing it. So I tried (c), which was
2641 problematic because that GCC extension has more bugs in it than a
2642 termite's nest.
2643
2644 So reluctantly I converted to the current way. Now, that was awhile ago
2645 (c. 1994), and it appears that the bug involving alloca in function calls
2646 has long since been fixed. More recently, I defined the new-dfc routines
2647 down below, which DO allow exactly such convenience of returning your
2648 args rather than store them in temp variables, and I also wrote a
2649 configure check to see whether alloca() causes crashes inside of function
2650 calls, and if so use the portable alloca() implementation in alloca.c.
2651 If you define TEST_NEW_DFC, the old routines get written in terms of the
2652 new ones, and I've had a beta put out with this on and it appeared to
2653 this appears to cause no problems -- so we should consider
2654 switching, and feel no compunctions about writing further such function-
2655 like alloca() routines in lieu of statement-like ones. --ben */
2611 2656
2612 #define TO_EXTERNAL_FORMAT(source_type, source, sink_type, sink, codesys) \ 2657 #define TO_EXTERNAL_FORMAT(source_type, source, sink_type, sink, codesys) \
2613 do { \ 2658 do { \
2614 dfc_conversion_type dfc_simplified_source_type; \ 2659 dfc_conversion_type dfc_simplified_source_type; \
2615 dfc_conversion_type dfc_simplified_sink_type; \ 2660 dfc_conversion_type dfc_simplified_sink_type; \
2800 /* + 2 because we double zero-extended to account for Unicode conversion */ 2845 /* + 2 because we double zero-extended to account for Unicode conversion */
2801 typedef union { char c; void *p; } *dfc_aliasing_voidpp; 2846 typedef union { char c; void *p; } *dfc_aliasing_voidpp;
2802 #define DFC_ALLOCA_USE_CONVERTED_DATA(sink) do { \ 2847 #define DFC_ALLOCA_USE_CONVERTED_DATA(sink) do { \
2803 void * dfc_sink_ret = ALLOCA (dfc_sink.data.len + 2); \ 2848 void * dfc_sink_ret = ALLOCA (dfc_sink.data.len + 2); \
2804 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 2); \ 2849 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 2); \
2805 ((dfc_aliasing_voidpp) &(DFC_CPP_CAR sink))->p = dfc_sink_ret; \ 2850 VOIDP_CAST (DFC_CPP_CAR sink) = dfc_sink_ret; \
2806 (DFC_CPP_CDR sink) = dfc_sink.data.len; \ 2851 (DFC_CPP_CDR sink) = dfc_sink.data.len; \
2807 } while (0) 2852 } while (0)
2808 #define DFC_MALLOC_USE_CONVERTED_DATA(sink) do { \ 2853 #define DFC_MALLOC_USE_CONVERTED_DATA(sink) do { \
2809 void * dfc_sink_ret = xmalloc (dfc_sink.data.len + 2); \ 2854 void * dfc_sink_ret = xmalloc (dfc_sink.data.len + 2); \
2810 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 2); \ 2855 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 2); \
2811 ((dfc_aliasing_voidpp) &(DFC_CPP_CAR sink))->p = dfc_sink_ret; \ 2856 VOIDP_CAST (DFC_CPP_CAR sink) = dfc_sink_ret; \
2812 (DFC_CPP_CDR sink) = dfc_sink.data.len; \ 2857 (DFC_CPP_CDR sink) = dfc_sink.data.len; \
2813 } while (0) 2858 } while (0)
2814 #define DFC_C_STRING_ALLOCA_USE_CONVERTED_DATA(sink) do { \ 2859 #define DFC_C_STRING_ALLOCA_USE_CONVERTED_DATA(sink) do { \
2815 void * dfc_sink_ret = ALLOCA (dfc_sink.data.len + 2); \ 2860 void * dfc_sink_ret = ALLOCA (dfc_sink.data.len + 2); \
2816 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 2); \ 2861 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 2); \
2817 ((dfc_aliasing_voidpp) &(sink))->p = dfc_sink_ret; \ 2862 VOIDP_CAST (sink) = dfc_sink_ret; \
2818 } while (0) 2863 } while (0)
2819 #define DFC_C_STRING_MALLOC_USE_CONVERTED_DATA(sink) do { \ 2864 #define DFC_C_STRING_MALLOC_USE_CONVERTED_DATA(sink) do { \
2820 void * dfc_sink_ret = xmalloc (dfc_sink.data.len + 2); \ 2865 void * dfc_sink_ret = xmalloc (dfc_sink.data.len + 2); \
2821 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 2); \ 2866 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 2); \
2822 ((dfc_aliasing_voidpp) &(sink))->p = dfc_sink_ret; \ 2867 VOIDP_CAST (sink) = dfc_sink_ret; \
2823 } while (0) 2868 } while (0)
2824 #define DFC_LISP_STRING_USE_CONVERTED_DATA(sink) \ 2869 #define DFC_LISP_STRING_USE_CONVERTED_DATA(sink) \
2825 sink = make_string ((Ibyte *) dfc_sink.data.ptr, dfc_sink.data.len) 2870 sink = make_string ((Ibyte *) dfc_sink.data.ptr, dfc_sink.data.len)
2826 #define DFC_LISP_OPAQUE_USE_CONVERTED_DATA(sink) \ 2871 #define DFC_LISP_OPAQUE_USE_CONVERTED_DATA(sink) \
2827 sink = make_opaque (dfc_sink.data.ptr, dfc_sink.data.len) 2872 sink = make_opaque (dfc_sink.data.ptr, dfc_sink.data.len)
2877 2922
2878 #ifdef TEST_NEW_DFC 2923 #ifdef TEST_NEW_DFC
2879 #define C_STRING_TO_EXTERNAL_MALLOC(in, out, codesys) \ 2924 #define C_STRING_TO_EXTERNAL_MALLOC(in, out, codesys) \
2880 do { * (Extbyte **) &(out) = \ 2925 do { * (Extbyte **) &(out) = \
2881 NEW_C_STRING_TO_EXTERNAL_MALLOC (in, codesys); } while (0) 2926 NEW_C_STRING_TO_EXTERNAL_MALLOC (in, codesys); } while (0)
2927 #define SIZED_C_STRING_TO_EXTERNAL_MALLOC(in, inlen, out, codesys) \
2928 do { * (Extbyte **) &(out) = \
2929 NEW_SIZED_C_STRING_TO_EXTERNAL_MALLOC (in, inlen, codesys); } \
2930 while (0)
2882 #define EXTERNAL_TO_C_STRING_MALLOC(in, out, codesys) \ 2931 #define EXTERNAL_TO_C_STRING_MALLOC(in, out, codesys) \
2883 do { * (Ibyte **) &(out) = \ 2932 do { * (Ibyte **) &(out) = \
2884 NEW_EXTERNAL_TO_C_STRING_MALLOC (in, codesys); } while (0) 2933 NEW_EXTERNAL_TO_C_STRING_MALLOC (in, codesys); } while (0)
2934 #define SIZED_EXTERNAL_TO_C_STRING_MALLOC(in, inlen, out, codesys) \
2935 do { * (Ibyte **) &(out) = \
2936 NEW_SIZED_EXTERNAL_TO_C_STRING_MALLOC (in, inlen, codesys); } \
2937 while (0)
2885 #define LISP_STRING_TO_EXTERNAL_MALLOC(in, out, codesys) \ 2938 #define LISP_STRING_TO_EXTERNAL_MALLOC(in, out, codesys) \
2886 do { * (Extbyte **) &(out) = \ 2939 do { * (Extbyte **) &(out) = \
2887 NEW_LISP_STRING_TO_EXTERNAL_MALLOC (in, codesys); } while (0) 2940 NEW_LISP_STRING_TO_EXTERNAL_MALLOC (in, codesys); } while (0)
2888 #else 2941 #else
2889 #define C_STRING_TO_EXTERNAL_MALLOC(in, out, codesys) \ 2942 #define C_STRING_TO_EXTERNAL_MALLOC(in, out, codesys) \
2890 TO_EXTERNAL_FORMAT (C_STRING, in, C_STRING_MALLOC, out, codesys) 2943 TO_EXTERNAL_FORMAT (C_STRING, in, C_STRING_MALLOC, out, codesys)
2944 #define SIZED_C_STRING_TO_EXTERNAL_MALLOC(in, inlen, out, codesys) \
2945 TO_EXTERNAL_FORMAT (DATA, (in, inlen), C_STRING_MALLOC, out, codesys)
2891 #define EXTERNAL_TO_C_STRING_MALLOC(in, out, codesys) \ 2946 #define EXTERNAL_TO_C_STRING_MALLOC(in, out, codesys) \
2892 TO_INTERNAL_FORMAT (C_STRING, in, C_STRING_MALLOC, out, codesys) 2947 TO_INTERNAL_FORMAT (C_STRING, in, C_STRING_MALLOC, out, codesys)
2948 #define SIZED_EXTERNAL_TO_C_STRING_MALLOC(in, inlen, out, codesys) \
2949 TO_INTERNAL_FORMAT (DATA, (in, inlen), C_STRING_MALLOC, out, codesys)
2893 #define LISP_STRING_TO_EXTERNAL_MALLOC(in, out, codesys) \ 2950 #define LISP_STRING_TO_EXTERNAL_MALLOC(in, out, codesys) \
2894 TO_EXTERNAL_FORMAT (LISP_STRING, in, C_STRING_MALLOC, out, codesys) 2951 TO_EXTERNAL_FORMAT (LISP_STRING, in, C_STRING_MALLOC, out, codesys)
2895 #endif /* TEST_NEW_DFC */ 2952 #endif /* TEST_NEW_DFC */
2953
2954 #define C_STRING_TO_SIZED_EXTERNAL_MALLOC(in, out, outlen, codesys) \
2955 TO_EXTERNAL_FORMAT (C_STRING, in, MALLOC, (out, outlen), codesys)
2956 #define SIZED_C_STRING_TO_SIZED_EXTERNAL_MALLOC(in, inlen, out, outlen, \
2957 codesys) \
2958 TO_EXTERNAL_FORMAT (DATA, (in, inlen), MALLOC, (out, outlen), codesys)
2959 #define EXTERNAL_TO_SIZED_C_STRING_MALLOC(in, out, outlen, codesys) \
2960 TO_INTERNAL_FORMAT (C_STRING, in, MALLOC, (out, outlen), codesys)
2961 #define SIZED_EXTERNAL_TO_SIZED_C_STRING_MALLOC(in, inlen, out, outlen, \
2962 codesys) \
2963 TO_INTERNAL_FORMAT (DATA, (in, inlen), MALLOC, (out, outlen), codesys)
2964 #define LISP_STRING_TO_SIZED_EXTERNAL_MALLOC(in, out, outlen, codesys) \
2965 TO_EXTERNAL_FORMAT (LISP_STRING, in, MALLOC, (out, outlen), codesys)
2896 2966
2897 enum new_dfc_src_type 2967 enum new_dfc_src_type
2898 { 2968 {
2899 DFC_EXTERNAL, 2969 DFC_EXTERNAL,
2900 DFC_SIZED_EXTERNAL, 2970 DFC_SIZED_EXTERNAL,
2904 }; 2974 };
2905 2975
2906 MODULE_API void *new_dfc_convert_malloc (const void *src, Bytecount src_size, 2976 MODULE_API void *new_dfc_convert_malloc (const void *src, Bytecount src_size,
2907 enum new_dfc_src_type type, 2977 enum new_dfc_src_type type,
2908 Lisp_Object codesys); 2978 Lisp_Object codesys);
2909 MODULE_API void *new_dfc_convert_alloca (const char *srctext, void *alloca_data); 2979 MODULE_API Bytecount new_dfc_convert_size (const char *srctext,
2910 MODULE_API Bytecount new_dfc_convert_size (const char *srctext, const void *src, 2980 const void *src,
2911 Bytecount src_size, 2981 Bytecount src_size,
2912 enum new_dfc_src_type type, 2982 enum new_dfc_src_type type,
2913 Lisp_Object codesys); 2983 Lisp_Object codesys);
2984 MODULE_API void *new_dfc_convert_copy_data (const char *srctext,
2985 void *alloca_data);
2914 2986
2915 END_C_DECLS 2987 END_C_DECLS
2916 2988
2917 /* Version of EXTERNAL_TO_C_STRING that *RETURNS* the translated string, 2989 /* Version of EXTERNAL_TO_C_STRING that *RETURNS* the translated string,
2918 still in alloca() space. Requires some trickiness to do this, but gets 2990 still in alloca() space. Requires some trickiness to do this, but gets
2930 variable, so that the call to alloca() is outside of 3002 variable, so that the call to alloca() is outside of
2931 new_dfc_convert_alloca(), won't help because the entire NEW_DFC call 3003 new_dfc_convert_alloca(), won't help because the entire NEW_DFC call
2932 could be inside of a function call. */ 3004 could be inside of a function call. */
2933 3005
2934 #define NEW_DFC_CONVERT_1_ALLOCA(src, src_size, type, codesys) \ 3006 #define NEW_DFC_CONVERT_1_ALLOCA(src, src_size, type, codesys) \
2935 new_dfc_convert_alloca \ 3007 new_dfc_convert_copy_data \
2936 (#src, ALLOCA_FUNCALL_OK (new_dfc_convert_size (#src, src, src_size, \ 3008 (#src, ALLOCA_FUNCALL_OK (new_dfc_convert_size (#src, src, src_size, \
2937 type, codesys))) 3009 type, codesys)))
2938 3010
2939 #define NEW_EXTERNAL_TO_C_STRING(src, codesys) \ 3011 #define NEW_EXTERNAL_TO_C_STRING(src, codesys) \
2940 (Ibyte *) NEW_DFC_CONVERT_1_ALLOCA (src, -1, DFC_EXTERNAL, codesys) 3012 (Ibyte *) NEW_DFC_CONVERT_1_ALLOCA (src, -1, DFC_EXTERNAL, codesys)
2957 DFC_LISP_STRING, codesys) 3029 DFC_LISP_STRING, codesys)
2958 #define NEW_LISP_STRING_TO_EXTERNAL_MALLOC(src, codesys) \ 3030 #define NEW_LISP_STRING_TO_EXTERNAL_MALLOC(src, codesys) \
2959 (Extbyte *) new_dfc_convert_malloc (LISP_TO_VOID (src), -1, \ 3031 (Extbyte *) new_dfc_convert_malloc (LISP_TO_VOID (src), -1, \
2960 DFC_LISP_STRING, codesys) 3032 DFC_LISP_STRING, codesys)
2961 3033
2962 /* Standins for various encodings, until we know them better */ 3034 /* Standins for various encodings. */
3035 #ifdef WEXTTEXT_IS_WIDE
3036 #define Qcommand_argument_encoding Qmswindows_unicode
3037 #define Qenvironment_variable_encoding Qmswindows_unicode
3038 #else
2963 #define Qcommand_argument_encoding Qnative 3039 #define Qcommand_argument_encoding Qnative
2964 #define Qenvironment_variable_encoding Qnative 3040 #define Qenvironment_variable_encoding Qnative
3041 #endif
2965 #define Qunix_host_name_encoding Qnative 3042 #define Qunix_host_name_encoding Qnative
2966 #define Qunix_service_name_encoding Qnative 3043 #define Qunix_service_name_encoding Qnative
2967 #define Qmswindows_host_name_encoding Qmswindows_multibyte 3044 #define Qmswindows_host_name_encoding Qmswindows_multibyte
2968 #define Qmswindows_service_name_encoding Qmswindows_multibyte 3045 #define Qmswindows_service_name_encoding Qmswindows_multibyte
2969 3046
2970 /* Standins for various X encodings, until we know them better. 3047 /* Wexttext functions. The type of Wexttext is selected at compile time
3048 and will sometimes be wchar_t, sometimes char. */
3049
3050 int wcscmp_ascii (const wchar_t *s1, const Ascbyte *s2);
3051 int wcsncmp_ascii (const wchar_t *s1, const Ascbyte *s2, Charcount len);
3052
3053 #ifdef WEXTTEXT_IS_WIDE /* defined under MS Windows i.e. WIN32_NATIVE */
3054 #define WEXTTEXT_ZTERM_SIZE sizeof (wchar_t)
3055 /* Extra indirection needed in case of manifest constant as arg */
3056 #define WEXTSTRING_1(arg) L##arg
3057 #define WEXTSTRING(arg) WEXTSTRING_1(arg)
3058 #define wext_strlen wcslen
3059 #define wext_strcmp wcscmp
3060 #define wext_strncmp wcsncmp
3061 #define wext_strcmp_ascii wcscmp_ascii
3062 #define wext_strncmp_ascii wcsncmp_ascii
3063 #define wext_strcpy wcscpy
3064 #define wext_strncpy wcsncpy
3065 #define wext_strchr wcschr
3066 #define wext_strrchr wcsrchr
3067 #define wext_strdup wcsdup
3068 #define wext_atol(str) wcstol (str, 0, 10)
3069 #define wext_sprintf wsprintfW /* Huh? both wsprintfA and wsprintfW? */
3070 #define wext_getenv _wgetenv
3071 #define build_wext_string(str, cs) build_ext_string ((Extbyte *) str, cs)
3072 #define WEXTTEXT_TO_8_BIT(arg) WEXTTEXT_TO_MULTIBYTE(arg)
3073 #ifdef WIN32_NATIVE
3074 int XCDECL wext_retry_open (const Wexttext *path, int oflag, ...);
3075 #else
3076 #error Cannot handle Wexttext yet on this system
3077 #endif
3078 #define wext_access _waccess
3079 #define wext_stat _wstat
3080 #else
3081 #define WEXTTEXT_ZTERM_SIZE sizeof (char)
3082 #define WEXTSTRING(arg) arg
3083 #define wext_strlen strlen
3084 #define wext_strcmp strcmp
3085 #define wext_strncmp strncmp
3086 #define wext_strcmp_ascii strcmp
3087 #define wext_strncmp_ascii strncmp
3088 #define wext_strcpy strcpy
3089 #define wext_strncpy strncpy
3090 #define wext_strchr strchr
3091 #define wext_strrchr strrchr
3092 #define wext_strdup xstrdup
3093 #define wext_atol(str) atol (str)
3094 #define wext_sprintf sprintf
3095 #define wext_getenv getenv
3096 #define build_wext_string build_ext_string
3097 #define wext_retry_open retry_open
3098 #define wext_access access
3099 #define wext_stat stat
3100 #define WEXTTEXT_TO_8_BIT(arg) ((Extbyte *) arg)
3101 #endif
3102
3103 /* Standins for various X encodings.
2971 3104
2972 About encodings in X: 3105 About encodings in X:
2973 3106
2974 X works with 5 different encodings: 3107 X works with 5 different encodings:
2975 3108
3039 #define Qx_application_class_encoding Qx_hpc_encoding 3172 #define Qx_application_class_encoding Qx_hpc_encoding
3040 /* the following probably must agree with Qcommand_argument_encoding and 3173 /* the following probably must agree with Qcommand_argument_encoding and
3041 Qenvironment_variable_encoding */ 3174 Qenvironment_variable_encoding */
3042 #define Qx_display_name_encoding Qx_hpc_encoding 3175 #define Qx_display_name_encoding Qx_hpc_encoding
3043 #define Qx_xpm_data_encoding Qx_hpc_encoding 3176 #define Qx_xpm_data_encoding Qx_hpc_encoding
3177
3178 /* !!#### Verify these! */
3179 #define Qxt_widget_arg_encoding Qnative
3180 #define Qdt_dnd_encoding Qnative
3181 #define Qoffix_dnd_encoding Qnative
3044 3182
3045 /* RedHat 6.2 contains a locale called "Francais" with the C-cedilla 3183 /* RedHat 6.2 contains a locale called "Francais" with the C-cedilla
3046 encoded in ISO2022! */ 3184 encoded in ISO2022! */
3047 #define Qlocale_name_encoding Qctext 3185 #define Qlocale_name_encoding Qctext
3048 3186