diff options
| author | Yuan Fu | 2022-05-07 01:57:39 -0700 |
|---|---|---|
| committer | Yuan Fu | 2022-05-07 01:57:39 -0700 |
| commit | 82d5e902af68695481b8809e511a7913ef9a75aa (patch) | |
| tree | e6a366278590e8906a9282d04e48de2061b6fe3f /src/data.c | |
| parent | 84847cad82e3b667c82f411627cd58d236f55e84 (diff) | |
| parent | 293a97d61e1977440f96b7fc91f281a06250ea72 (diff) | |
| download | emacs-82d5e902af68695481b8809e511a7913ef9a75aa.tar.gz emacs-82d5e902af68695481b8809e511a7913ef9a75aa.zip | |
; Merge from master.
Diffstat (limited to 'src/data.c')
| -rw-r--r-- | src/data.c | 95 |
1 files changed, 75 insertions, 20 deletions
diff --git a/src/data.c b/src/data.c index 9c711d20212..a28bf414147 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -211,6 +211,7 @@ for example, (type-of 1) returns `integer'. */) | |||
| 211 | return Qcons; | 211 | return Qcons; |
| 212 | 212 | ||
| 213 | case Lisp_Vectorlike: | 213 | case Lisp_Vectorlike: |
| 214 | /* WARNING!! Keep 'cl--typeof-types' in sync with this code!! */ | ||
| 214 | switch (PSEUDOVECTOR_TYPE (XVECTOR (object))) | 215 | switch (PSEUDOVECTOR_TYPE (XVECTOR (object))) |
| 215 | { | 216 | { |
| 216 | case PVEC_NORMAL_VECTOR: return Qvector; | 217 | case PVEC_NORMAL_VECTOR: return Qvector; |
| @@ -1076,6 +1077,7 @@ Value, if non-nil, is a list (interactive SPEC). */) | |||
| 1076 | (Lisp_Object cmd) | 1077 | (Lisp_Object cmd) |
| 1077 | { | 1078 | { |
| 1078 | Lisp_Object fun = indirect_function (cmd); /* Check cycles. */ | 1079 | Lisp_Object fun = indirect_function (cmd); /* Check cycles. */ |
| 1080 | bool genfun = false; | ||
| 1079 | 1081 | ||
| 1080 | if (NILP (fun)) | 1082 | if (NILP (fun)) |
| 1081 | return Qnil; | 1083 | return Qnil; |
| @@ -1094,10 +1096,10 @@ Value, if non-nil, is a list (interactive SPEC). */) | |||
| 1094 | 1096 | ||
| 1095 | if (SUBRP (fun)) | 1097 | if (SUBRP (fun)) |
| 1096 | { | 1098 | { |
| 1097 | if (SUBR_NATIVE_COMPILEDP (fun) && !NILP (XSUBR (fun)->native_intspec)) | 1099 | if (SUBR_NATIVE_COMPILEDP (fun) && !NILP (XSUBR (fun)->intspec.native)) |
| 1098 | return XSUBR (fun)->native_intspec; | 1100 | return XSUBR (fun)->intspec.native; |
| 1099 | 1101 | ||
| 1100 | const char *spec = XSUBR (fun)->intspec; | 1102 | const char *spec = XSUBR (fun)->intspec.string; |
| 1101 | if (spec) | 1103 | if (spec) |
| 1102 | return list2 (Qinteractive, | 1104 | return list2 (Qinteractive, |
| 1103 | (*spec != '(') ? build_string (spec) : | 1105 | (*spec != '(') ? build_string (spec) : |
| @@ -1108,15 +1110,17 @@ Value, if non-nil, is a list (interactive SPEC). */) | |||
| 1108 | if (PVSIZE (fun) > COMPILED_INTERACTIVE) | 1110 | if (PVSIZE (fun) > COMPILED_INTERACTIVE) |
| 1109 | { | 1111 | { |
| 1110 | Lisp_Object form = AREF (fun, COMPILED_INTERACTIVE); | 1112 | Lisp_Object form = AREF (fun, COMPILED_INTERACTIVE); |
| 1111 | if (VECTORP (form)) | 1113 | /* The vector form is the new form, where the first |
| 1112 | /* The vector form is the new form, where the first | 1114 | element is the interactive spec, and the second is the |
| 1113 | element is the interactive spec, and the second is the | 1115 | command modes. */ |
| 1114 | command modes. */ | 1116 | return list2 (Qinteractive, VECTORP (form) ? AREF (form, 0) : form); |
| 1115 | return list2 (Qinteractive, AREF (form, 0)); | ||
| 1116 | else | ||
| 1117 | /* Old form -- just the interactive spec. */ | ||
| 1118 | return list2 (Qinteractive, form); | ||
| 1119 | } | 1117 | } |
| 1118 | else if (PVSIZE (fun) > COMPILED_DOC_STRING) | ||
| 1119 | { | ||
| 1120 | Lisp_Object doc = AREF (fun, COMPILED_DOC_STRING); | ||
| 1121 | /* An invalid "docstring" is a sign that we have an OClosure. */ | ||
| 1122 | genfun = !(NILP (doc) || VALID_DOCSTRING_P (doc)); | ||
| 1123 | } | ||
| 1120 | } | 1124 | } |
| 1121 | #ifdef HAVE_MODULES | 1125 | #ifdef HAVE_MODULES |
| 1122 | else if (MODULE_FUNCTIONP (fun)) | 1126 | else if (MODULE_FUNCTIONP (fun)) |
| @@ -1139,13 +1143,21 @@ Value, if non-nil, is a list (interactive SPEC). */) | |||
| 1139 | if (EQ (funcar, Qclosure)) | 1143 | if (EQ (funcar, Qclosure)) |
| 1140 | form = Fcdr (form); | 1144 | form = Fcdr (form); |
| 1141 | Lisp_Object spec = Fassq (Qinteractive, form); | 1145 | Lisp_Object spec = Fassq (Qinteractive, form); |
| 1142 | if (NILP (Fcdr (Fcdr (spec)))) | 1146 | if (NILP (spec) && VALID_DOCSTRING_P (CAR_SAFE (form))) |
| 1147 | /* A "docstring" is a sign that we may have an OClosure. */ | ||
| 1148 | genfun = true; | ||
| 1149 | else if (NILP (Fcdr (Fcdr (spec)))) | ||
| 1143 | return spec; | 1150 | return spec; |
| 1144 | else | 1151 | else |
| 1145 | return list2 (Qinteractive, Fcar (Fcdr (spec))); | 1152 | return list2 (Qinteractive, Fcar (Fcdr (spec))); |
| 1146 | } | 1153 | } |
| 1147 | } | 1154 | } |
| 1148 | return Qnil; | 1155 | if (genfun |
| 1156 | /* Avoid burping during bootstrap. */ | ||
| 1157 | && !NILP (Fsymbol_function (Qoclosure_interactive_form))) | ||
| 1158 | return call1 (Qoclosure_interactive_form, fun); | ||
| 1159 | else | ||
| 1160 | return Qnil; | ||
| 1149 | } | 1161 | } |
| 1150 | 1162 | ||
| 1151 | DEFUN ("command-modes", Fcommand_modes, Scommand_modes, 1, 1, 0, | 1163 | DEFUN ("command-modes", Fcommand_modes, Scommand_modes, 1, 1, 0, |
| @@ -1171,7 +1183,11 @@ The value, if non-nil, is a list of mode name symbols. */) | |||
| 1171 | fun = Fsymbol_function (fun); | 1183 | fun = Fsymbol_function (fun); |
| 1172 | } | 1184 | } |
| 1173 | 1185 | ||
| 1174 | if (COMPILEDP (fun)) | 1186 | if (SUBRP (fun)) |
| 1187 | { | ||
| 1188 | return XSUBR (fun)->command_modes; | ||
| 1189 | } | ||
| 1190 | else if (COMPILEDP (fun)) | ||
| 1175 | { | 1191 | { |
| 1176 | if (PVSIZE (fun) <= COMPILED_INTERACTIVE) | 1192 | if (PVSIZE (fun) <= COMPILED_INTERACTIVE) |
| 1177 | return Qnil; | 1193 | return Qnil; |
| @@ -2817,6 +2833,9 @@ DEFUN ("<", Flss, Slss, 1, MANY, 0, | |||
| 2817 | usage: (< NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) | 2833 | usage: (< NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) |
| 2818 | (ptrdiff_t nargs, Lisp_Object *args) | 2834 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2819 | { | 2835 | { |
| 2836 | if (nargs == 2 && FIXNUMP (args[0]) && FIXNUMP (args[1])) | ||
| 2837 | return XFIXNUM (args[0]) < XFIXNUM (args[1]) ? Qt : Qnil; | ||
| 2838 | |||
| 2820 | return arithcompare_driver (nargs, args, ARITH_LESS); | 2839 | return arithcompare_driver (nargs, args, ARITH_LESS); |
| 2821 | } | 2840 | } |
| 2822 | 2841 | ||
| @@ -2825,6 +2844,9 @@ DEFUN (">", Fgtr, Sgtr, 1, MANY, 0, | |||
| 2825 | usage: (> NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) | 2844 | usage: (> NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) |
| 2826 | (ptrdiff_t nargs, Lisp_Object *args) | 2845 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2827 | { | 2846 | { |
| 2847 | if (nargs == 2 && FIXNUMP (args[0]) && FIXNUMP (args[1])) | ||
| 2848 | return XFIXNUM (args[0]) > XFIXNUM (args[1]) ? Qt : Qnil; | ||
| 2849 | |||
| 2828 | return arithcompare_driver (nargs, args, ARITH_GRTR); | 2850 | return arithcompare_driver (nargs, args, ARITH_GRTR); |
| 2829 | } | 2851 | } |
| 2830 | 2852 | ||
| @@ -2833,6 +2855,9 @@ DEFUN ("<=", Fleq, Sleq, 1, MANY, 0, | |||
| 2833 | usage: (<= NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) | 2855 | usage: (<= NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) |
| 2834 | (ptrdiff_t nargs, Lisp_Object *args) | 2856 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2835 | { | 2857 | { |
| 2858 | if (nargs == 2 && FIXNUMP (args[0]) && FIXNUMP (args[1])) | ||
| 2859 | return XFIXNUM (args[0]) <= XFIXNUM (args[1]) ? Qt : Qnil; | ||
| 2860 | |||
| 2836 | return arithcompare_driver (nargs, args, ARITH_LESS_OR_EQUAL); | 2861 | return arithcompare_driver (nargs, args, ARITH_LESS_OR_EQUAL); |
| 2837 | } | 2862 | } |
| 2838 | 2863 | ||
| @@ -2841,6 +2866,9 @@ DEFUN (">=", Fgeq, Sgeq, 1, MANY, 0, | |||
| 2841 | usage: (>= NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) | 2866 | usage: (>= NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) |
| 2842 | (ptrdiff_t nargs, Lisp_Object *args) | 2867 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2843 | { | 2868 | { |
| 2869 | if (nargs == 2 && FIXNUMP (args[0]) && FIXNUMP (args[1])) | ||
| 2870 | return XFIXNUM (args[0]) >= XFIXNUM (args[1]) ? Qt : Qnil; | ||
| 2871 | |||
| 2844 | return arithcompare_driver (nargs, args, ARITH_GRTR_OR_EQUAL); | 2872 | return arithcompare_driver (nargs, args, ARITH_GRTR_OR_EQUAL); |
| 2845 | } | 2873 | } |
| 2846 | 2874 | ||
| @@ -2972,6 +3000,29 @@ cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max) | |||
| 2972 | return val; | 3000 | return val; |
| 2973 | } | 3001 | } |
| 2974 | 3002 | ||
| 3003 | /* Render NUMBER in decimal into BUFFER which ends right before END. | ||
| 3004 | Return the start of the string; the end is always at END. | ||
| 3005 | The string is not null-terminated. */ | ||
| 3006 | char * | ||
| 3007 | fixnum_to_string (EMACS_INT number, char *buffer, char *end) | ||
| 3008 | { | ||
| 3009 | EMACS_INT x = number; | ||
| 3010 | bool negative = x < 0; | ||
| 3011 | if (negative) | ||
| 3012 | x = -x; | ||
| 3013 | char *p = end; | ||
| 3014 | do | ||
| 3015 | { | ||
| 3016 | eassume (p > buffer && p - 1 < end); | ||
| 3017 | *--p = '0' + x % 10; | ||
| 3018 | x /= 10; | ||
| 3019 | } | ||
| 3020 | while (x); | ||
| 3021 | if (negative) | ||
| 3022 | *--p = '-'; | ||
| 3023 | return p; | ||
| 3024 | } | ||
| 3025 | |||
| 2975 | DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0, | 3026 | DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0, |
| 2976 | doc: /* Return the decimal representation of NUMBER as a string. | 3027 | doc: /* Return the decimal representation of NUMBER as a string. |
| 2977 | Uses a minus sign if negative. | 3028 | Uses a minus sign if negative. |
| @@ -2979,19 +3030,22 @@ NUMBER may be an integer or a floating point number. */) | |||
| 2979 | (Lisp_Object number) | 3030 | (Lisp_Object number) |
| 2980 | { | 3031 | { |
| 2981 | char buffer[max (FLOAT_TO_STRING_BUFSIZE, INT_BUFSIZE_BOUND (EMACS_INT))]; | 3032 | char buffer[max (FLOAT_TO_STRING_BUFSIZE, INT_BUFSIZE_BOUND (EMACS_INT))]; |
| 2982 | int len; | ||
| 2983 | 3033 | ||
| 2984 | CHECK_NUMBER (number); | 3034 | if (FIXNUMP (number)) |
| 3035 | { | ||
| 3036 | char *end = buffer + sizeof buffer; | ||
| 3037 | char *p = fixnum_to_string (XFIXNUM (number), buffer, end); | ||
| 3038 | return make_unibyte_string (p, end - p); | ||
| 3039 | } | ||
| 2985 | 3040 | ||
| 2986 | if (BIGNUMP (number)) | 3041 | if (BIGNUMP (number)) |
| 2987 | return bignum_to_string (number, 10); | 3042 | return bignum_to_string (number, 10); |
| 2988 | 3043 | ||
| 2989 | if (FLOATP (number)) | 3044 | if (FLOATP (number)) |
| 2990 | len = float_to_string (buffer, XFLOAT_DATA (number)); | 3045 | return make_unibyte_string (buffer, |
| 2991 | else | 3046 | float_to_string (buffer, XFLOAT_DATA (number))); |
| 2992 | len = sprintf (buffer, "%"pI"d", XFIXNUM (number)); | ||
| 2993 | 3047 | ||
| 2994 | return make_unibyte_string (buffer, len); | 3048 | wrong_type_argument (Qnumberp, number); |
| 2995 | } | 3049 | } |
| 2996 | 3050 | ||
| 2997 | DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 2, 0, | 3051 | DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 2, 0, |
| @@ -4085,6 +4139,7 @@ syms_of_data (void) | |||
| 4085 | DEFSYM (Qchar_table_p, "char-table-p"); | 4139 | DEFSYM (Qchar_table_p, "char-table-p"); |
| 4086 | DEFSYM (Qvector_or_char_table_p, "vector-or-char-table-p"); | 4140 | DEFSYM (Qvector_or_char_table_p, "vector-or-char-table-p"); |
| 4087 | DEFSYM (Qfixnum_or_symbol_with_pos_p, "fixnum-or-symbol-with-pos-p"); | 4141 | DEFSYM (Qfixnum_or_symbol_with_pos_p, "fixnum-or-symbol-with-pos-p"); |
| 4142 | DEFSYM (Qoclosure_interactive_form, "oclosure-interactive-form"); | ||
| 4088 | 4143 | ||
| 4089 | DEFSYM (Qsubrp, "subrp"); | 4144 | DEFSYM (Qsubrp, "subrp"); |
| 4090 | DEFSYM (Qunevalled, "unevalled"); | 4145 | DEFSYM (Qunevalled, "unevalled"); |