comparison src/fns.c @ 434:9d177e8d4150 r21-2-25

Import from CVS: tag r21-2-25
author cvs
date Mon, 13 Aug 2007 11:30:53 +0200
parents 3ecd8885ac67
children 84b14dcb0985
comparison
equal deleted inserted replaced
433:892ca416f0fb 434:9d177e8d4150
1892 if (nil_means_not_present && NILP (v)) continue; 1892 if (nil_means_not_present && NILP (v)) continue;
1893 for (i = 0; i < fill; i++) 1893 for (i = 0; i < fill; i++)
1894 { 1894 {
1895 if (!laxp ? EQ (k, keys [i]) : internal_equal (k, keys [i], depth)) 1895 if (!laxp ? EQ (k, keys [i]) : internal_equal (k, keys [i], depth))
1896 { 1896 {
1897 if ((eqp 1897 if (eqp
1898 /* We narrowly escaped being Ebolified here. */ 1898 /* We narrowly escaped being Ebolified here. */
1899 ? !EQ_WITH_EBOLA_NOTICE (v, vals [i]) 1899 ? !EQ_WITH_EBOLA_NOTICE (v, vals [i])
1900 : !internal_equal (v, vals [i], depth))) 1900 : !internal_equal (v, vals [i], depth))
1901 /* a property in B has a different value than in A */ 1901 /* a property in B has a different value than in A */
1902 goto MISMATCH; 1902 goto MISMATCH;
1903 flags [i] = 1; 1903 flags [i] = 1;
1904 break; 1904 break;
1905 } 1905 }
2862 return internal_old_equal (obj1, obj2, 0) ? Qt : Qnil; 2862 return internal_old_equal (obj1, obj2, 0) ? Qt : Qnil;
2863 } 2863 }
2864 2864
2865 2865
2866 DEFUN ("fillarray", Ffillarray, 2, 2, 0, /* 2866 DEFUN ("fillarray", Ffillarray, 2, 2, 0, /*
2867 Store each element of ARRAY with ITEM. 2867 Destructively modify ARRAY by replacing each element with ITEM.
2868 ARRAY is a vector, bit vector, or string. 2868 ARRAY is a vector, bit vector, or string.
2869 */ 2869 */
2870 (array, item)) 2870 (array, item))
2871 { 2871 {
2872 retry: 2872 retry:
2873 if (STRINGP (array)) 2873 if (STRINGP (array))
2874 { 2874 {
2875 Emchar charval;
2876 struct Lisp_String *s = XSTRING (array); 2875 struct Lisp_String *s = XSTRING (array);
2877 Charcount len = string_char_length (s); 2876 Bytecount old_bytecount = string_length (s);
2878 Charcount i; 2877 Bytecount new_bytecount;
2878 Bytecount item_bytecount;
2879 Bufbyte item_buf[MAX_EMCHAR_LEN];
2880 Bufbyte *p;
2881 Bufbyte *end;
2882
2879 CHECK_CHAR_COERCE_INT (item); 2883 CHECK_CHAR_COERCE_INT (item);
2880 CHECK_LISP_WRITEABLE (array); 2884 CHECK_LISP_WRITEABLE (array);
2881 charval = XCHAR (item); 2885
2882 for (i = 0; i < len; i++) 2886 item_bytecount = set_charptr_emchar (item_buf, XCHAR (item));
2883 set_string_char (s, i, charval); 2887 new_bytecount = item_bytecount * string_char_length (s);
2888
2889 resize_string (s, -1, new_bytecount - old_bytecount);
2890
2891 for (p = string_data (s), end = p + new_bytecount;
2892 p < end;
2893 p += item_bytecount)
2894 memcpy (p, item_buf, item_bytecount);
2895 *p = '\0';
2896
2884 bump_string_modiff (array); 2897 bump_string_modiff (array);
2885 } 2898 }
2886 else if (VECTORP (array)) 2899 else if (VECTORP (array))
2887 { 2900 {
2888 Lisp_Object *p = XVECTOR_DATA (array); 2901 Lisp_Object *p = XVECTOR_DATA (array);
3041 } 3054 }
3042 RETURN_UNGCPRO (Qnil); /* No non-nil args provided. */ 3055 RETURN_UNGCPRO (Qnil); /* No non-nil args provided. */
3043 } 3056 }
3044 3057
3045 3058
3046 /* This is the guts of all mapping functions. 3059 /* This is the guts of several mapping functions.
3047 Apply fn to each element of seq, one by one, 3060 Apply FUNCTION to each element of SEQUENCE, one by one,
3048 storing the results into elements of vals, a C vector of Lisp_Objects. 3061 storing the results into elements of VALS, a C vector of Lisp_Objects.
3049 leni is the length of vals, which should also be the length of seq. 3062 LENI is the length of VALS, which should also be the length of SEQUENCE.
3050 3063
3051 If VALS is a null pointer, do not accumulate the results. */ 3064 If VALS is a null pointer, do not accumulate the results. */
3052 3065
3053 static void 3066 static void
3054 mapcar1 (size_t leni, Lisp_Object *vals, Lisp_Object fn, Lisp_Object seq) 3067 mapcar1 (size_t leni, Lisp_Object *vals,
3068 Lisp_Object function, Lisp_Object sequence)
3055 { 3069 {
3056 Lisp_Object result; 3070 Lisp_Object result;
3057 Lisp_Object args[2]; 3071 Lisp_Object args[2];
3058 int i; 3072 int i;
3059 struct gcpro gcpro1; 3073 struct gcpro gcpro1;
3062 { 3076 {
3063 GCPRO1 (vals[0]); 3077 GCPRO1 (vals[0]);
3064 gcpro1.nvars = 0; 3078 gcpro1.nvars = 0;
3065 } 3079 }
3066 3080
3067 args[0] = fn; 3081 args[0] = function;
3068 3082
3069 if (LISTP (seq)) 3083 if (LISTP (sequence))
3070 { 3084 {
3071 for (i = 0; i < leni; i++) 3085 /* A devious `function' could either:
3072 { 3086 - insert garbage into the list in front of us, causing XCDR to crash
3073 args[1] = XCAR (seq); 3087 - amputate the list behind us using (setcdr), causing the remaining
3074 seq = XCDR (seq); 3088 elts to lose their GCPRO status.
3075 result = Ffuncall (2, args); 3089
3076 if (vals) vals[gcpro1.nvars++] = result; 3090 if (vals != 0) we avoid this by copying the elts into the
3077 } 3091 `vals' array. By a stroke of luck, `vals' is exactly large
3078 } 3092 enough to hold the elts left to be traversed as well as the
3079 else if (VECTORP (seq)) 3093 results computed so far.
3080 { 3094
3081 Lisp_Object *objs = XVECTOR_DATA (seq); 3095 if (vals == 0) we don't have any free space available and
3096 don't want to eat up any more stack with alloca().
3097 So we use EXTERNAL_LIST_LOOP_3 and GCPRO the tail. */
3098
3099 if (vals)
3100 {
3101 Lisp_Object *val = vals;
3102 Lisp_Object elt;
3103
3104 LIST_LOOP_2 (elt, sequence)
3105 *val++ = elt;
3106
3107 gcpro1.nvars = leni;
3108
3109 for (i = 0; i < leni; i++)
3110 {
3111 args[1] = vals[i];
3112 vals[i] = Ffuncall (2, args);
3113 }
3114 }
3115 else
3116 {
3117 Lisp_Object elt, tail;
3118 struct gcpro ngcpro1;
3119
3120 NGCPRO1 (tail);
3121
3122 {
3123 EXTERNAL_LIST_LOOP_3 (elt, sequence, tail)
3124 {
3125 args[1] = elt;
3126 Ffuncall (2, args);
3127 }
3128 }
3129
3130 NUNGCPRO;
3131 }
3132 }
3133 else if (VECTORP (sequence))
3134 {
3135 Lisp_Object *objs = XVECTOR_DATA (sequence);
3082 for (i = 0; i < leni; i++) 3136 for (i = 0; i < leni; i++)
3083 { 3137 {
3084 args[1] = *objs++; 3138 args[1] = *objs++;
3085 result = Ffuncall (2, args); 3139 result = Ffuncall (2, args);
3086 if (vals) vals[gcpro1.nvars++] = result; 3140 if (vals) vals[gcpro1.nvars++] = result;
3087 } 3141 }
3088 } 3142 }
3089 else if (STRINGP (seq)) 3143 else if (STRINGP (sequence))
3090 { 3144 {
3091 Bufbyte *p = XSTRING_DATA (seq); 3145 /* The string data of `sequence' might be relocated during GC. */
3092 for (i = 0; i < leni; i++) 3146 Bytecount slen = XSTRING_LENGTH (sequence);
3147 Bufbyte *p = alloca_array (Bufbyte, slen);
3148 Bufbyte *end = p + slen;
3149
3150 memcpy (p, XSTRING_DATA (sequence), slen);
3151
3152 while (p < end)
3093 { 3153 {
3094 args[1] = make_char (charptr_emchar (p)); 3154 args[1] = make_char (charptr_emchar (p));
3095 INC_CHARPTR (p); 3155 INC_CHARPTR (p);
3096 result = Ffuncall (2, args); 3156 result = Ffuncall (2, args);
3097 if (vals) vals[gcpro1.nvars++] = result; 3157 if (vals) vals[gcpro1.nvars++] = result;
3098 } 3158 }
3099 } 3159 }
3100 else if (BIT_VECTORP (seq)) 3160 else if (BIT_VECTORP (sequence))
3101 { 3161 {
3102 struct Lisp_Bit_Vector *v = XBIT_VECTOR (seq); 3162 struct Lisp_Bit_Vector *v = XBIT_VECTOR (sequence);
3103 for (i = 0; i < leni; i++) 3163 for (i = 0; i < leni; i++)
3104 { 3164 {
3105 args[1] = make_int (bit_vector_bit (v, i)); 3165 args[1] = make_int (bit_vector_bit (v, i));
3106 result = Ffuncall (2, args); 3166 result = Ffuncall (2, args);
3107 if (vals) vals[gcpro1.nvars++] = result; 3167 if (vals) vals[gcpro1.nvars++] = result;
3108 } 3168 }
3109 } 3169 }
3110 else 3170 else
3111 abort(); /* cannot get here since Flength(seq) did not get an error */ 3171 abort(); /* cannot get here since Flength(sequence) did not get an error */
3112 3172
3113 if (vals) 3173 if (vals)
3114 UNGCPRO; 3174 UNGCPRO;
3115 } 3175 }
3116 3176
3117 DEFUN ("mapconcat", Fmapconcat, 3, 3, 0, /* 3177 DEFUN ("mapconcat", Fmapconcat, 3, 3, 0, /*
3118 Apply FN to each element of SEQ, and concat the results as strings. 3178 Apply FUNCTION to each element of SEQUENCE, and concat the results as strings.
3119 In between each pair of results, stick in SEP. 3179 In between each pair of results, insert SEPARATOR. Thus, using " " as
3120 Thus, " " as SEP results in spaces between the values returned by FN. 3180 SEPARATOR results in spaces between the values returned by FUNCTION.
3121 */ 3181 SEQUENCE may be a list, a vector, a bit vector, or a string.
3122 (fn, seq, sep)) 3182 */
3123 { 3183 (function, sequence, separator))
3124 size_t len = XINT (Flength (seq)); 3184 {
3185 size_t len = XINT (Flength (sequence));
3125 Lisp_Object *args; 3186 Lisp_Object *args;
3126 int i; 3187 int i;
3127 struct gcpro gcpro1; 3188 struct gcpro gcpro1;
3128 int nargs = len + len - 1; 3189 int nargs = len + len - 1;
3129 3190
3130 if (nargs < 0) return build_string (""); 3191 if (nargs < 0) return build_string ("");
3131 3192
3132 args = alloca_array (Lisp_Object, nargs); 3193 args = alloca_array (Lisp_Object, nargs);
3133 3194
3134 GCPRO1 (sep); 3195 GCPRO1 (separator);
3135 mapcar1 (len, args, fn, seq); 3196 mapcar1 (len, args, function, sequence);
3136 UNGCPRO; 3197 UNGCPRO;
3137 3198
3138 for (i = len - 1; i >= 0; i--) 3199 for (i = len - 1; i >= 0; i--)
3139 args[i + i] = args[i]; 3200 args[i + i] = args[i];
3140 3201
3141 for (i = 1; i < nargs; i += 2) 3202 for (i = 1; i < nargs; i += 2)
3142 args[i] = sep; 3203 args[i] = separator;
3143 3204
3144 return Fconcat (nargs, args); 3205 return Fconcat (nargs, args);
3145 } 3206 }
3146 3207
3147 DEFUN ("mapcar", Fmapcar, 2, 2, 0, /* 3208 DEFUN ("mapcar", Fmapcar, 2, 2, 0, /*
3148 Apply FUNCTION to each element of SEQUENCE, and make a list of the results. 3209 Apply FUNCTION to each element of SEQUENCE; return a list of the results.
3149 The result is a list just as long as SEQUENCE. 3210 The result is a list of the same length as SEQUENCE.
3150 SEQUENCE may be a list, a vector, a bit vector, or a string. 3211 SEQUENCE may be a list, a vector, a bit vector, or a string.
3151 */ 3212 */
3152 (fn, seq)) 3213 (function, sequence))
3153 { 3214 {
3154 size_t len = XINT (Flength (seq)); 3215 size_t len = XINT (Flength (sequence));
3155 Lisp_Object *args = alloca_array (Lisp_Object, len); 3216 Lisp_Object *args = alloca_array (Lisp_Object, len);
3156 3217
3157 mapcar1 (len, args, fn, seq); 3218 mapcar1 (len, args, function, sequence);
3158 3219
3159 return Flist (len, args); 3220 return Flist (len, args);
3160 } 3221 }
3161 3222
3162 DEFUN ("mapvector", Fmapvector, 2, 2, 0, /* 3223 DEFUN ("mapvector", Fmapvector, 2, 2, 0, /*
3163 Apply FUNCTION to each element of SEQUENCE, making a vector of the results. 3224 Apply FUNCTION to each element of SEQUENCE; return a vector of the results.
3164 The result is a vector of the same length as SEQUENCE. 3225 The result is a vector of the same length as SEQUENCE.
3165 SEQUENCE may be a list, a vector or a string. 3226 SEQUENCE may be a list, a vector, a bit vector, or a string.
3166 */ 3227 */
3167 (fn, seq)) 3228 (function, sequence))
3168 { 3229 {
3169 size_t len = XINT (Flength (seq)); 3230 size_t len = XINT (Flength (sequence));
3170 Lisp_Object result = make_vector (len, Qnil); 3231 Lisp_Object result = make_vector (len, Qnil);
3171 struct gcpro gcpro1; 3232 struct gcpro gcpro1;
3172 3233
3173 GCPRO1 (result); 3234 GCPRO1 (result);
3174 mapcar1 (len, XVECTOR_DATA (result), fn, seq); 3235 mapcar1 (len, XVECTOR_DATA (result), function, sequence);
3175 UNGCPRO; 3236 UNGCPRO;
3176 3237
3177 return result; 3238 return result;
3178 } 3239 }
3179 3240
3184 which is more efficient if you do not use the results. 3245 which is more efficient if you do not use the results.
3185 3246
3186 The difference between this and `mapc' is that `mapc' supports all 3247 The difference between this and `mapc' is that `mapc' supports all
3187 the spiffy Common Lisp arguments. You should normally use `mapc'. 3248 the spiffy Common Lisp arguments. You should normally use `mapc'.
3188 */ 3249 */
3189 (fn, seq)) 3250 (function, sequence))
3190 { 3251 {
3191 mapcar1 (XINT (Flength (seq)), 0, fn, seq); 3252 mapcar1 (XINT (Flength (sequence)), 0, function, sequence);
3192 3253
3193 return seq; 3254 return sequence;
3194 } 3255 }
3195 3256
3196 3257
3197 /* #### this function doesn't belong in this file! */ 3258 /* #### this function doesn't belong in this file! */
3198 3259