Mercurial > hg > xemacs-beta
comparison src/lisp.h @ 3063:d30cd499e445
[xemacs-hg @ 2005-11-13 10:48:01 by ben]
further error-checking, etc.
alloc.c, lrecord.h: Move around the handling of setting of lheader->uid so it's in
set_lheader_implementation() -- that way, even non-MC-ALLOC builds
get useful uid's in their bare lrecords. Redo related code for
strings so the non-ascii count that is stored in the uid isn't hosed.
events.c: Save and restore the uid around event zeroing/deadbeefing.
lisp.h: Set the correct value of MAX_STRING_ASCII_BEGIN under MC_ALLOC.
lisp.h: rearrange the basic code handling ints and chars. basic int stuff goes
first, followed by basic char stuff, followed in turn by stuff that
mixes ints and chars. this is required since some basic defn's have
become inline functions.
XCHAR and CHARP have additional error-checking in that they check to make
sure that the value in question is not just a character but a valid
character (i.e. its numeric value is valid).
print.c: debug_p4 now has a useful UID in all cases and uses it; but it also prints
the raw header address (previously, you just got one of them).
text.h: some basic char defn's that belonged in lisp.h have been moved there.
valid_ichar_p() is moved too since the inline functions need it.
author | ben |
---|---|
date | Sun, 13 Nov 2005 10:48:04 +0000 |
parents | 1e7cc382eb16 |
children | d9ca850d40de 3742ea8250b5 |
comparison
equal
deleted
inserted
replaced
3062:21d92abaac3a | 3063:d30cd499e445 |
---|---|
2312 Ibyte *data_; | 2312 Ibyte *data_; |
2313 Lisp_Object plist; | 2313 Lisp_Object plist; |
2314 }; | 2314 }; |
2315 typedef struct Lisp_String Lisp_String; | 2315 typedef struct Lisp_String Lisp_String; |
2316 | 2316 |
2317 #ifdef MC_ALLOC | |
2318 #define MAX_STRING_ASCII_BEGIN ((1 << 22) - 1) | |
2319 #else | |
2317 #define MAX_STRING_ASCII_BEGIN ((1 << 21) - 1) | 2320 #define MAX_STRING_ASCII_BEGIN ((1 << 21) - 1) |
2321 #endif | |
2318 | 2322 |
2319 DECLARE_MODULE_API_LRECORD (string, Lisp_String); | 2323 DECLARE_MODULE_API_LRECORD (string, Lisp_String); |
2320 #define XSTRING(x) XRECORD (x, string, Lisp_String) | 2324 #define XSTRING(x) XRECORD (x, string, Lisp_String) |
2321 #define wrap_string(p) wrap_record (p, string) | 2325 #define wrap_string(p) wrap_record (p, string) |
2322 #define STRINGP(x) RECORDP (x, string) | 2326 #define STRINGP(x) RECORDP (x, string) |
2557 /* if (INTP (XMARKER (x)->lheader.next.v)) ABORT (); */ | 2561 /* if (INTP (XMARKER (x)->lheader.next.v)) ABORT (); */ |
2558 | 2562 |
2559 #define marker_next(m) ((m)->next) | 2563 #define marker_next(m) ((m)->next) |
2560 #define marker_prev(m) ((m)->prev) | 2564 #define marker_prev(m) ((m)->prev) |
2561 | 2565 |
2566 /*-------------------basic int (no connection to char)------------------*/ | |
2567 | |
2568 #define ZEROP(x) EQ (x, Qzero) | |
2569 | |
2570 #ifdef ERROR_CHECK_TYPES | |
2571 | |
2572 #define XINT(x) XINT_1 (x, __FILE__, __LINE__) | |
2573 | |
2574 DECLARE_INLINE_HEADER ( | |
2575 EMACS_INT | |
2576 XINT_1 (Lisp_Object obj, const Ascbyte *file, int line) | |
2577 ) | |
2578 { | |
2579 assert_at_line (INTP (obj), file, line); | |
2580 return XREALINT (obj); | |
2581 } | |
2582 | |
2583 #else /* no error checking */ | |
2584 | |
2585 #define XINT(obj) XREALINT (obj) | |
2586 | |
2587 #endif /* no error checking */ | |
2588 | |
2589 #define CHECK_INT(x) do { \ | |
2590 if (!INTP (x)) \ | |
2591 dead_wrong_type_argument (Qintegerp, x); \ | |
2592 } while (0) | |
2593 | |
2594 #define CONCHECK_INT(x) do { \ | |
2595 if (!INTP (x)) \ | |
2596 x = wrong_type_argument (Qintegerp, x); \ | |
2597 } while (0) | |
2598 | |
2599 #define NATNUMP(x) (INTP (x) && XINT (x) >= 0) | |
2600 | |
2601 #define CHECK_NATNUM(x) do { \ | |
2602 if (!NATNUMP (x)) \ | |
2603 dead_wrong_type_argument (Qnatnump, x); \ | |
2604 } while (0) | |
2605 | |
2606 #define CONCHECK_NATNUM(x) do { \ | |
2607 if (!NATNUMP (x)) \ | |
2608 x = wrong_type_argument (Qnatnump, x); \ | |
2609 } while (0) | |
2610 | |
2562 /*------------------------------- char ---------------------------------*/ | 2611 /*------------------------------- char ---------------------------------*/ |
2563 | 2612 |
2564 #define CHARP(x) (XTYPE (x) == Lisp_Type_Char) | 2613 /* NOTE: There are basic functions for converting between a character and |
2614 the string representation of a character in text.h, as well as lots of | |
2615 other character-related stuff. There are other functions/macros for | |
2616 working with Ichars in charset.h, for retrieving the charset of an | |
2617 Ichar, the length of an Ichar when converted to text, etc. | |
2618 */ | |
2619 | |
2620 #ifdef MULE | |
2621 | |
2622 MODULE_API int non_ascii_valid_ichar_p (Ichar ch); | |
2623 | |
2624 /* Return whether the given Ichar is valid. | |
2625 */ | |
2626 | |
2627 DECLARE_INLINE_HEADER ( | |
2628 int | |
2629 valid_ichar_p (Ichar ch) | |
2630 ) | |
2631 { | |
2632 return (! (ch & ~0xFF)) || non_ascii_valid_ichar_p (ch); | |
2633 } | |
2634 | |
2635 #else /* not MULE */ | |
2636 | |
2637 /* This works when CH is negative, and correctly returns non-zero only when CH | |
2638 is in the range [0, 255], inclusive. */ | |
2639 #define valid_ichar_p(ch) (! (ch & ~0xFF)) | |
2640 | |
2641 #endif /* not MULE */ | |
2565 | 2642 |
2566 #ifdef ERROR_CHECK_TYPES | 2643 #ifdef ERROR_CHECK_TYPES |
2644 | |
2645 DECLARE_INLINE_HEADER ( | |
2646 int | |
2647 CHARP_1 (Lisp_Object obj, const Ascbyte *file, int line) | |
2648 ) | |
2649 { | |
2650 if (XTYPE (obj) != Lisp_Type_Char) | |
2651 return 0; | |
2652 assert_at_line (valid_ichar_p (XCHARVAL (obj)), file, line); | |
2653 return 1; | |
2654 } | |
2655 | |
2656 #define CHARP(x) CHARP_1 (x, __FILE__, __LINE__) | |
2567 | 2657 |
2568 DECLARE_INLINE_HEADER ( | 2658 DECLARE_INLINE_HEADER ( |
2569 Ichar | 2659 Ichar |
2570 XCHAR_1 (Lisp_Object obj, const Ascbyte *file, int line) | 2660 XCHAR_1 (Lisp_Object obj, const Ascbyte *file, int line) |
2571 ) | 2661 ) |
2572 { | 2662 { |
2663 Ichar ch; | |
2573 assert_at_line (CHARP (obj), file, line); | 2664 assert_at_line (CHARP (obj), file, line); |
2574 return XCHARVAL (obj); | 2665 ch = XCHARVAL (obj); |
2666 assert_at_line (valid_ichar_p (ch), file, line); | |
2667 return ch; | |
2575 } | 2668 } |
2576 | 2669 |
2577 #define XCHAR(x) XCHAR_1 (x, __FILE__, __LINE__) | 2670 #define XCHAR(x) XCHAR_1 (x, __FILE__, __LINE__) |
2578 | 2671 |
2579 #else /* no error checking */ | 2672 #else /* not ERROR_CHECK_TYPES */ |
2580 | 2673 |
2674 #define CHARP(x) (XTYPE (x) == Lisp_Type_Char) | |
2581 #define XCHAR(x) ((Ichar) XCHARVAL (x)) | 2675 #define XCHAR(x) ((Ichar) XCHARVAL (x)) |
2582 | 2676 |
2583 #endif /* no error checking */ | 2677 #endif /* (else) not ERROR_CHECK_TYPES */ |
2584 | 2678 |
2585 #define CHECK_CHAR(x) CHECK_NONRECORD (x, Lisp_Type_Char, Qcharacterp) | 2679 #define CONCHECK_CHAR(x) do { \ |
2586 #define CONCHECK_CHAR(x) CONCHECK_NONRECORD (x, Lisp_Type_Char, Qcharacterp) | 2680 if (!CHARP (x)) \ |
2587 | 2681 x = wrong_type_argument (Qcharacterp, x); \ |
2588 | 2682 } while (0) |
2589 /*------------------------------ float ---------------------------------*/ | 2683 |
2590 | 2684 #define CHECK_CHAR(x) do { \ |
2591 /* Note: the 'unused_next_' field exists only to ensure that the | 2685 if (!CHARP (x)) \ |
2592 `next' pointer fits within the structure, for the purposes of the | 2686 dead_wrong_type_argument (Qcharacterp, x); \ |
2593 free list. This makes a difference in the unlikely case of | 2687 } while (0) |
2594 sizeof(double) being smaller than sizeof(void *). */ | 2688 |
2595 | 2689 |
2596 struct Lisp_Float | 2690 DECLARE_INLINE_HEADER ( |
2597 { | 2691 Lisp_Object |
2598 struct lrecord_header lheader; | 2692 make_char (Ichar val) |
2599 union { double d; struct Lisp_Float *unused_next_; } data; | 2693 ) |
2600 }; | 2694 { |
2601 typedef struct Lisp_Float Lisp_Float; | 2695 type_checking_assert (valid_ichar_p (val)); |
2602 | 2696 /* This is defined in lisp-union.h or lisp-disunion.h */ |
2603 DECLARE_LRECORD (float, Lisp_Float); | 2697 return make_char_1 (val); |
2604 #define XFLOAT(x) XRECORD (x, float, Lisp_Float) | 2698 } |
2605 #define wrap_float(p) wrap_record (p, float) | 2699 |
2606 #define FLOATP(x) RECORDP (x, float) | 2700 /*------------------------- int-char connection ------------------------*/ |
2607 #define CHECK_FLOAT(x) CHECK_RECORD (x, float) | |
2608 #define CONCHECK_FLOAT(x) CONCHECK_RECORD (x, float) | |
2609 | |
2610 #define float_data(f) ((f)->data.d) | |
2611 #define XFLOAT_DATA(x) float_data (XFLOAT (x)) | |
2612 | |
2613 #define XFLOATINT(n) extract_float (n) | |
2614 | |
2615 #define CHECK_INT_OR_FLOAT(x) do { \ | |
2616 if (!INT_OR_FLOATP (x)) \ | |
2617 dead_wrong_type_argument (Qnumberp, x); \ | |
2618 } while (0) | |
2619 | |
2620 #define CONCHECK_INT_OR_FLOAT(x) do { \ | |
2621 if (!INT_OR_FLOATP (x)) \ | |
2622 x = wrong_type_argument (Qnumberp, x); \ | |
2623 } while (0) | |
2624 | |
2625 # define INT_OR_FLOATP(x) (INTP (x) || FLOATP (x)) | |
2626 | |
2627 /*-------------------------------- int ---------------------------------*/ | |
2628 | |
2629 #define ZEROP(x) EQ (x, Qzero) | |
2630 | 2701 |
2631 #ifdef ERROR_CHECK_TYPES | 2702 #ifdef ERROR_CHECK_TYPES |
2632 | 2703 |
2633 #define XCHAR_OR_INT(x) XCHAR_OR_INT_1 (x, __FILE__, __LINE__) | 2704 #define XCHAR_OR_INT(x) XCHAR_OR_INT_1 (x, __FILE__, __LINE__) |
2634 #define XINT(x) XINT_1 (x, __FILE__, __LINE__) | |
2635 | |
2636 DECLARE_INLINE_HEADER ( | |
2637 EMACS_INT | |
2638 XINT_1 (Lisp_Object obj, const Ascbyte *file, int line) | |
2639 ) | |
2640 { | |
2641 assert_at_line (INTP (obj), file, line); | |
2642 return XREALINT (obj); | |
2643 } | |
2644 | 2705 |
2645 DECLARE_INLINE_HEADER ( | 2706 DECLARE_INLINE_HEADER ( |
2646 EMACS_INT | 2707 EMACS_INT |
2647 XCHAR_OR_INT_1 (Lisp_Object obj, const Ascbyte *file, int line) | 2708 XCHAR_OR_INT_1 (Lisp_Object obj, const Ascbyte *file, int line) |
2648 ) | 2709 ) |
2651 return CHARP (obj) ? XCHAR (obj) : XINT (obj); | 2712 return CHARP (obj) ? XCHAR (obj) : XINT (obj); |
2652 } | 2713 } |
2653 | 2714 |
2654 #else /* no error checking */ | 2715 #else /* no error checking */ |
2655 | 2716 |
2656 #define XINT(obj) XREALINT (obj) | |
2657 #define XCHAR_OR_INT(obj) (CHARP (obj) ? XCHAR (obj) : XINT (obj)) | 2717 #define XCHAR_OR_INT(obj) (CHARP (obj) ? XCHAR (obj) : XINT (obj)) |
2658 | 2718 |
2659 #endif /* no error checking */ | 2719 #endif /* no error checking */ |
2660 | 2720 |
2661 #define CHECK_INT(x) do { \ | 2721 /* True of X is an integer whose value is the valid integral equivalent of a |
2662 if (!INTP (x)) \ | 2722 character. */ |
2663 dead_wrong_type_argument (Qintegerp, x); \ | 2723 |
2664 } while (0) | 2724 #define CHAR_INTP(x) (INTP (x) && valid_ichar_p (XINT (x))) |
2665 | 2725 |
2666 #define CONCHECK_INT(x) do { \ | 2726 /* True of X is a character or an integral value that can be converted into a |
2667 if (!INTP (x)) \ | 2727 character. */ |
2668 x = wrong_type_argument (Qintegerp, x); \ | 2728 #define CHAR_OR_CHAR_INTP(x) (CHARP (x) || CHAR_INTP (x)) |
2669 } while (0) | 2729 |
2670 | 2730 DECLARE_INLINE_HEADER ( |
2671 #define NATNUMP(x) (INTP (x) && XINT (x) >= 0) | 2731 Ichar |
2672 | 2732 XCHAR_OR_CHAR_INT (Lisp_Object obj) |
2673 #define CHECK_NATNUM(x) do { \ | 2733 ) |
2674 if (!NATNUMP (x)) \ | 2734 { |
2675 dead_wrong_type_argument (Qnatnump, x); \ | 2735 return CHARP (obj) ? XCHAR (obj) : XINT (obj); |
2676 } while (0) | 2736 } |
2677 | 2737 |
2678 #define CONCHECK_NATNUM(x) do { \ | 2738 /* Signal an error if CH is not a valid character or integer Lisp_Object. |
2679 if (!NATNUMP (x)) \ | 2739 If CH is an integer Lisp_Object, convert it to a character Lisp_Object, |
2680 x = wrong_type_argument (Qnatnump, x); \ | 2740 but merely by repackaging, without performing tests for char validity. |
2741 */ | |
2742 | |
2743 #define CHECK_CHAR_COERCE_INT(x) do { \ | |
2744 if (CHARP (x)) \ | |
2745 ; \ | |
2746 else if (CHAR_INTP (x)) \ | |
2747 x = make_char (XINT (x)); \ | |
2748 else \ | |
2749 x = wrong_type_argument (Qcharacterp, x); \ | |
2681 } while (0) | 2750 } while (0) |
2682 | 2751 |
2683 /* next three always continuable because they coerce their arguments. */ | 2752 /* next three always continuable because they coerce their arguments. */ |
2684 #define CHECK_INT_COERCE_CHAR(x) do { \ | 2753 #define CHECK_INT_COERCE_CHAR(x) do { \ |
2685 if (INTP (x)) \ | 2754 if (INTP (x)) \ |
2708 x = make_int (marker_position (x)); \ | 2777 x = make_int (marker_position (x)); \ |
2709 else \ | 2778 else \ |
2710 x = wrong_type_argument (Qinteger_char_or_marker_p, x); \ | 2779 x = wrong_type_argument (Qinteger_char_or_marker_p, x); \ |
2711 } while (0) | 2780 } while (0) |
2712 | 2781 |
2782 /*------------------------------ float ---------------------------------*/ | |
2783 | |
2784 /* Note: the 'unused_next_' field exists only to ensure that the | |
2785 `next' pointer fits within the structure, for the purposes of the | |
2786 free list. This makes a difference in the unlikely case of | |
2787 sizeof(double) being smaller than sizeof(void *). */ | |
2788 | |
2789 struct Lisp_Float | |
2790 { | |
2791 struct lrecord_header lheader; | |
2792 union { double d; struct Lisp_Float *unused_next_; } data; | |
2793 }; | |
2794 typedef struct Lisp_Float Lisp_Float; | |
2795 | |
2796 DECLARE_LRECORD (float, Lisp_Float); | |
2797 #define XFLOAT(x) XRECORD (x, float, Lisp_Float) | |
2798 #define wrap_float(p) wrap_record (p, float) | |
2799 #define FLOATP(x) RECORDP (x, float) | |
2800 #define CHECK_FLOAT(x) CHECK_RECORD (x, float) | |
2801 #define CONCHECK_FLOAT(x) CONCHECK_RECORD (x, float) | |
2802 | |
2803 #define float_data(f) ((f)->data.d) | |
2804 #define XFLOAT_DATA(x) float_data (XFLOAT (x)) | |
2805 | |
2806 #define XFLOATINT(n) extract_float (n) | |
2807 | |
2808 #define CHECK_INT_OR_FLOAT(x) do { \ | |
2809 if (!INT_OR_FLOATP (x)) \ | |
2810 dead_wrong_type_argument (Qnumberp, x); \ | |
2811 } while (0) | |
2812 | |
2813 #define CONCHECK_INT_OR_FLOAT(x) do { \ | |
2814 if (!INT_OR_FLOATP (x)) \ | |
2815 x = wrong_type_argument (Qnumberp, x); \ | |
2816 } while (0) | |
2817 | |
2818 # define INT_OR_FLOATP(x) (INTP (x) || FLOATP (x)) | |
2713 | 2819 |
2714 /*--------------------------- readonly objects -------------------------*/ | 2820 /*--------------------------- readonly objects -------------------------*/ |
2715 | 2821 |
2716 #ifndef MC_ALLOC | 2822 #ifndef MC_ALLOC |
2717 #define CHECK_C_WRITEABLE(obj) \ | 2823 #define CHECK_C_WRITEABLE(obj) \ |