aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
authorYuan Fu2022-05-07 01:57:39 -0700
committerYuan Fu2022-05-07 01:57:39 -0700
commit82d5e902af68695481b8809e511a7913ef9a75aa (patch)
treee6a366278590e8906a9282d04e48de2061b6fe3f /src/data.c
parent84847cad82e3b667c82f411627cd58d236f55e84 (diff)
parent293a97d61e1977440f96b7fc91f281a06250ea72 (diff)
downloademacs-82d5e902af68695481b8809e511a7913ef9a75aa.tar.gz
emacs-82d5e902af68695481b8809e511a7913ef9a75aa.zip
; Merge from master.
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c95
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
1151DEFUN ("command-modes", Fcommand_modes, Scommand_modes, 1, 1, 0, 1163DEFUN ("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,
2817usage: (< NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) 2833usage: (< 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,
2825usage: (> NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) 2844usage: (> 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,
2833usage: (<= NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) 2855usage: (<= 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,
2841usage: (>= NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */) 2866usage: (>= 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. */
3006char *
3007fixnum_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
2975DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0, 3026DEFUN ("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.
2977Uses a minus sign if negative. 3028Uses 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
2997DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 2, 0, 3051DEFUN ("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");