Mercurial > hg > xemacs-beta
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) |