comparison src/fns.c @ 5432:46491edfd94a

Merge with trunk.
author Mats Lidell <matsl@xemacs.org>
date Sun, 07 Nov 2010 00:22:33 +0100
parents b9167d522a9a 9f738305f80f
children 002cb5224e4f
comparison
equal deleted inserted replaced
5431:5cddeeeb25bb 5432:46491edfd94a
341 for shortest_length_among_sequences(), below, for the various sequence 341 for shortest_length_among_sequences(), below, for the various sequence
342 functions that can usefully operate on circular lists. */ 342 functions that can usefully operate on circular lists. */
343 343
344 DEFUN ("list-length", Flist_length, 1, 1, 0, /* 344 DEFUN ("list-length", Flist_length, 1, 1, 0, /*
345 Return the length of LIST. Return nil if LIST is circular. 345 Return the length of LIST. Return nil if LIST is circular.
346 Error if LIST is dotted.
346 */ 347 */
347 (list)) 348 (list))
348 { 349 {
349 Lisp_Object hare, tortoise; 350 Lisp_Object hare, tortoise;
350 Elemcount len; 351 Elemcount len;
353 CONSP (hare) && (! EQ (hare, tortoise) || len == 0); 354 CONSP (hare) && (! EQ (hare, tortoise) || len == 0);
354 hare = XCDR (hare), len++) 355 hare = XCDR (hare), len++)
355 { 356 {
356 if (len & 1) 357 if (len & 1)
357 tortoise = XCDR (tortoise); 358 tortoise = XCDR (tortoise);
359 }
360
361 if (!LISTP (hare))
362 {
363 signal_malformed_list_error (list);
358 } 364 }
359 365
360 return EQ (hare, tortoise) && len != 0 ? Qnil : make_int (len); 366 return EQ (hare, tortoise) && len != 0 ? Qnil : make_int (len);
361 } 367 }
362 368
2082 EQ_WITH_EBOLA_NOTICE (value, XCDR (elt)))); 2088 EQ_WITH_EBOLA_NOTICE (value, XCDR (elt))));
2083 return alist; 2089 return alist;
2084 } 2090 }
2085 2091
2086 DEFUN ("nreverse", Fnreverse, 1, 1, 0, /* 2092 DEFUN ("nreverse", Fnreverse, 1, 1, 0, /*
2087 Reverse LIST by destructively modifying cdr pointers. 2093 Reverse SEQUENCE, destructively.
2088 Return the beginning of the reversed list. 2094
2089 Also see: `reverse'. 2095 Return the beginning of the reversed sequence, which will be a distinct Lisp
2090 */ 2096 object if SEQUENCE is a list with length greater than one. See also
2091 (list)) 2097 `reverse', the non-destructive version of this function.
2092 { 2098 */
2093 struct gcpro gcpro1, gcpro2; 2099 (sequence))
2094 Lisp_Object prev = Qnil; 2100 {
2095 Lisp_Object tail = list; 2101 CHECK_SEQUENCE (sequence);
2096 2102
2097 /* We gcpro our args; see `nconc' */ 2103 if (CONSP (sequence))
2098 GCPRO2 (prev, tail); 2104 {
2099 while (!NILP (tail)) 2105 struct gcpro gcpro1, gcpro2;
2100 { 2106 Lisp_Object prev = Qnil;
2101 REGISTER Lisp_Object next; 2107 Lisp_Object tail = sequence;
2102 CONCHECK_CONS (tail); 2108
2103 next = XCDR (tail); 2109 /* We gcpro our args; see `nconc' */
2104 XCDR (tail) = prev; 2110 GCPRO2 (prev, tail);
2105 prev = tail; 2111 while (!NILP (tail))
2106 tail = next; 2112 {
2107 } 2113 REGISTER Lisp_Object next;
2108 UNGCPRO; 2114 CONCHECK_CONS (tail);
2109 return prev; 2115 next = XCDR (tail);
2116 XCDR (tail) = prev;
2117 prev = tail;
2118 tail = next;
2119 }
2120 UNGCPRO;
2121 return prev;
2122 }
2123 else if (VECTORP (sequence))
2124 {
2125 Elemcount length = XVECTOR_LENGTH (sequence), ii = length;
2126 Elemcount half = length / 2;
2127 Lisp_Object swap = Qnil;
2128
2129 while (ii > half)
2130 {
2131 swap = XVECTOR_DATA (sequence) [length - ii];
2132 XVECTOR_DATA (sequence) [length - ii]
2133 = XVECTOR_DATA (sequence) [ii - 1];
2134 XVECTOR_DATA (sequence) [ii - 1] = swap;
2135 --ii;
2136 }
2137 }
2138 else if (STRINGP (sequence))
2139 {
2140 Elemcount length = XSTRING_LENGTH (sequence);
2141 Ibyte *staging = alloca_ibytes (length), *staging_end = staging + length;
2142 Ibyte *cursor = XSTRING_DATA (sequence), *endp = cursor + length;
2143
2144 while (cursor < endp)
2145 {
2146 staging_end -= itext_ichar_len (cursor);
2147 itext_copy_ichar (cursor, staging_end);
2148 INC_IBYTEPTR (cursor);
2149 }
2150
2151 assert (staging == staging_end);
2152
2153 memcpy (XSTRING_DATA (sequence), staging, length);
2154 init_string_ascii_begin (sequence);
2155 bump_string_modiff (sequence);
2156 sledgehammer_check_ascii_begin (sequence);
2157 }
2158 else if (BIT_VECTORP (sequence))
2159 {
2160 Lisp_Bit_Vector *bv = XBIT_VECTOR (sequence);
2161 Elemcount length = bit_vector_length (bv), ii = length;
2162 Elemcount half = length / 2;
2163 int swap = 0;
2164
2165 while (ii > half)
2166 {
2167 swap = bit_vector_bit (bv, length - ii);
2168 set_bit_vector_bit (bv, length - ii, bit_vector_bit (bv, ii - 1));
2169 set_bit_vector_bit (bv, ii - 1, swap);
2170 --ii;
2171 }
2172 }
2173 else
2174 {
2175 assert (NILP (sequence));
2176 }
2177
2178 return sequence;
2110 } 2179 }
2111 2180
2112 DEFUN ("reverse", Freverse, 1, 1, 0, /* 2181 DEFUN ("reverse", Freverse, 1, 1, 0, /*
2113 Reverse LIST, copying. Return the beginning of the reversed list. 2182 Reverse SEQUENCE, copying. Return the reversed sequence.
2114 See also the function `nreverse', which is used more often. 2183 See also the function `nreverse', which is used more often.
2115 */ 2184 */
2116 (list)) 2185 (sequence))
2117 { 2186 {
2118 Lisp_Object reversed_list = Qnil; 2187 Lisp_Object result = Qnil;
2119 EXTERNAL_LIST_LOOP_2 (elt, list) 2188
2120 { 2189 CHECK_SEQUENCE (sequence);
2121 reversed_list = Fcons (elt, reversed_list); 2190
2122 } 2191 if (CONSP (sequence))
2123 return reversed_list; 2192 {
2193 EXTERNAL_LIST_LOOP_2 (elt, sequence)
2194 {
2195 result = Fcons (elt, result);
2196 }
2197 }
2198 else if (VECTORP (sequence))
2199 {
2200 Elemcount length = XVECTOR_LENGTH (sequence), ii = length;
2201 Lisp_Object *staging = alloca_array (Lisp_Object, length);
2202
2203 while (ii > 0)
2204 {
2205 staging[length - ii] = XVECTOR_DATA (sequence) [ii - 1];
2206 --ii;
2207 }
2208
2209 result = Fvector (length, staging);
2210 }
2211 else if (STRINGP (sequence))
2212 {
2213 Elemcount length = XSTRING_LENGTH (sequence);
2214 Ibyte *staging = alloca_ibytes (length), *staging_end = staging + length;
2215 Ibyte *cursor = XSTRING_DATA (sequence), *endp = cursor + length;
2216
2217 while (cursor < endp)
2218 {
2219 staging_end -= itext_ichar_len (cursor);
2220 itext_copy_ichar (cursor, staging_end);
2221 INC_IBYTEPTR (cursor);
2222 }
2223
2224 assert (staging == staging_end);
2225
2226 result = make_string (staging, length);
2227 }
2228 else if (BIT_VECTORP (sequence))
2229 {
2230 Lisp_Bit_Vector *bv = XBIT_VECTOR (sequence), *res;
2231 Elemcount length = bit_vector_length (bv), ii = length;
2232
2233 result = make_bit_vector (length, Qzero);
2234 res = XBIT_VECTOR (result);
2235
2236 while (ii > 0)
2237 {
2238 set_bit_vector_bit (res, length - ii, bit_vector_bit (bv, ii - 1));
2239 --ii;
2240 }
2241 }
2242 else
2243 {
2244 assert (NILP (sequence));
2245 }
2246
2247 return result;
2124 } 2248 }
2125 2249
2126 static Lisp_Object 2250 static Lisp_Object
2127 c_merge_predicate_key (Lisp_Object obj1, Lisp_Object obj2, 2251 c_merge_predicate_key (Lisp_Object obj1, Lisp_Object obj2,
2128 Lisp_Object pred, Lisp_Object key_func) 2252 Lisp_Object pred, Lisp_Object key_func)