Mercurial > hg > xemacs-beta
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 |