* configure.in: check for hstrerror.
[bpt/guile.git] / libguile / unif.c
CommitLineData
7dc6e754 1/* Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc.
0f2d19dd
JB
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
82892bed
JB
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
0f2d19dd
JB
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
82892bed 40 * If you do not wish that, delete this exception notice. */
0f2d19dd
JB
41\f
42
43#include <stdio.h>
44#include "_scm.h"
20e6290e
JB
45#include "chars.h"
46#include "eval.h"
ee149d03 47#include "fports.h"
20e6290e 48#include "smob.h"
20e6290e
JB
49#include "strop.h"
50#include "feature.h"
51
52#include "unif.h"
95b88819 53#include "ramap.h"
0f2d19dd 54
3d8d56df
GH
55#ifdef HAVE_UNISTD_H
56#include <unistd.h>
57#endif
58
0f2d19dd
JB
59\f
60/* The set of uniform scm_vector types is:
61 * Vector of: Called:
62 * unsigned char string
63 * char byvect
64 * boolean bvect
a515d287
MD
65 * signed long ivect
66 * unsigned long uvect
0f2d19dd
JB
67 * float fvect
68 * double dvect
69 * complex double cvect
70 * short svect
5c11cc9d 71 * long long llvect
0f2d19dd
JB
72 */
73
74long scm_tc16_array;
75
76/*
77 * This complicates things too much if allowed on any array.
78 * C code can safely call it on arrays known to be used in a single
79 * threaded manner.
80 *
81 * SCM_PROC(s_vector_set_length_x, "vector-set-length!", 2, 0, 0, scm_vector_set_length_x);
82 */
83static char s_vector_set_length_x[] = "vector-set-length!";
84
1cc91f1b 85
0f2d19dd
JB
86SCM
87scm_vector_set_length_x (vect, len)
88 SCM vect;
89 SCM len;
0f2d19dd
JB
90{
91 long l;
92 scm_sizet siz;
93 scm_sizet sz;
94
95 l = SCM_INUM (len);
96 SCM_ASRTGO (SCM_NIMP (vect), badarg1);
97 switch (SCM_TYP7 (vect))
98 {
99 default:
100 badarg1: scm_wta (vect, (char *) SCM_ARG1, s_vector_set_length_x);
101 case scm_tc7_string:
0f2d19dd
JB
102 SCM_ASRTGO (vect != scm_nullstr, badarg1);
103 sz = sizeof (char);
104 l++;
105 break;
106 case scm_tc7_vector:
95f5b0f5 107 case scm_tc7_wvect:
0f2d19dd
JB
108 SCM_ASRTGO (vect != scm_nullvect, badarg1);
109 sz = sizeof (SCM);
110 break;
111#ifdef ARRAYS
112 case scm_tc7_bvect:
113 l = (l + SCM_LONG_BIT - 1) / SCM_LONG_BIT;
114 case scm_tc7_uvect:
115 case scm_tc7_ivect:
116 sz = sizeof (long);
117 break;
118 case scm_tc7_byvect:
119 sz = sizeof (char);
120 break;
121
122 case scm_tc7_svect:
123 sz = sizeof (short);
124 break;
5c11cc9d 125#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
126 case scm_tc7_llvect:
127 sz = sizeof (long_long);
128 break;
129#endif
130
131#ifdef SCM_FLOATS
132#ifdef SCM_SINGLES
133 case scm_tc7_fvect:
134 sz = sizeof (float);
135 break;
136#endif
137 case scm_tc7_dvect:
138 sz = sizeof (double);
139 break;
140 case scm_tc7_cvect:
141 sz = 2 * sizeof (double);
142 break;
143#endif
144#endif
145 }
146 SCM_ASSERT (SCM_INUMP (len), len, SCM_ARG2, s_vector_set_length_x);
147 if (!l)
148 l = 1L;
149 siz = l * sz;
150 if (siz != l * sz)
151 scm_wta (SCM_MAKINUM (l * sz), (char *) SCM_NALLOC, s_vector_set_length_x);
152 SCM_REDEFER_INTS;
153 SCM_SETCHARS (vect,
154 ((char *)
155 scm_must_realloc (SCM_CHARS (vect),
156 (long) SCM_LENGTH (vect) * sz,
157 (long) siz,
158 s_vector_set_length_x)));
159 if (SCM_VECTORP (vect))
160 {
161 sz = SCM_LENGTH (vect);
162 while (l > sz)
163 SCM_VELTS (vect)[--l] = SCM_UNSPECIFIED;
164 }
165 else if (SCM_STRINGP (vect))
166 SCM_CHARS (vect)[l - 1] = 0;
167 SCM_SETLENGTH (vect, SCM_INUM (len), SCM_TYP7 (vect));
168 SCM_REALLOW_INTS;
169 return vect;
170}
171
172
173#ifdef ARRAYS
174
175#ifdef SCM_FLOATS
176#ifdef SCM_SINGLES
177
1cc91f1b 178
0f2d19dd 179SCM
805df3e8 180scm_makflo (float x)
0f2d19dd
JB
181{
182 SCM z;
183 if (x == 0.0)
184 return scm_flo0;
185 SCM_NEWCELL (z);
186 SCM_DEFER_INTS;
898a256f 187 SCM_SETCAR (z, scm_tc_flo);
0f2d19dd
JB
188 SCM_FLO (z) = x;
189 SCM_ALLOW_INTS;
190 return z;
191}
192#endif
193#endif
194
1cc91f1b 195
0f2d19dd
JB
196SCM
197scm_make_uve (k, prot)
198 long k;
199 SCM prot;
0f2d19dd
JB
200{
201 SCM v;
202 long i, type;
203 if (SCM_BOOL_T == prot)
204 {
205 i = sizeof (long) * ((k + SCM_LONG_BIT - 1) / SCM_LONG_BIT);
206 type = scm_tc7_bvect;
207 }
208 else if (SCM_ICHRP (prot) && (prot == SCM_MAKICHR ('\0')))
209 {
210 i = sizeof (char) * k;
211 type = scm_tc7_byvect;
212 }
213 else if (SCM_ICHRP (prot))
214 {
215 i = sizeof (char) * k;
216 type = scm_tc7_string;
217 }
218 else if (SCM_INUMP (prot))
219 {
220 i = sizeof (long) * k;
221 if (SCM_INUM (prot) > 0)
222 type = scm_tc7_uvect;
223 else
224 type = scm_tc7_ivect;
225 }
226 else if (SCM_NIMP (prot) && SCM_SYMBOLP (prot) && (1 == SCM_LENGTH (prot)))
227 {
228 char s;
229
230 s = SCM_CHARS (prot)[0];
231 if (s == 's')
232 {
233 i = sizeof (short) * k;
234 type = scm_tc7_svect;
235 }
5c11cc9d 236#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
237 else if (s == 'l')
238 {
239 i = sizeof (long_long) * k;
240 type = scm_tc7_llvect;
241 }
242#endif
243 else
244 {
a8741caa 245 return scm_make_vector (SCM_MAKINUM (k), SCM_UNDEFINED);
0f2d19dd
JB
246 }
247 }
248 else
249#ifdef SCM_FLOATS
250 if (SCM_IMP (prot) || !SCM_INEXP (prot))
251#endif
252 /* Huge non-unif vectors are NOT supported. */
5c11cc9d
GH
253 /* no special scm_vector */
254 return scm_make_vector (SCM_MAKINUM (k), SCM_UNDEFINED);
0f2d19dd
JB
255#ifdef SCM_FLOATS
256#ifdef SCM_SINGLES
257 else if (SCM_SINGP (prot))
258
259 {
260 i = sizeof (float) * k;
261 type = scm_tc7_fvect;
262 }
263#endif
264 else if (SCM_CPLXP (prot))
265 {
266 i = 2 * sizeof (double) * k;
267 type = scm_tc7_cvect;
268 }
269 else
270 {
271 i = sizeof (double) * k;
272 type = scm_tc7_dvect;
273 }
274#endif
275
276 SCM_NEWCELL (v);
277 SCM_DEFER_INTS;
5c11cc9d 278 SCM_SETCHARS (v, (char *) scm_must_malloc (i ? i : 1, "vector"));
0f2d19dd
JB
279 SCM_SETLENGTH (v, (k < SCM_LENGTH_MAX ? k : SCM_LENGTH_MAX), type);
280 SCM_ALLOW_INTS;
281 return v;
282}
283
284SCM_PROC(s_uniform_vector_length, "uniform-vector-length", 1, 0, 0, scm_uniform_vector_length);
1cc91f1b 285
0f2d19dd
JB
286SCM
287scm_uniform_vector_length (v)
288 SCM v;
0f2d19dd
JB
289{
290 SCM_ASRTGO (SCM_NIMP (v), badarg1);
291 switch SCM_TYP7
292 (v)
293 {
294 default:
295 badarg1:scm_wta (v, (char *) SCM_ARG1, s_uniform_vector_length);
296 case scm_tc7_bvect:
297 case scm_tc7_string:
298 case scm_tc7_byvect:
299 case scm_tc7_uvect:
300 case scm_tc7_ivect:
301 case scm_tc7_fvect:
302 case scm_tc7_dvect:
303 case scm_tc7_cvect:
304 case scm_tc7_vector:
95f5b0f5 305 case scm_tc7_wvect:
0f2d19dd 306 case scm_tc7_svect:
5c11cc9d 307#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
308 case scm_tc7_llvect:
309#endif
310 return SCM_MAKINUM (SCM_LENGTH (v));
311 }
312}
313
314SCM_PROC(s_array_p, "array?", 1, 1, 0, scm_array_p);
1cc91f1b 315
0f2d19dd
JB
316SCM
317scm_array_p (v, prot)
318 SCM v;
319 SCM prot;
0f2d19dd
JB
320{
321 int nprot;
322 int enclosed;
323 nprot = SCM_UNBNDP (prot);
324 enclosed = 0;
325 if (SCM_IMP (v))
326 return SCM_BOOL_F;
327loop:
328 switch (SCM_TYP7 (v))
329 {
330 case scm_tc7_smob:
331 if (!SCM_ARRAYP (v))
332 return SCM_BOOL_F;
333 if (nprot)
334 return SCM_BOOL_T;
335 if (enclosed++)
336 return SCM_BOOL_F;
337 v = SCM_ARRAY_V (v);
338 goto loop;
339 case scm_tc7_bvect:
340 return nprot || SCM_BOOL_T==prot ? SCM_BOOL_T : SCM_BOOL_F;
341 case scm_tc7_string:
342 return nprot || (SCM_ICHRP(prot) && (prot != SCM_MAKICHR('\0'))) ? SCM_BOOL_T : SCM_BOOL_F;
343 case scm_tc7_byvect:
344 return nprot || (prot == SCM_MAKICHR('\0')) ? SCM_BOOL_T : SCM_BOOL_F;
345 case scm_tc7_uvect:
346 return nprot || (SCM_INUMP(prot) && SCM_INUM(prot)>0) ? SCM_BOOL_T : SCM_BOOL_F;
347 case scm_tc7_ivect:
348 return nprot || (SCM_INUMP(prot) && SCM_INUM(prot)<=0) ? SCM_BOOL_T : SCM_BOOL_F;
349 case scm_tc7_svect:
350 return ( nprot
351 || (SCM_NIMP (prot)
352 && SCM_SYMBOLP (prot)
353 && (1 == SCM_LENGTH (prot))
354 && ('s' == SCM_CHARS (prot)[0])));
5c11cc9d 355#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
356 case scm_tc7_llvect:
357 return ( nprot
358 || (SCM_NIMP (prot)
359 && SCM_SYMBOLP (prot)
360 && (1 == SCM_LENGTH (prot))
361 && ('s' == SCM_CHARS (prot)[0])));
362#endif
363# ifdef SCM_FLOATS
364# ifdef SCM_SINGLES
365 case scm_tc7_fvect:
366 return nprot || (SCM_NIMP(prot) && SCM_SINGP(prot)) ? SCM_BOOL_T : SCM_BOOL_F;
367# endif
368 case scm_tc7_dvect:
369 return nprot || (SCM_NIMP(prot) && SCM_REALP(prot)) ? SCM_BOOL_T : SCM_BOOL_F;
370 case scm_tc7_cvect:
371 return nprot || (SCM_NIMP(prot) && SCM_CPLXP(prot)) ? SCM_BOOL_T : SCM_BOOL_F;
372# endif
373 case scm_tc7_vector:
95f5b0f5 374 case scm_tc7_wvect:
0f2d19dd
JB
375 return nprot || SCM_NULLP(prot) ? SCM_BOOL_T : SCM_BOOL_F;
376 default:;
377 }
378 return SCM_BOOL_F;
379}
380
381
382SCM_PROC(s_array_rank, "array-rank", 1, 0, 0, scm_array_rank);
1cc91f1b 383
0f2d19dd
JB
384SCM
385scm_array_rank (ra)
386 SCM ra;
0f2d19dd
JB
387{
388 if (SCM_IMP (ra))
389 return SCM_INUM0;
390 switch (SCM_TYP7 (ra))
391 {
392 default:
393 return SCM_INUM0;
394 case scm_tc7_string:
395 case scm_tc7_vector:
95f5b0f5 396 case scm_tc7_wvect:
0f2d19dd
JB
397 case scm_tc7_byvect:
398 case scm_tc7_uvect:
399 case scm_tc7_ivect:
400 case scm_tc7_fvect:
401 case scm_tc7_cvect:
402 case scm_tc7_dvect:
5c11cc9d 403#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
404 case scm_tc7_llvect:
405#endif
406 case scm_tc7_svect:
407 return SCM_MAKINUM (1L);
408 case scm_tc7_smob:
409 if (SCM_ARRAYP (ra))
410 return SCM_MAKINUM (SCM_ARRAY_NDIM (ra));
411 return SCM_INUM0;
412 }
413}
414
415
416SCM_PROC(s_array_dimensions, "array-dimensions", 1, 0, 0, scm_array_dimensions);
1cc91f1b 417
0f2d19dd
JB
418SCM
419scm_array_dimensions (ra)
420 SCM ra;
0f2d19dd
JB
421{
422 SCM res = SCM_EOL;
423 scm_sizet k;
424 scm_array_dim *s;
425 if (SCM_IMP (ra))
426 return SCM_BOOL_F;
427 switch (SCM_TYP7 (ra))
428 {
429 default:
430 return SCM_BOOL_F;
431 case scm_tc7_string:
432 case scm_tc7_vector:
95f5b0f5 433 case scm_tc7_wvect:
0f2d19dd
JB
434 case scm_tc7_bvect:
435 case scm_tc7_byvect:
436 case scm_tc7_uvect:
437 case scm_tc7_ivect:
438 case scm_tc7_fvect:
439 case scm_tc7_cvect:
440 case scm_tc7_dvect:
441 case scm_tc7_svect:
5c11cc9d 442#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
443 case scm_tc7_llvect:
444#endif
445 return scm_cons (SCM_MAKINUM (SCM_LENGTH (ra)), SCM_EOL);
446 case scm_tc7_smob:
447 if (!SCM_ARRAYP (ra))
448 return SCM_BOOL_F;
449 k = SCM_ARRAY_NDIM (ra);
450 s = SCM_ARRAY_DIMS (ra);
451 while (k--)
452 res = scm_cons (s[k].lbnd ? scm_cons2 (SCM_MAKINUM (s[k].lbnd), SCM_MAKINUM (s[k].ubnd), SCM_EOL) :
453 SCM_MAKINUM (1 + (s[k].ubnd))
454 , res);
455 return res;
456 }
457}
458
459
460static char s_bad_ind[] = "Bad scm_array index";
461
1cc91f1b 462
0f2d19dd
JB
463long
464scm_aind (ra, args, what)
1cc91f1b 465 SCM ra;
0f2d19dd 466 SCM args;
3eeba8d4 467 const char *what;
0f2d19dd
JB
468{
469 SCM ind;
470 register long j;
471 register scm_sizet pos = SCM_ARRAY_BASE (ra);
472 register scm_sizet k = SCM_ARRAY_NDIM (ra);
473 scm_array_dim *s = SCM_ARRAY_DIMS (ra);
474 if (SCM_INUMP (args))
0f2d19dd 475 {
f5bf2977 476 SCM_ASSERT (1 == k, scm_makfrom0str (what), SCM_WNA, NULL);
0f2d19dd
JB
477 return pos + (SCM_INUM (args) - s->lbnd) * (s->inc);
478 }
479 while (k && SCM_NIMP (args))
480 {
481 ind = SCM_CAR (args);
482 args = SCM_CDR (args);
483 SCM_ASSERT (SCM_INUMP (ind), ind, s_bad_ind, what);
484 j = SCM_INUM (ind);
485 SCM_ASSERT (j >= (s->lbnd) && j <= (s->ubnd), ind, SCM_OUTOFRANGE, what);
486 pos += (j - s->lbnd) * (s->inc);
487 k--;
488 s++;
489 }
f5bf2977
GH
490 SCM_ASSERT (0 == k && SCM_NULLP (args), scm_makfrom0str (what), SCM_WNA,
491 NULL);
0f2d19dd
JB
492 return pos;
493}
494
495
1cc91f1b 496
0f2d19dd
JB
497SCM
498scm_make_ra (ndim)
499 int ndim;
0f2d19dd
JB
500{
501 SCM ra;
502 SCM_NEWCELL (ra);
503 SCM_DEFER_INTS;
23a62151
MD
504 SCM_NEWSMOB(ra, ((long) ndim << 17) + scm_tc16_array,
505 scm_must_malloc ((long) (sizeof (scm_array) + ndim * sizeof (scm_array_dim)),
0f2d19dd 506 "array"));
0f2d19dd
JB
507 SCM_ARRAY_V (ra) = scm_nullvect;
508 SCM_ALLOW_INTS;
509 return ra;
510}
511
512static char s_bad_spec[] = "Bad scm_array dimension";
513/* Increments will still need to be set. */
514
1cc91f1b 515
0f2d19dd
JB
516SCM
517scm_shap2ra (args, what)
518 SCM args;
3eeba8d4 519 const char *what;
0f2d19dd
JB
520{
521 scm_array_dim *s;
522 SCM ra, spec, sp;
523 int ndim = scm_ilength (args);
524 SCM_ASSERT (0 <= ndim, args, s_bad_spec, what);
525 ra = scm_make_ra (ndim);
526 SCM_ARRAY_BASE (ra) = 0;
527 s = SCM_ARRAY_DIMS (ra);
528 for (; SCM_NIMP (args); s++, args = SCM_CDR (args))
529 {
530 spec = SCM_CAR (args);
531 if (SCM_IMP (spec))
532
533 {
20a54673
GH
534 SCM_ASSERT (SCM_INUMP (spec) && SCM_INUM (spec) >= 0, spec,
535 s_bad_spec, what);
0f2d19dd
JB
536 s->lbnd = 0;
537 s->ubnd = SCM_INUM (spec) - 1;
538 s->inc = 1;
539 }
540 else
541 {
20a54673
GH
542 SCM_ASSERT (SCM_CONSP (spec) && SCM_INUMP (SCM_CAR (spec)), spec,
543 s_bad_spec, what);
0f2d19dd
JB
544 s->lbnd = SCM_INUM (SCM_CAR (spec));
545 sp = SCM_CDR (spec);
20a54673
GH
546 SCM_ASSERT (SCM_NIMP (sp) && SCM_CONSP (sp)
547 && SCM_INUMP (SCM_CAR (sp)) && SCM_NULLP (SCM_CDR (sp)),
548 spec, s_bad_spec, what);
0f2d19dd
JB
549 s->ubnd = SCM_INUM (SCM_CAR (sp));
550 s->inc = 1;
551 }
552 }
553 return ra;
554}
555
5c11cc9d 556SCM_PROC(s_dimensions_to_uniform_array, "dimensions->uniform-array", 2, 1, 0, scm_dimensions_to_uniform_array);
1cc91f1b 557
0f2d19dd
JB
558SCM
559scm_dimensions_to_uniform_array (dims, prot, fill)
560 SCM dims;
561 SCM prot;
562 SCM fill;
0f2d19dd
JB
563{
564 scm_sizet k, vlen = 1;
565 long rlen = 1;
566 scm_array_dim *s;
567 SCM ra;
568 if (SCM_INUMP (dims))
cda139a7 569 {
0f2d19dd
JB
570 if (SCM_INUM (dims) < SCM_LENGTH_MAX)
571 {
5c11cc9d
GH
572 SCM answer = scm_make_uve (SCM_INUM (dims), prot);
573
574 if (!SCM_UNBNDP (fill))
575 scm_array_fill_x (answer, fill);
0f2d19dd
JB
576 else if (SCM_NIMP (prot) && SCM_SYMBOLP (prot))
577 scm_array_fill_x (answer, SCM_MAKINUM (0));
578 else
579 scm_array_fill_x (answer, prot);
580 return answer;
581 }
582 else
583 dims = scm_cons (dims, SCM_EOL);
cda139a7 584 }
0f2d19dd
JB
585 SCM_ASSERT (SCM_NULLP (dims) || (SCM_NIMP (dims) && SCM_CONSP (dims)),
586 dims, SCM_ARG1, s_dimensions_to_uniform_array);
587 ra = scm_shap2ra (dims, s_dimensions_to_uniform_array);
898a256f 588 SCM_SETOR_CAR (ra, SCM_ARRAY_CONTIGUOUS);
0f2d19dd
JB
589 s = SCM_ARRAY_DIMS (ra);
590 k = SCM_ARRAY_NDIM (ra);
591 while (k--)
592 {
593 s[k].inc = (rlen > 0 ? rlen : 0);
594 rlen = (s[k].ubnd - s[k].lbnd + 1) * s[k].inc;
595 vlen *= (s[k].ubnd - s[k].lbnd + 1);
596 }
597 if (rlen < SCM_LENGTH_MAX)
598 SCM_ARRAY_V (ra) = scm_make_uve ((rlen > 0 ? rlen : 0L), prot);
599 else
600 {
601 scm_sizet bit;
602 switch (SCM_TYP7 (scm_make_uve (0L, prot)))
603 {
604 default:
605 bit = SCM_LONG_BIT;
606 break;
607 case scm_tc7_bvect:
608 bit = 1;
609 break;
610 case scm_tc7_string:
611 bit = SCM_CHAR_BIT;
612 break;
613 case scm_tc7_fvect:
614 bit = sizeof (float) * SCM_CHAR_BIT / sizeof (char);
615 break;
616 case scm_tc7_dvect:
617 bit = sizeof (double) * SCM_CHAR_BIT / sizeof (char);
618 break;
619 case scm_tc7_cvect:
620 bit = 2 * sizeof (double) * SCM_CHAR_BIT / sizeof (char);
621 break;
622 }
623 SCM_ARRAY_BASE (ra) = (SCM_LONG_BIT + bit - 1) / bit;
624 rlen += SCM_ARRAY_BASE (ra);
625 SCM_ARRAY_V (ra) = scm_make_uve (rlen, prot);
626 *((long *) SCM_VELTS (SCM_ARRAY_V (ra))) = rlen;
627 }
5c11cc9d 628 if (!SCM_UNBNDP (fill))
0f2d19dd 629 {
5c11cc9d 630 scm_array_fill_x (ra, fill);
0f2d19dd
JB
631 }
632 else if (SCM_NIMP (prot) && SCM_SYMBOLP (prot))
633 scm_array_fill_x (ra, SCM_MAKINUM (0));
634 else
635 scm_array_fill_x (ra, prot);
636 if (1 == SCM_ARRAY_NDIM (ra) && 0 == SCM_ARRAY_BASE (ra))
637 if (s->ubnd < s->lbnd || (0 == s->lbnd && 1 == s->inc))
638 return SCM_ARRAY_V (ra);
639 return ra;
640}
641
1cc91f1b 642
0f2d19dd
JB
643void
644scm_ra_set_contp (ra)
645 SCM ra;
0f2d19dd
JB
646{
647 scm_sizet k = SCM_ARRAY_NDIM (ra);
0f2d19dd 648 if (k)
0f2d19dd 649 {
fe0c6dae
JB
650 long inc = SCM_ARRAY_DIMS (ra)[k - 1].inc;
651 while (k--)
0f2d19dd 652 {
fe0c6dae
JB
653 if (inc != SCM_ARRAY_DIMS (ra)[k].inc)
654 {
898a256f 655 SCM_SETAND_CAR (ra, ~SCM_ARRAY_CONTIGUOUS);
fe0c6dae
JB
656 return;
657 }
658 inc *= (SCM_ARRAY_DIMS (ra)[k].ubnd
659 - SCM_ARRAY_DIMS (ra)[k].lbnd + 1);
0f2d19dd 660 }
0f2d19dd 661 }
898a256f 662 SCM_SETOR_CAR (ra, SCM_ARRAY_CONTIGUOUS);
0f2d19dd
JB
663}
664
665
666SCM_PROC(s_make_shared_array, "make-shared-array", 2, 0, 1, scm_make_shared_array);
1cc91f1b 667
0f2d19dd
JB
668SCM
669scm_make_shared_array (oldra, mapfunc, dims)
670 SCM oldra;
671 SCM mapfunc;
672 SCM dims;
0f2d19dd
JB
673{
674 SCM ra;
675 SCM inds, indptr;
676 SCM imap;
677 scm_sizet i, k;
678 long old_min, new_min, old_max, new_max;
679 scm_array_dim *s;
680 SCM_ASSERT (SCM_BOOL_T == scm_procedure_p (mapfunc), mapfunc, SCM_ARG2, s_make_shared_array);
681 SCM_ASSERT (SCM_NIMP (oldra) && (SCM_BOOL_F != scm_array_p (oldra, SCM_UNDEFINED)), oldra, SCM_ARG1, s_make_shared_array);
682 ra = scm_shap2ra (dims, s_make_shared_array);
683 if (SCM_ARRAYP (oldra))
684 {
685 SCM_ARRAY_V (ra) = SCM_ARRAY_V (oldra);
686 old_min = old_max = SCM_ARRAY_BASE (oldra);
687 s = SCM_ARRAY_DIMS (oldra);
688 k = SCM_ARRAY_NDIM (oldra);
689 while (k--)
690 {
691 if (s[k].inc > 0)
692 old_max += (s[k].ubnd - s[k].lbnd) * s[k].inc;
693 else
694 old_min += (s[k].ubnd - s[k].lbnd) * s[k].inc;
695 }
696 }
697 else
698 {
699 SCM_ARRAY_V (ra) = oldra;
700 old_min = 0;
701 old_max = (long) SCM_LENGTH (oldra) - 1;
702 }
703 inds = SCM_EOL;
704 s = SCM_ARRAY_DIMS (ra);
705 for (k = 0; k < SCM_ARRAY_NDIM (ra); k++)
706 {
707 inds = scm_cons (SCM_MAKINUM (s[k].lbnd), inds);
708 if (s[k].ubnd < s[k].lbnd)
709 {
710 if (1 == SCM_ARRAY_NDIM (ra))
711 ra = scm_make_uve (0L, scm_array_prototype (ra));
712 else
713 SCM_ARRAY_V (ra) = scm_make_uve (0L, scm_array_prototype (ra));
714 return ra;
715 }
716 }
92396c0a 717 imap = scm_apply (mapfunc, scm_reverse (inds), SCM_EOL);
0f2d19dd
JB
718 if (SCM_ARRAYP (oldra))
719 i = (scm_sizet) scm_aind (oldra, imap, s_make_shared_array);
720 else
721 {
722 if (SCM_NINUMP (imap))
723
724 {
725 SCM_ASSERT (1 == scm_ilength (imap) && SCM_INUMP (SCM_CAR (imap)),
726 imap, s_bad_ind, s_make_shared_array);
727 imap = SCM_CAR (imap);
728 }
729 i = SCM_INUM (imap);
730 }
731 SCM_ARRAY_BASE (ra) = new_min = new_max = i;
732 indptr = inds;
733 k = SCM_ARRAY_NDIM (ra);
734 while (k--)
735 {
736 if (s[k].ubnd > s[k].lbnd)
737 {
898a256f 738 SCM_SETCAR (indptr, SCM_MAKINUM (SCM_INUM (SCM_CAR (indptr)) + 1));
0f2d19dd
JB
739 imap = scm_apply (mapfunc, scm_reverse (inds), SCM_EOL);
740 if (SCM_ARRAYP (oldra))
741
742 s[k].inc = scm_aind (oldra, imap, s_make_shared_array) - i;
743 else
744 {
745 if (SCM_NINUMP (imap))
746
747 {
748 SCM_ASSERT (1 == scm_ilength (imap) && SCM_INUMP (SCM_CAR (imap)),
749 imap, s_bad_ind, s_make_shared_array);
750 imap = SCM_CAR (imap);
751 }
752 s[k].inc = (long) SCM_INUM (imap) - i;
753 }
754 i += s[k].inc;
755 if (s[k].inc > 0)
756 new_max += (s[k].ubnd - s[k].lbnd) * s[k].inc;
757 else
758 new_min += (s[k].ubnd - s[k].lbnd) * s[k].inc;
759 }
760 else
761 s[k].inc = new_max - new_min + 1; /* contiguous by default */
762 indptr = SCM_CDR (indptr);
763 }
764 SCM_ASSERT (old_min <= new_min && old_max >= new_max, SCM_UNDEFINED,
765 "mapping out of range", s_make_shared_array);
766 if (1 == SCM_ARRAY_NDIM (ra) && 0 == SCM_ARRAY_BASE (ra))
767 {
768 if (1 == s->inc && 0 == s->lbnd
769 && SCM_LENGTH (SCM_ARRAY_V (ra)) == 1 + s->ubnd)
770 return SCM_ARRAY_V (ra);
771 if (s->ubnd < s->lbnd)
772 return scm_make_uve (0L, scm_array_prototype (ra));
773 }
774 scm_ra_set_contp (ra);
775 return ra;
776}
777
778
779/* args are RA . DIMS */
780SCM_PROC(s_transpose_array, "transpose-array", 0, 0, 1, scm_transpose_array);
1cc91f1b 781
0f2d19dd
JB
782SCM
783scm_transpose_array (args)
784 SCM args;
0f2d19dd
JB
785{
786 SCM ra, res, vargs, *ve = &vargs;
787 scm_array_dim *s, *r;
788 int ndim, i, k;
f5bf2977
GH
789 SCM_ASSERT (SCM_NNULLP (args), scm_makfrom0str (s_transpose_array),
790 SCM_WNA, NULL);
0f2d19dd 791 ra = SCM_CAR (args);
f5bf2977 792 SCM_ASSERT (SCM_NIMP (ra), ra, SCM_ARG1, s_transpose_array);
0f2d19dd 793 args = SCM_CDR (args);
f5bf2977 794 switch (SCM_TYP7 (ra))
0f2d19dd
JB
795 {
796 default:
20a54673 797 badarg:scm_wta (ra, (char *) SCM_ARG1, s_transpose_array);
0f2d19dd
JB
798 case scm_tc7_bvect:
799 case scm_tc7_string:
800 case scm_tc7_byvect:
801 case scm_tc7_uvect:
802 case scm_tc7_ivect:
803 case scm_tc7_fvect:
804 case scm_tc7_dvect:
805 case scm_tc7_cvect:
806 case scm_tc7_svect:
5c11cc9d 807#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
808 case scm_tc7_llvect:
809#endif
f5bf2977
GH
810 SCM_ASSERT (SCM_NIMP (args) && SCM_NULLP (SCM_CDR (args)),
811 scm_makfrom0str (s_transpose_array), SCM_WNA, NULL);
812 SCM_ASSERT (SCM_INUMP (SCM_CAR (args)), SCM_CAR (args), SCM_ARG2,
813 s_transpose_array);
814 SCM_ASSERT (SCM_INUM0 == SCM_CAR (args), SCM_CAR (args), SCM_OUTOFRANGE,
815 s_transpose_array);
0f2d19dd
JB
816 return ra;
817 case scm_tc7_smob:
818 SCM_ASRTGO (SCM_ARRAYP (ra), badarg);
819 vargs = scm_vector (args);
f5bf2977
GH
820 SCM_ASSERT (SCM_LENGTH (vargs) == SCM_ARRAY_NDIM (ra),
821 scm_makfrom0str (s_transpose_array), SCM_WNA, NULL);
822 ve = SCM_VELTS (vargs);
0f2d19dd
JB
823 ndim = 0;
824 for (k = 0; k < SCM_ARRAY_NDIM (ra); k++)
825 {
20a54673
GH
826 SCM_ASSERT (SCM_INUMP (ve[k]), ve[k], (SCM_ARG2 + k),
827 s_transpose_array);
0f2d19dd 828 i = SCM_INUM (ve[k]);
20a54673
GH
829 SCM_ASSERT (i >= 0 && i < SCM_ARRAY_NDIM (ra), ve[k],
830 SCM_OUTOFRANGE, s_transpose_array);
0f2d19dd
JB
831 if (ndim < i)
832 ndim = i;
833 }
834 ndim++;
835 res = scm_make_ra (ndim);
836 SCM_ARRAY_V (res) = SCM_ARRAY_V (ra);
837 SCM_ARRAY_BASE (res) = SCM_ARRAY_BASE (ra);
838 for (k = ndim; k--;)
839 {
840 SCM_ARRAY_DIMS (res)[k].lbnd = 0;
841 SCM_ARRAY_DIMS (res)[k].ubnd = -1;
842 }
843 for (k = SCM_ARRAY_NDIM (ra); k--;)
844 {
845 i = SCM_INUM (ve[k]);
846 s = &(SCM_ARRAY_DIMS (ra)[k]);
847 r = &(SCM_ARRAY_DIMS (res)[i]);
848 if (r->ubnd < r->lbnd)
849 {
850 r->lbnd = s->lbnd;
851 r->ubnd = s->ubnd;
852 r->inc = s->inc;
853 ndim--;
854 }
855 else
856 {
857 if (r->ubnd > s->ubnd)
858 r->ubnd = s->ubnd;
859 if (r->lbnd < s->lbnd)
860 {
861 SCM_ARRAY_BASE (res) += (s->lbnd - r->lbnd) * r->inc;
862 r->lbnd = s->lbnd;
863 }
864 r->inc += s->inc;
865 }
866 }
20a54673 867 SCM_ASSERT (ndim <= 0, args, "bad argument list", s_transpose_array);
0f2d19dd
JB
868 scm_ra_set_contp (res);
869 return res;
870 }
871}
872
873/* args are RA . AXES */
874SCM_PROC(s_enclose_array, "enclose-array", 0, 0, 1, scm_enclose_array);
1cc91f1b 875
0f2d19dd
JB
876SCM
877scm_enclose_array (axes)
878 SCM axes;
0f2d19dd
JB
879{
880 SCM axv, ra, res, ra_inr;
881 scm_array_dim vdim, *s = &vdim;
882 int ndim, j, k, ninr, noutr;
f5bf2977
GH
883 SCM_ASSERT (SCM_NIMP (axes), scm_makfrom0str (s_enclose_array), SCM_WNA,
884 NULL);
0f2d19dd
JB
885 ra = SCM_CAR (axes);
886 axes = SCM_CDR (axes);
887 if (SCM_NULLP (axes))
888
889 axes = scm_cons ((SCM_ARRAYP (ra) ? SCM_MAKINUM (SCM_ARRAY_NDIM (ra) - 1) : SCM_INUM0), SCM_EOL);
890 ninr = scm_ilength (axes);
891 ra_inr = scm_make_ra (ninr);
892 SCM_ASRTGO (SCM_NIMP (ra), badarg1);
893 switch SCM_TYP7
894 (ra)
895 {
896 default:
897 badarg1:scm_wta (ra, (char *) SCM_ARG1, s_enclose_array);
898 case scm_tc7_string:
899 case scm_tc7_bvect:
900 case scm_tc7_byvect:
901 case scm_tc7_uvect:
902 case scm_tc7_ivect:
903 case scm_tc7_fvect:
904 case scm_tc7_dvect:
905 case scm_tc7_cvect:
906 case scm_tc7_vector:
95f5b0f5 907 case scm_tc7_wvect:
0f2d19dd 908 case scm_tc7_svect:
5c11cc9d 909#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
910 case scm_tc7_llvect:
911#endif
912 s->lbnd = 0;
913 s->ubnd = SCM_LENGTH (ra) - 1;
914 s->inc = 1;
915 SCM_ARRAY_V (ra_inr) = ra;
916 SCM_ARRAY_BASE (ra_inr) = 0;
917 ndim = 1;
918 break;
919 case scm_tc7_smob:
920 SCM_ASRTGO (SCM_ARRAYP (ra), badarg1);
921 s = SCM_ARRAY_DIMS (ra);
922 SCM_ARRAY_V (ra_inr) = SCM_ARRAY_V (ra);
923 SCM_ARRAY_BASE (ra_inr) = SCM_ARRAY_BASE (ra);
924 ndim = SCM_ARRAY_NDIM (ra);
925 break;
926 }
927 noutr = ndim - ninr;
928 axv = scm_make_string (SCM_MAKINUM (ndim), SCM_MAKICHR (0));
f5bf2977
GH
929 SCM_ASSERT (0 <= noutr && 0 <= ninr, scm_makfrom0str (s_enclose_array),
930 SCM_WNA, NULL);
0f2d19dd
JB
931 res = scm_make_ra (noutr);
932 SCM_ARRAY_BASE (res) = SCM_ARRAY_BASE (ra_inr);
933 SCM_ARRAY_V (res) = ra_inr;
934 for (k = 0; k < ninr; k++, axes = SCM_CDR (axes))
935 {
936 SCM_ASSERT (SCM_INUMP (SCM_CAR (axes)), SCM_CAR (axes), "bad axis", s_enclose_array);
937 j = SCM_INUM (SCM_CAR (axes));
938 SCM_ARRAY_DIMS (ra_inr)[k].lbnd = s[j].lbnd;
939 SCM_ARRAY_DIMS (ra_inr)[k].ubnd = s[j].ubnd;
940 SCM_ARRAY_DIMS (ra_inr)[k].inc = s[j].inc;
941 SCM_CHARS (axv)[j] = 1;
942 }
943 for (j = 0, k = 0; k < noutr; k++, j++)
944 {
945 while (SCM_CHARS (axv)[j])
946 j++;
947 SCM_ARRAY_DIMS (res)[k].lbnd = s[j].lbnd;
948 SCM_ARRAY_DIMS (res)[k].ubnd = s[j].ubnd;
949 SCM_ARRAY_DIMS (res)[k].inc = s[j].inc;
950 }
951 scm_ra_set_contp (ra_inr);
952 scm_ra_set_contp (res);
953 return res;
954}
955
956
957
958SCM_PROC(s_array_in_bounds_p, "array-in-bounds?", 0, 0, 1, scm_array_in_bounds_p);
1cc91f1b 959
0f2d19dd
JB
960SCM
961scm_array_in_bounds_p (args)
962 SCM args;
0f2d19dd
JB
963{
964 SCM v, ind = SCM_EOL;
965 long pos = 0;
966 register scm_sizet k;
967 register long j;
968 scm_array_dim *s;
f5bf2977
GH
969 SCM_ASSERT (SCM_NIMP (args), scm_makfrom0str (s_array_in_bounds_p),
970 SCM_WNA, NULL);
0f2d19dd
JB
971 v = SCM_CAR (args);
972 args = SCM_CDR (args);
973 SCM_ASRTGO (SCM_NIMP (v), badarg1);
974 if (SCM_NIMP (args))
975
976 {
977 ind = SCM_CAR (args);
978 args = SCM_CDR (args);
979 SCM_ASSERT (SCM_INUMP (ind), ind, SCM_ARG2, s_array_in_bounds_p);
980 pos = SCM_INUM (ind);
981 }
982tail:
983 switch SCM_TYP7
984 (v)
985 {
986 default:
987 badarg1:scm_wta (v, (char *) SCM_ARG1, s_array_in_bounds_p);
f5bf2977 988 wna: scm_wrong_num_args (scm_makfrom0str (s_array_in_bounds_p));
0f2d19dd
JB
989 case scm_tc7_smob:
990 k = SCM_ARRAY_NDIM (v);
991 s = SCM_ARRAY_DIMS (v);
992 pos = SCM_ARRAY_BASE (v);
993 if (!k)
994 {
995 SCM_ASRTGO (SCM_NULLP (ind), wna);
996 ind = SCM_INUM0;
997 }
998 else
999 while (!0)
1000 {
1001 j = SCM_INUM (ind);
1002 if (!(j >= (s->lbnd) && j <= (s->ubnd)))
1003 {
1004 SCM_ASRTGO (--k == scm_ilength (args), wna);
1005 return SCM_BOOL_F;
1006 }
1007 pos += (j - s->lbnd) * (s->inc);
1008 if (!(--k && SCM_NIMP (args)))
1009 break;
1010 ind = SCM_CAR (args);
1011 args = SCM_CDR (args);
1012 s++;
1013 SCM_ASSERT (SCM_INUMP (ind), ind, s_bad_ind, s_array_in_bounds_p);
1014 }
1015 SCM_ASRTGO (0 == k, wna);
1016 v = SCM_ARRAY_V (v);
1017 goto tail;
1018 case scm_tc7_bvect:
1019 case scm_tc7_string:
1020 case scm_tc7_byvect:
1021 case scm_tc7_uvect:
1022 case scm_tc7_ivect:
1023 case scm_tc7_fvect:
1024 case scm_tc7_dvect:
1025 case scm_tc7_cvect:
1026 case scm_tc7_svect:
5c11cc9d 1027#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
1028 case scm_tc7_llvect:
1029#endif
1030 case scm_tc7_vector:
95f5b0f5 1031 case scm_tc7_wvect:
0f2d19dd
JB
1032 SCM_ASRTGO (SCM_NULLP (args) && SCM_INUMP (ind), wna);
1033 return pos >= 0 && pos < SCM_LENGTH (v) ? SCM_BOOL_T : SCM_BOOL_F;
1034 }
1035}
1036
1037
1038SCM_PROC(s_array_ref, "array-ref", 1, 0, 1, scm_uniform_vector_ref);
1039SCM_PROC(s_uniform_vector_ref, "uniform-vector-ref", 2, 0, 0, scm_uniform_vector_ref);
1cc91f1b 1040
0f2d19dd
JB
1041SCM
1042scm_uniform_vector_ref (v, args)
1043 SCM v;
1044 SCM args;
0f2d19dd
JB
1045{
1046 long pos;
0f2d19dd 1047
35de7ebe 1048 if (SCM_IMP (v))
0f2d19dd
JB
1049 {
1050 SCM_ASRTGO (SCM_NULLP (args), badarg);
1051 return v;
1052 }
1053 else if (SCM_ARRAYP (v))
0f2d19dd
JB
1054 {
1055 pos = scm_aind (v, args, s_uniform_vector_ref);
1056 v = SCM_ARRAY_V (v);
1057 }
1058 else
1059 {
1060 if (SCM_NIMP (args))
1061
1062 {
1063 SCM_ASSERT (SCM_CONSP (args) && SCM_INUMP (SCM_CAR (args)), args, SCM_ARG2, s_uniform_vector_ref);
1064 pos = SCM_INUM (SCM_CAR (args));
1065 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args)), wna);
1066 }
1067 else
1068 {
1069 SCM_ASSERT (SCM_INUMP (args), args, SCM_ARG2, s_uniform_vector_ref);
1070 pos = SCM_INUM (args);
1071 }
1072 SCM_ASRTGO (pos >= 0 && pos < SCM_LENGTH (v), outrng);
1073 }
1074 switch SCM_TYP7
1075 (v)
1076 {
1077 default:
1078 if (SCM_NULLP (args))
1079 return v;
35de7ebe
JB
1080 badarg:
1081 scm_wta (v, (char *) SCM_ARG1, s_uniform_vector_ref);
1082 abort ();
52859adf 1083 outrng:scm_out_of_range (s_uniform_vector_ref, SCM_MAKINUM (pos));
f5bf2977 1084 wna: scm_wrong_num_args (scm_makfrom0str (s_uniform_vector_ref));
0f2d19dd
JB
1085 case scm_tc7_smob:
1086 { /* enclosed */
1087 int k = SCM_ARRAY_NDIM (v);
1088 SCM res = scm_make_ra (k);
1089 SCM_ARRAY_V (res) = SCM_ARRAY_V (v);
1090 SCM_ARRAY_BASE (res) = pos;
1091 while (k--)
1092 {
1093 SCM_ARRAY_DIMS (res)[k].lbnd = SCM_ARRAY_DIMS (v)[k].lbnd;
1094 SCM_ARRAY_DIMS (res)[k].ubnd = SCM_ARRAY_DIMS (v)[k].ubnd;
1095 SCM_ARRAY_DIMS (res)[k].inc = SCM_ARRAY_DIMS (v)[k].inc;
1096 }
1097 return res;
1098 }
1099 case scm_tc7_bvect:
1100 if (SCM_VELTS (v)[pos / SCM_LONG_BIT] & (1L << (pos % SCM_LONG_BIT)))
1101 return SCM_BOOL_T;
1102 else
1103 return SCM_BOOL_F;
1104 case scm_tc7_string:
fc1d67c4 1105 return SCM_MAKICHR (SCM_UCHARS (v)[pos]);
0f2d19dd
JB
1106 case scm_tc7_byvect:
1107 return SCM_MAKINUM (((char *)SCM_CHARS (v))[pos]);
1108# ifdef SCM_INUMS_ONLY
1109 case scm_tc7_uvect:
1110 case scm_tc7_ivect:
1111 return SCM_MAKINUM (SCM_VELTS (v)[pos]);
1112# else
1113 case scm_tc7_uvect:
1114 return scm_ulong2num(SCM_VELTS(v)[pos]);
1115 case scm_tc7_ivect:
1116 return scm_long2num(SCM_VELTS(v)[pos]);
1117# endif
1118
1119 case scm_tc7_svect:
1120 return SCM_MAKINUM (((short *) SCM_CDR (v))[pos]);
5c11cc9d 1121#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
1122 case scm_tc7_llvect:
1123 return scm_long_long2num (((long_long *) SCM_CDR (v))[pos]);
1124#endif
1125
1126#ifdef SCM_FLOATS
1127#ifdef SCM_SINGLES
1128 case scm_tc7_fvect:
1129 return scm_makflo (((float *) SCM_CDR (v))[pos]);
1130#endif
1131 case scm_tc7_dvect:
1132 return scm_makdbl (((double *) SCM_CDR (v))[pos], 0.0);
1133 case scm_tc7_cvect:
1134 return scm_makdbl (((double *) SCM_CDR (v))[2 * pos],
1135 ((double *) SCM_CDR (v))[2 * pos + 1]);
1136#endif
1137 case scm_tc7_vector:
95f5b0f5 1138 case scm_tc7_wvect:
0f2d19dd
JB
1139 return SCM_VELTS (v)[pos];
1140 }
1141}
1142
1143/* Internal version of scm_uniform_vector_ref for uves that does no error checking and
1144 tries to recycle conses. (Make *sure* you want them recycled.) */
1cc91f1b 1145
0f2d19dd
JB
1146SCM
1147scm_cvref (v, pos, last)
1148 SCM v;
1149 scm_sizet pos;
1150 SCM last;
0f2d19dd 1151{
5c11cc9d 1152 switch SCM_TYP7 (v)
0f2d19dd
JB
1153 {
1154 default:
1155 scm_wta (v, (char *) SCM_ARG1, "PROGRAMMING ERROR: scm_cvref");
1156 case scm_tc7_bvect:
1157 if (SCM_VELTS (v)[pos / SCM_LONG_BIT] & (1L << (pos % SCM_LONG_BIT)))
1158 return SCM_BOOL_T;
1159 else
1160 return SCM_BOOL_F;
1161 case scm_tc7_string:
fc1d67c4 1162 return SCM_MAKICHR (SCM_UCHARS (v)[pos]);
0f2d19dd
JB
1163 case scm_tc7_byvect:
1164 return SCM_MAKINUM (((char *)SCM_CHARS (v))[pos]);
1165# ifdef SCM_INUMS_ONLY
1166 case scm_tc7_uvect:
1167 case scm_tc7_ivect:
1168 return SCM_MAKINUM (SCM_VELTS (v)[pos]);
1169# else
1170 case scm_tc7_uvect:
1171 return scm_ulong2num(SCM_VELTS(v)[pos]);
1172 case scm_tc7_ivect:
1173 return scm_long2num(SCM_VELTS(v)[pos]);
1174# endif
1175 case scm_tc7_svect:
1176 return SCM_MAKINUM (((short *) SCM_CDR (v))[pos]);
5c11cc9d 1177#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
1178 case scm_tc7_llvect:
1179 return scm_long_long2num (((long_long *) SCM_CDR (v))[pos]);
1180#endif
1181#ifdef SCM_FLOATS
1182#ifdef SCM_SINGLES
1183 case scm_tc7_fvect:
1184 if (SCM_NIMP (last) && (last != scm_flo0) && (scm_tc_flo == SCM_CAR (last)))
1185 {
1186 SCM_FLO (last) = ((float *) SCM_CDR (v))[pos];
1187 return last;
1188 }
1189 return scm_makflo (((float *) SCM_CDR (v))[pos]);
1190#endif
1191 case scm_tc7_dvect:
1192#ifdef SCM_SINGLES
1193 if (SCM_NIMP (last) && scm_tc_dblr == SCM_CAR (last))
1194#else
1195 if (SCM_NIMP (last) && (last != scm_flo0) && (scm_tc_dblr == SCM_CAR (last)))
1196#endif
1197 {
1198 SCM_REAL (last) = ((double *) SCM_CDR (v))[pos];
1199 return last;
1200 }
1201 return scm_makdbl (((double *) SCM_CDR (v))[pos], 0.0);
1202 case scm_tc7_cvect:
1203 if (SCM_NIMP (last) && scm_tc_dblc == SCM_CAR (last))
1204 {
1205 SCM_REAL (last) = ((double *) SCM_CDR (v))[2 * pos];
1206 SCM_IMAG (last) = ((double *) SCM_CDR (v))[2 * pos + 1];
1207 return last;
1208 }
1209 return scm_makdbl (((double *) SCM_CDR (v))[2 * pos],
1210 ((double *) SCM_CDR (v))[2 * pos + 1]);
1211#endif
1212 case scm_tc7_vector:
95f5b0f5 1213 case scm_tc7_wvect:
0f2d19dd
JB
1214 return SCM_VELTS (v)[pos];
1215 case scm_tc7_smob:
1216 { /* enclosed scm_array */
1217 int k = SCM_ARRAY_NDIM (v);
1218 SCM res = scm_make_ra (k);
1219 SCM_ARRAY_V (res) = SCM_ARRAY_V (v);
1220 SCM_ARRAY_BASE (res) = pos;
1221 while (k--)
1222 {
1223 SCM_ARRAY_DIMS (res)[k].ubnd = SCM_ARRAY_DIMS (v)[k].ubnd;
1224 SCM_ARRAY_DIMS (res)[k].lbnd = SCM_ARRAY_DIMS (v)[k].lbnd;
1225 SCM_ARRAY_DIMS (res)[k].inc = SCM_ARRAY_DIMS (v)[k].inc;
1226 }
1227 return res;
1228 }
1229 }
1230}
1231
1232SCM_PROC(s_uniform_array_set1_x, "uniform-array-set1!", 3, 0, 0, scm_array_set_x);
1233SCM_PROC(s_array_set_x, "array-set!", 2, 0, 1, scm_array_set_x);
1cc91f1b 1234
0aa0871f
GH
1235/* Note that args may be a list or an immediate object, depending which
1236 PROC is used (and it's called from C too). */
0f2d19dd
JB
1237SCM
1238scm_array_set_x (v, obj, args)
1239 SCM v;
1240 SCM obj;
1241 SCM args;
0f2d19dd 1242{
f3667f52 1243 long pos = 0;
0f2d19dd
JB
1244 SCM_ASRTGO (SCM_NIMP (v), badarg1);
1245 if (SCM_ARRAYP (v))
0f2d19dd
JB
1246 {
1247 pos = scm_aind (v, args, s_array_set_x);
1248 v = SCM_ARRAY_V (v);
1249 }
1250 else
1251 {
1252 if (SCM_NIMP (args))
0f2d19dd 1253 {
0aa0871f
GH
1254 SCM_ASSERT (SCM_CONSP(args) && SCM_INUMP (SCM_CAR (args)), args,
1255 SCM_ARG3, s_array_set_x);
0f2d19dd 1256 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args)), wna);
0aa0871f 1257 pos = SCM_INUM (SCM_CAR (args));
0f2d19dd
JB
1258 }
1259 else
1260 {
0aa0871f 1261 SCM_ASSERT (SCM_INUMP (args), args, SCM_ARG3, s_array_set_x);
0f2d19dd
JB
1262 pos = SCM_INUM (args);
1263 }
1264 SCM_ASRTGO (pos >= 0 && pos < SCM_LENGTH (v), outrng);
1265 }
1266 switch (SCM_TYP7 (v))
1267 {
35de7ebe
JB
1268 default: badarg1:
1269 scm_wta (v, (char *) SCM_ARG1, s_array_set_x);
1270 abort ();
52859adf 1271 outrng:scm_out_of_range (s_array_set_x, SCM_MAKINUM (pos));
f5bf2977 1272 wna: scm_wrong_num_args (scm_makfrom0str (s_array_set_x));
0f2d19dd
JB
1273 case scm_tc7_smob: /* enclosed */
1274 goto badarg1;
1275 case scm_tc7_bvect:
1276 if (SCM_BOOL_F == obj)
1277 SCM_VELTS (v)[pos / SCM_LONG_BIT] &= ~(1L << (pos % SCM_LONG_BIT));
1278 else if (SCM_BOOL_T == obj)
1279 SCM_VELTS (v)[pos / SCM_LONG_BIT] |= (1L << (pos % SCM_LONG_BIT));
1280 else
0aa0871f 1281 badobj:scm_wta (obj, (char *) SCM_ARG2, s_array_set_x);
0f2d19dd
JB
1282 break;
1283 case scm_tc7_string:
0aa0871f 1284 SCM_ASRTGO (SCM_ICHRP (obj), badobj);
fc1d67c4 1285 SCM_UCHARS (v)[pos] = SCM_ICHR (obj);
0f2d19dd
JB
1286 break;
1287 case scm_tc7_byvect:
1288 if (SCM_ICHRP (obj))
b1d24656 1289 obj = SCM_MAKINUM ((char) SCM_ICHR (obj));
0aa0871f 1290 SCM_ASRTGO (SCM_INUMP (obj), badobj);
0f2d19dd
JB
1291 ((char *)SCM_CHARS (v))[pos] = SCM_INUM (obj);
1292 break;
1293# ifdef SCM_INUMS_ONLY
1294 case scm_tc7_uvect:
0aa0871f 1295 SCM_ASRTGO (SCM_INUM (obj) >= 0, badobj);
0f2d19dd 1296 case scm_tc7_ivect:
0aa0871f 1297 SCM_ASRTGO(SCM_INUMP(obj), badobj); SCM_VELTS(v)[pos] = SCM_INUM(obj); break;
0f2d19dd
JB
1298# else
1299 case scm_tc7_uvect:
0aa0871f 1300 SCM_VELTS(v)[pos] = scm_num2ulong(obj, (char *)SCM_ARG2, s_array_set_x); break;
0f2d19dd 1301 case scm_tc7_ivect:
3ffc7a36 1302 SCM_VELTS(v)[pos] = scm_num2long(obj, (char *)SCM_ARG2, s_array_set_x); break;
0f2d19dd
JB
1303# endif
1304 break;
1305
1306 case scm_tc7_svect:
0aa0871f 1307 SCM_ASRTGO (SCM_INUMP (obj), badobj);
0f2d19dd
JB
1308 ((short *) SCM_CDR (v))[pos] = SCM_INUM (obj);
1309 break;
5c11cc9d 1310#ifdef HAVE_LONG_LONGS
0f2d19dd 1311 case scm_tc7_llvect:
0aa0871f 1312 ((long_long *) SCM_CDR (v))[pos] = scm_num2long_long (obj, (char *)SCM_ARG2, s_array_set_x);
0f2d19dd
JB
1313 break;
1314#endif
1315
1316
1317#ifdef SCM_FLOATS
1318#ifdef SCM_SINGLES
1319 case scm_tc7_fvect:
f6957503 1320 ((float *) SCM_CDR (v))[pos] = (float)scm_num2dbl(obj, s_array_set_x); break;
0f2d19dd
JB
1321 break;
1322#endif
1323 case scm_tc7_dvect:
f6957503 1324 ((double *) SCM_CDR (v))[pos] = scm_num2dbl(obj, s_array_set_x); break;
0f2d19dd
JB
1325 break;
1326 case scm_tc7_cvect:
0aa0871f 1327 SCM_ASRTGO (SCM_NIMP (obj) && SCM_INEXP (obj), badobj);
0f2d19dd
JB
1328 ((double *) SCM_CDR (v))[2 * pos] = SCM_REALPART (obj);
1329 ((double *) SCM_CDR (v))[2 * pos + 1] = SCM_CPLXP (obj) ? SCM_IMAG (obj) : 0.0;
1330 break;
1331#endif
1332 case scm_tc7_vector:
95f5b0f5 1333 case scm_tc7_wvect:
0f2d19dd
JB
1334 SCM_VELTS (v)[pos] = obj;
1335 break;
1336 }
1337 return SCM_UNSPECIFIED;
1338}
1339
5c11cc9d
GH
1340/* extract an array from "ra" (regularised?), which may be an smob type.
1341 returns #f on failure. */
0f2d19dd 1342SCM_PROC(s_array_contents, "array-contents", 1, 1, 0, scm_array_contents);
1cc91f1b 1343
0f2d19dd
JB
1344SCM
1345scm_array_contents (ra, strict)
1346 SCM ra;
5c11cc9d 1347 SCM strict; /* more checks if not SCM_UNDEFINED. */
0f2d19dd
JB
1348{
1349 SCM sra;
1350 if (SCM_IMP (ra))
f3667f52 1351 return SCM_BOOL_F;
5c11cc9d 1352 switch SCM_TYP7 (ra)
0f2d19dd
JB
1353 {
1354 default:
1355 return SCM_BOOL_F;
1356 case scm_tc7_vector:
95f5b0f5 1357 case scm_tc7_wvect:
0f2d19dd
JB
1358 case scm_tc7_string:
1359 case scm_tc7_bvect:
1360 case scm_tc7_byvect:
1361 case scm_tc7_uvect:
1362 case scm_tc7_ivect:
1363 case scm_tc7_fvect:
1364 case scm_tc7_dvect:
1365 case scm_tc7_cvect:
1366 case scm_tc7_svect:
5c11cc9d 1367#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
1368 case scm_tc7_llvect:
1369#endif
1370 return ra;
1371 case scm_tc7_smob:
1372 {
1373 scm_sizet k, ndim = SCM_ARRAY_NDIM (ra), len = 1;
1374 if (!SCM_ARRAYP (ra) || !SCM_ARRAY_CONTP (ra))
1375 return SCM_BOOL_F;
1376 for (k = 0; k < ndim; k++)
1377 len *= SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd + 1;
1378 if (!SCM_UNBNDP (strict))
1379 {
0f2d19dd
JB
1380 if (ndim && (1 != SCM_ARRAY_DIMS (ra)[ndim - 1].inc))
1381 return SCM_BOOL_F;
1382 if (scm_tc7_bvect == SCM_TYP7 (SCM_ARRAY_V (ra)))
1383 {
1384 if (len != SCM_LENGTH (SCM_ARRAY_V (ra)) ||
1385 SCM_ARRAY_BASE (ra) % SCM_LONG_BIT ||
1386 len % SCM_LONG_BIT)
1387 return SCM_BOOL_F;
1388 }
1389 }
1390 if ((len == SCM_LENGTH (SCM_ARRAY_V (ra))) && 0 == SCM_ARRAY_BASE (ra) && SCM_ARRAY_DIMS (ra)->inc)
1391 return SCM_ARRAY_V (ra);
1392 sra = scm_make_ra (1);
1393 SCM_ARRAY_DIMS (sra)->lbnd = 0;
1394 SCM_ARRAY_DIMS (sra)->ubnd = len - 1;
1395 SCM_ARRAY_V (sra) = SCM_ARRAY_V (ra);
1396 SCM_ARRAY_BASE (sra) = SCM_ARRAY_BASE (ra);
1397 SCM_ARRAY_DIMS (sra)->inc = (ndim ? SCM_ARRAY_DIMS (ra)[ndim - 1].inc : 1);
1398 return sra;
1399 }
1400 }
1401}
1402
1cc91f1b 1403
0f2d19dd
JB
1404SCM
1405scm_ra2contig (ra, copy)
1406 SCM ra;
1407 int copy;
0f2d19dd
JB
1408{
1409 SCM ret;
1410 long inc = 1;
1411 scm_sizet k, len = 1;
1412 for (k = SCM_ARRAY_NDIM (ra); k--;)
1413 len *= SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd + 1;
1414 k = SCM_ARRAY_NDIM (ra);
1415 if (SCM_ARRAY_CONTP (ra) && ((0 == k) || (1 == SCM_ARRAY_DIMS (ra)[k - 1].inc)))
1416 {
1417 if (scm_tc7_bvect != SCM_TYP7 (ra))
1418 return ra;
1419 if ((len == SCM_LENGTH (SCM_ARRAY_V (ra)) &&
1420 0 == SCM_ARRAY_BASE (ra) % SCM_LONG_BIT &&
1421 0 == len % SCM_LONG_BIT))
1422 return ra;
1423 }
1424 ret = scm_make_ra (k);
1425 SCM_ARRAY_BASE (ret) = 0;
1426 while (k--)
1427 {
1428 SCM_ARRAY_DIMS (ret)[k].lbnd = SCM_ARRAY_DIMS (ra)[k].lbnd;
1429 SCM_ARRAY_DIMS (ret)[k].ubnd = SCM_ARRAY_DIMS (ra)[k].ubnd;
1430 SCM_ARRAY_DIMS (ret)[k].inc = inc;
1431 inc *= SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd + 1;
1432 }
1433 SCM_ARRAY_V (ret) = scm_make_uve ((inc - 1), scm_array_prototype (ra));
1434 if (copy)
1435 scm_array_copy_x (ra, ret);
1436 return ret;
1437}
1438
1439
1440
3d8d56df 1441SCM_PROC(s_uniform_array_read_x, "uniform-array-read!", 1, 3, 0, scm_uniform_array_read_x);
1cc91f1b 1442
0f2d19dd 1443SCM
1146b6cd 1444scm_uniform_array_read_x (ra, port_or_fd, start, end)
0f2d19dd 1445 SCM ra;
3d8d56df 1446 SCM port_or_fd;
1146b6cd
GH
1447 SCM start;
1448 SCM end;
0f2d19dd 1449{
35de7ebe 1450 SCM cra = SCM_UNDEFINED, v = ra;
3d8d56df 1451 long sz, vlen, ans;
1146b6cd
GH
1452 long cstart = 0;
1453 long cend;
1454 long offset = 0;
35de7ebe 1455
0f2d19dd 1456 SCM_ASRTGO (SCM_NIMP (v), badarg1);
3d8d56df
GH
1457 if (SCM_UNBNDP (port_or_fd))
1458 port_or_fd = scm_cur_inp;
1459 else
1460 SCM_ASSERT (SCM_INUMP (port_or_fd)
6c951427 1461 || (SCM_NIMP (port_or_fd) && SCM_OPINPORTP (port_or_fd)),
3d8d56df
GH
1462 port_or_fd, SCM_ARG2, s_uniform_array_read_x);
1463 vlen = SCM_LENGTH (v);
35de7ebe 1464
0f2d19dd 1465loop:
35de7ebe 1466 switch SCM_TYP7 (v)
0f2d19dd
JB
1467 {
1468 default:
1469 badarg1:scm_wta (v, (char *) SCM_ARG1, s_uniform_array_read_x);
1470 case scm_tc7_smob:
1471 SCM_ASRTGO (SCM_ARRAYP (v), badarg1);
1472 cra = scm_ra2contig (ra, 0);
1146b6cd 1473 cstart += SCM_ARRAY_BASE (cra);
3d8d56df 1474 vlen = SCM_ARRAY_DIMS (cra)->inc *
0f2d19dd
JB
1475 (SCM_ARRAY_DIMS (cra)->ubnd - SCM_ARRAY_DIMS (cra)->lbnd + 1);
1476 v = SCM_ARRAY_V (cra);
1477 goto loop;
1478 case scm_tc7_string:
1479 case scm_tc7_byvect:
1480 sz = sizeof (char);
1481 break;
1482 case scm_tc7_bvect:
3d8d56df 1483 vlen = (vlen + SCM_LONG_BIT - 1) / SCM_LONG_BIT;
1146b6cd 1484 cstart /= SCM_LONG_BIT;
0f2d19dd
JB
1485 case scm_tc7_uvect:
1486 case scm_tc7_ivect:
1487 sz = sizeof (long);
1488 break;
1489 case scm_tc7_svect:
1490 sz = sizeof (short);
1491 break;
5c11cc9d 1492#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
1493 case scm_tc7_llvect:
1494 sz = sizeof (long_long);
1495 break;
1496#endif
1497#ifdef SCM_FLOATS
1498#ifdef SCM_SINGLES
1499 case scm_tc7_fvect:
1500 sz = sizeof (float);
1501 break;
1502#endif
1503 case scm_tc7_dvect:
1504 sz = sizeof (double);
1505 break;
1506 case scm_tc7_cvect:
1507 sz = 2 * sizeof (double);
1508 break;
1509#endif
1510 }
3d8d56df 1511
1146b6cd
GH
1512 cend = vlen;
1513 if (!SCM_UNBNDP (start))
3d8d56df 1514 {
1146b6cd
GH
1515 offset =
1516 scm_num2long (start, (char *) SCM_ARG3, s_uniform_array_read_x);
35de7ebe 1517
1146b6cd
GH
1518 if (offset < 0 || offset >= cend)
1519 scm_out_of_range (s_uniform_array_read_x, start);
1520
1521 if (!SCM_UNBNDP (end))
1522 {
1523 long tend =
1524 scm_num2long (end, (char *) SCM_ARG4, s_uniform_array_read_x);
3d8d56df 1525
1146b6cd
GH
1526 if (tend <= offset || tend > cend)
1527 scm_out_of_range (s_uniform_array_read_x, end);
1528 cend = tend;
1529 }
0f2d19dd 1530 }
35de7ebe 1531
3d8d56df
GH
1532 if (SCM_NIMP (port_or_fd))
1533 {
6c951427
GH
1534 scm_port *pt = SCM_PTAB_ENTRY (port_or_fd);
1535 int remaining = (cend - offset) * sz;
1536 char *dest = SCM_CHARS (v) + (cstart + offset) * sz;
1537
1538 if (pt->rw_active == SCM_PORT_WRITE)
affc96b5 1539 scm_flush (port_or_fd);
6c951427
GH
1540
1541 ans = cend - offset;
1542 while (remaining > 0)
3d8d56df 1543 {
6c951427
GH
1544 if (pt->read_pos < pt->read_end)
1545 {
1546 int to_copy = min (pt->read_end - pt->read_pos,
1547 remaining);
1548
1549 memcpy (dest, pt->read_pos, to_copy);
1550 pt->read_pos += to_copy;
1551 remaining -= to_copy;
1552 dest += to_copy;
1553 }
1554 else
1555 {
affc96b5 1556 if (scm_fill_input (port_or_fd) == EOF)
6c951427
GH
1557 {
1558 if (remaining % sz != 0)
1559 {
1560 scm_misc_error (s_uniform_array_read_x,
1561 "unexpected EOF",
1562 SCM_EOL);
1563 }
1564 ans -= remaining / sz;
1565 break;
1566 }
6c951427 1567 }
3d8d56df 1568 }
6c951427
GH
1569
1570 if (pt->rw_random)
1571 pt->rw_active = SCM_PORT_READ;
3d8d56df
GH
1572 }
1573 else /* file descriptor. */
1574 {
1575 SCM_SYSCALL (ans = read (SCM_INUM (port_or_fd),
1146b6cd
GH
1576 SCM_CHARS (v) + (cstart + offset) * sz,
1577 (scm_sizet) (sz * (cend - offset))));
3d8d56df
GH
1578 if (ans == -1)
1579 scm_syserror (s_uniform_array_read_x);
1580 }
0f2d19dd
JB
1581 if (SCM_TYP7 (v) == scm_tc7_bvect)
1582 ans *= SCM_LONG_BIT;
35de7ebe 1583
0f2d19dd
JB
1584 if (v != ra && cra != ra)
1585 scm_array_copy_x (cra, ra);
35de7ebe 1586
0f2d19dd
JB
1587 return SCM_MAKINUM (ans);
1588}
1589
3d8d56df 1590SCM_PROC(s_uniform_array_write, "uniform-array-write", 1, 3, 0, scm_uniform_array_write);
1cc91f1b 1591
0f2d19dd 1592SCM
1146b6cd 1593scm_uniform_array_write (v, port_or_fd, start, end)
0f2d19dd 1594 SCM v;
3d8d56df 1595 SCM port_or_fd;
1146b6cd
GH
1596 SCM start;
1597 SCM end;
0f2d19dd 1598{
3d8d56df 1599 long sz, vlen, ans;
1146b6cd
GH
1600 long offset = 0;
1601 long cstart = 0;
1602 long cend;
3d8d56df 1603
78446828
MV
1604 port_or_fd = SCM_COERCE_OUTPORT (port_or_fd);
1605
0f2d19dd 1606 SCM_ASRTGO (SCM_NIMP (v), badarg1);
3d8d56df
GH
1607 if (SCM_UNBNDP (port_or_fd))
1608 port_or_fd = scm_cur_outp;
1609 else
1610 SCM_ASSERT (SCM_INUMP (port_or_fd)
6c951427 1611 || (SCM_NIMP (port_or_fd) && SCM_OPOUTPORTP (port_or_fd)),
3d8d56df
GH
1612 port_or_fd, SCM_ARG2, s_uniform_array_write);
1613 vlen = SCM_LENGTH (v);
1614
0f2d19dd 1615loop:
3d8d56df 1616 switch SCM_TYP7 (v)
0f2d19dd
JB
1617 {
1618 default:
1619 badarg1:scm_wta (v, (char *) SCM_ARG1, s_uniform_array_write);
1620 case scm_tc7_smob:
1621 SCM_ASRTGO (SCM_ARRAYP (v), badarg1);
1622 v = scm_ra2contig (v, 1);
1146b6cd 1623 cstart = SCM_ARRAY_BASE (v);
3d8d56df
GH
1624 vlen = SCM_ARRAY_DIMS (v)->inc
1625 * (SCM_ARRAY_DIMS (v)->ubnd - SCM_ARRAY_DIMS (v)->lbnd + 1);
0f2d19dd
JB
1626 v = SCM_ARRAY_V (v);
1627 goto loop;
0f2d19dd 1628 case scm_tc7_string:
3d8d56df 1629 case scm_tc7_byvect:
0f2d19dd
JB
1630 sz = sizeof (char);
1631 break;
1632 case scm_tc7_bvect:
3d8d56df 1633 vlen = (vlen + SCM_LONG_BIT - 1) / SCM_LONG_BIT;
1146b6cd 1634 cstart /= SCM_LONG_BIT;
0f2d19dd
JB
1635 case scm_tc7_uvect:
1636 case scm_tc7_ivect:
1637 sz = sizeof (long);
1638 break;
1639 case scm_tc7_svect:
1640 sz = sizeof (short);
1641 break;
5c11cc9d 1642#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
1643 case scm_tc7_llvect:
1644 sz = sizeof (long_long);
1645 break;
1646#endif
1647#ifdef SCM_FLOATS
1648#ifdef SCM_SINGLES
1649 case scm_tc7_fvect:
1650 sz = sizeof (float);
1651 break;
1652#endif
1653 case scm_tc7_dvect:
1654 sz = sizeof (double);
1655 break;
1656 case scm_tc7_cvect:
1657 sz = 2 * sizeof (double);
1658 break;
1659#endif
1660 }
3d8d56df 1661
1146b6cd
GH
1662 cend = vlen;
1663 if (!SCM_UNBNDP (start))
3d8d56df 1664 {
1146b6cd
GH
1665 offset =
1666 scm_num2long (start, (char *) SCM_ARG3, s_uniform_array_write);
3d8d56df 1667
1146b6cd
GH
1668 if (offset < 0 || offset >= cend)
1669 scm_out_of_range (s_uniform_array_write, start);
1670
1671 if (!SCM_UNBNDP (end))
1672 {
1673 long tend =
1674 scm_num2long (end, (char *) SCM_ARG4, s_uniform_array_write);
3d8d56df 1675
1146b6cd
GH
1676 if (tend <= offset || tend > cend)
1677 scm_out_of_range (s_uniform_array_write, end);
1678 cend = tend;
1679 }
3d8d56df
GH
1680 }
1681
1682 if (SCM_NIMP (port_or_fd))
1683 {
6c951427 1684 char *source = SCM_CHARS (v) + (cstart + offset) * sz;
6c951427
GH
1685
1686 ans = cend - offset;
265e6a4d 1687 scm_lfwrite (source, ans * sz, port_or_fd);
3d8d56df
GH
1688 }
1689 else /* file descriptor. */
1690 {
1691 SCM_SYSCALL (ans = write (SCM_INUM (port_or_fd),
1146b6cd
GH
1692 SCM_CHARS (v) + (cstart + offset) * sz,
1693 (scm_sizet) (sz * (cend - offset))));
3d8d56df
GH
1694 if (ans == -1)
1695 scm_syserror (s_uniform_array_write);
1696 }
0f2d19dd
JB
1697 if (SCM_TYP7 (v) == scm_tc7_bvect)
1698 ans *= SCM_LONG_BIT;
3d8d56df 1699
0f2d19dd
JB
1700 return SCM_MAKINUM (ans);
1701}
1702
1703
1704static char cnt_tab[16] =
1705{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
1706
1707SCM_PROC(s_bit_count, "bit-count", 2, 0, 0, scm_bit_count);
1cc91f1b 1708
0f2d19dd
JB
1709SCM
1710scm_bit_count (item, seq)
1711 SCM item;
1712 SCM seq;
0f2d19dd
JB
1713{
1714 long i;
1715 register unsigned long cnt = 0, w;
1716 SCM_ASSERT (SCM_NIMP (seq), seq, SCM_ARG2, s_bit_count);
5c11cc9d 1717 switch SCM_TYP7 (seq)
0f2d19dd
JB
1718 {
1719 default:
1720 scm_wta (seq, (char *) SCM_ARG2, s_bit_count);
1721 case scm_tc7_bvect:
1722 if (0 == SCM_LENGTH (seq))
1723 return SCM_INUM0;
1724 i = (SCM_LENGTH (seq) - 1) / SCM_LONG_BIT;
1725 w = SCM_VELTS (seq)[i];
1726 if (SCM_FALSEP (item))
1727 w = ~w;
1728 w <<= SCM_LONG_BIT - 1 - ((SCM_LENGTH (seq) - 1) % SCM_LONG_BIT);
1729 while (!0)
1730 {
1731 for (; w; w >>= 4)
1732 cnt += cnt_tab[w & 0x0f];
1733 if (0 == i--)
1734 return SCM_MAKINUM (cnt);
1735 w = SCM_VELTS (seq)[i];
1736 if (SCM_FALSEP (item))
1737 w = ~w;
1738 }
1739 }
1740}
1741
1742
1743SCM_PROC(s_bit_position, "bit-position", 3, 0, 0, scm_bit_position);
1cc91f1b 1744
0f2d19dd
JB
1745SCM
1746scm_bit_position (item, v, k)
1747 SCM item;
1748 SCM v;
1749 SCM k;
0f2d19dd
JB
1750{
1751 long i, lenw, xbits, pos = SCM_INUM (k);
1752 register unsigned long w;
1753 SCM_ASSERT (SCM_NIMP (v), v, SCM_ARG2, s_bit_position);
1754 SCM_ASSERT (SCM_INUMP (k), k, SCM_ARG3, s_bit_position);
1755 SCM_ASSERT ((pos <= SCM_LENGTH (v)) && (pos >= 0),
1756 k, SCM_OUTOFRANGE, s_bit_position);
1757 if (pos == SCM_LENGTH (v))
1758 return SCM_BOOL_F;
5c11cc9d 1759 switch SCM_TYP7 (v)
0f2d19dd
JB
1760 {
1761 default:
1762 scm_wta (v, (char *) SCM_ARG2, s_bit_position);
1763 case scm_tc7_bvect:
1764 if (0 == SCM_LENGTH (v))
1765 return SCM_MAKINUM (-1L);
1766 lenw = (SCM_LENGTH (v) - 1) / SCM_LONG_BIT; /* watch for part words */
1767 i = pos / SCM_LONG_BIT;
1768 w = SCM_VELTS (v)[i];
1769 if (SCM_FALSEP (item))
1770 w = ~w;
1771 xbits = (pos % SCM_LONG_BIT);
1772 pos -= xbits;
1773 w = ((w >> xbits) << xbits);
1774 xbits = SCM_LONG_BIT - 1 - (SCM_LENGTH (v) - 1) % SCM_LONG_BIT;
1775 while (!0)
1776 {
1777 if (w && (i == lenw))
1778 w = ((w << xbits) >> xbits);
1779 if (w)
1780 while (w)
1781 switch (w & 0x0f)
1782 {
1783 default:
1784 return SCM_MAKINUM (pos);
1785 case 2:
1786 case 6:
1787 case 10:
1788 case 14:
1789 return SCM_MAKINUM (pos + 1);
1790 case 4:
1791 case 12:
1792 return SCM_MAKINUM (pos + 2);
1793 case 8:
1794 return SCM_MAKINUM (pos + 3);
1795 case 0:
1796 pos += 4;
1797 w >>= 4;
1798 }
1799 if (++i > lenw)
1800 break;
1801 pos += SCM_LONG_BIT;
1802 w = SCM_VELTS (v)[i];
1803 if (SCM_FALSEP (item))
1804 w = ~w;
1805 }
1806 return SCM_BOOL_F;
1807 }
1808}
1809
1810
1811SCM_PROC(s_bit_set_star_x, "bit-set*!", 3, 0, 0, scm_bit_set_star_x);
1cc91f1b 1812
0f2d19dd
JB
1813SCM
1814scm_bit_set_star_x (v, kv, obj)
1815 SCM v;
1816 SCM kv;
1817 SCM obj;
0f2d19dd
JB
1818{
1819 register long i, k, vlen;
1820 SCM_ASRTGO (SCM_NIMP (v), badarg1);
1821 SCM_ASRTGO (SCM_NIMP (kv), badarg2);
5c11cc9d 1822 switch SCM_TYP7 (kv)
0f2d19dd
JB
1823 {
1824 default:
1825 badarg2:scm_wta (kv, (char *) SCM_ARG2, s_bit_set_star_x);
1826 case scm_tc7_uvect:
5c11cc9d 1827 switch SCM_TYP7 (v)
0f2d19dd
JB
1828 {
1829 default:
1830 badarg1:scm_wta (v, (char *) SCM_ARG1, s_bit_set_star_x);
1831 case scm_tc7_bvect:
1832 vlen = SCM_LENGTH (v);
1833 if (SCM_BOOL_F == obj)
1834 for (i = SCM_LENGTH (kv); i;)
1835 {
1836 k = SCM_VELTS (kv)[--i];
1837 SCM_ASSERT ((k < vlen), SCM_MAKINUM (k), SCM_OUTOFRANGE, s_bit_set_star_x);
1838 SCM_VELTS (v)[k / SCM_LONG_BIT] &= ~(1L << (k % SCM_LONG_BIT));
1839 }
1840 else if (SCM_BOOL_T == obj)
1841 for (i = SCM_LENGTH (kv); i;)
1842 {
1843 k = SCM_VELTS (kv)[--i];
1844 SCM_ASSERT ((k < vlen), SCM_MAKINUM (k), SCM_OUTOFRANGE, s_bit_set_star_x);
1845 SCM_VELTS (v)[k / SCM_LONG_BIT] |= (1L << (k % SCM_LONG_BIT));
1846 }
1847 else
1848 badarg3:scm_wta (obj, (char *) SCM_ARG3, s_bit_set_star_x);
1849 }
1850 break;
1851 case scm_tc7_bvect:
1852 SCM_ASRTGO (SCM_TYP7 (v) == scm_tc7_bvect && SCM_LENGTH (v) == SCM_LENGTH (kv), badarg1);
1853 if (SCM_BOOL_F == obj)
1854 for (k = (SCM_LENGTH (v) + SCM_LONG_BIT - 1) / SCM_LONG_BIT; k--;)
1855 SCM_VELTS (v)[k] &= ~(SCM_VELTS (kv)[k]);
1856 else if (SCM_BOOL_T == obj)
1857 for (k = (SCM_LENGTH (v) + SCM_LONG_BIT - 1) / SCM_LONG_BIT; k--;)
1858 SCM_VELTS (v)[k] |= SCM_VELTS (kv)[k];
1859 else
1860 goto badarg3;
1861 break;
1862 }
1863 return SCM_UNSPECIFIED;
1864}
1865
1866
1867SCM_PROC(s_bit_count_star, "bit-count*", 3, 0, 0, scm_bit_count_star);
1cc91f1b 1868
0f2d19dd
JB
1869SCM
1870scm_bit_count_star (v, kv, obj)
1871 SCM v;
1872 SCM kv;
1873 SCM obj;
0f2d19dd
JB
1874{
1875 register long i, vlen, count = 0;
1876 register unsigned long k;
1877 SCM_ASRTGO (SCM_NIMP (v), badarg1);
1878 SCM_ASRTGO (SCM_NIMP (kv), badarg2);
5c11cc9d 1879 switch SCM_TYP7 (kv)
0f2d19dd
JB
1880 {
1881 default:
1882 badarg2:scm_wta (kv, (char *) SCM_ARG2, s_bit_count_star);
1883 case scm_tc7_uvect:
1884 switch SCM_TYP7
1885 (v)
1886 {
1887 default:
1888 badarg1:scm_wta (v, (char *) SCM_ARG1, s_bit_count_star);
1889 case scm_tc7_bvect:
1890 vlen = SCM_LENGTH (v);
1891 if (SCM_BOOL_F == obj)
1892 for (i = SCM_LENGTH (kv); i;)
1893 {
1894 k = SCM_VELTS (kv)[--i];
1895 SCM_ASSERT ((k < vlen), SCM_MAKINUM (k), SCM_OUTOFRANGE, s_bit_count_star);
1896 if (!(SCM_VELTS (v)[k / SCM_LONG_BIT] & (1L << (k % SCM_LONG_BIT))))
1897 count++;
1898 }
1899 else if (SCM_BOOL_T == obj)
1900 for (i = SCM_LENGTH (kv); i;)
1901 {
1902 k = SCM_VELTS (kv)[--i];
1903 SCM_ASSERT ((k < vlen), SCM_MAKINUM (k), SCM_OUTOFRANGE, s_bit_count_star);
1904 if (SCM_VELTS (v)[k / SCM_LONG_BIT] & (1L << (k % SCM_LONG_BIT)))
1905 count++;
1906 }
1907 else
1908 badarg3:scm_wta (obj, (char *) SCM_ARG3, s_bit_count_star);
1909 }
1910 break;
1911 case scm_tc7_bvect:
1912 SCM_ASRTGO (SCM_TYP7 (v) == scm_tc7_bvect && SCM_LENGTH (v) == SCM_LENGTH (kv), badarg1);
1913 if (0 == SCM_LENGTH (v))
1914 return SCM_INUM0;
1915 SCM_ASRTGO (SCM_BOOL_T == obj || SCM_BOOL_F == obj, badarg3);
1916 obj = (SCM_BOOL_T == obj);
1917 i = (SCM_LENGTH (v) - 1) / SCM_LONG_BIT;
1918 k = SCM_VELTS (kv)[i] & (obj ? SCM_VELTS (v)[i] : ~SCM_VELTS (v)[i]);
1919 k <<= SCM_LONG_BIT - 1 - ((SCM_LENGTH (v) - 1) % SCM_LONG_BIT);
1920 while (!0)
1921 {
1922 for (; k; k >>= 4)
1923 count += cnt_tab[k & 0x0f];
1924 if (0 == i--)
1925 return SCM_MAKINUM (count);
1926 k = SCM_VELTS (kv)[i] & (obj ? SCM_VELTS (v)[i] : ~SCM_VELTS (v)[i]);
1927 }
1928 }
1929 return SCM_MAKINUM (count);
1930}
1931
1932
1933SCM_PROC(s_bit_invert_x, "bit-invert!", 1, 0, 0, scm_bit_invert_x);
1cc91f1b 1934
0f2d19dd
JB
1935SCM
1936scm_bit_invert_x (v)
1937 SCM v;
0f2d19dd
JB
1938{
1939 register long k;
1940 SCM_ASRTGO (SCM_NIMP (v), badarg1);
1941 k = SCM_LENGTH (v);
1942 switch SCM_TYP7
1943 (v)
1944 {
1945 case scm_tc7_bvect:
1946 for (k = (k + SCM_LONG_BIT - 1) / SCM_LONG_BIT; k--;)
1947 SCM_VELTS (v)[k] = ~SCM_VELTS (v)[k];
1948 break;
1949 default:
1950 badarg1:scm_wta (v, (char *) SCM_ARG1, s_bit_invert_x);
1951 }
1952 return SCM_UNSPECIFIED;
1953}
1954
1955
0f2d19dd
JB
1956SCM
1957scm_istr2bve (str, len)
1958 char *str;
1959 long len;
0f2d19dd
JB
1960{
1961 SCM v = scm_make_uve (len, SCM_BOOL_T);
1962 long *data = (long *) SCM_VELTS (v);
1963 register unsigned long mask;
1964 register long k;
1965 register long j;
1966 for (k = 0; k < (len + SCM_LONG_BIT - 1) / SCM_LONG_BIT; k++)
1967 {
1968 data[k] = 0L;
1969 j = len - k * SCM_LONG_BIT;
1970 if (j > SCM_LONG_BIT)
1971 j = SCM_LONG_BIT;
1972 for (mask = 1L; j--; mask <<= 1)
1973 switch (*str++)
1974 {
1975 case '0':
1976 break;
1977 case '1':
1978 data[k] |= mask;
1979 break;
1980 default:
1981 return SCM_BOOL_F;
1982 }
1983 }
1984 return v;
1985}
1986
1987
1cc91f1b
JB
1988
1989static SCM ra2l SCM_P ((SCM ra, scm_sizet base, scm_sizet k));
1990
0f2d19dd
JB
1991static SCM
1992ra2l (ra, base, k)
1993 SCM ra;
1994 scm_sizet base;
1995 scm_sizet k;
0f2d19dd
JB
1996{
1997 register SCM res = SCM_EOL;
1998 register long inc = SCM_ARRAY_DIMS (ra)[k].inc;
1999 register scm_sizet i;
2000 if (SCM_ARRAY_DIMS (ra)[k].ubnd < SCM_ARRAY_DIMS (ra)[k].lbnd)
2001 return SCM_EOL;
2002 i = base + (1 + SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd) * inc;
2003 if (k < SCM_ARRAY_NDIM (ra) - 1)
2004 {
2005 do
2006 {
2007 i -= inc;
2008 res = scm_cons (ra2l (ra, i, k + 1), res);
2009 }
2010 while (i != base);
2011 }
2012 else
2013 do
2014 {
2015 i -= inc;
2016 res = scm_cons (scm_uniform_vector_ref (SCM_ARRAY_V (ra), SCM_MAKINUM (i)), res);
2017 }
2018 while (i != base);
2019 return res;
2020}
2021
2022
2023SCM_PROC(s_array_to_list, "array->list", 1, 0, 0, scm_array_to_list);
1cc91f1b 2024
0f2d19dd
JB
2025SCM
2026scm_array_to_list (v)
2027 SCM v;
0f2d19dd
JB
2028{
2029 SCM res = SCM_EOL;
2030 register long k;
2031 SCM_ASRTGO (SCM_NIMP (v), badarg1);
2032 switch SCM_TYP7
2033 (v)
2034 {
2035 default:
2036 badarg1:scm_wta (v, (char *) SCM_ARG1, s_array_to_list);
2037 case scm_tc7_smob:
2038 SCM_ASRTGO (SCM_ARRAYP (v), badarg1);
2039 return ra2l (v, SCM_ARRAY_BASE (v), 0);
2040 case scm_tc7_vector:
95f5b0f5 2041 case scm_tc7_wvect:
0f2d19dd
JB
2042 return scm_vector_to_list (v);
2043 case scm_tc7_string:
2044 return scm_string_to_list (v);
2045 case scm_tc7_bvect:
2046 {
2047 long *data = (long *) SCM_VELTS (v);
2048 register unsigned long mask;
2049 for (k = (SCM_LENGTH (v) - 1) / SCM_LONG_BIT; k > 0; k--)
cdbadcac 2050 for (mask = 1UL << (SCM_LONG_BIT - 1); mask; mask >>= 1)
0f2d19dd
JB
2051 res = scm_cons (((long *) data)[k] & mask ? SCM_BOOL_T : SCM_BOOL_F, res);
2052 for (mask = 1L << ((SCM_LENGTH (v) % SCM_LONG_BIT) - 1); mask; mask >>= 1)
2053 res = scm_cons (((long *) data)[k] & mask ? SCM_BOOL_T : SCM_BOOL_F, res);
2054 return res;
2055 }
2056# ifdef SCM_INUMS_ONLY
2057 case scm_tc7_uvect:
2058 case scm_tc7_ivect:
2059 {
2060 long *data = (long *) SCM_VELTS (v);
2061 for (k = SCM_LENGTH (v) - 1; k >= 0; k--)
2062 res = scm_cons (SCM_MAKINUM (data[k]), res);
2063 return res;
2064 }
2065# else
2066 case scm_tc7_uvect: {
2067 long *data = (long *)SCM_VELTS(v);
2068 for (k = SCM_LENGTH(v) - 1; k >= 0; k--)
2069 res = scm_cons(scm_ulong2num(data[k]), res);
2070 return res;
2071 }
2072 case scm_tc7_ivect: {
2073 long *data = (long *)SCM_VELTS(v);
2074 for (k = SCM_LENGTH(v) - 1; k >= 0; k--)
2075 res = scm_cons(scm_long2num(data[k]), res);
2076 return res;
2077 }
2078# endif
2079 case scm_tc7_svect: {
2080 short *data;
2081 data = (short *)SCM_VELTS(v);
2082 for (k = SCM_LENGTH(v) - 1; k >= 0; k--)
2083 res = scm_cons(SCM_MAKINUM (data[k]), res);
2084 return res;
2085 }
5c11cc9d 2086#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
2087 case scm_tc7_llvect: {
2088 long_long *data;
2089 data = (long_long *)SCM_VELTS(v);
2090 for (k = SCM_LENGTH(v) - 1; k >= 0; k--)
2091 res = scm_cons(scm_long_long2num(data[k]), res);
2092 return res;
2093 }
2094#endif
2095
2096
2097#ifdef SCM_FLOATS
2098#ifdef SCM_SINGLES
2099 case scm_tc7_fvect:
2100 {
2101 float *data = (float *) SCM_VELTS (v);
2102 for (k = SCM_LENGTH (v) - 1; k >= 0; k--)
2103 res = scm_cons (scm_makflo (data[k]), res);
2104 return res;
2105 }
2106#endif /*SCM_SINGLES*/
2107 case scm_tc7_dvect:
2108 {
2109 double *data = (double *) SCM_VELTS (v);
2110 for (k = SCM_LENGTH (v) - 1; k >= 0; k--)
2111 res = scm_cons (scm_makdbl (data[k], 0.0), res);
2112 return res;
2113 }
2114 case scm_tc7_cvect:
2115 {
2116 double (*data)[2] = (double (*)[2]) SCM_VELTS (v);
2117 for (k = SCM_LENGTH (v) - 1; k >= 0; k--)
2118 res = scm_cons (scm_makdbl (data[k][0], data[k][1]), res);
2119 return res;
2120 }
2121#endif /*SCM_FLOATS*/
2122 }
2123}
2124
2125
20a54673 2126static char s_bad_ralst[] = "Bad scm_array contents list";
1cc91f1b
JB
2127
2128static int l2ra SCM_P ((SCM lst, SCM ra, scm_sizet base, scm_sizet k));
0f2d19dd
JB
2129
2130SCM_PROC(s_list_to_uniform_array, "list->uniform-array", 3, 0, 0, scm_list_to_uniform_array);
1cc91f1b 2131
0f2d19dd
JB
2132SCM
2133scm_list_to_uniform_array (ndim, prot, lst)
2134 SCM ndim;
2135 SCM prot;
2136 SCM lst;
0f2d19dd
JB
2137{
2138 SCM shp = SCM_EOL;
2139 SCM row = lst;
2140 SCM ra;
2141 scm_sizet k;
2142 long n;
2143 SCM_ASSERT (SCM_INUMP (ndim), ndim, SCM_ARG1, s_list_to_uniform_array);
2144 k = SCM_INUM (ndim);
2145 while (k--)
2146 {
2147 n = scm_ilength (row);
0aa0871f 2148 SCM_ASSERT (n >= 0, lst, SCM_ARG3, s_list_to_uniform_array);
0f2d19dd
JB
2149 shp = scm_cons (SCM_MAKINUM (n), shp);
2150 if (SCM_NIMP (row))
2151 row = SCM_CAR (row);
2152 }
2153 ra = scm_dimensions_to_uniform_array (scm_reverse (shp), prot, SCM_EOL);
2154 if (SCM_NULLP (shp))
2155
2156 {
2157 SCM_ASRTGO (1 == scm_ilength (lst), badlst);
2158 scm_array_set_x (ra, SCM_CAR (lst), SCM_EOL);
2159 return ra;
2160 }
2161 if (!SCM_ARRAYP (ra))
2162 {
2163 for (k = 0; k < SCM_LENGTH (ra); k++, lst = SCM_CDR (lst))
2164 scm_array_set_x (ra, SCM_CAR (lst), SCM_MAKINUM (k));
2165 return ra;
2166 }
2167 if (l2ra (lst, ra, SCM_ARRAY_BASE (ra), 0))
2168 return ra;
2169 else
2170 badlst:scm_wta (lst, s_bad_ralst, s_list_to_uniform_array);
2171 return SCM_BOOL_F;
2172}
2173
0f2d19dd
JB
2174static int
2175l2ra (lst, ra, base, k)
2176 SCM lst;
2177 SCM ra;
2178 scm_sizet base;
2179 scm_sizet k;
0f2d19dd
JB
2180{
2181 register long inc = SCM_ARRAY_DIMS (ra)[k].inc;
2182 register long n = (1 + SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd);
2183 int ok = 1;
2184 if (n <= 0)
2185 return (SCM_EOL == lst);
2186 if (k < SCM_ARRAY_NDIM (ra) - 1)
2187 {
2188 while (n--)
2189 {
2190 if (SCM_IMP (lst) || SCM_NCONSP (lst))
2191 return 0;
2192 ok = ok && l2ra (SCM_CAR (lst), ra, base, k + 1);
2193 base += inc;
2194 lst = SCM_CDR (lst);
2195 }
2196 if (SCM_NNULLP (lst))
2197 return 0;
2198 }
2199 else
2200 {
2201 while (n--)
2202 {
2203 if (SCM_IMP (lst) || SCM_NCONSP (lst))
2204 return 0;
2205 ok = ok && scm_array_set_x (SCM_ARRAY_V (ra), SCM_CAR (lst), SCM_MAKINUM (base));
2206 base += inc;
2207 lst = SCM_CDR (lst);
2208 }
2209 if (SCM_NNULLP (lst))
2210 return 0;
2211 }
2212 return ok;
2213}
2214
1cc91f1b
JB
2215
2216static void rapr1 SCM_P ((SCM ra, scm_sizet j, scm_sizet k, SCM port, scm_print_state *pstate));
2217
0f2d19dd 2218static void
9882ea19 2219rapr1 (ra, j, k, port, pstate)
0f2d19dd
JB
2220 SCM ra;
2221 scm_sizet j;
2222 scm_sizet k;
2223 SCM port;
9882ea19 2224 scm_print_state *pstate;
0f2d19dd
JB
2225{
2226 long inc = 1;
2227 long n = SCM_LENGTH (ra);
2228 int enclosed = 0;
2229tail:
5c11cc9d 2230 switch SCM_TYP7 (ra)
0f2d19dd
JB
2231 {
2232 case scm_tc7_smob:
2233 if (enclosed++)
2234 {
2235 SCM_ARRAY_BASE (ra) = j;
2236 if (n-- > 0)
9882ea19 2237 scm_iprin1 (ra, port, pstate);
0f2d19dd
JB
2238 for (j += inc; n-- > 0; j += inc)
2239 {
b7f3516f 2240 scm_putc (' ', port);
0f2d19dd 2241 SCM_ARRAY_BASE (ra) = j;
9882ea19 2242 scm_iprin1 (ra, port, pstate);
0f2d19dd
JB
2243 }
2244 break;
2245 }
2246 if (k + 1 < SCM_ARRAY_NDIM (ra))
2247 {
2248 long i;
2249 inc = SCM_ARRAY_DIMS (ra)[k].inc;
2250 for (i = SCM_ARRAY_DIMS (ra)[k].lbnd; i < SCM_ARRAY_DIMS (ra)[k].ubnd; i++)
2251 {
b7f3516f 2252 scm_putc ('(', port);
9882ea19 2253 rapr1 (ra, j, k + 1, port, pstate);
b7f3516f 2254 scm_puts (") ", port);
0f2d19dd
JB
2255 j += inc;
2256 }
2257 if (i == SCM_ARRAY_DIMS (ra)[k].ubnd)
2258 { /* could be zero size. */
b7f3516f 2259 scm_putc ('(', port);
9882ea19 2260 rapr1 (ra, j, k + 1, port, pstate);
b7f3516f 2261 scm_putc (')', port);
0f2d19dd
JB
2262 }
2263 break;
2264 }
2265 if SCM_ARRAY_NDIM
2266 (ra)
2267 { /* Could be zero-dimensional */
2268 inc = SCM_ARRAY_DIMS (ra)[k].inc;
2269 n = (SCM_ARRAY_DIMS (ra)[k].ubnd - SCM_ARRAY_DIMS (ra)[k].lbnd + 1);
2270 }
2271 else
2272 n = 1;
2273 ra = SCM_ARRAY_V (ra);
2274 goto tail;
2275 default:
5c11cc9d 2276 /* scm_tc7_bvect and scm_tc7_llvect only? */
0f2d19dd 2277 if (n-- > 0)
9882ea19 2278 scm_iprin1 (scm_uniform_vector_ref (ra, SCM_MAKINUM (j)), port, pstate);
0f2d19dd
JB
2279 for (j += inc; n-- > 0; j += inc)
2280 {
b7f3516f 2281 scm_putc (' ', port);
9882ea19 2282 scm_iprin1 (scm_cvref (ra, j, SCM_UNDEFINED), port, pstate);
0f2d19dd
JB
2283 }
2284 break;
2285 case scm_tc7_string:
2286 if (n-- > 0)
fc1d67c4 2287 scm_iprin1 (SCM_MAKICHR (SCM_UCHARS (ra)[j]), port, pstate);
9882ea19 2288 if (SCM_WRITINGP (pstate))
0f2d19dd
JB
2289 for (j += inc; n-- > 0; j += inc)
2290 {
b7f3516f 2291 scm_putc (' ', port);
fc1d67c4 2292 scm_iprin1 (SCM_MAKICHR (SCM_UCHARS (ra)[j]), port, pstate);
0f2d19dd
JB
2293 }
2294 else
2295 for (j += inc; n-- > 0; j += inc)
b7f3516f 2296 scm_putc (SCM_CHARS (ra)[j], port);
0f2d19dd
JB
2297 break;
2298 case scm_tc7_byvect:
2299 if (n-- > 0)
2300 scm_intprint (((char *)SCM_CDR (ra))[j], 10, port);
2301 for (j += inc; n-- > 0; j += inc)
2302 {
b7f3516f 2303 scm_putc (' ', port);
0f2d19dd
JB
2304 scm_intprint (((char *)SCM_CDR (ra))[j], 10, port);
2305 }
2306 break;
2307
2308 case scm_tc7_uvect:
5c11cc9d
GH
2309 {
2310 char str[11];
2311
2312 if (n-- > 0)
2313 {
2314 /* intprint can't handle >= 2^31. */
2315 sprintf (str, "%lu", (unsigned long) SCM_VELTS (ra)[j]);
2316 scm_puts (str, port);
2317 }
2318 for (j += inc; n-- > 0; j += inc)
2319 {
2320 scm_putc (' ', port);
2321 sprintf (str, "%lu", (unsigned long) SCM_VELTS (ra)[j]);
2322 scm_puts (str, port);
2323 }
2324 }
0f2d19dd
JB
2325 case scm_tc7_ivect:
2326 if (n-- > 0)
2327 scm_intprint (SCM_VELTS (ra)[j], 10, port);
2328 for (j += inc; n-- > 0; j += inc)
2329 {
b7f3516f 2330 scm_putc (' ', port);
0f2d19dd
JB
2331 scm_intprint (SCM_VELTS (ra)[j], 10, port);
2332 }
2333 break;
2334
2335 case scm_tc7_svect:
2336 if (n-- > 0)
2337 scm_intprint (((short *)SCM_CDR (ra))[j], 10, port);
2338 for (j += inc; n-- > 0; j += inc)
2339 {
b7f3516f 2340 scm_putc (' ', port);
0f2d19dd
JB
2341 scm_intprint (((short *)SCM_CDR (ra))[j], 10, port);
2342 }
2343 break;
2344
2345#ifdef SCM_FLOATS
2346#ifdef SCM_SINGLES
2347 case scm_tc7_fvect:
2348 if (n-- > 0)
2349 {
2350 SCM z = scm_makflo (1.0);
2351 SCM_FLO (z) = ((float *) SCM_VELTS (ra))[j];
9882ea19 2352 scm_floprint (z, port, pstate);
0f2d19dd
JB
2353 for (j += inc; n-- > 0; j += inc)
2354 {
b7f3516f 2355 scm_putc (' ', port);
0f2d19dd 2356 SCM_FLO (z) = ((float *) SCM_VELTS (ra))[j];
9882ea19 2357 scm_floprint (z, port, pstate);
0f2d19dd
JB
2358 }
2359 }
2360 break;
2361#endif /*SCM_SINGLES*/
2362 case scm_tc7_dvect:
2363 if (n-- > 0)
2364 {
2365 SCM z = scm_makdbl (1.0 / 3.0, 0.0);
2366 SCM_REAL (z) = ((double *) SCM_VELTS (ra))[j];
9882ea19 2367 scm_floprint (z, port, pstate);
0f2d19dd
JB
2368 for (j += inc; n-- > 0; j += inc)
2369 {
b7f3516f 2370 scm_putc (' ', port);
0f2d19dd 2371 SCM_REAL (z) = ((double *) SCM_VELTS (ra))[j];
9882ea19 2372 scm_floprint (z, port, pstate);
0f2d19dd
JB
2373 }
2374 }
2375 break;
2376 case scm_tc7_cvect:
2377 if (n-- > 0)
2378 {
2379 SCM cz = scm_makdbl (0.0, 1.0), z = scm_makdbl (1.0 / 3.0, 0.0);
2380 SCM_REAL (z) = SCM_REAL (cz) = (((double *) SCM_VELTS (ra))[2 * j]);
2381 SCM_IMAG (cz) = ((double *) SCM_VELTS (ra))[2 * j + 1];
9882ea19 2382 scm_floprint ((0.0 == SCM_IMAG (cz) ? z : cz), port, pstate);
0f2d19dd
JB
2383 for (j += inc; n-- > 0; j += inc)
2384 {
b7f3516f 2385 scm_putc (' ', port);
0f2d19dd
JB
2386 SCM_REAL (z) = SCM_REAL (cz) = ((double *) SCM_VELTS (ra))[2 * j];
2387 SCM_IMAG (cz) = ((double *) SCM_VELTS (ra))[2 * j + 1];
9882ea19 2388 scm_floprint ((0.0 == SCM_IMAG (cz) ? z : cz), port, pstate);
0f2d19dd
JB
2389 }
2390 }
2391 break;
2392#endif /*SCM_FLOATS*/
2393 }
2394}
2395
2396
1cc91f1b 2397
0f2d19dd 2398int
9882ea19 2399scm_raprin1 (exp, port, pstate)
0f2d19dd
JB
2400 SCM exp;
2401 SCM port;
9882ea19 2402 scm_print_state *pstate;
0f2d19dd
JB
2403{
2404 SCM v = exp;
2405 scm_sizet base = 0;
b7f3516f 2406 scm_putc ('#', port);
0f2d19dd 2407tail:
5c11cc9d 2408 switch SCM_TYP7 (v)
0f2d19dd
JB
2409 {
2410 case scm_tc7_smob:
2411 {
2412 long ndim = SCM_ARRAY_NDIM (v);
2413 base = SCM_ARRAY_BASE (v);
2414 v = SCM_ARRAY_V (v);
2415 if (SCM_ARRAYP (v))
2416
2417 {
b7f3516f 2418 scm_puts ("<enclosed-array ", port);
9882ea19 2419 rapr1 (exp, base, 0, port, pstate);
b7f3516f 2420 scm_putc ('>', port);
0f2d19dd
JB
2421 return 1;
2422 }
2423 else
2424 {
2425 scm_intprint (ndim, 10, port);
2426 goto tail;
2427 }
2428 }
2429 case scm_tc7_bvect:
2430 if (exp == v)
2431 { /* a uve, not an scm_array */
2432 register long i, j, w;
b7f3516f 2433 scm_putc ('*', port);
0f2d19dd
JB
2434 for (i = 0; i < (SCM_LENGTH (exp)) / SCM_LONG_BIT; i++)
2435 {
2436 w = SCM_VELTS (exp)[i];
2437 for (j = SCM_LONG_BIT; j; j--)
2438 {
b7f3516f 2439 scm_putc (w & 1 ? '1' : '0', port);
0f2d19dd
JB
2440 w >>= 1;
2441 }
2442 }
2443 j = SCM_LENGTH (exp) % SCM_LONG_BIT;
2444 if (j)
2445 {
2446 w = SCM_VELTS (exp)[SCM_LENGTH (exp) / SCM_LONG_BIT];
2447 for (; j; j--)
2448 {
b7f3516f 2449 scm_putc (w & 1 ? '1' : '0', port);
0f2d19dd
JB
2450 w >>= 1;
2451 }
2452 }
2453 return 1;
2454 }
2455 else
b7f3516f 2456 scm_putc ('b', port);
0f2d19dd
JB
2457 break;
2458 case scm_tc7_string:
b7f3516f 2459 scm_putc ('a', port);
0f2d19dd
JB
2460 break;
2461 case scm_tc7_byvect:
05c33d09 2462 scm_putc ('y', port);
0f2d19dd
JB
2463 break;
2464 case scm_tc7_uvect:
b7f3516f 2465 scm_putc ('u', port);
0f2d19dd
JB
2466 break;
2467 case scm_tc7_ivect:
b7f3516f 2468 scm_putc ('e', port);
0f2d19dd
JB
2469 break;
2470 case scm_tc7_svect:
05c33d09 2471 scm_putc ('h', port);
0f2d19dd 2472 break;
5c11cc9d 2473#ifdef HAVE_LONG_LONGS
0f2d19dd 2474 case scm_tc7_llvect:
5c11cc9d 2475 scm_putc ('l', port);
0f2d19dd
JB
2476 break;
2477#endif
2478#ifdef SCM_FLOATS
2479#ifdef SCM_SINGLES
2480 case scm_tc7_fvect:
b7f3516f 2481 scm_putc ('s', port);
0f2d19dd
JB
2482 break;
2483#endif /*SCM_SINGLES*/
2484 case scm_tc7_dvect:
b7f3516f 2485 scm_putc ('i', port);
0f2d19dd
JB
2486 break;
2487 case scm_tc7_cvect:
b7f3516f 2488 scm_putc ('c', port);
0f2d19dd
JB
2489 break;
2490#endif /*SCM_FLOATS*/
2491 }
b7f3516f 2492 scm_putc ('(', port);
9882ea19 2493 rapr1 (exp, base, 0, port, pstate);
b7f3516f 2494 scm_putc (')', port);
0f2d19dd
JB
2495 return 1;
2496}
2497
2498SCM_PROC(s_array_prototype, "array-prototype", 1, 0, 0, scm_array_prototype);
1cc91f1b 2499
0f2d19dd
JB
2500SCM
2501scm_array_prototype (ra)
2502 SCM ra;
0f2d19dd
JB
2503{
2504 int enclosed = 0;
2505 SCM_ASRTGO (SCM_NIMP (ra), badarg);
2506loop:
2507 switch SCM_TYP7
2508 (ra)
2509 {
2510 default:
2511 badarg:scm_wta (ra, (char *) SCM_ARG1, s_array_prototype);
2512 case scm_tc7_smob:
2513 SCM_ASRTGO (SCM_ARRAYP (ra), badarg);
2514 if (enclosed++)
2515 return SCM_UNSPECIFIED;
2516 ra = SCM_ARRAY_V (ra);
2517 goto loop;
2518 case scm_tc7_vector:
95f5b0f5 2519 case scm_tc7_wvect:
0f2d19dd
JB
2520 return SCM_EOL;
2521 case scm_tc7_bvect:
2522 return SCM_BOOL_T;
2523 case scm_tc7_string:
2524 return SCM_MAKICHR ('a');
2525 case scm_tc7_byvect:
2526 return SCM_MAKICHR ('\0');
2527 case scm_tc7_uvect:
2528 return SCM_MAKINUM (1L);
2529 case scm_tc7_ivect:
2530 return SCM_MAKINUM (-1L);
2531 case scm_tc7_svect:
2532 return SCM_CDR (scm_intern ("s", 1));
5c11cc9d 2533#ifdef HAVE_LONG_LONGS
0f2d19dd
JB
2534 case scm_tc7_llvect:
2535 return SCM_CDR (scm_intern ("l", 1));
2536#endif
2537#ifdef SCM_FLOATS
2538#ifdef SCM_SINGLES
2539 case scm_tc7_fvect:
2540 return scm_makflo (1.0);
2541#endif
2542 case scm_tc7_dvect:
2543 return scm_makdbl (1.0 / 3.0, 0.0);
2544 case scm_tc7_cvect:
2545 return scm_makdbl (0.0, 1.0);
2546#endif
2547 }
2548}
2549
1cc91f1b
JB
2550
2551static SCM markra SCM_P ((SCM ptr));
2552
0f2d19dd
JB
2553static SCM
2554markra (ptr)
2555 SCM ptr;
0f2d19dd 2556{
0f2d19dd
JB
2557 return SCM_ARRAY_V (ptr);
2558}
2559
1cc91f1b
JB
2560
2561static scm_sizet freera SCM_P ((SCM ptr));
2562
0f2d19dd
JB
2563static scm_sizet
2564freera (ptr)
2565 SCM ptr;
0f2d19dd
JB
2566{
2567 scm_must_free (SCM_CHARS (ptr));
2568 return sizeof (scm_array) + SCM_ARRAY_NDIM (ptr) * sizeof (scm_array_dim);
2569}
2570
0f2d19dd 2571/* This must be done after scm_init_scl() */
1cc91f1b 2572
0f2d19dd
JB
2573void
2574scm_init_unif ()
0f2d19dd 2575{
23a62151
MD
2576 scm_tc16_array = scm_make_smob_type_mfpe ("array", 0,
2577 markra,
2578 freera,
2579 scm_raprin1,
2580 scm_array_equal_p);
0f2d19dd 2581 scm_add_feature ("array");
23a62151 2582#include "unif.x"
0f2d19dd
JB
2583}
2584
2585#else /* ARRAYS */
2586
1cc91f1b 2587
0f2d19dd 2588int
9882ea19 2589scm_raprin1 (exp, port, pstate)
0f2d19dd
JB
2590 SCM exp;
2591 SCM port;
9882ea19 2592 scm_print_state *pstate;
0f2d19dd
JB
2593{
2594 return 0;
2595}
2596
1cc91f1b 2597
0f2d19dd
JB
2598SCM
2599scm_istr2bve (str, len)
2600 char *str;
2601 long len;
0f2d19dd
JB
2602{
2603 return SCM_BOOL_F;
2604}
2605
0f2d19dd
JB
2606void
2607scm_init_unif ()
2608{
175475a8 2609#include "unif.x"
0f2d19dd
JB
2610 scm_make_subr (s_resizuve, scm_tc7_subr_2, scm_vector_set_length_x);
2611}
2612
2613#endif /* ARRAYS */