Mercurial > hg > xemacs-beta
comparison src/buffer.h @ 412:697ef44129c6 r21-2-14
Import from CVS: tag r21-2-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:20:41 +0200 |
parents | 501cfd01ee6d |
children | 95016f13131a |
comparison
equal
deleted
inserted
replaced
411:12e008d41344 | 412:697ef44129c6 |
---|---|
27 FSF: long ago. | 27 FSF: long ago. |
28 JWZ: separated out bufslots.h, early in Lemacs. | 28 JWZ: separated out bufslots.h, early in Lemacs. |
29 Ben Wing: almost completely rewritten for Mule, 19.12. | 29 Ben Wing: almost completely rewritten for Mule, 19.12. |
30 */ | 30 */ |
31 | 31 |
32 #ifndef INCLUDED_buffer_h_ | 32 #ifndef _XEMACS_BUFFER_H_ |
33 #define INCLUDED_buffer_h_ | 33 #define _XEMACS_BUFFER_H_ |
34 | 34 |
35 #ifdef MULE | 35 #ifdef MULE |
36 #include "mule-charset.h" | 36 #include "mule-charset.h" |
37 #endif | 37 #endif |
38 | 38 |
164 #endif /* REGION_CACHE_NEEDS_WORK */ | 164 #endif /* REGION_CACHE_NEEDS_WORK */ |
165 | 165 |
166 /* The markers that refer to this buffer. This is actually a single | 166 /* The markers that refer to this buffer. This is actually a single |
167 marker -- successive elements in its marker `chain' are the other | 167 marker -- successive elements in its marker `chain' are the other |
168 markers referring to this buffer */ | 168 markers referring to this buffer */ |
169 Lisp_Marker *markers; | 169 struct Lisp_Marker *markers; |
170 | 170 |
171 /* The buffer's extent info. This is its own type, an extent-info | 171 /* The buffer's extent info. This is its own type, an extent-info |
172 object (done this way for ease in marking / finalizing). */ | 172 object (done this way for ease in marking / finalizing). */ |
173 Lisp_Object extent_info; | 173 Lisp_Object extent_info; |
174 | 174 |
196 0 means visited file modtime unknown; in no case complain | 196 0 means visited file modtime unknown; in no case complain |
197 about any mismatch on next save attempt. */ | 197 about any mismatch on next save attempt. */ |
198 int modtime; | 198 int modtime; |
199 | 199 |
200 /* the value of text->modiff at the last auto-save. */ | 200 /* the value of text->modiff at the last auto-save. */ |
201 long auto_save_modified; | 201 int auto_save_modified; |
202 | 202 |
203 /* The time at which we detected a failure to auto-save, | 203 /* The time at which we detected a failure to auto-save, |
204 Or -1 if we didn't have a failure. */ | 204 Or -1 if we didn't have a failure. */ |
205 int auto_save_failure_time; | 205 int auto_save_failure_time; |
206 | 206 |
217 | 217 |
218 DECLARE_LRECORD (buffer, struct buffer); | 218 DECLARE_LRECORD (buffer, struct buffer); |
219 #define XBUFFER(x) XRECORD (x, buffer, struct buffer) | 219 #define XBUFFER(x) XRECORD (x, buffer, struct buffer) |
220 #define XSETBUFFER(x, p) XSETRECORD (x, p, buffer) | 220 #define XSETBUFFER(x, p) XSETRECORD (x, p, buffer) |
221 #define BUFFERP(x) RECORDP (x, buffer) | 221 #define BUFFERP(x) RECORDP (x, buffer) |
222 #define GC_BUFFERP(x) GC_RECORDP (x, buffer) | |
222 #define CHECK_BUFFER(x) CHECK_RECORD (x, buffer) | 223 #define CHECK_BUFFER(x) CHECK_RECORD (x, buffer) |
223 #define CONCHECK_BUFFER(x) CONCHECK_RECORD (x, buffer) | 224 #define CONCHECK_BUFFER(x) CONCHECK_RECORD (x, buffer) |
224 | 225 |
225 #define BUFFER_LIVE_P(b) (!NILP ((b)->name)) | 226 #define BUFFER_LIVE_P(b) (!NILP ((b)->name)) |
226 | 227 |
406 the character it's moving over. */ | 407 the character it's moving over. */ |
407 | 408 |
408 #define REAL_INC_CHARPTR(ptr) \ | 409 #define REAL_INC_CHARPTR(ptr) \ |
409 ((void) ((ptr) += REP_BYTES_BY_FIRST_BYTE (* (unsigned char *) (ptr)))) | 410 ((void) ((ptr) += REP_BYTES_BY_FIRST_BYTE (* (unsigned char *) (ptr)))) |
410 | 411 |
411 #define REAL_INC_CHARBYTIND(ptr,pos) \ | |
412 (pos += REP_BYTES_BY_FIRST_BYTE (* (unsigned char *) (ptr))) | |
413 | |
414 #define REAL_DEC_CHARPTR(ptr) do { \ | 412 #define REAL_DEC_CHARPTR(ptr) do { \ |
415 (ptr)--; \ | 413 (ptr)--; \ |
416 } while (!VALID_CHARPTR_P (ptr)) | 414 } while (!VALID_CHARPTR_P (ptr)) |
417 | 415 |
418 #ifdef ERROR_CHECK_BUFPOS | 416 #ifdef ERROR_CHECK_BUFPOS |
419 #define INC_CHARPTR(ptr) do { \ | 417 #define INC_CHARPTR(ptr) do { \ |
420 ASSERT_VALID_CHARPTR (ptr); \ | 418 ASSERT_VALID_CHARPTR (ptr); \ |
421 REAL_INC_CHARPTR (ptr); \ | 419 REAL_INC_CHARPTR (ptr); \ |
422 } while (0) | 420 } while (0) |
423 | 421 |
424 #define INC_CHARBYTIND(ptr,pos) do { \ | |
425 ASSERT_VALID_CHARPTR (ptr); \ | |
426 REAL_INC_CHARBYTIND (ptr,pos); \ | |
427 } while (0) | |
428 | |
429 #define DEC_CHARPTR(ptr) do { \ | 422 #define DEC_CHARPTR(ptr) do { \ |
430 const Bufbyte *dc_ptr1 = (ptr); \ | 423 CONST Bufbyte *dc_ptr1 = (ptr); \ |
431 const Bufbyte *dc_ptr2 = dc_ptr1; \ | 424 CONST Bufbyte *dc_ptr2 = dc_ptr1; \ |
432 REAL_DEC_CHARPTR (dc_ptr2); \ | 425 REAL_DEC_CHARPTR (dc_ptr2); \ |
433 assert (dc_ptr1 - dc_ptr2 == \ | 426 assert (dc_ptr1 - dc_ptr2 == \ |
434 REP_BYTES_BY_FIRST_BYTE (*dc_ptr2)); \ | 427 REP_BYTES_BY_FIRST_BYTE (*dc_ptr2)); \ |
435 (ptr) = dc_ptr2; \ | 428 (ptr) = dc_ptr2; \ |
436 } while (0) | 429 } while (0) |
437 | 430 |
438 #else /* ! ERROR_CHECK_BUFPOS */ | 431 #else /* ! ERROR_CHECK_BUFPOS */ |
439 #define INC_CHARBYTIND(ptr,pos) REAL_INC_CHARBYTIND (ptr,pos) | |
440 #define INC_CHARPTR(ptr) REAL_INC_CHARPTR (ptr) | 432 #define INC_CHARPTR(ptr) REAL_INC_CHARPTR (ptr) |
441 #define DEC_CHARPTR(ptr) REAL_DEC_CHARPTR (ptr) | 433 #define DEC_CHARPTR(ptr) REAL_DEC_CHARPTR (ptr) |
442 #endif /* ! ERROR_CHECK_BUFPOS */ | 434 #endif /* ! ERROR_CHECK_BUFPOS */ |
443 | 435 |
444 #ifdef MULE | 436 #ifdef MULE |
468 /* -------------------------------------------------------------- */ | 460 /* -------------------------------------------------------------- */ |
469 /* (B) For working with the length (in bytes and characters) of a */ | 461 /* (B) For working with the length (in bytes and characters) of a */ |
470 /* section of internally-formatted text */ | 462 /* section of internally-formatted text */ |
471 /* -------------------------------------------------------------- */ | 463 /* -------------------------------------------------------------- */ |
472 | 464 |
473 INLINE_HEADER const Bufbyte * | 465 INLINE CONST Bufbyte *charptr_n_addr (CONST Bufbyte *ptr, Charcount offset); |
474 charptr_n_addr (const Bufbyte *ptr, Charcount offset); | 466 INLINE CONST Bufbyte * |
475 INLINE_HEADER const Bufbyte * | 467 charptr_n_addr (CONST Bufbyte *ptr, Charcount offset) |
476 charptr_n_addr (const Bufbyte *ptr, Charcount offset) | |
477 { | 468 { |
478 return ptr + charcount_to_bytecount (ptr, offset); | 469 return ptr + charcount_to_bytecount (ptr, offset); |
479 } | 470 } |
480 | 471 |
481 /* -------------------------------------------------------------------- */ | 472 /* -------------------------------------------------------------------- */ |
486 #define simple_set_charptr_emchar(ptr, x) ((ptr)[0] = (Bufbyte) (x), 1) | 477 #define simple_set_charptr_emchar(ptr, x) ((ptr)[0] = (Bufbyte) (x), 1) |
487 #define simple_charptr_copy_char(ptr, ptr2) ((ptr2)[0] = *(ptr), 1) | 478 #define simple_charptr_copy_char(ptr, ptr2) ((ptr2)[0] = *(ptr), 1) |
488 | 479 |
489 #ifdef MULE | 480 #ifdef MULE |
490 | 481 |
491 Emchar non_ascii_charptr_emchar (const Bufbyte *ptr); | 482 Emchar non_ascii_charptr_emchar (CONST Bufbyte *ptr); |
492 Bytecount non_ascii_set_charptr_emchar (Bufbyte *ptr, Emchar c); | 483 Bytecount non_ascii_set_charptr_emchar (Bufbyte *ptr, Emchar c); |
493 Bytecount non_ascii_charptr_copy_char (const Bufbyte *ptr, Bufbyte *ptr2); | 484 Bytecount non_ascii_charptr_copy_char (CONST Bufbyte *ptr, Bufbyte *ptr2); |
494 | 485 |
495 INLINE_HEADER Emchar charptr_emchar (const Bufbyte *ptr); | 486 INLINE Emchar charptr_emchar (CONST Bufbyte *ptr); |
496 INLINE_HEADER Emchar | 487 INLINE Emchar |
497 charptr_emchar (const Bufbyte *ptr) | 488 charptr_emchar (CONST Bufbyte *ptr) |
498 { | 489 { |
499 return BYTE_ASCII_P (*ptr) ? | 490 return BYTE_ASCII_P (*ptr) ? |
500 simple_charptr_emchar (ptr) : | 491 simple_charptr_emchar (ptr) : |
501 non_ascii_charptr_emchar (ptr); | 492 non_ascii_charptr_emchar (ptr); |
502 } | 493 } |
503 | 494 |
504 INLINE_HEADER Bytecount set_charptr_emchar (Bufbyte *ptr, Emchar x); | 495 INLINE Bytecount set_charptr_emchar (Bufbyte *ptr, Emchar x); |
505 INLINE_HEADER Bytecount | 496 INLINE Bytecount |
506 set_charptr_emchar (Bufbyte *ptr, Emchar x) | 497 set_charptr_emchar (Bufbyte *ptr, Emchar x) |
507 { | 498 { |
508 return !CHAR_MULTIBYTE_P (x) ? | 499 return !CHAR_MULTIBYTE_P (x) ? |
509 simple_set_charptr_emchar (ptr, x) : | 500 simple_set_charptr_emchar (ptr, x) : |
510 non_ascii_set_charptr_emchar (ptr, x); | 501 non_ascii_set_charptr_emchar (ptr, x); |
511 } | 502 } |
512 | 503 |
513 INLINE_HEADER Bytecount | 504 INLINE Bytecount charptr_copy_char (CONST Bufbyte *ptr, Bufbyte *ptr2); |
514 charptr_copy_char (const Bufbyte *ptr, Bufbyte *ptr2); | 505 INLINE Bytecount |
515 INLINE_HEADER Bytecount | 506 charptr_copy_char (CONST Bufbyte *ptr, Bufbyte *ptr2) |
516 charptr_copy_char (const Bufbyte *ptr, Bufbyte *ptr2) | |
517 { | 507 { |
518 return BYTE_ASCII_P (*ptr) ? | 508 return BYTE_ASCII_P (*ptr) ? |
519 simple_charptr_copy_char (ptr, ptr2) : | 509 simple_charptr_copy_char (ptr, ptr2) : |
520 non_ascii_charptr_copy_char (ptr, ptr2); | 510 non_ascii_charptr_copy_char (ptr, ptr2); |
521 } | 511 } |
538 | 528 |
539 #ifdef MULE | 529 #ifdef MULE |
540 | 530 |
541 int non_ascii_valid_char_p (Emchar ch); | 531 int non_ascii_valid_char_p (Emchar ch); |
542 | 532 |
543 INLINE_HEADER int valid_char_p (Emchar ch); | 533 INLINE int valid_char_p (Emchar ch); |
544 INLINE_HEADER int | 534 INLINE int |
545 valid_char_p (Emchar ch) | 535 valid_char_p (Emchar ch) |
546 { | 536 { |
547 return ((unsigned int) (ch) <= 0xff) || non_ascii_valid_char_p (ch); | 537 return ((unsigned int) (ch) <= 0xff) || non_ascii_valid_char_p (ch); |
548 } | 538 } |
549 | 539 |
557 | 547 |
558 #define CHAR_OR_CHAR_INTP(x) (CHARP (x) || CHAR_INTP (x)) | 548 #define CHAR_OR_CHAR_INTP(x) (CHARP (x) || CHAR_INTP (x)) |
559 | 549 |
560 #ifdef ERROR_CHECK_TYPECHECK | 550 #ifdef ERROR_CHECK_TYPECHECK |
561 | 551 |
562 INLINE_HEADER Emchar XCHAR_OR_CHAR_INT (Lisp_Object obj); | 552 INLINE Emchar XCHAR_OR_CHAR_INT (Lisp_Object obj); |
563 INLINE_HEADER Emchar | 553 INLINE Emchar |
564 XCHAR_OR_CHAR_INT (Lisp_Object obj) | 554 XCHAR_OR_CHAR_INT (Lisp_Object obj) |
565 { | 555 { |
566 assert (CHAR_OR_CHAR_INTP (obj)); | 556 assert (CHAR_OR_CHAR_INTP (obj)); |
567 return CHARP (obj) ? XCHAR (obj) : XINT (obj); | 557 return CHARP (obj) ? XCHAR (obj) : XINT (obj); |
568 } | 558 } |
569 | 559 |
570 #else | 560 #else |
571 | 561 |
572 #define XCHAR_OR_CHAR_INT(obj) (CHARP (obj) ? XCHAR (obj) : XINT (obj)) | 562 #define XCHAR_OR_CHAR_INT(obj) (CHARP ((obj)) ? XCHAR ((obj)) : XINT ((obj))) |
573 | 563 |
574 #endif | 564 #endif |
575 | 565 |
576 #define CHECK_CHAR_COERCE_INT(x) do { \ | 566 #define CHECK_CHAR_COERCE_INT(x) do { \ |
577 if (CHARP (x)) \ | 567 if (CHARP (x)) \ |
622 /*----------------------------------------------------------------------*/ | 612 /*----------------------------------------------------------------------*/ |
623 /* Converting between positions and addresses */ | 613 /* Converting between positions and addresses */ |
624 /*----------------------------------------------------------------------*/ | 614 /*----------------------------------------------------------------------*/ |
625 | 615 |
626 /* Convert the address of a byte in the buffer into a position. */ | 616 /* Convert the address of a byte in the buffer into a position. */ |
627 INLINE_HEADER Bytind BI_BUF_PTR_BYTE_POS (struct buffer *buf, Bufbyte *ptr); | 617 INLINE Bytind BI_BUF_PTR_BYTE_POS (struct buffer *buf, Bufbyte *ptr); |
628 INLINE_HEADER Bytind | 618 INLINE Bytind |
629 BI_BUF_PTR_BYTE_POS (struct buffer *buf, Bufbyte *ptr) | 619 BI_BUF_PTR_BYTE_POS (struct buffer *buf, Bufbyte *ptr) |
630 { | 620 { |
631 return (ptr - buf->text->beg + 1 | 621 return ((ptr) - (buf)->text->beg + 1 |
632 - ((ptr - buf->text->beg + 1) > buf->text->gpt | 622 - ((ptr - (buf)->text->beg + 1) > (buf)->text->gpt |
633 ? buf->text->gap_size : 0)); | 623 ? (buf)->text->gap_size : 0)); |
634 } | 624 } |
635 | 625 |
636 #define BUF_PTR_BYTE_POS(buf, ptr) \ | 626 #define BUF_PTR_BYTE_POS(buf, ptr) \ |
637 bytind_to_bufpos (buf, BI_BUF_PTR_BYTE_POS (buf, ptr)) | 627 bytind_to_bufpos (buf, BI_BUF_PTR_BYTE_POS (buf, ptr)) |
638 | 628 |
639 /* Address of byte at position POS in buffer. */ | 629 /* Address of byte at position POS in buffer. */ |
640 INLINE_HEADER Bufbyte * BI_BUF_BYTE_ADDRESS (struct buffer *buf, Bytind pos); | 630 INLINE Bufbyte * BI_BUF_BYTE_ADDRESS (struct buffer *buf, Bytind pos); |
641 INLINE_HEADER Bufbyte * | 631 INLINE Bufbyte * |
642 BI_BUF_BYTE_ADDRESS (struct buffer *buf, Bytind pos) | 632 BI_BUF_BYTE_ADDRESS (struct buffer *buf, Bytind pos) |
643 { | 633 { |
644 return (buf->text->beg + | 634 return ((buf)->text->beg + |
645 ((pos >= buf->text->gpt ? (pos + buf->text->gap_size) : pos) | 635 ((pos >= (buf)->text->gpt ? (pos + (buf)->text->gap_size) : pos) |
646 - 1)); | 636 - 1)); |
647 } | 637 } |
648 | 638 |
649 #define BUF_BYTE_ADDRESS(buf, pos) \ | 639 #define BUF_BYTE_ADDRESS(buf, pos) \ |
650 BI_BUF_BYTE_ADDRESS (buf, bufpos_to_bytind (buf, pos)) | 640 BI_BUF_BYTE_ADDRESS (buf, bufpos_to_bytind (buf, pos)) |
651 | 641 |
652 /* Address of byte before position POS in buffer. */ | 642 /* Address of byte before position POS in buffer. */ |
653 INLINE_HEADER Bufbyte * BI_BUF_BYTE_ADDRESS_BEFORE (struct buffer *buf, Bytind pos); | 643 INLINE Bufbyte * BI_BUF_BYTE_ADDRESS_BEFORE (struct buffer *buf, Bytind pos); |
654 INLINE_HEADER Bufbyte * | 644 INLINE Bufbyte * |
655 BI_BUF_BYTE_ADDRESS_BEFORE (struct buffer *buf, Bytind pos) | 645 BI_BUF_BYTE_ADDRESS_BEFORE (struct buffer *buf, Bytind pos) |
656 { | 646 { |
657 return (buf->text->beg + | 647 return ((buf)->text->beg + |
658 ((pos > buf->text->gpt ? (pos + buf->text->gap_size) : pos) | 648 ((pos > (buf)->text->gpt ? (pos + (buf)->text->gap_size) : pos) |
659 - 2)); | 649 - 2)); |
660 } | 650 } |
661 | 651 |
662 #define BUF_BYTE_ADDRESS_BEFORE(buf, pos) \ | 652 #define BUF_BYTE_ADDRESS_BEFORE(buf, pos) \ |
663 BI_BUF_BYTE_ADDRESS_BEFORE (buf, bufpos_to_bytind (buf, pos)) | 653 BI_BUF_BYTE_ADDRESS_BEFORE (buf, bufpos_to_bytind (buf, pos)) |
664 | 654 |
665 /*----------------------------------------------------------------------*/ | 655 /*----------------------------------------------------------------------*/ |
666 /* Converting between byte indices and memory indices */ | 656 /* Converting between byte indices and memory indices */ |
667 /*----------------------------------------------------------------------*/ | 657 /*----------------------------------------------------------------------*/ |
668 | 658 |
669 INLINE_HEADER int valid_memind_p (struct buffer *buf, Memind x); | 659 INLINE int valid_memind_p (struct buffer *buf, Memind x); |
670 INLINE_HEADER int | 660 INLINE int |
671 valid_memind_p (struct buffer *buf, Memind x) | 661 valid_memind_p (struct buffer *buf, Memind x) |
672 { | 662 { |
673 return ((x >= 1 && x <= (Memind) buf->text->gpt) || | 663 return ((x >= 1 && x <= (Memind) (buf)->text->gpt) || |
674 (x > (Memind) (buf->text->gpt + buf->text->gap_size) && | 664 (x > (Memind) ((buf)->text->gpt + (buf)->text->gap_size) && |
675 x <= (Memind) (buf->text->z + buf->text->gap_size))); | 665 x <= (Memind) ((buf)->text->z + (buf)->text->gap_size))); |
676 } | 666 } |
677 | 667 |
678 INLINE_HEADER Memind bytind_to_memind (struct buffer *buf, Bytind x); | 668 INLINE Memind bytind_to_memind (struct buffer *buf, Bytind x); |
679 INLINE_HEADER Memind | 669 INLINE Memind |
680 bytind_to_memind (struct buffer *buf, Bytind x) | 670 bytind_to_memind (struct buffer *buf, Bytind x) |
681 { | 671 { |
682 return (Memind) ((x > buf->text->gpt) ? (x + buf->text->gap_size) : x); | 672 return (Memind) ((x > (buf)->text->gpt) ? (x + (buf)->text->gap_size) : x); |
683 } | 673 } |
684 | 674 |
685 | 675 |
686 INLINE_HEADER Bytind memind_to_bytind (struct buffer *buf, Memind x); | 676 INLINE Bytind memind_to_bytind (struct buffer *buf, Memind x); |
687 INLINE_HEADER Bytind | 677 INLINE Bytind |
688 memind_to_bytind (struct buffer *buf, Memind x) | 678 memind_to_bytind (struct buffer *buf, Memind x) |
689 { | 679 { |
690 #ifdef ERROR_CHECK_BUFPOS | 680 #ifdef ERROR_CHECK_BUFPOS |
691 assert (valid_memind_p (buf, x)); | 681 assert (valid_memind_p (buf, x)); |
692 #endif | 682 #endif |
693 return (Bytind) ((x > (Memind) buf->text->gpt) ? | 683 return (Bytind) ((x > (Memind) (buf)->text->gpt) ? |
694 x - buf->text->gap_size : | 684 x - (buf)->text->gap_size : |
695 x); | 685 x); |
696 } | 686 } |
697 | 687 |
698 #define memind_to_bufpos(buf, x) \ | 688 #define memind_to_bufpos(buf, x) \ |
699 bytind_to_bufpos (buf, memind_to_bytind (buf, x)) | 689 bytind_to_bufpos (buf, memind_to_bytind (buf, x)) |
902 the correct side of the gap */ \ | 892 the correct side of the gap */ \ |
903 (x)--; \ | 893 (x)--; \ |
904 VALIDATE_BYTIND_BACKWARD (buf, x); \ | 894 VALIDATE_BYTIND_BACKWARD (buf, x); \ |
905 } while (0) | 895 } while (0) |
906 | 896 |
907 INLINE_HEADER Bytind prev_bytind (struct buffer *buf, Bytind x); | 897 INLINE Bytind prev_bytind (struct buffer *buf, Bytind x); |
908 INLINE_HEADER Bytind | 898 INLINE Bytind |
909 prev_bytind (struct buffer *buf, Bytind x) | 899 prev_bytind (struct buffer *buf, Bytind x) |
910 { | 900 { |
911 DEC_BYTIND (buf, x); | 901 DEC_BYTIND (buf, x); |
912 return x; | 902 return x; |
913 } | 903 } |
914 | 904 |
915 INLINE_HEADER Bytind next_bytind (struct buffer *buf, Bytind x); | 905 INLINE Bytind next_bytind (struct buffer *buf, Bytind x); |
916 INLINE_HEADER Bytind | 906 INLINE Bytind |
917 next_bytind (struct buffer *buf, Bytind x) | 907 next_bytind (struct buffer *buf, Bytind x) |
918 { | 908 { |
919 INC_BYTIND (buf, x); | 909 INC_BYTIND (buf, x); |
920 return x; | 910 return x; |
921 } | 911 } |
973 64K for width-three characters. | 963 64K for width-three characters. |
974 */ | 964 */ |
975 | 965 |
976 extern short three_to_one_table[]; | 966 extern short three_to_one_table[]; |
977 | 967 |
978 INLINE_HEADER int real_bufpos_to_bytind (struct buffer *buf, Bufpos x); | 968 INLINE int real_bufpos_to_bytind (struct buffer *buf, Bufpos x); |
979 INLINE_HEADER int | 969 INLINE int |
980 real_bufpos_to_bytind (struct buffer *buf, Bufpos x) | 970 real_bufpos_to_bytind (struct buffer *buf, Bufpos x) |
981 { | 971 { |
982 if (x >= buf->text->mule_bufmin && x <= buf->text->mule_bufmax) | 972 if (x >= buf->text->mule_bufmin && x <= buf->text->mule_bufmax) |
983 return (buf->text->mule_bytmin + | 973 return (buf->text->mule_bytmin + |
984 ((x - buf->text->mule_bufmin) << buf->text->mule_shifter) + | 974 ((x - buf->text->mule_bufmin) << buf->text->mule_shifter) + |
985 (buf->text->mule_three_p ? (x - buf->text->mule_bufmin) : 0)); | 975 (buf->text->mule_three_p ? (x - buf->text->mule_bufmin) : 0)); |
986 else | 976 else |
987 return bufpos_to_bytind_func (buf, x); | 977 return bufpos_to_bytind_func (buf, x); |
988 } | 978 } |
989 | 979 |
990 INLINE_HEADER int real_bytind_to_bufpos (struct buffer *buf, Bytind x); | 980 INLINE int real_bytind_to_bufpos (struct buffer *buf, Bytind x); |
991 INLINE_HEADER int | 981 INLINE int |
992 real_bytind_to_bufpos (struct buffer *buf, Bytind x) | 982 real_bytind_to_bufpos (struct buffer *buf, Bytind x) |
993 { | 983 { |
994 if (x >= buf->text->mule_bytmin && x <= buf->text->mule_bytmax) | 984 if (x >= buf->text->mule_bytmin && x <= buf->text->mule_bytmax) |
995 return (buf->text->mule_bufmin + | 985 return (buf->text->mule_bufmin + |
996 ((buf->text->mule_three_p | 986 ((buf->text->mule_three_p |
1038 # define BI_BUF_CHARPTR_COPY_CHAR(buf, pos, str) \ | 1028 # define BI_BUF_CHARPTR_COPY_CHAR(buf, pos, str) \ |
1039 charptr_copy_char (BI_BUF_BYTE_ADDRESS (buf, pos), str) | 1029 charptr_copy_char (BI_BUF_BYTE_ADDRESS (buf, pos), str) |
1040 #define BUF_CHARPTR_COPY_CHAR(buf, pos, str) \ | 1030 #define BUF_CHARPTR_COPY_CHAR(buf, pos, str) \ |
1041 BI_BUF_CHARPTR_COPY_CHAR (buf, bufpos_to_bytind (buf, pos), str) | 1031 BI_BUF_CHARPTR_COPY_CHAR (buf, bufpos_to_bytind (buf, pos), str) |
1042 | 1032 |
1033 | |
1034 | |
1043 | 1035 |
1044 /************************************************************************/ | 1036 /************************************************************************/ |
1045 /* */ | 1037 /* */ |
1046 /* Converting between internal and external format */ | 1038 /* working with externally-formatted data */ |
1047 /* */ | 1039 /* */ |
1048 /************************************************************************/ | 1040 /************************************************************************/ |
1049 /* | 1041 |
1050 All client code should use only the two macros | 1042 /* Sometimes strings need to be converted into one or another |
1051 | 1043 external format, for passing to a library function. (Note |
1052 TO_EXTERNAL_FORMAT (source_type, source, sink_type, sink, coding_system) | 1044 that we encapsulate and automatically convert the arguments |
1053 TO_INTERNAL_FORMAT (source_type, source, sink_type, sink, coding_system) | 1045 of some functions, but not others.) At times this conversion |
1054 | 1046 also has to go the other way -- i.e. when we get external- |
1055 Typical use is | 1047 format strings back from a library function. |
1056 | 1048 */ |
1057 TO_EXTERNAL_FORMAT (DATA, (ptr, len), | |
1058 LISP_BUFFER, buffer, | |
1059 Qfile_name); | |
1060 | |
1061 The source or sink can be specified in one of these ways: | |
1062 | |
1063 DATA, (ptr, len), // input data is a fixed buffer of size len | |
1064 ALLOCA, (ptr, len), // output data is in a alloca()ed buffer of size len | |
1065 MALLOC, (ptr, len), // output data is in a malloc()ed buffer of size len | |
1066 C_STRING_ALLOCA, ptr, // equivalent to ALLOCA (ptr, len_ignored) on output. | |
1067 C_STRING_MALLOC, ptr, // equivalent to MALLOC (ptr, len_ignored) on output. | |
1068 C_STRING, ptr, // equivalent to DATA, (ptr, strlen (ptr) + 1) on input | |
1069 LISP_STRING, string, // input or output is a Lisp_Object of type string | |
1070 LISP_BUFFER, buffer, // output is written to (point) in lisp buffer | |
1071 LISP_LSTREAM, lstream, // input or output is a Lisp_Object of type lstream | |
1072 LISP_OPAQUE, object, // input or output is a Lisp_Object of type opaque | |
1073 | |
1074 When specifying the sink, use lvalues, since the macro will assign to them, | |
1075 except when the sink is an lstream or a lisp buffer. | |
1076 | |
1077 The macros accept the kinds of sources and sinks appropriate for | |
1078 internal and external data representation. See the type_checking_assert | |
1079 macros below for the actual allowed types. | |
1080 | |
1081 Since some sources and sinks use one argument (a Lisp_Object) to | |
1082 specify them, while others take a (pointer, length) pair, we use | |
1083 some C preprocessor trickery to allow pair arguments to be specified | |
1084 by parenthesizing them, as in the examples above. | |
1085 | |
1086 Anything prefixed by dfc_ (`data format conversion') is private. | |
1087 They are only used to implement these macros. | |
1088 | |
1089 Using C_STRING* is appropriate for using with external APIs that take | |
1090 null-terminated strings. For internal data, we should try to be | |
1091 '\0'-clean - i.e. allow arbitrary data to contain embedded '\0'. | |
1092 | |
1093 Sometime in the future we might allow output to C_STRING_ALLOCA or | |
1094 C_STRING_MALLOC _only_ with TO_EXTERNAL_FORMAT(), not | |
1095 TO_INTERNAL_FORMAT(). */ | |
1096 | |
1097 #define TO_EXTERNAL_FORMAT(source_type, source, sink_type, sink, coding_system) \ | |
1098 do { \ | |
1099 dfc_conversion_type dfc_simplified_source_type; \ | |
1100 dfc_conversion_type dfc_simplified_sink_type; \ | |
1101 dfc_conversion_data dfc_source; \ | |
1102 dfc_conversion_data dfc_sink; \ | |
1103 \ | |
1104 type_checking_assert \ | |
1105 ((DFC_TYPE_##source_type == DFC_TYPE_DATA || \ | |
1106 DFC_TYPE_##source_type == DFC_TYPE_C_STRING || \ | |
1107 DFC_TYPE_##source_type == DFC_TYPE_LISP_STRING || \ | |
1108 DFC_TYPE_##source_type == DFC_TYPE_LISP_OPAQUE || \ | |
1109 DFC_TYPE_##source_type == DFC_TYPE_LISP_LSTREAM) \ | |
1110 && \ | |
1111 (DFC_TYPE_##sink_type == DFC_TYPE_ALLOCA || \ | |
1112 DFC_TYPE_##sink_type == DFC_TYPE_MALLOC || \ | |
1113 DFC_TYPE_##sink_type == DFC_TYPE_C_STRING_ALLOCA || \ | |
1114 DFC_TYPE_##sink_type == DFC_TYPE_C_STRING_MALLOC || \ | |
1115 DFC_TYPE_##sink_type == DFC_TYPE_LISP_LSTREAM || \ | |
1116 DFC_TYPE_##sink_type == DFC_TYPE_LISP_OPAQUE)); \ | |
1117 \ | |
1118 DFC_SOURCE_##source_type##_TO_ARGS (source); \ | |
1119 DFC_SINK_##sink_type##_TO_ARGS (sink); \ | |
1120 \ | |
1121 DFC_CONVERT_TO_EXTERNAL_FORMAT (dfc_simplified_source_type, &dfc_source, \ | |
1122 coding_system, \ | |
1123 dfc_simplified_sink_type, &dfc_sink); \ | |
1124 \ | |
1125 DFC_##sink_type##_USE_CONVERTED_DATA (sink); \ | |
1126 } while (0) | |
1127 | |
1128 #define TO_INTERNAL_FORMAT(source_type, source, sink_type, sink, coding_system) \ | |
1129 do { \ | |
1130 dfc_conversion_type dfc_simplified_source_type; \ | |
1131 dfc_conversion_type dfc_simplified_sink_type; \ | |
1132 dfc_conversion_data dfc_source; \ | |
1133 dfc_conversion_data dfc_sink; \ | |
1134 \ | |
1135 type_checking_assert \ | |
1136 ((DFC_TYPE_##source_type == DFC_TYPE_DATA || \ | |
1137 DFC_TYPE_##source_type == DFC_TYPE_C_STRING || \ | |
1138 DFC_TYPE_##source_type == DFC_TYPE_LISP_OPAQUE || \ | |
1139 DFC_TYPE_##source_type == DFC_TYPE_LISP_LSTREAM) \ | |
1140 && \ | |
1141 (DFC_TYPE_##sink_type == DFC_TYPE_ALLOCA || \ | |
1142 DFC_TYPE_##sink_type == DFC_TYPE_MALLOC || \ | |
1143 DFC_TYPE_##sink_type == DFC_TYPE_C_STRING_ALLOCA || \ | |
1144 DFC_TYPE_##sink_type == DFC_TYPE_C_STRING_MALLOC || \ | |
1145 DFC_TYPE_##sink_type == DFC_TYPE_LISP_STRING || \ | |
1146 DFC_TYPE_##sink_type == DFC_TYPE_LISP_LSTREAM || \ | |
1147 DFC_TYPE_##sink_type == DFC_TYPE_LISP_BUFFER)); \ | |
1148 \ | |
1149 DFC_SOURCE_##source_type##_TO_ARGS (source); \ | |
1150 DFC_SINK_##sink_type##_TO_ARGS (sink); \ | |
1151 \ | |
1152 DFC_CONVERT_TO_INTERNAL_FORMAT (dfc_simplified_source_type, &dfc_source, \ | |
1153 coding_system, \ | |
1154 dfc_simplified_sink_type, &dfc_sink); \ | |
1155 \ | |
1156 DFC_##sink_type##_USE_CONVERTED_DATA (sink); \ | |
1157 } while (0) | |
1158 | 1049 |
1159 #ifdef FILE_CODING | 1050 #ifdef FILE_CODING |
1160 #define DFC_CONVERT_TO_EXTERNAL_FORMAT dfc_convert_to_external_format | |
1161 #define DFC_CONVERT_TO_INTERNAL_FORMAT dfc_convert_to_internal_format | |
1162 #else | |
1163 /* ignore coding_system argument */ | |
1164 #define DFC_CONVERT_TO_EXTERNAL_FORMAT(a, b, coding_system, c, d) \ | |
1165 dfc_convert_to_external_format (a, b, c, d) | |
1166 #define DFC_CONVERT_TO_INTERNAL_FORMAT(a, b, coding_system, c, d) \ | |
1167 dfc_convert_to_internal_format (a, b, c, d) | |
1168 #endif | |
1169 | |
1170 typedef union | |
1171 { | |
1172 struct { const void *ptr; size_t len; } data; | |
1173 Lisp_Object lisp_object; | |
1174 } dfc_conversion_data; | |
1175 | |
1176 enum dfc_conversion_type | |
1177 { | |
1178 DFC_TYPE_DATA, | |
1179 DFC_TYPE_ALLOCA, | |
1180 DFC_TYPE_MALLOC, | |
1181 DFC_TYPE_C_STRING, | |
1182 DFC_TYPE_C_STRING_ALLOCA, | |
1183 DFC_TYPE_C_STRING_MALLOC, | |
1184 DFC_TYPE_LISP_STRING, | |
1185 DFC_TYPE_LISP_LSTREAM, | |
1186 DFC_TYPE_LISP_OPAQUE, | |
1187 DFC_TYPE_LISP_BUFFER | |
1188 }; | |
1189 typedef enum dfc_conversion_type dfc_conversion_type; | |
1190 | 1051 |
1191 /* WARNING: These use a static buffer. This can lead to disaster if | 1052 /* WARNING: These use a static buffer. This can lead to disaster if |
1192 these functions are not used *very* carefully. Another reason to only use | 1053 these functions are not used *very* carefully. Under normal |
1193 TO_EXTERNAL_FORMATf() and TO_INTERNAL_FORMAT(). */ | 1054 circumstances, do not call these functions; call the front ends |
1194 void | 1055 below. */ |
1195 dfc_convert_to_external_format (dfc_conversion_type source_type, | 1056 |
1196 dfc_conversion_data *source, | 1057 Extbyte *convert_to_external_format (CONST Bufbyte *ptr, |
1197 #ifdef FILE_CODING | 1058 Bytecount len, |
1198 Lisp_Object coding_system, | 1059 Extcount *len_out, |
1199 #endif | 1060 enum external_data_format fmt); |
1200 dfc_conversion_type sink_type, | 1061 Bufbyte *convert_from_external_format (CONST Extbyte *ptr, |
1201 dfc_conversion_data *sink); | 1062 Extcount len, |
1202 void | 1063 Bytecount *len_out, |
1203 dfc_convert_to_internal_format (dfc_conversion_type source_type, | 1064 enum external_data_format fmt); |
1204 dfc_conversion_data *source, | 1065 |
1205 #ifdef FILE_CODING | 1066 #else /* ! MULE */ |
1206 Lisp_Object coding_system, | 1067 |
1207 #endif | 1068 #define convert_to_external_format(ptr, len, len_out, fmt) \ |
1208 dfc_conversion_type sink_type, | 1069 (*(len_out) = (int) (len), (Extbyte *) (ptr)) |
1209 dfc_conversion_data *sink); | 1070 #define convert_from_external_format(ptr, len, len_out, fmt) \ |
1210 /* CPP Trickery */ | 1071 (*(len_out) = (Bytecount) (len), (Bufbyte *) (ptr)) |
1211 #define DFC_CPP_CAR(x,y) (x) | 1072 |
1212 #define DFC_CPP_CDR(x,y) (y) | 1073 #endif /* ! MULE */ |
1213 | 1074 |
1214 /* Convert `source' to args for dfc_convert_to_*_format() */ | 1075 /* In all of the following macros we use the following general principles: |
1215 #define DFC_SOURCE_DATA_TO_ARGS(val) do { \ | 1076 |
1216 dfc_source.data.ptr = DFC_CPP_CAR val; \ | 1077 -- Functions that work with charptr's accept two sorts of charptr's: |
1217 dfc_source.data.len = DFC_CPP_CDR val; \ | 1078 |
1218 dfc_simplified_source_type = DFC_TYPE_DATA; \ | 1079 a) Pointers to memory with a length specified. The pointer will be |
1219 } while (0) | 1080 fundamentally of type `unsigned char *' (although labelled |
1220 #define DFC_SOURCE_C_STRING_TO_ARGS(val) do { \ | 1081 as `Bufbyte *' for internal-format data and `Extbyte *' for |
1221 dfc_source.data.len = \ | 1082 external-format data) and the length will be fundamentally of |
1222 strlen ((char *) (dfc_source.data.ptr = (val))); \ | 1083 type `int' (although labelled as `Bytecount' for internal-format |
1223 dfc_simplified_source_type = DFC_TYPE_DATA; \ | 1084 data and `Extcount' for external-format data). The length is |
1224 } while (0) | 1085 always a count in bytes. |
1225 #define DFC_SOURCE_LISP_STRING_TO_ARGS(val) do { \ | 1086 b) Zero-terminated pointers; no length specified. The pointer |
1226 Lisp_Object dfc_slsta = (val); \ | 1087 is of type `char *', whether the data pointed to is internal-format |
1227 type_checking_assert (STRINGP (dfc_slsta)); \ | 1088 or external-format. These sorts of pointers are available for |
1228 dfc_source.lisp_object = dfc_slsta; \ | 1089 convenience in working with C library functions and literal |
1229 dfc_simplified_source_type = DFC_TYPE_LISP_STRING; \ | 1090 strings. In general you should use these sorts of pointers only |
1230 } while (0) | 1091 to interface to library routines and not for general manipulation, |
1231 #define DFC_SOURCE_LISP_LSTREAM_TO_ARGS(val) do { \ | 1092 as you are liable to lose embedded nulls and such. This could |
1232 Lisp_Object dfc_sllta = (val); \ | 1093 be a big problem for routines that want Unicode-formatted data, |
1233 type_checking_assert (LSTREAMP (dfc_sllta)); \ | 1094 which is likely to have lots of embedded nulls in it. |
1234 dfc_source.lisp_object = dfc_sllta; \ | 1095 (In the real world, though, external Unicode data will be UTF-8, |
1235 dfc_simplified_source_type = DFC_TYPE_LISP_LSTREAM; \ | 1096 which will not have embedded nulls and is ASCII-compatible - martin) |
1236 } while (0) | 1097 |
1237 #define DFC_SOURCE_LISP_OPAQUE_TO_ARGS(val) do { \ | 1098 -- Functions that work with Lisp strings accept strings as Lisp Objects |
1238 Lisp_Opaque *dfc_slota = XOPAQUE (val); \ | 1099 (as opposed to the `struct Lisp_String *' for some of the other |
1239 dfc_source.data.ptr = OPAQUE_DATA (dfc_slota); \ | 1100 string accessors). This is for convenience in working with the |
1240 dfc_source.data.len = OPAQUE_SIZE (dfc_slota); \ | 1101 functions, as otherwise you will almost always have to call |
1241 dfc_simplified_source_type = DFC_TYPE_DATA; \ | 1102 XSTRING() on the object. |
1242 } while (0) | 1103 |
1243 | 1104 -- Functions that work with charptr's are not guaranteed to copy |
1244 /* Convert `sink' to args for dfc_convert_to_*_format() */ | 1105 their data into alloca()ed space. Functions that work with |
1245 #define DFC_SINK_ALLOCA_TO_ARGS(val) \ | 1106 Lisp strings are, however. The reason is that Lisp strings can |
1246 dfc_simplified_sink_type = DFC_TYPE_DATA | 1107 be relocated any time a GC happens, and it could happen at some |
1247 #define DFC_SINK_C_STRING_ALLOCA_TO_ARGS(val) \ | 1108 rather unexpected times. The internal-external conversion is |
1248 dfc_simplified_sink_type = DFC_TYPE_DATA | 1109 rarely done in time-critical functions, and so the slight |
1249 #define DFC_SINK_MALLOC_TO_ARGS(val) \ | 1110 extra time required for alloca() and copy is well-worth the |
1250 dfc_simplified_sink_type = DFC_TYPE_DATA | 1111 safety of knowing your string data won't be relocated out from |
1251 #define DFC_SINK_C_STRING_MALLOC_TO_ARGS(val) \ | 1112 under you. |
1252 dfc_simplified_sink_type = DFC_TYPE_DATA | 1113 */ |
1253 #define DFC_SINK_LISP_STRING_TO_ARGS(val) \ | 1114 |
1254 dfc_simplified_sink_type = DFC_TYPE_DATA | 1115 |
1255 #define DFC_SINK_LISP_OPAQUE_TO_ARGS(val) \ | 1116 /* Maybe convert charptr's data into ext-format and store the result in |
1256 dfc_simplified_sink_type = DFC_TYPE_DATA | 1117 alloca()'ed space. |
1257 #define DFC_SINK_LISP_LSTREAM_TO_ARGS(val) do { \ | 1118 |
1258 Lisp_Object dfc_sllta = (val); \ | 1119 You may wonder why this is written in this fashion and not as a |
1259 type_checking_assert (LSTREAMP (dfc_sllta)); \ | 1120 function call. With a little trickery it could certainly be |
1260 dfc_sink.lisp_object = dfc_sllta; \ | 1121 written this way, but it won't work because of those DAMN GCC WANKERS |
1261 dfc_simplified_sink_type = DFC_TYPE_LISP_LSTREAM; \ | 1122 who couldn't be bothered to handle alloca() properly on the x86 |
1262 } while (0) | 1123 architecture. (If you put a call to alloca() in the argument to |
1263 #define DFC_SINK_LISP_BUFFER_TO_ARGS(val) do { \ | 1124 a function call, the stack space gets allocated right in the |
1264 struct buffer *dfc_slbta = XBUFFER (val); \ | 1125 middle of the arguments to the function call and you are unbelievably |
1265 dfc_sink.lisp_object = \ | 1126 hosed.) */ |
1266 make_lisp_buffer_output_stream \ | 1127 |
1267 (dfc_slbta, BUF_PT (dfc_slbta), 0); \ | 1128 #ifdef MULE |
1268 dfc_simplified_sink_type = DFC_TYPE_LISP_LSTREAM; \ | 1129 |
1269 } while (0) | 1130 #define GET_CHARPTR_EXT_DATA_ALLOCA(ptr, len, fmt, ptr_out, len_out) do \ |
1270 | 1131 { \ |
1271 /* Assign to the `sink' lvalue(s) using the converted data. */ | 1132 Bytecount gceda_len_in = (Bytecount) (len); \ |
1272 typedef union { char c; void *p; } *dfc_aliasing_voidpp; | 1133 Extcount gceda_len_out; \ |
1273 #define DFC_ALLOCA_USE_CONVERTED_DATA(sink) do { \ | 1134 CONST Bufbyte *gceda_ptr_in = (ptr); \ |
1274 void * dfc_sink_ret = alloca (dfc_sink.data.len + 1); \ | 1135 Extbyte *gceda_ptr_out = \ |
1275 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 1); \ | 1136 convert_to_external_format (gceda_ptr_in, gceda_len_in, \ |
1276 ((dfc_aliasing_voidpp) &(DFC_CPP_CAR sink))->p = dfc_sink_ret; \ | 1137 &gceda_len_out, fmt); \ |
1277 (DFC_CPP_CDR sink) = dfc_sink.data.len; \ | 1138 /* If the new string is identical to the old (will be the case most \ |
1278 } while (0) | 1139 of the time), just return the same string back. This saves \ |
1279 #define DFC_MALLOC_USE_CONVERTED_DATA(sink) do { \ | 1140 on alloca()ing, which can be useful on C alloca() machines and \ |
1280 void * dfc_sink_ret = xmalloc (dfc_sink.data.len + 1); \ | 1141 on stack-space-challenged environments. */ \ |
1281 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 1); \ | 1142 \ |
1282 ((dfc_aliasing_voidpp) &(DFC_CPP_CAR sink))->p = dfc_sink_ret; \ | 1143 if (gceda_len_in == gceda_len_out && \ |
1283 (DFC_CPP_CDR sink) = dfc_sink.data.len; \ | 1144 !memcmp (gceda_ptr_in, gceda_ptr_out, gceda_len_out)) \ |
1284 } while (0) | 1145 { \ |
1285 #define DFC_C_STRING_ALLOCA_USE_CONVERTED_DATA(sink) do { \ | 1146 (ptr_out) = (Extbyte *) gceda_ptr_in; \ |
1286 void * dfc_sink_ret = alloca (dfc_sink.data.len + 1); \ | 1147 } \ |
1287 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 1); \ | 1148 else \ |
1288 (sink) = (char *) dfc_sink_ret; \ | 1149 { \ |
1289 } while (0) | 1150 (ptr_out) = (Extbyte *) alloca (1 + gceda_len_out); \ |
1290 #define DFC_C_STRING_MALLOC_USE_CONVERTED_DATA(sink) do { \ | 1151 memcpy ((void *) ptr_out, gceda_ptr_out, 1 + gceda_len_out); \ |
1291 void * dfc_sink_ret = xmalloc (dfc_sink.data.len + 1); \ | 1152 } \ |
1292 memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 1); \ | 1153 (len_out) = gceda_len_out; \ |
1293 (sink) = (char *) dfc_sink_ret; \ | 1154 } while (0) |
1294 } while (0) | 1155 |
1295 #define DFC_LISP_STRING_USE_CONVERTED_DATA(sink) \ | 1156 #else /* ! MULE */ |
1296 sink = make_string ((Bufbyte *) dfc_sink.data.ptr, dfc_sink.data.len) | 1157 |
1297 #define DFC_LISP_OPAQUE_USE_CONVERTED_DATA(sink) \ | 1158 #define GET_CHARPTR_EXT_DATA_ALLOCA(ptr, len, fmt, ptr_out, len_out) do \ |
1298 sink = make_opaque (dfc_sink.data.ptr, dfc_sink.data.len) | 1159 { \ |
1299 #define DFC_LISP_LSTREAM_USE_CONVERTED_DATA(sink) /* data already used */ | 1160 (ptr_out) = (Extbyte *) (ptr); \ |
1300 #define DFC_LISP_BUFFER_USE_CONVERTED_DATA(sink) \ | 1161 (len_out) = (Extcount) (len); \ |
1301 Lstream_delete (XLSTREAM (dfc_sink.lisp_object)) | 1162 } while (0) |
1302 | 1163 |
1303 /* Someday we might want to distinguish between Qnative and Qfile_name | 1164 #endif /* ! MULE */ |
1304 by using coding-system aliases, but for now it suffices to have | 1165 |
1305 these be identical. Qnative can be used as the coding_system | 1166 #define GET_C_CHARPTR_EXT_DATA_ALLOCA(ptr, fmt, ptr_out) do \ |
1306 argument to TO_EXTERNAL_FORMAT() and TO_INTERNAL_FORMAT(). */ | 1167 { \ |
1307 #define Qnative Qfile_name | 1168 Extcount gcceda_ignored_len; \ |
1308 | 1169 CONST Bufbyte *gcceda_ptr_in = (CONST Bufbyte *) (ptr); \ |
1309 #ifdef HAVE_MS_WINDOWS | 1170 Extbyte *gcceda_ptr_out; \ |
1310 /* #### kludge!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | 1171 \ |
1311 Remove this as soon as my Mule code is integrated. */ | 1172 GET_CHARPTR_EXT_DATA_ALLOCA (gcceda_ptr_in, \ |
1312 #define Qmswindows_tstr Qnative | 1173 strlen ((char *) gcceda_ptr_in), \ |
1313 #endif | 1174 fmt, \ |
1175 gcceda_ptr_out, \ | |
1176 gcceda_ignored_len); \ | |
1177 (ptr_out) = (char *) gcceda_ptr_out; \ | |
1178 } while (0) | |
1179 | |
1180 #define GET_C_CHARPTR_EXT_BINARY_DATA_ALLOCA(ptr, ptr_out) \ | |
1181 GET_C_CHARPTR_EXT_DATA_ALLOCA (ptr, FORMAT_BINARY, ptr_out) | |
1182 #define GET_CHARPTR_EXT_BINARY_DATA_ALLOCA(ptr, len, ptr_out, len_out) \ | |
1183 GET_CHARPTR_EXT_DATA_ALLOCA (ptr, len, FORMAT_BINARY, ptr_out, len_out) | |
1184 | |
1185 #define GET_C_CHARPTR_EXT_FILENAME_DATA_ALLOCA(ptr, ptr_out) \ | |
1186 GET_C_CHARPTR_EXT_DATA_ALLOCA (ptr, FORMAT_FILENAME, ptr_out) | |
1187 #define GET_CHARPTR_EXT_FILENAME_DATA_ALLOCA(ptr, len, ptr_out, len_out) \ | |
1188 GET_CHARPTR_EXT_DATA_ALLOCA (ptr, len, FORMAT_FILENAME, ptr_out, len_out) | |
1189 | |
1190 #define GET_C_CHARPTR_EXT_CTEXT_DATA_ALLOCA(ptr, ptr_out) \ | |
1191 GET_C_CHARPTR_EXT_DATA_ALLOCA (ptr, FORMAT_CTEXT, ptr_out) | |
1192 #define GET_CHARPTR_EXT_CTEXT_DATA_ALLOCA(ptr, len, ptr_out, len_out) \ | |
1193 GET_CHARPTR_EXT_DATA_ALLOCA (ptr, len, FORMAT_CTEXT, ptr_out, len_out) | |
1194 | |
1195 /* Maybe convert external charptr's data into internal format and store | |
1196 the result in alloca()'ed space. | |
1197 | |
1198 You may wonder why this is written in this fashion and not as a | |
1199 function call. With a little trickery it could certainly be | |
1200 written this way, but it won't work because of those DAMN GCC WANKERS | |
1201 who couldn't be bothered to handle alloca() properly on the x86 | |
1202 architecture. (If you put a call to alloca() in the argument to | |
1203 a function call, the stack space gets allocated right in the | |
1204 middle of the arguments to the function call and you are unbelievably | |
1205 hosed.) */ | |
1206 | |
1207 #ifdef MULE | |
1208 | |
1209 #define GET_CHARPTR_INT_DATA_ALLOCA(ptr, len, fmt, ptr_out, len_out) do \ | |
1210 { \ | |
1211 Extcount gcida_len_in = (Extcount) (len); \ | |
1212 Bytecount gcida_len_out; \ | |
1213 CONST Extbyte *gcida_ptr_in = (ptr); \ | |
1214 Bufbyte *gcida_ptr_out = \ | |
1215 convert_from_external_format (gcida_ptr_in, gcida_len_in, \ | |
1216 &gcida_len_out, fmt); \ | |
1217 /* If the new string is identical to the old (will be the case most \ | |
1218 of the time), just return the same string back. This saves \ | |
1219 on alloca()ing, which can be useful on C alloca() machines and \ | |
1220 on stack-space-challenged environments. */ \ | |
1221 \ | |
1222 if (gcida_len_in == gcida_len_out && \ | |
1223 !memcmp (gcida_ptr_in, gcida_ptr_out, gcida_len_out)) \ | |
1224 { \ | |
1225 (ptr_out) = (Bufbyte *) gcida_ptr_in; \ | |
1226 } \ | |
1227 else \ | |
1228 { \ | |
1229 (ptr_out) = (Extbyte *) alloca (1 + gcida_len_out); \ | |
1230 memcpy ((void *) ptr_out, gcida_ptr_out, 1 + gcida_len_out); \ | |
1231 } \ | |
1232 (len_out) = gcida_len_out; \ | |
1233 } while (0) | |
1234 | |
1235 #else /* ! MULE */ | |
1236 | |
1237 #define GET_CHARPTR_INT_DATA_ALLOCA(ptr, len, fmt, ptr_out, len_out) do \ | |
1238 { \ | |
1239 (ptr_out) = (Bufbyte *) (ptr); \ | |
1240 (len_out) = (Bytecount) (len); \ | |
1241 } while (0) | |
1242 | |
1243 #endif /* ! MULE */ | |
1244 | |
1245 #define GET_C_CHARPTR_INT_DATA_ALLOCA(ptr, fmt, ptr_out) do \ | |
1246 { \ | |
1247 Bytecount gccida_ignored_len; \ | |
1248 CONST Extbyte *gccida_ptr_in = (CONST Extbyte *) (ptr); \ | |
1249 Bufbyte *gccida_ptr_out; \ | |
1250 \ | |
1251 GET_CHARPTR_INT_DATA_ALLOCA (gccida_ptr_in, \ | |
1252 strlen ((char *) gccida_ptr_in), \ | |
1253 fmt, \ | |
1254 gccida_ptr_out, \ | |
1255 gccida_ignored_len); \ | |
1256 (ptr_out) = gccida_ptr_out; \ | |
1257 } while (0) | |
1258 | |
1259 #define GET_C_CHARPTR_INT_BINARY_DATA_ALLOCA(ptr, ptr_out) \ | |
1260 GET_C_CHARPTR_INT_DATA_ALLOCA (ptr, FORMAT_BINARY, ptr_out) | |
1261 #define GET_CHARPTR_INT_BINARY_DATA_ALLOCA(ptr, len, ptr_out, len_out) \ | |
1262 GET_CHARPTR_INT_DATA_ALLOCA (ptr, len, FORMAT_BINARY, ptr_out, len_out) | |
1263 | |
1264 #define GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA(ptr, ptr_out) \ | |
1265 GET_C_CHARPTR_INT_DATA_ALLOCA (ptr, FORMAT_FILENAME, ptr_out) | |
1266 #define GET_CHARPTR_INT_FILENAME_DATA_ALLOCA(ptr, len, ptr_out, len_out) \ | |
1267 GET_CHARPTR_INT_DATA_ALLOCA (ptr, len, FORMAT_FILENAME, ptr_out, len_out) | |
1268 | |
1269 #define GET_C_CHARPTR_INT_CTEXT_DATA_ALLOCA(ptr, ptr_out) \ | |
1270 GET_C_CHARPTR_INT_DATA_ALLOCA (ptr, FORMAT_CTEXT, ptr_out) | |
1271 #define GET_CHARPTR_INT_CTEXT_DATA_ALLOCA(ptr, len, ptr_out, len_out) \ | |
1272 GET_CHARPTR_INT_DATA_ALLOCA (ptr, len, FORMAT_CTEXT, ptr_out, len_out) | |
1273 | |
1274 | |
1275 /* Maybe convert Lisp string's data into ext-format and store the result in | |
1276 alloca()'ed space. | |
1277 | |
1278 You may wonder why this is written in this fashion and not as a | |
1279 function call. With a little trickery it could certainly be | |
1280 written this way, but it won't work because of those DAMN GCC WANKERS | |
1281 who couldn't be bothered to handle alloca() properly on the x86 | |
1282 architecture. (If you put a call to alloca() in the argument to | |
1283 a function call, the stack space gets allocated right in the | |
1284 middle of the arguments to the function call and you are unbelievably | |
1285 hosed.) */ | |
1286 | |
1287 #define GET_STRING_EXT_DATA_ALLOCA(s, fmt, ptr_out, len_out) do \ | |
1288 { \ | |
1289 Extcount gseda_len_out; \ | |
1290 struct Lisp_String *gseda_s = XSTRING (s); \ | |
1291 Extbyte * gseda_ptr_out = \ | |
1292 convert_to_external_format (string_data (gseda_s), \ | |
1293 string_length (gseda_s), \ | |
1294 &gseda_len_out, fmt); \ | |
1295 (ptr_out) = (Extbyte *) alloca (1 + gseda_len_out); \ | |
1296 memcpy ((void *) ptr_out, gseda_ptr_out, 1 + gseda_len_out); \ | |
1297 (len_out) = gseda_len_out; \ | |
1298 } while (0) | |
1299 | |
1300 | |
1301 #define GET_C_STRING_EXT_DATA_ALLOCA(s, fmt, ptr_out) do \ | |
1302 { \ | |
1303 Extcount gcseda_ignored_len; \ | |
1304 Extbyte *gcseda_ptr_out; \ | |
1305 \ | |
1306 GET_STRING_EXT_DATA_ALLOCA (s, fmt, gcseda_ptr_out, \ | |
1307 gcseda_ignored_len); \ | |
1308 (ptr_out) = (char *) gcseda_ptr_out; \ | |
1309 } while (0) | |
1310 | |
1311 #define GET_STRING_BINARY_DATA_ALLOCA(s, ptr_out, len_out) \ | |
1312 GET_STRING_EXT_DATA_ALLOCA (s, FORMAT_BINARY, ptr_out, len_out) | |
1313 #define GET_C_STRING_BINARY_DATA_ALLOCA(s, ptr_out) \ | |
1314 GET_C_STRING_EXT_DATA_ALLOCA (s, FORMAT_BINARY, ptr_out) | |
1315 | |
1316 #define GET_STRING_FILENAME_DATA_ALLOCA(s, ptr_out, len_out) \ | |
1317 GET_STRING_EXT_DATA_ALLOCA (s, FORMAT_FILENAME, ptr_out, len_out) | |
1318 #define GET_C_STRING_FILENAME_DATA_ALLOCA(s, ptr_out) \ | |
1319 GET_C_STRING_EXT_DATA_ALLOCA (s, FORMAT_FILENAME, ptr_out) | |
1320 | |
1321 #define GET_STRING_OS_DATA_ALLOCA(s, ptr_out, len_out) \ | |
1322 GET_STRING_EXT_DATA_ALLOCA (s, FORMAT_OS, ptr_out, len_out) | |
1323 #define GET_C_STRING_OS_DATA_ALLOCA(s, ptr_out) \ | |
1324 GET_C_STRING_EXT_DATA_ALLOCA (s, FORMAT_OS, ptr_out) | |
1325 | |
1326 #define GET_STRING_CTEXT_DATA_ALLOCA(s, ptr_out, len_out) \ | |
1327 GET_STRING_EXT_DATA_ALLOCA (s, FORMAT_CTEXT, ptr_out, len_out) | |
1328 #define GET_C_STRING_CTEXT_DATA_ALLOCA(s, ptr_out) \ | |
1329 GET_C_STRING_EXT_DATA_ALLOCA (s, FORMAT_CTEXT, ptr_out) | |
1330 | |
1331 | |
1314 | 1332 |
1315 /************************************************************************/ | 1333 /************************************************************************/ |
1316 /* */ | 1334 /* */ |
1317 /* fake charset functions */ | 1335 /* fake charset functions */ |
1318 /* */ | 1336 /* */ |
1413 /* Face changed. */ | 1431 /* Face changed. */ |
1414 #define BUF_FACECHANGE(buf) ((buf)->face_change) | 1432 #define BUF_FACECHANGE(buf) ((buf)->face_change) |
1415 | 1433 |
1416 #define POINT_MARKER_P(marker) \ | 1434 #define POINT_MARKER_P(marker) \ |
1417 (XMARKER (marker)->buffer != 0 && \ | 1435 (XMARKER (marker)->buffer != 0 && \ |
1418 EQ (marker, XMARKER (marker)->buffer->point_marker)) | 1436 EQ ((marker), XMARKER (marker)->buffer->point_marker)) |
1419 | 1437 |
1420 #define BUF_MARKERS(buf) ((buf)->markers) | 1438 #define BUF_MARKERS(buf) ((buf)->markers) |
1421 | 1439 |
1422 /* WARNING: | 1440 /* WARNING: |
1423 | 1441 |
1540 | 1558 |
1541 /* Allocation of buffer data. */ | 1559 /* Allocation of buffer data. */ |
1542 | 1560 |
1543 #ifdef REL_ALLOC | 1561 #ifdef REL_ALLOC |
1544 | 1562 |
1545 char *r_alloc (unsigned char **, size_t); | 1563 char *r_alloc (unsigned char **, unsigned long); |
1546 char *r_re_alloc (unsigned char **, size_t); | 1564 char *r_re_alloc (unsigned char **, unsigned long); |
1547 void r_alloc_free (unsigned char **); | 1565 void r_alloc_free (unsigned char **); |
1548 | 1566 |
1549 #define BUFFER_ALLOC(data, size) \ | 1567 #define BUFFER_ALLOC(data, size) \ |
1550 ((Bufbyte *) r_alloc ((unsigned char **) &data, (size) * sizeof(Bufbyte))) | 1568 ((Bufbyte *) r_alloc ((unsigned char **) &data, (size) * sizeof(Bufbyte))) |
1551 #define BUFFER_REALLOC(data, size) \ | 1569 #define BUFFER_REALLOC(data, size) \ |
1574 int beginning_of_line_p (struct buffer *b, Bufpos pt); | 1592 int beginning_of_line_p (struct buffer *b, Bufpos pt); |
1575 | 1593 |
1576 /* from insdel.c */ | 1594 /* from insdel.c */ |
1577 void set_buffer_point (struct buffer *buf, Bufpos pos, Bytind bipos); | 1595 void set_buffer_point (struct buffer *buf, Bufpos pos, Bytind bipos); |
1578 void find_charsets_in_bufbyte_string (unsigned char *charsets, | 1596 void find_charsets_in_bufbyte_string (unsigned char *charsets, |
1579 const Bufbyte *str, | 1597 CONST Bufbyte *str, |
1580 Bytecount len); | 1598 Bytecount len); |
1581 void find_charsets_in_emchar_string (unsigned char *charsets, | 1599 void find_charsets_in_emchar_string (unsigned char *charsets, |
1582 const Emchar *str, | 1600 CONST Emchar *str, |
1583 Charcount len); | 1601 Charcount len); |
1584 int bufbyte_string_displayed_columns (const Bufbyte *str, Bytecount len); | 1602 int bufbyte_string_displayed_columns (CONST Bufbyte *str, Bytecount len); |
1585 int emchar_string_displayed_columns (const Emchar *str, Charcount len); | 1603 int emchar_string_displayed_columns (CONST Emchar *str, Charcount len); |
1586 void convert_bufbyte_string_into_emchar_dynarr (const Bufbyte *str, | 1604 void convert_bufbyte_string_into_emchar_dynarr (CONST Bufbyte *str, |
1587 Bytecount len, | 1605 Bytecount len, |
1588 Emchar_dynarr *dyn); | 1606 Emchar_dynarr *dyn); |
1589 Charcount convert_bufbyte_string_into_emchar_string (const Bufbyte *str, | 1607 Charcount convert_bufbyte_string_into_emchar_string (CONST Bufbyte *str, |
1590 Bytecount len, | 1608 Bytecount len, |
1591 Emchar *arr); | 1609 Emchar *arr); |
1592 void convert_emchar_string_into_bufbyte_dynarr (Emchar *arr, int nels, | 1610 void convert_emchar_string_into_bufbyte_dynarr (Emchar *arr, int nels, |
1593 Bufbyte_dynarr *dyn); | 1611 Bufbyte_dynarr *dyn); |
1594 Bufbyte *convert_emchar_string_into_malloced_string (Emchar *arr, int nels, | 1612 Bufbyte *convert_emchar_string_into_malloced_string (Emchar *arr, int nels, |
1680 string_char (XSTRING (table), (Charcount) ch) | 1698 string_char (XSTRING (table), (Charcount) ch) |
1681 # define SET_TRT_TABLE_CHAR_1(table, ch1, ch2) \ | 1699 # define SET_TRT_TABLE_CHAR_1(table, ch1, ch2) \ |
1682 set_string_char (XSTRING (table), (Charcount) ch1, ch2) | 1700 set_string_char (XSTRING (table), (Charcount) ch1, ch2) |
1683 | 1701 |
1684 #ifdef MULE | 1702 #ifdef MULE |
1685 # define MAKE_MIRROR_TRT_TABLE() make_opaque (OPAQUE_CLEAR, 256) | 1703 # define MAKE_MIRROR_TRT_TABLE() make_opaque (256, 0) |
1686 # define MIRROR_TRT_TABLE_AS_STRING(table) ((Bufbyte *) XOPAQUE_DATA (table)) | 1704 # define MIRROR_TRT_TABLE_AS_STRING(table) ((Bufbyte *) XOPAQUE_DATA (table)) |
1687 # define MIRROR_TRT_TABLE_CHAR_1(table, ch) \ | 1705 # define MIRROR_TRT_TABLE_CHAR_1(table, ch) \ |
1688 ((Emchar) (MIRROR_TRT_TABLE_AS_STRING (table)[ch])) | 1706 ((Emchar) (MIRROR_TRT_TABLE_AS_STRING (table)[ch])) |
1689 # define SET_MIRROR_TRT_TABLE_CHAR_1(table, ch1, ch2) \ | 1707 # define SET_MIRROR_TRT_TABLE_CHAR_1(table, ch1, ch2) \ |
1690 (MIRROR_TRT_TABLE_AS_STRING (table)[ch1] = (Bufbyte) (ch2)) | 1708 (MIRROR_TRT_TABLE_AS_STRING (table)[ch1] = (Bufbyte) (ch2)) |
1710 TRT_TABLE_AS_STRING (buf->case_canon_table) | 1728 TRT_TABLE_AS_STRING (buf->case_canon_table) |
1711 #define MIRROR_EQV_TABLE_AS_STRING(buf) \ | 1729 #define MIRROR_EQV_TABLE_AS_STRING(buf) \ |
1712 TRT_TABLE_AS_STRING (buf->case_eqv_table) | 1730 TRT_TABLE_AS_STRING (buf->case_eqv_table) |
1713 #endif | 1731 #endif |
1714 | 1732 |
1715 INLINE_HEADER Emchar TRT_TABLE_OF (Lisp_Object trt, Emchar c); | 1733 INLINE Emchar TRT_TABLE_OF (Lisp_Object trt, Emchar c); |
1716 INLINE_HEADER Emchar | 1734 INLINE Emchar |
1717 TRT_TABLE_OF (Lisp_Object trt, Emchar c) | 1735 TRT_TABLE_OF (Lisp_Object trt, Emchar c) |
1718 { | 1736 { |
1719 return IN_TRT_TABLE_DOMAIN (c) ? TRT_TABLE_CHAR_1 (trt, c) : c; | 1737 return IN_TRT_TABLE_DOMAIN (c) ? TRT_TABLE_CHAR_1 (trt, c) : c; |
1720 } | 1738 } |
1721 | 1739 |
1723 #define DOWNCASE_TABLE_OF(buf, c) TRT_TABLE_OF (buf->downcase_table, c) | 1741 #define DOWNCASE_TABLE_OF(buf, c) TRT_TABLE_OF (buf->downcase_table, c) |
1724 #define UPCASE_TABLE_OF(buf, c) TRT_TABLE_OF (buf->upcase_table, c) | 1742 #define UPCASE_TABLE_OF(buf, c) TRT_TABLE_OF (buf->upcase_table, c) |
1725 | 1743 |
1726 /* 1 if CH is upper case. */ | 1744 /* 1 if CH is upper case. */ |
1727 | 1745 |
1728 INLINE_HEADER int UPPERCASEP (struct buffer *buf, Emchar ch); | 1746 INLINE int UPPERCASEP (struct buffer *buf, Emchar ch); |
1729 INLINE_HEADER int | 1747 INLINE int |
1730 UPPERCASEP (struct buffer *buf, Emchar ch) | 1748 UPPERCASEP (struct buffer *buf, Emchar ch) |
1731 { | 1749 { |
1732 return DOWNCASE_TABLE_OF (buf, ch) != ch; | 1750 return DOWNCASE_TABLE_OF (buf, ch) != ch; |
1733 } | 1751 } |
1734 | 1752 |
1735 /* 1 if CH is lower case. */ | 1753 /* 1 if CH is lower case. */ |
1736 | 1754 |
1737 INLINE_HEADER int LOWERCASEP (struct buffer *buf, Emchar ch); | 1755 INLINE int LOWERCASEP (struct buffer *buf, Emchar ch); |
1738 INLINE_HEADER int | 1756 INLINE int |
1739 LOWERCASEP (struct buffer *buf, Emchar ch) | 1757 LOWERCASEP (struct buffer *buf, Emchar ch) |
1740 { | 1758 { |
1741 return (UPCASE_TABLE_OF (buf, ch) != ch && | 1759 return (UPCASE_TABLE_OF (buf, ch) != ch && |
1742 DOWNCASE_TABLE_OF (buf, ch) == ch); | 1760 DOWNCASE_TABLE_OF (buf, ch) == ch); |
1743 } | 1761 } |
1744 | 1762 |
1745 /* 1 if CH is neither upper nor lower case. */ | 1763 /* 1 if CH is neither upper nor lower case. */ |
1746 | 1764 |
1747 INLINE_HEADER int NOCASEP (struct buffer *buf, Emchar ch); | 1765 INLINE int NOCASEP (struct buffer *buf, Emchar ch); |
1748 INLINE_HEADER int | 1766 INLINE int |
1749 NOCASEP (struct buffer *buf, Emchar ch) | 1767 NOCASEP (struct buffer *buf, Emchar ch) |
1750 { | 1768 { |
1751 return UPCASE_TABLE_OF (buf, ch) == ch; | 1769 return UPCASE_TABLE_OF (buf, ch) == ch; |
1752 } | 1770 } |
1753 | 1771 |
1754 /* Upcase a character, or make no change if that cannot be done. */ | 1772 /* Upcase a character, or make no change if that cannot be done. */ |
1755 | 1773 |
1756 INLINE_HEADER Emchar UPCASE (struct buffer *buf, Emchar ch); | 1774 INLINE Emchar UPCASE (struct buffer *buf, Emchar ch); |
1757 INLINE_HEADER Emchar | 1775 INLINE Emchar |
1758 UPCASE (struct buffer *buf, Emchar ch) | 1776 UPCASE (struct buffer *buf, Emchar ch) |
1759 { | 1777 { |
1760 return (DOWNCASE_TABLE_OF (buf, ch) == ch) ? UPCASE_TABLE_OF (buf, ch) : ch; | 1778 return (DOWNCASE_TABLE_OF (buf, ch) == ch) ? UPCASE_TABLE_OF (buf, ch) : ch; |
1761 } | 1779 } |
1762 | 1780 |
1766 | 1784 |
1767 /* Downcase a character, or make no change if that cannot be done. */ | 1785 /* Downcase a character, or make no change if that cannot be done. */ |
1768 | 1786 |
1769 #define DOWNCASE(buf, ch) DOWNCASE_TABLE_OF (buf, ch) | 1787 #define DOWNCASE(buf, ch) DOWNCASE_TABLE_OF (buf, ch) |
1770 | 1788 |
1771 #endif /* INCLUDED_buffer_h_ */ | 1789 #endif /* _XEMACS_BUFFER_H_ */ |