~ubuntu-branches/ubuntu/jaunty/gimp/jaunty-security

« back to all changes in this revision

Viewing changes to plug-ins/script-fu/siod/sliba.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2007-05-02 16:33:03 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070502163303-bvzhjzbpw8qglc4y
Tags: 2.3.16-1ubuntu1
* Resynchronized with Debian, remaining Ubuntu changes:
  - debian/rules: i18n magic.
* debian/control.in:
  - Maintainer: Ubuntu Core Developers <ubuntu-devel@lists.ubuntu.com>
* debian/patches/02_help-message.patch,
  debian/patches/03_gimp.desktop.in.in.patch,
  debian/patches/10_dont_show_wizard.patch: updated.
* debian/patches/04_composite-signedness.patch,
  debian/patches/05_add-letter-spacing.patch: dropped, used upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
 
3
 
/*
4
 
 *                   COPYRIGHT (c) 1988-1994 BY                             *
5
 
 *        PARADIGM ASSOCIATES INCORPORATED, CAMBRIDGE, MASSACHUSETTS.       *
6
 
 *        See the source file SLIB.C for more information.                  *
7
 
 
8
 
 Array-hacking code moved to another source file.
9
 
 
10
 
 */
11
 
 
12
 
#include <stdio.h>
13
 
#include <string.h>
14
 
#include <setjmp.h>
15
 
#include <stdlib.h>
16
 
#include <stdarg.h>
17
 
#include <math.h>
18
 
 
19
 
#include <glib.h>
20
 
 
21
 
#include "siod.h"
22
 
#include "siodp.h"
23
 
 
24
 
static void
25
 
init_sliba_version (void)
26
 
{
27
 
  setvar (cintern ("*sliba-version*"),
28
 
          cintern ("$Id: sliba.c,v 1.14 2004/08/08 19:59:16 neo Exp $"),
29
 
          NIL);
30
 
}
31
 
 
32
 
static LISP sym_plists = NIL;
33
 
static LISP bashnum = NIL;
34
 
static LISP sym_e = NIL;
35
 
static LISP sym_f = NIL;
36
 
 
37
 
void
38
 
init_storage_a1 (long type)
39
 
{
40
 
  long j;
41
 
  struct user_type_hooks *p;
42
 
  set_gc_hooks (type,
43
 
                array_gc_relocate,
44
 
                array_gc_mark,
45
 
                array_gc_scan,
46
 
                array_gc_free,
47
 
                &j);
48
 
  set_print_hooks (type, array_prin1);
49
 
  p = get_user_type_hooks (type);
50
 
  p->fast_print = array_fast_print;
51
 
  p->fast_read = array_fast_read;
52
 
  p->equal = array_equal;
53
 
  p->c_sxhash = array_sxhash;
54
 
}
55
 
 
56
 
void
57
 
init_storage_a (void)
58
 
{
59
 
  gc_protect (&bashnum);
60
 
  bashnum = newcell (tc_flonum);
61
 
  init_storage_a1 (tc_string);
62
 
  init_storage_a1 (tc_double_array);
63
 
  init_storage_a1 (tc_long_array);
64
 
  init_storage_a1 (tc_lisp_array);
65
 
  init_storage_a1 (tc_byte_array);
66
 
}
67
 
 
68
 
LISP
69
 
array_gc_relocate (LISP ptr)
70
 
{
71
 
  LISP nw;
72
 
  if ((nw = heap) >= heap_end)
73
 
    gc_fatal_error ();
74
 
  heap = nw + 1;
75
 
  memcpy (nw, ptr, sizeof (struct obj));
76
 
  return (nw);
77
 
}
78
 
 
79
 
void
80
 
array_gc_scan (LISP ptr)
81
 
{
82
 
  long j;
83
 
  if TYPEP
84
 
    (ptr, tc_lisp_array)
85
 
      for (j = 0; j < ptr->storage_as.lisp_array.dim; ++j)
86
 
      ptr->storage_as.lisp_array.data[j] =
87
 
        gc_relocate (ptr->storage_as.lisp_array.data[j]);
88
 
}
89
 
 
90
 
LISP
91
 
array_gc_mark (LISP ptr)
92
 
{
93
 
  long j;
94
 
  if TYPEP
95
 
    (ptr, tc_lisp_array)
96
 
      for (j = 0; j < ptr->storage_as.lisp_array.dim; ++j)
97
 
      gc_mark (ptr->storage_as.lisp_array.data[j]);
98
 
  return (NIL);
99
 
}
100
 
 
101
 
void
102
 
array_gc_free (LISP ptr)
103
 
{
104
 
  switch (ptr->type)
105
 
    {
106
 
    case tc_string:
107
 
    case tc_byte_array:
108
 
      free (ptr->storage_as.string.data);
109
 
      break;
110
 
    case tc_double_array:
111
 
      free (ptr->storage_as.double_array.data);
112
 
      break;
113
 
    case tc_long_array:
114
 
      free (ptr->storage_as.long_array.data);
115
 
      break;
116
 
    case tc_lisp_array:
117
 
      free (ptr->storage_as.lisp_array.data);
118
 
      break;
119
 
    }
120
 
}
121
 
 
122
 
void
123
 
array_prin1 (LISP ptr, struct gen_printio *f)
124
 
{
125
 
  int i, j;
126
 
  switch (ptr->type)
127
 
    {
128
 
    case tc_string:
129
 
      gput_st (f, "\"");
130
 
      if (strcspn (ptr->storage_as.string.data, "\"\\\n\r\t") ==
131
 
          strlen (ptr->storage_as.string.data))
132
 
        gput_st (f, ptr->storage_as.string.data);
133
 
      else
134
 
        {
135
 
          int n, c;
136
 
          char cbuff[3];
137
 
          n = strlen (ptr->storage_as.string.data);
138
 
          for (j = 0; j < n; ++j)
139
 
            switch (c = ptr->storage_as.string.data[j])
140
 
              {
141
 
              case '\\':
142
 
              case '"':
143
 
                cbuff[0] = '\\';
144
 
                cbuff[1] = c;
145
 
                cbuff[2] = 0;
146
 
                gput_st (f, cbuff);
147
 
                break;
148
 
              case '\n':
149
 
                gput_st (f, "\\n");
150
 
                break;
151
 
              case '\r':
152
 
                gput_st (f, "\\r");
153
 
                break;
154
 
              case '\t':
155
 
                gput_st (f, "\\t");
156
 
                break;
157
 
              default:
158
 
                cbuff[0] = c;
159
 
                cbuff[1] = 0;
160
 
                gput_st (f, cbuff);
161
 
                break;
162
 
              }
163
 
        }
164
 
      gput_st (f, "\"");
165
 
      break;
166
 
    case tc_double_array:
167
 
      gput_st (f, "#(");
168
 
      for (j = 0; j < ptr->storage_as.double_array.dim; ++j)
169
 
        {
170
 
          g_ascii_formatd (tkbuffer, TKBUFFERN, "%g",
171
 
                           ptr->storage_as.double_array.data[j]);
172
 
          gput_st (f, tkbuffer);
173
 
          if ((j + 1) < ptr->storage_as.double_array.dim)
174
 
            gput_st (f, " ");
175
 
        }
176
 
      gput_st (f, ")");
177
 
      break;
178
 
    case tc_long_array:
179
 
      gput_st (f, "#(");
180
 
      for (j = 0; j < ptr->storage_as.long_array.dim; ++j)
181
 
        {
182
 
          sprintf (tkbuffer, "%ld", ptr->storage_as.long_array.data[j]);
183
 
          gput_st (f, tkbuffer);
184
 
          if ((j + 1) < ptr->storage_as.long_array.dim)
185
 
            gput_st (f, " ");
186
 
        }
187
 
      gput_st (f, ")");
188
 
    case tc_byte_array:
189
 
      sprintf (tkbuffer, "#%ld\"", ptr->storage_as.string.dim);
190
 
      gput_st (f, tkbuffer);
191
 
      for (j = 0, i = 0; j < ptr->storage_as.string.dim; j++)
192
 
        {
193
 
          sprintf (tkbuffer + i, "%02x",
194
 
                   ptr->storage_as.string.data[j] & 0xFF);
195
 
          i += 2;
196
 
          if (i % TKBUFFERN == 0)
197
 
            {
198
 
              gput_st (f, tkbuffer);
199
 
              i = 0;
200
 
            }
201
 
        }
202
 
      if (i)
203
 
        gput_st (f, tkbuffer);
204
 
      gput_st (f, "\"");
205
 
      break;
206
 
    case tc_lisp_array:
207
 
      gput_st (f, "#(");
208
 
      for (j = 0; j < ptr->storage_as.lisp_array.dim; ++j)
209
 
        {
210
 
          lprin1g (ptr->storage_as.lisp_array.data[j], f);
211
 
          if ((j + 1) < ptr->storage_as.lisp_array.dim)
212
 
            gput_st (f, " ");
213
 
        }
214
 
      gput_st (f, ")");
215
 
      break;
216
 
    }
217
 
}
218
 
 
219
 
LISP
220
 
strcons (long length, char *data)
221
 
{
222
 
  long flag;
223
 
  LISP s;
224
 
  flag = no_interrupt (1);
225
 
  s = cons (NIL, NIL);
226
 
  s->type = tc_string;
227
 
  if (length == -1)
228
 
    length = strlen (data);
229
 
  s->storage_as.string.data = must_malloc (length + 1);
230
 
  s->storage_as.string.dim = length;
231
 
  if (data)
232
 
    memcpy (s->storage_as.string.data, data, length);
233
 
  s->storage_as.string.data[length] = 0;
234
 
  no_interrupt (flag);
235
 
  return (s);
236
 
}
237
 
 
238
 
int
239
 
rfs_getc (unsigned char **p)
240
 
{
241
 
  int i;
242
 
  i = **p;
243
 
  if (!i)
244
 
    return (EOF);
245
 
  *p = *p + 1;
246
 
  return (i);
247
 
}
248
 
 
249
 
void
250
 
rfs_ungetc (unsigned char c, unsigned char **p)
251
 
{
252
 
  *p = *p - 1;
253
 
}
254
 
 
255
 
LISP
256
 
read_from_string (LISP x)
257
 
{
258
 
  char *p;
259
 
  struct gen_readio s;
260
 
  p = get_c_string (x);
261
 
  s.getc_fcn = (int (*)(void *)) rfs_getc;
262
 
  s.ungetc_fcn = (void (*)(int, void *)) rfs_ungetc;
263
 
  s.cb_argument = (char *) &p;
264
 
  return (readtl (&s));
265
 
}
266
 
 
267
 
int
268
 
pts_puts (char *from, void *cb)
269
 
{
270
 
  LISP into;
271
 
  size_t fromlen, intolen, intosize, fitsize;
272
 
  into = (LISP) cb;
273
 
  fromlen = strlen (from);
274
 
  intolen = strlen (into->storage_as.string.data);
275
 
  intosize = into->storage_as.string.dim - intolen;
276
 
  fitsize = (fromlen < intosize) ? fromlen : intosize;
277
 
  memcpy (&into->storage_as.string.data[intolen], from, fitsize);
278
 
  into->storage_as.string.data[intolen + fitsize] = 0;
279
 
  if (fitsize < fromlen)
280
 
    my_err ("print to string overflow", NIL);
281
 
  return (1);
282
 
}
283
 
 
284
 
LISP
285
 
err_wta_str (LISP exp)
286
 
{
287
 
  return (my_err ("not a string", exp));
288
 
}
289
 
 
290
 
LISP
291
 
print_to_string (LISP exp, LISP str, LISP nostart)
292
 
{
293
 
  struct gen_printio s;
294
 
  if NTYPEP
295
 
    (str, tc_string) err_wta_str (str);
296
 
  s.putc_fcn = NULL;
297
 
  s.puts_fcn = pts_puts;
298
 
  s.cb_argument = str;
299
 
  if NULLP
300
 
    (nostart)
301
 
      str->storage_as.string.data[0] = 0;
302
 
  lprin1g (exp, &s);
303
 
  return (str);
304
 
}
305
 
 
306
 
LISP
307
 
aref1 (LISP a, LISP i)
308
 
{
309
 
  long k;
310
 
  if NFLONUMP
311
 
    (i) my_err ("bad index to aref", i);
312
 
  k = (long) FLONM (i);
313
 
  if (k < 0)
314
 
    my_err ("negative index to aref", i);
315
 
  switch TYPE
316
 
    (a)
317
 
    {
318
 
    case tc_string:
319
 
    case tc_byte_array:
320
 
      if (k >= a->storage_as.string.dim)
321
 
        my_err ("index too large", i);
322
 
      return (flocons ((double) a->storage_as.string.data[k]));
323
 
    case tc_double_array:
324
 
      if (k >= a->storage_as.double_array.dim)
325
 
        my_err ("index too large", i);
326
 
      return (flocons (a->storage_as.double_array.data[k]));
327
 
    case tc_long_array:
328
 
      if (k >= a->storage_as.long_array.dim)
329
 
        my_err ("index too large", i);
330
 
      return (flocons (a->storage_as.long_array.data[k]));
331
 
    case tc_lisp_array:
332
 
      if (k >= a->storage_as.lisp_array.dim)
333
 
        my_err ("index too large", i);
334
 
      return (a->storage_as.lisp_array.data[k]);
335
 
    default:
336
 
      return (my_err ("invalid argument to aref", a));
337
 
    }
338
 
}
339
 
 
340
 
void
341
 
err1_aset1 (LISP i)
342
 
{
343
 
  my_err ("index to aset too large", i);
344
 
}
345
 
 
346
 
void
347
 
err2_aset1 (LISP v)
348
 
{
349
 
  my_err ("bad value to store in array", v);
350
 
}
351
 
 
352
 
LISP
353
 
aset1 (LISP a, LISP i, LISP v)
354
 
{
355
 
  long k;
356
 
  if NFLONUMP
357
 
    (i) my_err ("bad index to aset", i);
358
 
  k = (long) FLONM (i);
359
 
  if (k < 0)
360
 
    my_err ("negative index to aset", i);
361
 
  switch TYPE
362
 
    (a)
363
 
    {
364
 
    case tc_string:
365
 
    case tc_byte_array:
366
 
      if NFLONUMP
367
 
        (v) err2_aset1 (v);
368
 
      if (k >= a->storage_as.string.dim)
369
 
        err1_aset1 (i);
370
 
      a->storage_as.string.data[k] = (char) FLONM (v);
371
 
      return (v);
372
 
    case tc_double_array:
373
 
      if NFLONUMP
374
 
        (v) err2_aset1 (v);
375
 
      if (k >= a->storage_as.double_array.dim)
376
 
        err1_aset1 (i);
377
 
      a->storage_as.double_array.data[k] = FLONM (v);
378
 
      return (v);
379
 
    case tc_long_array:
380
 
      if NFLONUMP
381
 
        (v) err2_aset1 (v);
382
 
      if (k >= a->storage_as.long_array.dim)
383
 
        err1_aset1 (i);
384
 
      a->storage_as.long_array.data[k] = (long) FLONM (v);
385
 
      return (v);
386
 
    case tc_lisp_array:
387
 
      if (k >= a->storage_as.lisp_array.dim)
388
 
        err1_aset1 (i);
389
 
      a->storage_as.lisp_array.data[k] = v;
390
 
      return (v);
391
 
    default:
392
 
      return (my_err ("invalid argument to aset", a));
393
 
    }
394
 
}
395
 
 
396
 
LISP
397
 
arcons (long typecode, long n, long initp)
398
 
{
399
 
  LISP a;
400
 
  long flag, j;
401
 
  flag = no_interrupt (1);
402
 
  a = cons (NIL, NIL);
403
 
  switch (typecode)
404
 
    {
405
 
    case tc_double_array:
406
 
      a->storage_as.double_array.dim = n;
407
 
      a->storage_as.double_array.data = (double *) must_malloc (n *
408
 
                                                           sizeof (double));
409
 
      if (initp)
410
 
        for (j = 0; j < n; ++j)
411
 
          a->storage_as.double_array.data[j] = 0.0;
412
 
      break;
413
 
    case tc_long_array:
414
 
      a->storage_as.long_array.dim = n;
415
 
      a->storage_as.long_array.data = (long *) must_malloc (n * sizeof (long));
416
 
      if (initp)
417
 
        for (j = 0; j < n; ++j)
418
 
          a->storage_as.long_array.data[j] = 0;
419
 
      break;
420
 
    case tc_string:
421
 
      a->storage_as.string.dim = n;
422
 
      a->storage_as.string.data = (char *) must_malloc (n + 1);
423
 
      a->storage_as.string.data[n] = 0;
424
 
      if (initp)
425
 
        for (j = 0; j < n; ++j)
426
 
          a->storage_as.string.data[j] = ' ';
427
 
    case tc_byte_array:
428
 
      a->storage_as.string.dim = n;
429
 
      a->storage_as.string.data = (char *) must_malloc (n);
430
 
      if (initp)
431
 
        for (j = 0; j < n; ++j)
432
 
          a->storage_as.string.data[j] = 0;
433
 
      break;
434
 
    case tc_lisp_array:
435
 
      a->storage_as.lisp_array.dim = n;
436
 
      a->storage_as.lisp_array.data = (LISP *) must_malloc (n * sizeof (LISP));
437
 
      for (j = 0; j < n; ++j)
438
 
        a->storage_as.lisp_array.data[j] = NIL;
439
 
      break;
440
 
    default:
441
 
      errswitch ();
442
 
    }
443
 
  a->type = typecode;
444
 
  no_interrupt (flag);
445
 
  return (a);
446
 
}
447
 
 
448
 
LISP
449
 
mallocl (void *place, long size)
450
 
{
451
 
  long n, r;
452
 
  LISP retval;
453
 
  n = size / sizeof (long);
454
 
  r = size % sizeof (long);
455
 
  if (r)
456
 
    ++n;
457
 
  retval = arcons (tc_long_array, n, 0);
458
 
  *(long **) place = retval->storage_as.long_array.data;
459
 
  return (retval);
460
 
}
461
 
 
462
 
LISP
463
 
cons_array (LISP dim, LISP kind)
464
 
{
465
 
  LISP a;
466
 
  long flag, n, j;
467
 
  if (NFLONUMP (dim) || (FLONM (dim) < 0))
468
 
    return (my_err ("bad dimension to cons-array", dim));
469
 
  else
470
 
    n = (long) FLONM (dim);
471
 
  flag = no_interrupt (1);
472
 
  a = cons (NIL, NIL);
473
 
  if EQ
474
 
    (cintern ("double"), kind)
475
 
    {
476
 
      a->type = tc_double_array;
477
 
      a->storage_as.double_array.dim = n;
478
 
      a->storage_as.double_array.data = (double *) must_malloc (n *
479
 
                                                           sizeof (double));
480
 
      for (j = 0; j < n; ++j)
481
 
        a->storage_as.double_array.data[j] = 0.0;
482
 
    }
483
 
  else if EQ
484
 
    (cintern ("long"), kind)
485
 
    {
486
 
      a->type = tc_long_array;
487
 
      a->storage_as.long_array.dim = n;
488
 
      a->storage_as.long_array.data = (long *) must_malloc (n * sizeof (long));
489
 
      for (j = 0; j < n; ++j)
490
 
        a->storage_as.long_array.data[j] = 0;
491
 
    }
492
 
  else if EQ
493
 
    (cintern ("string"), kind)
494
 
    {
495
 
      a->type = tc_string;
496
 
      a->storage_as.string.dim = n;
497
 
      a->storage_as.string.data = (char *) must_malloc (n + 1);
498
 
      a->storage_as.string.data[n] = 0;
499
 
      for (j = 0; j < n; ++j)
500
 
        a->storage_as.string.data[j] = ' ';
501
 
    }
502
 
  else if EQ
503
 
    (cintern ("byte"), kind)
504
 
    {
505
 
      a->type = tc_byte_array;
506
 
      a->storage_as.string.dim = n;
507
 
      a->storage_as.string.data = (char *) must_malloc (n);
508
 
      for (j = 0; j < n; ++j)
509
 
        a->storage_as.string.data[j] = 0;
510
 
    }
511
 
  else if (EQ (cintern ("lisp"), kind) || NULLP (kind))
512
 
    {
513
 
      a->type = tc_lisp_array;
514
 
      a->storage_as.lisp_array.dim = n;
515
 
      a->storage_as.lisp_array.data = (LISP *) must_malloc (n * sizeof (LISP));
516
 
      for (j = 0; j < n; ++j)
517
 
        a->storage_as.lisp_array.data[j] = NIL;
518
 
    }
519
 
  else
520
 
    my_err ("bad type of array", kind);
521
 
  no_interrupt (flag);
522
 
  return (a);
523
 
}
524
 
 
525
 
LISP
526
 
string_append (LISP args)
527
 
{
528
 
  long size;
529
 
  LISP l, s;
530
 
  char *data;
531
 
  size = 0;
532
 
  for (l = args; NNULLP (l); l = cdr (l))
533
 
    size += strlen (get_c_string (car (l)));
534
 
  s = strcons (size, NULL);
535
 
  data = s->storage_as.string.data;
536
 
  data[0] = 0;
537
 
  for (l = args; NNULLP (l); l = cdr (l))
538
 
    strcat (data, get_c_string (car (l)));
539
 
  return (s);
540
 
}
541
 
 
542
 
LISP
543
 
bytes_append (LISP args)
544
 
{
545
 
  long size, n, j;
546
 
  LISP l, s;
547
 
  char *data, *ptr;
548
 
  size = 0;
549
 
  for (l = args; NNULLP (l); l = cdr (l))
550
 
    {
551
 
      get_c_string_dim (car (l), &n);
552
 
      size += n;
553
 
    }
554
 
  s = arcons (tc_byte_array, size, 0);
555
 
  data = s->storage_as.string.data;
556
 
  for (j = 0, l = args; NNULLP (l); l = cdr (l))
557
 
    {
558
 
      ptr = get_c_string_dim (car (l), &n);
559
 
      memcpy (&data[j], ptr, n);
560
 
      j += n;
561
 
    }
562
 
  return (s);
563
 
}
564
 
 
565
 
LISP
566
 
substring (LISP str, LISP start, LISP end)
567
 
{
568
 
  long s, e, n;
569
 
  char *data;
570
 
  data = get_c_string_dim (str, &n);
571
 
  s = get_c_long (start);
572
 
  if NULLP
573
 
    (end)
574
 
      e = n;
575
 
  else
576
 
    e = get_c_long (end);
577
 
  if ((s < 0) || (s > e))
578
 
    my_err ("bad start index", start);
579
 
  if ((e < 0) || (e > n))
580
 
    my_err ("bad end index", end);
581
 
  return (strcons (e - s, &data[s]));
582
 
}
583
 
 
584
 
LISP
585
 
string_search (LISP token, LISP str)
586
 
{
587
 
  char *s1, *s2, *ptr;
588
 
  s1 = get_c_string (str);
589
 
  s2 = get_c_string (token);
590
 
  ptr = strstr (s1, s2);
591
 
  if (ptr)
592
 
    return (flocons (ptr - s1));
593
 
  else
594
 
    return (NIL);
595
 
}
596
 
 
597
 
#define IS_TRIM_SPACE(_x) (strchr(" \t\r\n",(_x)))
598
 
 
599
 
LISP
600
 
string_trim (LISP str)
601
 
{
602
 
  char *start, *end; /*, *sp = " \t\r\n";*/
603
 
  start = get_c_string (str);
604
 
  while (*start && IS_TRIM_SPACE (*start))
605
 
    ++start;
606
 
  end = &start[strlen (start)];
607
 
  while ((end > start) && IS_TRIM_SPACE (*(end - 1)))
608
 
    --end;
609
 
  return (strcons (end - start, start));
610
 
}
611
 
 
612
 
LISP
613
 
string_trim_left (LISP str)
614
 
{
615
 
  char *start, *end;
616
 
  start = get_c_string (str);
617
 
  while (*start && IS_TRIM_SPACE (*start))
618
 
    ++start;
619
 
  end = &start[strlen (start)];
620
 
  return (strcons (end - start, start));
621
 
}
622
 
 
623
 
LISP
624
 
string_trim_right (LISP str)
625
 
{
626
 
  char *start, *end;
627
 
  start = get_c_string (str);
628
 
  end = &start[strlen (start)];
629
 
  while ((end > start) && IS_TRIM_SPACE (*(end - 1)))
630
 
    --end;
631
 
  return (strcons (end - start, start));
632
 
}
633
 
 
634
 
LISP
635
 
string_upcase (LISP str)
636
 
{
637
 
  LISP result;
638
 
  char *s1, *s2;
639
 
  long j, n;
640
 
  s1 = get_c_string (str);
641
 
  n = strlen (s1);
642
 
  result = strcons (n, s1);
643
 
  s2 = get_c_string (result);
644
 
  for (j = 0; j < n; ++j)
645
 
    s2[j] = g_ascii_toupper (s2[j]);
646
 
  return (result);
647
 
}
648
 
 
649
 
LISP
650
 
string_downcase (LISP str)
651
 
{
652
 
  LISP result;
653
 
  char *s1, *s2;
654
 
  long j, n;
655
 
  s1 = get_c_string (str);
656
 
  n = strlen (s1);
657
 
  result = strcons (n, s1);
658
 
  s2 = get_c_string (result);
659
 
  for (j = 0; j < n; ++j)
660
 
    s2[j] = g_ascii_tolower (s2[j]);
661
 
  return (result);
662
 
}
663
 
 
664
 
LISP
665
 
lreadstring (struct gen_readio * f)
666
 
{
667
 
  int j, c, n, ndigits;
668
 
  char *p;
669
 
  j = 0;
670
 
  p = tkbuffer;
671
 
  while (((c = GETC_FCN (f)) != '"') && (c != EOF))
672
 
    {
673
 
      if (c == '\\')
674
 
        {
675
 
          c = GETC_FCN (f);
676
 
          if (c == EOF)
677
 
            my_err ("eof after \\", NIL);
678
 
          switch (c)
679
 
            {
680
 
            case '\\':
681
 
              c = '\\';
682
 
              break;
683
 
            case 'n':
684
 
              c = '\n';
685
 
              break;
686
 
            case 't':
687
 
              c = '\t';
688
 
              break;
689
 
            case 'r':
690
 
              c = '\r';
691
 
              break;
692
 
            case 'd':
693
 
              c = 0x04;
694
 
              break;
695
 
            case 'N':
696
 
              c = 0;
697
 
              break;
698
 
            case 's':
699
 
              c = ' ';
700
 
              break;
701
 
            case '0':
702
 
            case '1':
703
 
            case '2':
704
 
            case '3':
705
 
            case '4':
706
 
            case '5':
707
 
            case '6':
708
 
            case '7':
709
 
              n = c - '0';
710
 
              ndigits = 1;
711
 
              while (ndigits < 3)
712
 
                {
713
 
                  c = GETC_FCN (f);
714
 
                  if (c == EOF)
715
 
                    my_err ("eof after \\0", NIL);
716
 
                  if (c >= '0' && c <= '7')
717
 
                    {
718
 
                      n = n * 8 + c - '0';
719
 
                      ndigits++;
720
 
                    }
721
 
                  else
722
 
                    {
723
 
                      UNGETC_FCN (c, f);
724
 
                      break;
725
 
                    }
726
 
                }
727
 
              c = n;
728
 
            }
729
 
        }
730
 
      if ((j + 1) >= TKBUFFERN)
731
 
        my_err ("read string overflow", NIL);
732
 
      ++j;
733
 
      *p++ = c;
734
 
    }
735
 
  *p = 0;
736
 
  return (strcons (j, tkbuffer));
737
 
}
738
 
 
739
 
 
740
 
LISP
741
 
lreadsharp (struct gen_readio * f)
742
 
{
743
 
  LISP obj, l, result;
744
 
  long j, n;
745
 
  int c;
746
 
  c = GETC_FCN (f);
747
 
  switch (c)
748
 
    {
749
 
    case '(':
750
 
      UNGETC_FCN (c, f);
751
 
      obj = lreadr (f);
752
 
      n = nlength (obj);
753
 
      result = arcons (tc_lisp_array, n, 1);
754
 
      for (l = obj, j = 0; j < n; l = cdr (l), ++j)
755
 
        result->storage_as.lisp_array.data[j] = car (l);
756
 
      return (result);
757
 
    case '.':
758
 
      obj = lreadr (f);
759
 
      return (leval (obj, NIL));
760
 
    case 'f':
761
 
      return (NIL);
762
 
    case 't':
763
 
      return (flocons (1));
764
 
    default:
765
 
      return (my_err ("readsharp syntax not handled", NIL));
766
 
    }
767
 
}
768
 
 
769
 
#define HASH_COMBINE(_h1,_h2,_mod) ((((_h1) * 17 + 1) ^ (_h2)) % (_mod))
770
 
 
771
 
long
772
 
c_sxhash (LISP obj, long n)
773
 
{
774
 
  long hash;
775
 
  unsigned char *s;
776
 
  LISP tmp;
777
 
  struct user_type_hooks *p;
778
 
  STACK_CHECK (&obj);
779
 
  INTERRUPT_CHECK ();
780
 
  switch TYPE
781
 
    (obj)
782
 
    {
783
 
    case tc_nil:
784
 
      return (0);
785
 
    case tc_cons:
786
 
      hash = c_sxhash (CAR (obj), n);
787
 
      for (tmp = CDR (obj); CONSP (tmp); tmp = CDR (tmp))
788
 
        hash = HASH_COMBINE (hash, c_sxhash (CAR (tmp), n), n);
789
 
      hash = HASH_COMBINE (hash, c_sxhash (tmp, n), n);
790
 
      return (hash);
791
 
    case tc_symbol:
792
 
      for (hash = 0, s = (unsigned char *) PNAME (obj); *s; ++s)
793
 
        hash = HASH_COMBINE (hash, *s, n);
794
 
      return (hash);
795
 
    case tc_subr_0:
796
 
    case tc_subr_1:
797
 
    case tc_subr_2:
798
 
    case tc_subr_3:
799
 
    case tc_subr_4:
800
 
    case tc_subr_5:
801
 
    case tc_lsubr:
802
 
    case tc_fsubr:
803
 
    case tc_msubr:
804
 
      for (hash = 0, s = (unsigned char *) obj->storage_as.subr.name; *s; ++s)
805
 
        hash = HASH_COMBINE (hash, *s, n);
806
 
      return (hash);
807
 
    case tc_flonum:
808
 
      return (((unsigned long) FLONM (obj)) % n);
809
 
    default:
810
 
      p = get_user_type_hooks (TYPE (obj));
811
 
      if (p->c_sxhash)
812
 
        return ((*p->c_sxhash) (obj, n));
813
 
      else
814
 
        return (0);
815
 
    }
816
 
}
817
 
 
818
 
LISP
819
 
sxhash (LISP obj, LISP n)
820
 
{
821
 
  return (flocons (c_sxhash (obj, FLONUMP (n) ? (long) FLONM (n) : 10000)));
822
 
}
823
 
 
824
 
LISP
825
 
equal (LISP a, LISP b)
826
 
{
827
 
  struct user_type_hooks *p;
828
 
  long atype;
829
 
  STACK_CHECK (&a);
830
 
loop:
831
 
  INTERRUPT_CHECK ();
832
 
  if EQ
833
 
    (a, b) return (sym_t);
834
 
  atype = TYPE (a);
835
 
  if (atype != TYPE (b))
836
 
    return (NIL);
837
 
  switch (atype)
838
 
    {
839
 
    case tc_cons:
840
 
      if NULLP
841
 
        (equal (car (a), car (b))) return (NIL);
842
 
      a = cdr (a);
843
 
      b = cdr (b);
844
 
      goto loop;
845
 
    case tc_flonum:
846
 
      return ((FLONM (a) == FLONM (b)) ? sym_t : NIL);
847
 
    case tc_symbol:
848
 
      return (NIL);
849
 
    default:
850
 
      p = get_user_type_hooks (atype);
851
 
      if (p->equal)
852
 
        return ((*p->equal) (a, b));
853
 
      else
854
 
        return (NIL);
855
 
    }
856
 
}
857
 
 
858
 
LISP
859
 
array_equal (LISP a, LISP b)
860
 
{
861
 
  long j, len;
862
 
  switch (TYPE (a))
863
 
    {
864
 
    case tc_string:
865
 
    case tc_byte_array:
866
 
      len = a->storage_as.string.dim;
867
 
      if (len != b->storage_as.string.dim)
868
 
        return (NIL);
869
 
      if (memcmp (a->storage_as.string.data, b->storage_as.string.data, len) == 0)
870
 
        return (sym_t);
871
 
      else
872
 
        return (NIL);
873
 
    case tc_long_array:
874
 
      len = a->storage_as.long_array.dim;
875
 
      if (len != b->storage_as.long_array.dim)
876
 
        return (NIL);
877
 
      if (memcmp (a->storage_as.long_array.data,
878
 
                  b->storage_as.long_array.data,
879
 
                  len * sizeof (long)) == 0)
880
 
          return (sym_t);
881
 
      else
882
 
        return (NIL);
883
 
    case tc_double_array:
884
 
      len = a->storage_as.double_array.dim;
885
 
      if (len != b->storage_as.double_array.dim)
886
 
        return (NIL);
887
 
      for (j = 0; j < len; ++j)
888
 
        if (a->storage_as.double_array.data[j] !=
889
 
            b->storage_as.double_array.data[j])
890
 
          return (NIL);
891
 
      return (sym_t);
892
 
    case tc_lisp_array:
893
 
      len = a->storage_as.lisp_array.dim;
894
 
      if (len != b->storage_as.lisp_array.dim)
895
 
        return (NIL);
896
 
      for (j = 0; j < len; ++j)
897
 
        if NULLP
898
 
          (equal (a->storage_as.lisp_array.data[j],
899
 
                  b->storage_as.lisp_array.data[j]))
900
 
            return (NIL);
901
 
      return (sym_t);
902
 
    default:
903
 
      return (errswitch ());
904
 
    }
905
 
}
906
 
 
907
 
long
908
 
array_sxhash (LISP a, long n)
909
 
{
910
 
  long j, len, hash;
911
 
  unsigned char *char_data;
912
 
  unsigned long *long_data;
913
 
  double *double_data;
914
 
  switch (TYPE (a))
915
 
    {
916
 
    case tc_string:
917
 
    case tc_byte_array:
918
 
      len = a->storage_as.string.dim;
919
 
      for (j = 0, hash = 0, char_data = (unsigned char *) a->storage_as.string.data;
920
 
           j < len;
921
 
           ++j, ++char_data)
922
 
        hash = HASH_COMBINE (hash, *char_data, n);
923
 
      return (hash);
924
 
    case tc_long_array:
925
 
      len = a->storage_as.long_array.dim;
926
 
      for (j = 0, hash = 0, long_data = (unsigned long *) a->storage_as.long_array.data;
927
 
           j < len;
928
 
           ++j, ++long_data)
929
 
        hash = HASH_COMBINE (hash, *long_data % n, n);
930
 
      return (hash);
931
 
    case tc_double_array:
932
 
      len = a->storage_as.double_array.dim;
933
 
      for (j = 0, hash = 0, double_data = a->storage_as.double_array.data;
934
 
           j < len;
935
 
           ++j, ++double_data)
936
 
        hash = HASH_COMBINE (hash, (unsigned long) *double_data % n, n);
937
 
      return (hash);
938
 
    case tc_lisp_array:
939
 
      len = a->storage_as.lisp_array.dim;
940
 
      for (j = 0, hash = 0; j < len; ++j)
941
 
        hash = HASH_COMBINE (hash,
942
 
                             c_sxhash (a->storage_as.lisp_array.data[j], n),
943
 
                             n);
944
 
      return (hash);
945
 
    default:
946
 
      errswitch ();
947
 
      return (0);
948
 
    }
949
 
}
950
 
 
951
 
long
952
 
href_index (LISP table, LISP key)
953
 
{
954
 
  long index;
955
 
  if NTYPEP
956
 
    (table, tc_lisp_array) my_err ("not a hash table", table);
957
 
  index = c_sxhash (key, table->storage_as.lisp_array.dim);
958
 
  if ((index < 0) || (index >= table->storage_as.lisp_array.dim))
959
 
    {
960
 
      my_err ("sxhash inconsistency", table);
961
 
      return (0);
962
 
    }
963
 
  else
964
 
    return (index);
965
 
}
966
 
 
967
 
LISP
968
 
href (LISP table, LISP key)
969
 
{
970
 
  return (cdr (assoc (key,
971
 
              table->storage_as.lisp_array.data[href_index (table, key)])));
972
 
}
973
 
 
974
 
LISP
975
 
hset (LISP table, LISP key, LISP value)
976
 
{
977
 
  long index;
978
 
  LISP cell, l;
979
 
  index = href_index (table, key);
980
 
  l = table->storage_as.lisp_array.data[index];
981
 
  if NNULLP
982
 
    (cell = assoc (key, l))
983
 
      return (setcdr (cell, value));
984
 
  cell = cons (key, value);
985
 
  table->storage_as.lisp_array.data[index] = cons (cell, l);
986
 
  return (value);
987
 
}
988
 
 
989
 
LISP
990
 
assoc (LISP x, LISP alist)
991
 
{
992
 
  LISP l, tmp;
993
 
  for (l = alist; CONSP (l); l = CDR (l))
994
 
    {
995
 
      tmp = CAR (l);
996
 
      if (CONSP (tmp) && equal (CAR (tmp), x))
997
 
        return (tmp);
998
 
      INTERRUPT_CHECK ();
999
 
    }
1000
 
  if EQ
1001
 
    (l, NIL) return (NIL);
1002
 
  return (my_err ("improper list to assoc", alist));
1003
 
}
1004
 
 
1005
 
LISP
1006
 
assv (LISP x, LISP alist)
1007
 
{
1008
 
  LISP l, tmp;
1009
 
  for (l = alist; CONSP (l); l = CDR (l))
1010
 
    {
1011
 
      tmp = CAR (l);
1012
 
      if (CONSP (tmp) && NNULLP (eql (CAR (tmp), x)))
1013
 
        return (tmp);
1014
 
      INTERRUPT_CHECK ();
1015
 
    }
1016
 
  if EQ
1017
 
    (l, NIL) return (NIL);
1018
 
  return (my_err ("improper list to assv", alist));
1019
 
}
1020
 
 
1021
 
void
1022
 
put_long (long i, FILE * f)
1023
 
{
1024
 
  fwrite (&i, sizeof (long), 1, f);
1025
 
}
1026
 
 
1027
 
long
1028
 
get_long (FILE * f)
1029
 
{
1030
 
  long i;
1031
 
  fread (&i, sizeof (long), 1, f);
1032
 
  return (i);
1033
 
}
1034
 
 
1035
 
long
1036
 
fast_print_table (LISP obj, LISP table)
1037
 
{
1038
 
  FILE *f;
1039
 
  LISP ht, index;
1040
 
  f = get_c_file (car (table), (FILE *) NULL);
1041
 
  if NULLP
1042
 
    (ht = car (cdr (table)))
1043
 
      return (1);
1044
 
  index = href (ht, obj);
1045
 
  if NNULLP
1046
 
    (index)
1047
 
    {
1048
 
      putc (FO_fetch, f);
1049
 
      put_long (get_c_long (index), f);
1050
 
      return (0);
1051
 
    }
1052
 
  if NULLP
1053
 
    (index = car (cdr (cdr (table))))
1054
 
      return (1);
1055
 
  hset (ht, obj, index);
1056
 
  FLONM (bashnum) = 1.0;
1057
 
  setcar (cdr (cdr (table)), plus (index, bashnum));
1058
 
  putc (FO_store, f);
1059
 
  put_long (get_c_long (index), f);
1060
 
  return (1);
1061
 
}
1062
 
 
1063
 
LISP
1064
 
fast_print (LISP obj, LISP table)
1065
 
{
1066
 
  FILE *f;
1067
 
  long len;
1068
 
  LISP tmp;
1069
 
  struct user_type_hooks *p;
1070
 
  STACK_CHECK (&obj);
1071
 
  f = get_c_file (car (table), (FILE *) NULL);
1072
 
  switch (TYPE (obj))
1073
 
    {
1074
 
    case tc_nil:
1075
 
      putc (tc_nil, f);
1076
 
      return (NIL);
1077
 
    case tc_cons:
1078
 
      for (len = 0, tmp = obj; CONSP (tmp); tmp = CDR (tmp))
1079
 
        {
1080
 
          INTERRUPT_CHECK ();
1081
 
          ++len;
1082
 
        }
1083
 
      if (len == 1)
1084
 
        {
1085
 
          putc (tc_cons, f);
1086
 
          fast_print (car (obj), table);
1087
 
          fast_print (cdr (obj), table);
1088
 
        }
1089
 
      else if NULLP
1090
 
        (tmp)
1091
 
        {
1092
 
          putc (FO_list, f);
1093
 
          put_long (len, f);
1094
 
          for (tmp = obj; CONSP (tmp); tmp = CDR (tmp))
1095
 
            fast_print (CAR (tmp), table);
1096
 
        }
1097
 
      else
1098
 
        {
1099
 
          putc (FO_listd, f);
1100
 
          put_long (len, f);
1101
 
          for (tmp = obj; CONSP (tmp); tmp = CDR (tmp))
1102
 
            fast_print (CAR (tmp), table);
1103
 
          fast_print (tmp, table);
1104
 
        }
1105
 
      return (NIL);
1106
 
    case tc_flonum:
1107
 
      putc (tc_flonum, f);
1108
 
      fwrite (&obj->storage_as.flonum.data,
1109
 
              sizeof (obj->storage_as.flonum.data),
1110
 
              1,
1111
 
              f);
1112
 
      return (NIL);
1113
 
    case tc_symbol:
1114
 
      if (fast_print_table (obj, table))
1115
 
        {
1116
 
          putc (tc_symbol, f);
1117
 
          len = strlen (PNAME (obj));
1118
 
          if (len >= TKBUFFERN)
1119
 
            my_err ("symbol name too long", obj);
1120
 
          put_long (len, f);
1121
 
          fwrite (PNAME (obj), len, 1, f);
1122
 
          return (sym_t);
1123
 
        }
1124
 
      else
1125
 
        return (NIL);
1126
 
    default:
1127
 
      p = get_user_type_hooks (TYPE (obj));
1128
 
      if (p->fast_print)
1129
 
        return ((*p->fast_print) (obj, table));
1130
 
      else
1131
 
        return (my_err ("cannot fast-print", obj));
1132
 
    }
1133
 
}
1134
 
 
1135
 
LISP
1136
 
fast_read (LISP table)
1137
 
{
1138
 
  FILE *f;
1139
 
  LISP tmp, l;
1140
 
  struct user_type_hooks *p;
1141
 
  int c;
1142
 
  long len;
1143
 
  f = get_c_file (car (table), (FILE *) NULL);
1144
 
  c = getc (f);
1145
 
  if (c == EOF)
1146
 
    return (table);
1147
 
  switch (c)
1148
 
    {
1149
 
    case FO_comment:
1150
 
      while ((c = getc (f)))
1151
 
        switch (c)
1152
 
          {
1153
 
          case EOF:
1154
 
            return (table);
1155
 
          case '\n':
1156
 
            return (fast_read (table));
1157
 
          }
1158
 
    case FO_fetch:
1159
 
      len = get_long (f);
1160
 
      FLONM (bashnum) = len;
1161
 
      return (href (car (cdr (table)), bashnum));
1162
 
    case FO_store:
1163
 
      len = get_long (f);
1164
 
      tmp = fast_read (table);
1165
 
      hset (car (cdr (table)), flocons (len), tmp);
1166
 
      return (tmp);
1167
 
    case tc_nil:
1168
 
      return (NIL);
1169
 
    case tc_cons:
1170
 
      tmp = fast_read (table);
1171
 
      return (cons (tmp, fast_read (table)));
1172
 
    case FO_list:
1173
 
    case FO_listd:
1174
 
      len = get_long (f);
1175
 
      FLONM (bashnum) = len;
1176
 
      l = make_list (bashnum, NIL);
1177
 
      tmp = l;
1178
 
      while (len > 1)
1179
 
        {
1180
 
          CAR (tmp) = fast_read (table);
1181
 
          tmp = CDR (tmp);
1182
 
          --len;
1183
 
        }
1184
 
      CAR (tmp) = fast_read (table);
1185
 
      if (c == FO_listd)
1186
 
        CDR (tmp) = fast_read (table);
1187
 
      return (l);
1188
 
    case tc_flonum:
1189
 
      tmp = newcell (tc_flonum);
1190
 
      fread (&tmp->storage_as.flonum.data,
1191
 
             sizeof (tmp->storage_as.flonum.data),
1192
 
             1,
1193
 
             f);
1194
 
      return (tmp);
1195
 
    case tc_symbol:
1196
 
      len = get_long (f);
1197
 
      if (len >= TKBUFFERN)
1198
 
        my_err ("symbol name too long", NIL);
1199
 
      fread (tkbuffer, len, 1, f);
1200
 
      tkbuffer[len] = 0;
1201
 
      return (rintern (tkbuffer));
1202
 
    default:
1203
 
      p = get_user_type_hooks (c);
1204
 
      if (p->fast_read)
1205
 
        return (*p->fast_read) (c, table);
1206
 
      else
1207
 
        return (my_err ("unknown fast-read opcode", flocons (c)));
1208
 
    }
1209
 
}
1210
 
 
1211
 
LISP
1212
 
array_fast_print (LISP ptr, LISP table)
1213
 
{
1214
 
  int j, len;
1215
 
  FILE *f;
1216
 
  f = get_c_file (car (table), (FILE *) NULL);
1217
 
  switch (ptr->type)
1218
 
    {
1219
 
    case tc_string:
1220
 
    case tc_byte_array:
1221
 
      putc (ptr->type, f);
1222
 
      len = ptr->storage_as.string.dim;
1223
 
      put_long (len, f);
1224
 
      fwrite (ptr->storage_as.string.data, len, 1, f);
1225
 
      return (NIL);
1226
 
    case tc_double_array:
1227
 
      putc (tc_double_array, f);
1228
 
      len = ptr->storage_as.double_array.dim * sizeof (double);
1229
 
      put_long (len, f);
1230
 
      fwrite (ptr->storage_as.double_array.data, len, 1, f);
1231
 
      return (NIL);
1232
 
    case tc_long_array:
1233
 
      putc (tc_long_array, f);
1234
 
      len = ptr->storage_as.long_array.dim * sizeof (long);
1235
 
      put_long (len, f);
1236
 
      fwrite (ptr->storage_as.long_array.data, len, 1, f);
1237
 
      return (NIL);
1238
 
    case tc_lisp_array:
1239
 
      putc (tc_lisp_array, f);
1240
 
      len = ptr->storage_as.lisp_array.dim;
1241
 
      put_long (len, f);
1242
 
      for (j = 0; j < len; ++j)
1243
 
        fast_print (ptr->storage_as.lisp_array.data[j], table);
1244
 
      return (NIL);
1245
 
    default:
1246
 
      return (errswitch ());
1247
 
    }
1248
 
}
1249
 
 
1250
 
LISP
1251
 
array_fast_read (int code, LISP table)
1252
 
{
1253
 
  long j, len, iflag;
1254
 
  FILE *f;
1255
 
  LISP ptr;
1256
 
  f = get_c_file (car (table), (FILE *) NULL);
1257
 
  switch (code)
1258
 
    {
1259
 
    case tc_string:
1260
 
      len = get_long (f);
1261
 
      ptr = strcons (len, NULL);
1262
 
      fread (ptr->storage_as.string.data, len, 1, f);
1263
 
      ptr->storage_as.string.data[len] = 0;
1264
 
      return (ptr);
1265
 
    case tc_byte_array:
1266
 
      len = get_long (f);
1267
 
      iflag = no_interrupt (1);
1268
 
      ptr = newcell (tc_byte_array);
1269
 
      ptr->storage_as.string.dim = len;
1270
 
      ptr->storage_as.string.data =
1271
 
        (char *) must_malloc (len);
1272
 
      fread (ptr->storage_as.string.data, len, 1, f);
1273
 
      no_interrupt (iflag);
1274
 
      return (ptr);
1275
 
    case tc_double_array:
1276
 
      len = get_long (f);
1277
 
      iflag = no_interrupt (1);
1278
 
      ptr = newcell (tc_double_array);
1279
 
      ptr->storage_as.double_array.dim = len;
1280
 
      ptr->storage_as.double_array.data =
1281
 
        (double *) must_malloc (len * sizeof (double));
1282
 
      fread (ptr->storage_as.double_array.data, sizeof (double), len, f);
1283
 
      no_interrupt (iflag);
1284
 
      return (ptr);
1285
 
    case tc_long_array:
1286
 
      len = get_long (f);
1287
 
      iflag = no_interrupt (1);
1288
 
      ptr = newcell (tc_long_array);
1289
 
      ptr->storage_as.long_array.dim = len;
1290
 
      ptr->storage_as.long_array.data =
1291
 
        (long *) must_malloc (len * sizeof (long));
1292
 
      fread (ptr->storage_as.long_array.data, sizeof (long), len, f);
1293
 
      no_interrupt (iflag);
1294
 
      return (ptr);
1295
 
    case tc_lisp_array:
1296
 
      len = get_long (f);
1297
 
      FLONM (bashnum) = len;
1298
 
      ptr = cons_array (bashnum, NIL);
1299
 
      for (j = 0; j < len; ++j)
1300
 
        ptr->storage_as.lisp_array.data[j] = fast_read (table);
1301
 
      return (ptr);
1302
 
    default:
1303
 
      return (errswitch ());
1304
 
    }
1305
 
}
1306
 
 
1307
 
long
1308
 
get_c_long (LISP x)
1309
 
{
1310
 
  if NFLONUMP
1311
 
    (x) my_err ("not a number", x);
1312
 
  return ((long) FLONM (x));
1313
 
}
1314
 
 
1315
 
double
1316
 
get_c_double (LISP x)
1317
 
{
1318
 
  if NFLONUMP
1319
 
    (x) my_err ("not a number", x);
1320
 
  return (FLONM (x));
1321
 
}
1322
 
 
1323
 
LISP
1324
 
make_list (LISP x, LISP v)
1325
 
{
1326
 
  long n;
1327
 
  LISP l;
1328
 
  n = get_c_long (x);
1329
 
  l = NIL;
1330
 
  while (n > 0)
1331
 
    {
1332
 
      l = cons (v, l);
1333
 
      --n;
1334
 
    }
1335
 
  return (l);
1336
 
}
1337
 
 
1338
 
LISP
1339
 
lfread (LISP size, LISP file)
1340
 
{
1341
 
  long flag, n, ret, m;
1342
 
  char *buffer;
1343
 
  LISP s;
1344
 
  FILE *f;
1345
 
  f = get_c_file (file, stdin);
1346
 
  flag = no_interrupt (1);
1347
 
  switch (TYPE (size))
1348
 
    {
1349
 
    case tc_string:
1350
 
    case tc_byte_array:
1351
 
      s = size;
1352
 
      buffer = s->storage_as.string.data;
1353
 
      n = s->storage_as.string.dim;
1354
 
      m = 0;
1355
 
      break;
1356
 
    default:
1357
 
      n = get_c_long (size);
1358
 
      buffer = (char *) must_malloc (n + 1);
1359
 
      buffer[n] = 0;
1360
 
      m = 1;
1361
 
    }
1362
 
  ret = fread (buffer, 1, n, f);
1363
 
  if (ret == 0)
1364
 
    {
1365
 
      if (m)
1366
 
        free (buffer);
1367
 
      no_interrupt (flag);
1368
 
      return (NIL);
1369
 
    }
1370
 
  if (m)
1371
 
    {
1372
 
      if (ret == n)
1373
 
        {
1374
 
          s = cons (NIL, NIL);
1375
 
          s->type = tc_string;
1376
 
          s->storage_as.string.data = buffer;
1377
 
          s->storage_as.string.dim = n;
1378
 
        }
1379
 
      else
1380
 
        {
1381
 
          s = strcons (ret, NULL);
1382
 
          memcpy (s->storage_as.string.data, buffer, ret);
1383
 
          free (buffer);
1384
 
        }
1385
 
      no_interrupt (flag);
1386
 
      return (s);
1387
 
    }
1388
 
  no_interrupt (flag);
1389
 
  return (flocons ((double) ret));
1390
 
}
1391
 
 
1392
 
LISP
1393
 
lfwrite (LISP string, LISP file)
1394
 
{
1395
 
  FILE *f;
1396
 
  long flag;
1397
 
  char *data;
1398
 
  long dim, len;
1399
 
  f = get_c_file (file, stdout);
1400
 
  data = get_c_string_dim (CONSP (string) ? car (string) : string, &dim);
1401
 
  len = CONSP (string) ? get_c_long (cadr (string)) : dim;
1402
 
  if (len <= 0)
1403
 
    return (NIL);
1404
 
  if (len > dim)
1405
 
    my_err ("write length too long", string);
1406
 
  flag = no_interrupt (1);
1407
 
  fwrite (data, 1, len, f);
1408
 
  no_interrupt (flag);
1409
 
  return (NIL);
1410
 
}
1411
 
 
1412
 
LISP
1413
 
lfflush (LISP file)
1414
 
{
1415
 
  FILE *f;
1416
 
  long flag;
1417
 
  f = get_c_file (file, stdout);
1418
 
  flag = no_interrupt (1);
1419
 
  fflush (f);
1420
 
  no_interrupt (flag);
1421
 
  return (NIL);
1422
 
}
1423
 
 
1424
 
LISP
1425
 
string_length (LISP string)
1426
 
{
1427
 
  if NTYPEP
1428
 
    (string, tc_string) err_wta_str (string);
1429
 
  return (flocons (strlen (string->storage_as.string.data)));
1430
 
}
1431
 
 
1432
 
LISP
1433
 
string_dim (LISP string)
1434
 
{
1435
 
  if NTYPEP
1436
 
    (string, tc_string) err_wta_str (string);
1437
 
  return (flocons ((double) string->storage_as.string.dim));
1438
 
}
1439
 
 
1440
 
long
1441
 
nlength (LISP obj)
1442
 
{
1443
 
  LISP l;
1444
 
  long n;
1445
 
  switch TYPE
1446
 
    (obj)
1447
 
    {
1448
 
    case tc_string:
1449
 
      return (strlen (obj->storage_as.string.data));
1450
 
    case tc_byte_array:
1451
 
      return (obj->storage_as.string.dim);
1452
 
    case tc_double_array:
1453
 
      return (obj->storage_as.double_array.dim);
1454
 
    case tc_long_array:
1455
 
      return (obj->storage_as.long_array.dim);
1456
 
    case tc_lisp_array:
1457
 
      return (obj->storage_as.lisp_array.dim);
1458
 
    case tc_nil:
1459
 
      return (0);
1460
 
    case tc_cons:
1461
 
      for (l = obj, n = 0; CONSP (l); l = CDR (l), ++n)
1462
 
        INTERRUPT_CHECK ();
1463
 
      if NNULLP
1464
 
        (l) my_err ("improper list to length", obj);
1465
 
      return (n);
1466
 
    default:
1467
 
      my_err ("wta to length", obj);
1468
 
      return (0);
1469
 
    }
1470
 
}
1471
 
 
1472
 
LISP
1473
 
llength (LISP obj)
1474
 
{
1475
 
  return (flocons (nlength (obj)));
1476
 
}
1477
 
 
1478
 
LISP
1479
 
number2string (LISP x, LISP b, LISP w, LISP p)
1480
 
{
1481
 
  char buffer[1000];
1482
 
  double y;
1483
 
  long base, width, prec;
1484
 
  if NFLONUMP
1485
 
    (x) my_err ("wta", x);
1486
 
  y = FLONM (x);
1487
 
  width = NNULLP (w) ? get_c_long (w) : -1;
1488
 
  if (width > 100)
1489
 
    my_err ("width too long", w);
1490
 
  prec = NNULLP (p) ? get_c_long (p) : -1;
1491
 
  if (prec > 100)
1492
 
    my_err ("precision too large", p);
1493
 
  if (NULLP (b) || EQ (sym_e, b) || EQ (sym_f, b))
1494
 
    {
1495
 
      char format[32];
1496
 
 
1497
 
      if ((width >= 0) && (prec >= 0))
1498
 
        sprintf (format,
1499
 
                 NULLP (b) ? "%%%ld.%ldg" :
1500
 
                 EQ (sym_e, b) ? "%%%ld.%ldd" : "%%%ld.%ldf",
1501
 
                 width, prec);
1502
 
      else if (width >= 0)
1503
 
        sprintf (format,
1504
 
                 NULLP (b) ? "%%%ldg" : EQ (sym_e, b) ? "%%%lde" : "%%%ldf",
1505
 
                 width);
1506
 
      else if (prec >= 0)
1507
 
        sprintf (format,
1508
 
                 NULLP (b) ? "%%.%ldg" : EQ (sym_e, b) ? "%%.%lde" : "%%.%ldf",
1509
 
                 prec);
1510
 
      else
1511
 
        sprintf (format, NULLP (b) ? "%%g" : EQ (sym_e, b) ? "%%e" : "%%f");
1512
 
 
1513
 
      g_ascii_formatd (buffer, sizeof(buffer), format, y);
1514
 
    }
1515
 
  else if (((base = get_c_long (b)) == 10) || (base == 8) || (base == 16))
1516
 
    {
1517
 
      if (width >= 0)
1518
 
        sprintf (buffer,
1519
 
                 (base == 10) ? "%0*ld" : (base == 8) ? "%0*lo" : "%0*lX",
1520
 
                 (int) width,
1521
 
                 (long) y);
1522
 
      else
1523
 
        sprintf (buffer,
1524
 
                 (base == 10) ? "%ld" : (base == 8) ? "%lo" : "%lX",
1525
 
                 (long) y);
1526
 
    }
1527
 
  else
1528
 
    my_err ("number base not handled", b);
1529
 
  return (strcons (strlen (buffer), buffer));
1530
 
}
1531
 
 
1532
 
LISP
1533
 
string2number (LISP x, LISP b)
1534
 
{
1535
 
  char *str;
1536
 
  long base, value = 0;
1537
 
  double result = 0.0;
1538
 
  str = get_c_string (x);
1539
 
  if NULLP
1540
 
    (b)
1541
 
      result = g_ascii_strtod (str, NULL);
1542
 
  else if ((base = get_c_long (b)) == 10)
1543
 
    {
1544
 
      sscanf (str, "%ld", &value);
1545
 
      result = (double) value;
1546
 
    }
1547
 
  else if (base == 8)
1548
 
    {
1549
 
      sscanf (str, "%lo", &value);
1550
 
      result = (double) value;
1551
 
    }
1552
 
  else if (base == 16)
1553
 
    {
1554
 
      sscanf (str, "%lx", &value);
1555
 
      result = (double) value;
1556
 
    }
1557
 
  else if ((base >= 1) && (base <= 16))
1558
 
    {
1559
 
      for (result = 0.0; *str; ++str)
1560
 
        if (g_ascii_isdigit (*str))
1561
 
          result = result * base + *str - '0';
1562
 
        else if (g_ascii_isxdigit (*str))
1563
 
          result = result * base + g_ascii_toupper (*str) - 'A' + 10;
1564
 
    }
1565
 
  else
1566
 
    my_err ("number base not handled", b);
1567
 
  return (flocons (result));
1568
 
}
1569
 
 
1570
 
LISP
1571
 
lstrcmp (LISP s1, LISP s2)
1572
 
{
1573
 
  return (flocons (strcmp (get_c_string (s1), get_c_string (s2))));
1574
 
}
1575
 
 
1576
 
void
1577
 
chk_string (LISP s, char **data, long *dim)
1578
 
{
1579
 
  if TYPEP
1580
 
    (s, tc_string)
1581
 
    {
1582
 
      *data = s->storage_as.string.data;
1583
 
      *dim = s->storage_as.string.dim;
1584
 
    }
1585
 
  else
1586
 
    err_wta_str (s);
1587
 
}
1588
 
 
1589
 
LISP
1590
 
lstrcpy (LISP dest, LISP src)
1591
 
{
1592
 
  long ddim, slen;
1593
 
  char *d, *s;
1594
 
  chk_string (dest, &d, &ddim);
1595
 
  s = get_c_string (src);
1596
 
  slen = strlen (s);
1597
 
  if (slen > ddim)
1598
 
    my_err ("string too long", src);
1599
 
  memcpy (d, s, slen);
1600
 
  d[slen] = 0;
1601
 
  return (NIL);
1602
 
}
1603
 
 
1604
 
LISP
1605
 
lstrcat (LISP dest, LISP src)
1606
 
{
1607
 
  long ddim, dlen, slen;
1608
 
  char *d, *s;
1609
 
  chk_string (dest, &d, &ddim);
1610
 
  s = get_c_string (src);
1611
 
  slen = strlen (s);
1612
 
  dlen = strlen (d);
1613
 
  if ((slen + dlen) > ddim)
1614
 
    my_err ("string too long", src);
1615
 
  memcpy (&d[dlen], s, slen);
1616
 
  d[dlen + slen] = 0;
1617
 
  return (NIL);
1618
 
}
1619
 
 
1620
 
LISP
1621
 
lstrbreakup (LISP str, LISP lmarker)
1622
 
{
1623
 
  char *start, *end, *marker;
1624
 
  size_t k;
1625
 
  LISP result = NIL;
1626
 
  start = end = get_c_string (str);
1627
 
  marker = get_c_string (lmarker);
1628
 
  k = strlen (marker);
1629
 
  if (*marker)
1630
 
    {
1631
 
      while (*end)
1632
 
        {
1633
 
          if (!(end = strstr (start, marker)))
1634
 
            end = &start[strlen (start)];
1635
 
          result = cons (strcons (end - start, start), result);
1636
 
          start = (*end) ? end + k : end;
1637
 
        }
1638
 
      return (nreverse (result));
1639
 
    }
1640
 
  else
1641
 
    return (strcons (strlen (start), start));
1642
 
}
1643
 
 
1644
 
LISP
1645
 
lstrunbreakup (LISP elems, LISP lmarker)
1646
 
{
1647
 
  LISP result, l;
1648
 
  for (l = elems, result = NIL; NNULLP (l); l = cdr (l))
1649
 
    if EQ
1650
 
      (l, elems)
1651
 
        result = cons (car (l), result);
1652
 
    else
1653
 
      result = cons (car (l), cons (lmarker, result));
1654
 
  return (string_append (nreverse (result)));
1655
 
}
1656
 
 
1657
 
LISP
1658
 
stringp (LISP x)
1659
 
{
1660
 
  return (TYPEP (x, tc_string) ? sym_t : NIL);
1661
 
}
1662
 
 
1663
 
static char *base64_encode_table = "\
1664
 
ABCDEFGHIJKLMNOPQRSTUVWXYZ\
1665
 
abcdefghijklmnopqrstuvwxyz\
1666
 
0123456789+/=";
1667
 
 
1668
 
static char *base64_decode_table = NULL;
1669
 
 
1670
 
static void
1671
 
init_base64_table (void)
1672
 
{
1673
 
  int j;
1674
 
  base64_decode_table = (char *) malloc (256);
1675
 
  memset (base64_decode_table, -1, 256);
1676
 
  for (j = 0; j < 65; ++j)
1677
 
    base64_decode_table[(unsigned char) base64_encode_table[j]] = j;
1678
 
}
1679
 
 
1680
 
#define BITMSK(N) ((1 << (N)) - 1)
1681
 
 
1682
 
#define ITEM1(X)   (X >> 2) & BITMSK(6)
1683
 
#define ITEM2(X,Y) ((X & BITMSK(2)) << 4) | ((Y >> 4) & BITMSK(4))
1684
 
#define ITEM3(X,Y) ((X & BITMSK(4)) << 2) | ((Y >> 6) & BITMSK(2))
1685
 
#define ITEM4(X)   X & BITMSK(6)
1686
 
 
1687
 
LISP
1688
 
base64encode (LISP in)
1689
 
{
1690
 
  char *s, *t = base64_encode_table;
1691
 
  unsigned char *p1, *p2;
1692
 
  LISP out;
1693
 
  long j, m, n, chunks, leftover;
1694
 
  s = get_c_string_dim (in, &n);
1695
 
  chunks = n / 3;
1696
 
  leftover = n % 3;
1697
 
  m = (chunks + ((leftover) ? 1 : 0)) * 4;
1698
 
  out = strcons (m, NULL);
1699
 
  p2 = (unsigned char *) get_c_string (out);
1700
 
  for (j = 0, p1 = (unsigned char *) s; j < chunks; ++j, p1 += 3)
1701
 
    {
1702
 
      *p2++ = t[ITEM1 (p1[0])];
1703
 
      *p2++ = t[ITEM2 (p1[0], p1[1])];
1704
 
      *p2++ = t[ITEM3 (p1[1], p1[2])];
1705
 
      *p2++ = t[ITEM4 (p1[2])];
1706
 
    }
1707
 
  switch (leftover)
1708
 
    {
1709
 
    case 0:
1710
 
      break;
1711
 
    case 1:
1712
 
      *p2++ = t[ITEM1 (p1[0])];
1713
 
      *p2++ = t[ITEM2 (p1[0], 0)];
1714
 
      *p2++ = base64_encode_table[64];
1715
 
      *p2++ = base64_encode_table[64];
1716
 
      break;
1717
 
    case 2:
1718
 
      *p2++ = t[ITEM1 (p1[0])];
1719
 
      *p2++ = t[ITEM2 (p1[0], p1[1])];
1720
 
      *p2++ = t[ITEM3 (p1[1], 0)];
1721
 
      *p2++ = base64_encode_table[64];
1722
 
      break;
1723
 
    default:
1724
 
      errswitch ();
1725
 
    }
1726
 
  return (out);
1727
 
}
1728
 
 
1729
 
LISP
1730
 
base64decode (LISP in)
1731
 
{
1732
 
  char *s, *t = base64_decode_table;
1733
 
  LISP out;
1734
 
  unsigned char *p1, *p2;
1735
 
  long j, m, n, chunks, leftover, item1, item2, item3, item4;
1736
 
  s = get_c_string (in);
1737
 
  n = strlen (s);
1738
 
  if (n == 0)
1739
 
    return (strcons (0, NULL));
1740
 
  if (n % 4)
1741
 
    my_err ("illegal base64 data length", in);
1742
 
  if (s[n - 1] == base64_encode_table[64])
1743
 
    {
1744
 
      if (s[n - 2] == base64_encode_table[64])
1745
 
        leftover = 1;
1746
 
      else
1747
 
        leftover = 2;
1748
 
    }
1749
 
  else
1750
 
    leftover = 0;
1751
 
  chunks = (n / 4) - ((leftover) ? 1 : 0);
1752
 
  m = (chunks * 3) + leftover;
1753
 
  out = strcons (m, NULL);
1754
 
  p2 = (unsigned char *) get_c_string (out);
1755
 
  for (j = 0, p1 = (unsigned char *) s; j < chunks; ++j, p1 += 4)
1756
 
    {
1757
 
      if ((item1 = t[p1[0]]) & ~BITMSK (6))
1758
 
        return (NIL);
1759
 
      if ((item2 = t[p1[1]]) & ~BITMSK (6))
1760
 
        return (NIL);
1761
 
      if ((item3 = t[p1[2]]) & ~BITMSK (6))
1762
 
        return (NIL);
1763
 
      if ((item4 = t[p1[3]]) & ~BITMSK (6))
1764
 
        return (NIL);
1765
 
      *p2++ = (item1 << 2) | (item2 >> 4);
1766
 
      *p2++ = (item2 << 4) | (item3 >> 2);
1767
 
      *p2++ = (item3 << 6) | item4;
1768
 
    }
1769
 
  switch (leftover)
1770
 
    {
1771
 
    case 0:
1772
 
      break;
1773
 
    case 1:
1774
 
      if ((item1 = t[p1[0]]) & ~BITMSK (6))
1775
 
        return (NIL);
1776
 
      if ((item2 = t[p1[1]]) & ~BITMSK (6))
1777
 
        return (NIL);
1778
 
      *p2++ = (item1 << 2) | (item2 >> 4);
1779
 
      break;
1780
 
    case 2:
1781
 
      if ((item1 = t[p1[0]]) & ~BITMSK (6))
1782
 
        return (NIL);
1783
 
      if ((item2 = t[p1[1]]) & ~BITMSK (6))
1784
 
        return (NIL);
1785
 
      if ((item3 = t[p1[2]]) & ~BITMSK (6))
1786
 
        return (NIL);
1787
 
      *p2++ = (item1 << 2) | (item2 >> 4);
1788
 
      *p2++ = (item2 << 4) | (item3 >> 2);
1789
 
      break;
1790
 
    default:
1791
 
      errswitch ();
1792
 
    }
1793
 
  return (out);
1794
 
}
1795
 
 
1796
 
LISP
1797
 
memq (LISP x, LISP il)
1798
 
{
1799
 
  LISP l, tmp;
1800
 
  for (l = il; CONSP (l); l = CDR (l))
1801
 
    {
1802
 
      tmp = CAR (l);
1803
 
      if EQ
1804
 
        (x, tmp) return (l);
1805
 
      INTERRUPT_CHECK ();
1806
 
    }
1807
 
  if EQ
1808
 
    (l, NIL) return (NIL);
1809
 
  return (my_err ("improper list to memq", il));
1810
 
}
1811
 
 
1812
 
LISP
1813
 
member (LISP x, LISP il)
1814
 
{
1815
 
  LISP l, tmp;
1816
 
  for (l = il; CONSP (l); l = CDR (l))
1817
 
    {
1818
 
      tmp = CAR (l);
1819
 
      if NNULLP
1820
 
        (equal (x, tmp)) return (l);
1821
 
      INTERRUPT_CHECK ();
1822
 
    }
1823
 
  if EQ
1824
 
    (l, NIL) return (NIL);
1825
 
  return (my_err ("improper list to member", il));
1826
 
}
1827
 
 
1828
 
LISP
1829
 
memv (LISP x, LISP il)
1830
 
{
1831
 
  LISP l, tmp;
1832
 
  for (l = il; CONSP (l); l = CDR (l))
1833
 
    {
1834
 
      tmp = CAR (l);
1835
 
      if NNULLP
1836
 
        (eql (x, tmp)) return (l);
1837
 
      INTERRUPT_CHECK ();
1838
 
    }
1839
 
  if EQ
1840
 
    (l, NIL) return (NIL);
1841
 
  return (my_err ("improper list to memv", il));
1842
 
}
1843
 
 
1844
 
 
1845
 
LISP
1846
 
nth (LISP x, LISP li)
1847
 
{
1848
 
  LISP l;
1849
 
  long j, n = get_c_long (x);
1850
 
  for (j = 0, l = li; (j < n) && CONSP (l); ++j)
1851
 
    l = CDR (l);
1852
 
  if CONSP
1853
 
    (l)
1854
 
      return (CAR (l));
1855
 
  else
1856
 
    return (my_err ("bad arg to nth", x));
1857
 
}
1858
 
 
1859
 
/* these lxxx_default functions are convenient for manipulating
1860
 
   command-line argument lists */
1861
 
 
1862
 
LISP
1863
 
lref_default (LISP li, LISP x, LISP fcn)
1864
 
{
1865
 
  LISP l;
1866
 
  long j, n = get_c_long (x);
1867
 
  for (j = 0, l = li; (j < n) && CONSP (l); ++j)
1868
 
    l = CDR (l);
1869
 
  if CONSP
1870
 
    (l)
1871
 
      return (CAR (l));
1872
 
  else if NNULLP
1873
 
    (fcn)
1874
 
      return (lapply (fcn, NIL));
1875
 
  else
1876
 
    return (NIL);
1877
 
}
1878
 
 
1879
 
LISP
1880
 
larg_default (LISP li, LISP x, LISP dval)
1881
 
{
1882
 
  LISP l = li, elem;
1883
 
  long j = 0, n = get_c_long (x);
1884
 
  while NNULLP
1885
 
    (l)
1886
 
    {
1887
 
      elem = car (l);
1888
 
      if (TYPEP (elem, tc_string) && strchr ("-:", *get_c_string (elem)))
1889
 
        l = cdr (l);
1890
 
      else if (j == n)
1891
 
        return (elem);
1892
 
      else
1893
 
        {
1894
 
          l = cdr (l);
1895
 
          ++j;
1896
 
        }
1897
 
    }
1898
 
  return (dval);
1899
 
}
1900
 
 
1901
 
LISP
1902
 
lkey_default (LISP li, LISP key, LISP dval)
1903
 
{
1904
 
  LISP l = li, elem;
1905
 
  char *ckey, *celem;
1906
 
  long n;
1907
 
  ckey = get_c_string (key);
1908
 
  n = strlen (ckey);
1909
 
  while NNULLP
1910
 
    (l)
1911
 
    {
1912
 
      elem = car (l);
1913
 
      if (TYPEP (elem, tc_string) && (*(celem = get_c_string (elem)) == ':') &&
1914
 
          (strncmp (&celem[1], ckey, n) == 0) && (celem[n + 1] == '='))
1915
 
        return (strcons (strlen (&celem[n + 2]), &celem[n + 2]));
1916
 
      l = cdr (l);
1917
 
    }
1918
 
  return (dval);
1919
 
}
1920
 
 
1921
 
 
1922
 
LISP
1923
 
llist (LISP l)
1924
 
{
1925
 
  return (l);
1926
 
}
1927
 
 
1928
 
LISP
1929
 
writes1 (FILE * f, LISP l)
1930
 
{
1931
 
  LISP v;
1932
 
  STACK_CHECK (&v);
1933
 
  INTERRUPT_CHECK ();
1934
 
  for (v = l; CONSP (v); v = CDR (v))
1935
 
    writes1 (f, CAR (v));
1936
 
  switch TYPE
1937
 
    (v)
1938
 
    {
1939
 
    case tc_nil:
1940
 
      break;
1941
 
    case tc_symbol:
1942
 
    case tc_string:
1943
 
      fput_st (f, get_c_string (v));
1944
 
      break;
1945
 
    default:
1946
 
      lprin1f (v, f);
1947
 
      break;
1948
 
    }
1949
 
  return (NIL);
1950
 
}
1951
 
 
1952
 
LISP
1953
 
writes (LISP args)
1954
 
{
1955
 
  return (writes1 (get_c_file (car (args), stdout), cdr (args)));
1956
 
}
1957
 
 
1958
 
LISP
1959
 
last (LISP l)
1960
 
{
1961
 
  LISP v1, v2;
1962
 
  v1 = l;
1963
 
  v2 = CONSP (v1) ? CDR (v1) : my_err ("bad arg to last", l);
1964
 
  while (CONSP (v2))
1965
 
    {
1966
 
      INTERRUPT_CHECK ();
1967
 
      v1 = v2;
1968
 
      v2 = CDR (v2);
1969
 
    }
1970
 
  return (v1);
1971
 
}
1972
 
 
1973
 
LISP
1974
 
butlast (LISP l)
1975
 
{
1976
 
  INTERRUPT_CHECK ();
1977
 
  STACK_CHECK (&l);
1978
 
  if NULLP
1979
 
    (l) my_err ("list is empty", l);
1980
 
  if CONSP (l)
1981
 
    {
1982
 
      if NULLP (CDR (l))
1983
 
        return (NIL);
1984
 
      else
1985
 
        return (cons (CAR (l), butlast (CDR (l))));
1986
 
    }
1987
 
  return (my_err ("not a list", l));
1988
 
}
1989
 
 
1990
 
LISP
1991
 
nconc (LISP a, LISP b)
1992
 
{
1993
 
  if NULLP
1994
 
    (a)
1995
 
      return (b);
1996
 
  setcdr (last (a), b);
1997
 
  return (a);
1998
 
}
1999
 
 
2000
 
LISP
2001
 
funcall1 (LISP fcn, LISP a1)
2002
 
{
2003
 
  switch TYPE
2004
 
    (fcn)
2005
 
    {
2006
 
    case tc_subr_1:
2007
 
      STACK_CHECK (&fcn);
2008
 
      INTERRUPT_CHECK ();
2009
 
      return (SUBR1 (fcn) (a1));
2010
 
    case tc_closure:
2011
 
      if TYPEP
2012
 
        (fcn->storage_as.closure.code, tc_subr_2)
2013
 
        {
2014
 
          STACK_CHECK (&fcn);
2015
 
          INTERRUPT_CHECK ();
2016
 
          return (SUBR2 (fcn->storage_as.closure.code)
2017
 
                  (fcn->storage_as.closure.env, a1));
2018
 
        }
2019
 
    default:
2020
 
      return (lapply (fcn, cons (a1, NIL)));
2021
 
    }
2022
 
}
2023
 
 
2024
 
LISP
2025
 
funcall2 (LISP fcn, LISP a1, LISP a2)
2026
 
{
2027
 
  switch TYPE
2028
 
    (fcn)
2029
 
    {
2030
 
    case tc_subr_2:
2031
 
    case tc_subr_2n:
2032
 
      STACK_CHECK (&fcn);
2033
 
      INTERRUPT_CHECK ();
2034
 
      return (SUBR2 (fcn) (a1, a2));
2035
 
    default:
2036
 
      return (lapply (fcn, cons (a1, cons (a2, NIL))));
2037
 
    }
2038
 
}
2039
 
 
2040
 
LISP
2041
 
lqsort (LISP l, LISP f, LISP g)
2042
 
     /* this is a stupid recursive qsort */
2043
 
{
2044
 
  int j, n;
2045
 
  LISP v, mark, less, notless;
2046
 
  for (v = l, n = 0; CONSP (v); v = CDR (v), ++n)
2047
 
    INTERRUPT_CHECK ();
2048
 
  if NNULLP
2049
 
    (v) my_err ("bad list to qsort", l);
2050
 
  if (n == 0)
2051
 
    return (NIL);
2052
 
  j = rand () % n;
2053
 
  for (v = l, n = 0; n < j; ++n)
2054
 
    v = CDR (v);
2055
 
  mark = CAR (v);
2056
 
  for (less = NIL, notless = NIL, v = l, n = 0; NNULLP (v); v = CDR (v), ++n)
2057
 
    if (j != n)
2058
 
      {
2059
 
        if NNULLP
2060
 
          (funcall2 (f,
2061
 
                     NULLP (g) ? CAR (v) : funcall1 (g, CAR (v)),
2062
 
                     NULLP (g) ? mark : funcall1 (g, mark)))
2063
 
            less = cons (CAR (v), less);
2064
 
        else
2065
 
          notless = cons (CAR (v), notless);
2066
 
      }
2067
 
  return (nconc (lqsort (less, f, g),
2068
 
                 cons (mark,
2069
 
                       lqsort (notless, f, g))));
2070
 
}
2071
 
 
2072
 
LISP
2073
 
string_lessp (LISP s1, LISP s2)
2074
 
{
2075
 
  if (strcmp (get_c_string (s1), get_c_string (s2)) < 0)
2076
 
    return (sym_t);
2077
 
  else
2078
 
    return (NIL);
2079
 
}
2080
 
 
2081
 
LISP
2082
 
benchmark_funcall1 (LISP ln, LISP f, LISP a1)
2083
 
{
2084
 
  long j, n;
2085
 
  LISP value = NIL;
2086
 
  n = get_c_long (ln);
2087
 
  for (j = 0; j < n; ++j)
2088
 
    value = funcall1 (f, a1);
2089
 
  return (value);
2090
 
}
2091
 
 
2092
 
LISP
2093
 
benchmark_funcall2 (LISP l)
2094
 
{
2095
 
  long j, n;
2096
 
  LISP ln = car (l);
2097
 
  LISP f = car (cdr (l));
2098
 
  LISP a1 = car (cdr (cdr (l)));
2099
 
  LISP a2 = car (cdr (cdr (cdr (l))));
2100
 
  LISP value = NULL;
2101
 
  n = get_c_long (ln);
2102
 
  for (j = 0; j < n; ++j)
2103
 
    value = funcall2 (f, a1, a2);
2104
 
  return (value);
2105
 
}
2106
 
 
2107
 
LISP
2108
 
benchmark_eval (LISP ln, LISP exp, LISP env)
2109
 
{
2110
 
  long j, n;
2111
 
  LISP value = NIL;
2112
 
  n = get_c_long (ln);
2113
 
  for (j = 0; j < n; ++j)
2114
 
    value = leval (exp, env);
2115
 
  return (value);
2116
 
}
2117
 
 
2118
 
LISP
2119
 
mapcar1 (LISP fcn, LISP in)
2120
 
{
2121
 
  LISP res, ptr, l;
2122
 
  if NULLP
2123
 
    (in) return (NIL);
2124
 
  res = ptr = cons (funcall1 (fcn, car (in)), NIL);
2125
 
  for (l = cdr (in); CONSP (l); l = CDR (l))
2126
 
    ptr = CDR (ptr) = cons (funcall1 (fcn, CAR (l)), CDR (ptr));
2127
 
  return (res);
2128
 
}
2129
 
 
2130
 
LISP
2131
 
mapcar2 (LISP fcn, LISP in1, LISP in2)
2132
 
{
2133
 
  LISP res, ptr, l1, l2;
2134
 
  if (NULLP (in1) || NULLP (in2))
2135
 
    return (NIL);
2136
 
  res = ptr = cons (funcall2 (fcn, car (in1), car (in2)), NIL);
2137
 
  for (l1 = cdr (in1), l2 = cdr (in2); CONSP (l1) && CONSP (l2); l1 = CDR (l1), l2 = CDR (l2))
2138
 
    ptr = CDR (ptr) = cons (funcall2 (fcn, CAR (l1), CAR (l2)), CDR (ptr));
2139
 
  return (res);
2140
 
}
2141
 
 
2142
 
LISP
2143
 
mapcar (LISP l)
2144
 
{
2145
 
  LISP fcn = car (l);
2146
 
  switch (get_c_long (llength (l)))
2147
 
    {
2148
 
    case 2:
2149
 
      return (mapcar1 (fcn, car (cdr (l))));
2150
 
    case 3:
2151
 
      return (mapcar2 (fcn, car (cdr (l)), car (cdr (cdr (l)))));
2152
 
    default:
2153
 
      return (my_err ("mapcar case not handled", l));
2154
 
    }
2155
 
}
2156
 
 
2157
 
LISP
2158
 
lfmod (LISP x, LISP y)
2159
 
{
2160
 
  if NFLONUMP
2161
 
    (x) my_err ("wta(1st) to fmod", x);
2162
 
  if NFLONUMP
2163
 
    (y) my_err ("wta(2nd) to fmod", y);
2164
 
  return (flocons (fmod (FLONM (x), FLONM (y))));
2165
 
}
2166
 
 
2167
 
LISP
2168
 
lsubset (LISP fcn, LISP l)
2169
 
{
2170
 
  LISP result = NIL, v;
2171
 
  for (v = l; CONSP (v); v = CDR (v))
2172
 
    if NNULLP
2173
 
      (funcall1 (fcn, CAR (v)))
2174
 
        result = cons (CAR (v), result);
2175
 
  return (nreverse (result));
2176
 
}
2177
 
 
2178
 
LISP
2179
 
ass (LISP x, LISP alist, LISP fcn)
2180
 
{
2181
 
  LISP l, tmp;
2182
 
  for (l = alist; CONSP (l); l = CDR (l))
2183
 
    {
2184
 
      tmp = CAR (l);
2185
 
      if (CONSP (tmp) && NNULLP (funcall2 (fcn, CAR (tmp), x)))
2186
 
        return (tmp);
2187
 
      INTERRUPT_CHECK ();
2188
 
    }
2189
 
  if EQ
2190
 
    (l, NIL) return (NIL);
2191
 
  return (my_err ("improper list to ass", alist));
2192
 
}
2193
 
 
2194
 
LISP
2195
 
append2 (LISP l1, LISP l2)
2196
 
{
2197
 
  long n;
2198
 
  LISP result = NIL, p1, p2;
2199
 
  n = nlength (l1) + nlength (l2);
2200
 
  while (n > 0)
2201
 
    {
2202
 
      result = cons (NIL, result);
2203
 
      --n;
2204
 
    }
2205
 
  for (p1 = result, p2 = l1; NNULLP (p2); p1 = cdr (p1), p2 = cdr (p2))
2206
 
    setcar (p1, car (p2));
2207
 
  for (p2 = l2; NNULLP (p2); p1 = cdr (p1), p2 = cdr (p2))
2208
 
    setcar (p1, car (p2));
2209
 
  return (result);
2210
 
}
2211
 
 
2212
 
LISP
2213
 
append (LISP l)
2214
 
{
2215
 
  STACK_CHECK (&l);
2216
 
  INTERRUPT_CHECK ();
2217
 
  if NULLP
2218
 
    (l)
2219
 
      return (NIL);
2220
 
  else if NULLP
2221
 
    (cdr (l))
2222
 
      return (car (l));
2223
 
  else if NULLP
2224
 
    (cddr (l))
2225
 
      return (append2 (car (l), cadr (l)));
2226
 
  else
2227
 
    return (append2 (car (l), append (cdr (l))));
2228
 
}
2229
 
 
2230
 
LISP
2231
 
listn (long n,...)
2232
 
{
2233
 
  LISP result, ptr;
2234
 
  long j;
2235
 
  va_list args;
2236
 
  for (j = 0, result = NIL; j < n; ++j)
2237
 
    result = cons (NIL, result);
2238
 
  va_start (args, n);
2239
 
  for (j = 0, ptr = result; j < n; ptr = cdr (ptr), ++j)
2240
 
    setcar (ptr, va_arg (args, LISP));
2241
 
  va_end (args);
2242
 
  return (result);
2243
 
}
2244
 
 
2245
 
 
2246
 
LISP
2247
 
fast_load (LISP lfname, LISP noeval)
2248
 
{
2249
 
  char *fname;
2250
 
  LISP stream;
2251
 
  LISP result = NIL, form;
2252
 
  fname = get_c_string (lfname);
2253
 
  if (siod_verbose_level >= 3)
2254
 
    {
2255
 
      put_st ("fast loading ");
2256
 
      put_st (fname);
2257
 
      put_st ("\n");
2258
 
    }
2259
 
  stream = listn (3,
2260
 
                  fopen_c (fname, "rb"),
2261
 
                  cons_array (flocons (100), NIL),
2262
 
                  flocons (0));
2263
 
  while (NEQ (stream, form = fast_read (stream)))
2264
 
    {
2265
 
      if (siod_verbose_level >= 5)
2266
 
        lprint (form, NIL);
2267
 
      if NULLP
2268
 
        (noeval)
2269
 
          leval (form, NIL);
2270
 
      else
2271
 
        result = cons (form, result);
2272
 
    }
2273
 
  fclose_l (car (stream));
2274
 
  if (siod_verbose_level >= 3)
2275
 
    put_st ("done.\n");
2276
 
  return (nreverse (result));
2277
 
}
2278
 
 
2279
 
static void
2280
 
shexstr (char *outstr, void *buff, size_t len)
2281
 
{
2282
 
  unsigned char *data = buff;
2283
 
  size_t j;
2284
 
  for (j = 0; j < len; ++j)
2285
 
    sprintf (&outstr[j * 2], "%02X", data[j]);
2286
 
}
2287
 
 
2288
 
LISP
2289
 
fast_save (LISP fname, LISP forms, LISP nohash, LISP comment)
2290
 
{
2291
 
  char *cname, msgbuff[100], databuff[50];
2292
 
  LISP stream, l;
2293
 
  FILE *f;
2294
 
  long l_one = 1;
2295
 
  double d_one = 1.0;
2296
 
  cname = get_c_string (fname);
2297
 
  if (siod_verbose_level >= 3)
2298
 
    {
2299
 
      put_st ("fast saving forms to ");
2300
 
      put_st (cname);
2301
 
      put_st ("\n");
2302
 
    }
2303
 
  stream = listn (3,
2304
 
                  fopen_c (cname, "wb"),
2305
 
                  NNULLP (nohash) ? NIL : cons_array (flocons (100), NIL),
2306
 
                  flocons (0));
2307
 
  f = get_c_file (car (stream), NULL);
2308
 
  if NNULLP
2309
 
    (comment)
2310
 
      fput_st (f, get_c_string (comment));
2311
 
  sprintf (msgbuff, "# Siod Binary Object Save File\n");
2312
 
  fput_st (f, msgbuff);
2313
 
  sprintf (msgbuff, "# sizeof(long) = %d\n# sizeof(double) = %d\n",
2314
 
           (int) sizeof (long), (int) sizeof (double));
2315
 
  fput_st (f, msgbuff);
2316
 
  shexstr (databuff, &l_one, sizeof (l_one));
2317
 
  sprintf (msgbuff, "# 1 = %s\n", databuff);
2318
 
  fput_st (f, msgbuff);
2319
 
  shexstr (databuff, &d_one, sizeof (d_one));
2320
 
  sprintf (msgbuff, "# 1.0 = %s\n", databuff);
2321
 
  fput_st (f, msgbuff);
2322
 
  for (l = forms; NNULLP (l); l = cdr (l))
2323
 
    fast_print (car (l), stream);
2324
 
  fclose_l (car (stream));
2325
 
  if (siod_verbose_level >= 3)
2326
 
    put_st ("done.\n");
2327
 
  return (NIL);
2328
 
}
2329
 
 
2330
 
void
2331
 
swrite1 (LISP stream, LISP data)
2332
 
{
2333
 
  FILE *f = get_c_file (stream, stdout);
2334
 
  switch TYPE
2335
 
    (data)
2336
 
    {
2337
 
    case tc_symbol:
2338
 
    case tc_string:
2339
 
      fput_st (f, get_c_string (data));
2340
 
      break;
2341
 
    default:
2342
 
      lprin1f (data, f);
2343
 
      break;
2344
 
    }
2345
 
}
2346
 
 
2347
 
LISP
2348
 
swrite (LISP stream, LISP table, LISP data)
2349
 
{
2350
 
  LISP value, key;
2351
 
  long j, k, m, n;
2352
 
  switch (TYPE (data))
2353
 
    {
2354
 
    case tc_symbol:
2355
 
      value = href (table, data);
2356
 
      if CONSP
2357
 
        (value)
2358
 
        {
2359
 
          swrite1 (stream, CAR (value));
2360
 
          if NNULLP
2361
 
            (CDR (value))
2362
 
              hset (table, data, CDR (value));
2363
 
        }
2364
 
      else
2365
 
        swrite1 (stream, value);
2366
 
      break;
2367
 
    case tc_lisp_array:
2368
 
      n = data->storage_as.lisp_array.dim;
2369
 
      if (n < 1)
2370
 
        my_err ("no object repeat count", data);
2371
 
      key = data->storage_as.lisp_array.data[0];
2372
 
      if NULLP
2373
 
        (value = href (table, key))
2374
 
          value = key;
2375
 
      else if CONSP
2376
 
        (value)
2377
 
        {
2378
 
          if NNULLP
2379
 
            (CDR (value))
2380
 
              hset (table, key, CDR (value));
2381
 
          value = CAR (value);
2382
 
        }
2383
 
      m = get_c_long (value);
2384
 
      for (k = 0; k < m; ++k)
2385
 
        for (j = 1; j < n; ++j)
2386
 
          swrite (stream, table, data->storage_as.lisp_array.data[j]);
2387
 
      break;
2388
 
    case tc_cons:
2389
 
      /* this should be handled similar to the array case */
2390
 
    default:
2391
 
      swrite1 (stream, data);
2392
 
    }
2393
 
  return (NIL);
2394
 
}
2395
 
 
2396
 
LISP
2397
 
ltrunc (LISP x)
2398
 
{
2399
 
  double cx = get_c_double (x);
2400
 
  return (flocons (cx < 0.0 ? ceil (cx) : floor (cx)));
2401
 
}
2402
 
 
2403
 
LISP
2404
 
lpow (LISP x, LISP y)
2405
 
{
2406
 
  if NFLONUMP
2407
 
    (x) my_err ("wta(1st) to pow", x);
2408
 
  if NFLONUMP
2409
 
    (y) my_err ("wta(2nd) to pow", y);
2410
 
  return (flocons (pow (FLONM (x), FLONM (y))));
2411
 
}
2412
 
 
2413
 
LISP
2414
 
lexp (LISP x)
2415
 
{
2416
 
  return (flocons (exp (get_c_double (x))));
2417
 
}
2418
 
 
2419
 
LISP
2420
 
llog (LISP x)
2421
 
{
2422
 
  return (flocons (log (get_c_double (x))));
2423
 
}
2424
 
 
2425
 
LISP
2426
 
lsin (LISP x)
2427
 
{
2428
 
  return (flocons (sin (get_c_double (x))));
2429
 
}
2430
 
 
2431
 
LISP
2432
 
lcos (LISP x)
2433
 
{
2434
 
  return (flocons (cos (get_c_double (x))));
2435
 
}
2436
 
 
2437
 
LISP
2438
 
ltan (LISP x)
2439
 
{
2440
 
  return (flocons (tan (get_c_double (x))));
2441
 
}
2442
 
 
2443
 
LISP
2444
 
lasin (LISP x)
2445
 
{
2446
 
  return (flocons (asin (get_c_double (x))));
2447
 
}
2448
 
 
2449
 
LISP
2450
 
lacos (LISP x)
2451
 
{
2452
 
  return (flocons (acos (get_c_double (x))));
2453
 
}
2454
 
 
2455
 
LISP
2456
 
latan (LISP x)
2457
 
{
2458
 
  return (flocons (atan (get_c_double (x))));
2459
 
}
2460
 
 
2461
 
LISP
2462
 
latan2 (LISP x, LISP y)
2463
 
{
2464
 
  return (flocons (atan2 (get_c_double (x), get_c_double (y))));
2465
 
}
2466
 
 
2467
 
LISP
2468
 
hexstr (LISP a)
2469
 
{
2470
 
  unsigned char *in;
2471
 
  char *out;
2472
 
  LISP result;
2473
 
  long j, dim;
2474
 
  in = (unsigned char *) get_c_string_dim (a, &dim);
2475
 
  result = strcons (dim * 2, NULL);
2476
 
  for (out = get_c_string (result), j = 0; j < dim; ++j, out += 2)
2477
 
    sprintf (out, "%02x", in[j]);
2478
 
  return (result);
2479
 
}
2480
 
 
2481
 
static int
2482
 
xdigitvalue (int c)
2483
 
{
2484
 
  if (g_ascii_isdigit (c))
2485
 
      return (c - '0');
2486
 
  if (g_ascii_isxdigit (c))
2487
 
      return (g_ascii_toupper (c) - 'A' + 10);
2488
 
  return (0);
2489
 
}
2490
 
 
2491
 
LISP
2492
 
hexstr2bytes (LISP a)
2493
 
{
2494
 
  char *in;
2495
 
  unsigned char *out;
2496
 
  LISP result;
2497
 
  long j, dim;
2498
 
  in = get_c_string (a);
2499
 
  dim = strlen (in) / 2;
2500
 
  result = arcons (tc_byte_array, dim, 0);
2501
 
  out = (unsigned char *) result->storage_as.string.data;
2502
 
  for (j = 0; j < dim; ++j)
2503
 
    out[j] = xdigitvalue (in[j * 2]) * 16 + xdigitvalue (in[j * 2 + 1]);
2504
 
  return (result);
2505
 
}
2506
 
 
2507
 
LISP
2508
 
getprop (LISP plist, LISP key)
2509
 
{
2510
 
  LISP l;
2511
 
  for (l = cdr (plist); NNULLP (l); l = cddr (l))
2512
 
    if EQ
2513
 
      (car (l), key)
2514
 
        return (cadr (l));
2515
 
    else
2516
 
      INTERRUPT_CHECK ();
2517
 
  return (NIL);
2518
 
}
2519
 
 
2520
 
LISP
2521
 
setprop (LISP plist, LISP key, LISP value)
2522
 
{
2523
 
  my_err ("not implemented", NIL);
2524
 
  return (NIL);
2525
 
}
2526
 
 
2527
 
LISP
2528
 
putprop (LISP plist, LISP value, LISP key)
2529
 
{
2530
 
  return (setprop (plist, key, value));
2531
 
}
2532
 
 
2533
 
LISP
2534
 
ltypeof (LISP obj)
2535
 
{
2536
 
  long x;
2537
 
  x = TYPE (obj);
2538
 
  switch (x)
2539
 
    {
2540
 
    case tc_nil:
2541
 
      return (cintern ("tc_nil"));
2542
 
    case tc_cons:
2543
 
      return (cintern ("tc_cons"));
2544
 
    case tc_flonum:
2545
 
      return (cintern ("tc_flonum"));
2546
 
    case tc_symbol:
2547
 
      return (cintern ("tc_symbol"));
2548
 
    case tc_subr_0:
2549
 
      return (cintern ("tc_subr_0"));
2550
 
    case tc_subr_1:
2551
 
      return (cintern ("tc_subr_1"));
2552
 
    case tc_subr_2:
2553
 
      return (cintern ("tc_subr_2"));
2554
 
    case tc_subr_2n:
2555
 
      return (cintern ("tc_subr_2n"));
2556
 
    case tc_subr_3:
2557
 
      return (cintern ("tc_subr_3"));
2558
 
    case tc_subr_4:
2559
 
      return (cintern ("tc_subr_4"));
2560
 
    case tc_subr_5:
2561
 
      return (cintern ("tc_subr_5"));
2562
 
    case tc_lsubr:
2563
 
      return (cintern ("tc_lsubr"));
2564
 
    case tc_fsubr:
2565
 
      return (cintern ("tc_fsubr"));
2566
 
    case tc_msubr:
2567
 
      return (cintern ("tc_msubr"));
2568
 
    case tc_closure:
2569
 
      return (cintern ("tc_closure"));
2570
 
    case tc_free_cell:
2571
 
      return (cintern ("tc_free_cell"));
2572
 
    case tc_string:
2573
 
      return (cintern ("tc_string"));
2574
 
    case tc_byte_array:
2575
 
      return (cintern ("tc_byte_array"));
2576
 
    case tc_double_array:
2577
 
      return (cintern ("tc_double_array"));
2578
 
    case tc_long_array:
2579
 
      return (cintern ("tc_long_array"));
2580
 
    case tc_lisp_array:
2581
 
      return (cintern ("tc_lisp_array"));
2582
 
    case tc_c_file:
2583
 
      return (cintern ("tc_c_file"));
2584
 
    default:
2585
 
      return (flocons (x));
2586
 
    }
2587
 
}
2588
 
 
2589
 
LISP
2590
 
caaar (LISP x)
2591
 
{
2592
 
  return (car (car (car (x))));
2593
 
}
2594
 
 
2595
 
LISP
2596
 
caadr (LISP x)
2597
 
{
2598
 
  return (car (car (cdr (x))));
2599
 
}
2600
 
 
2601
 
LISP
2602
 
cadar (LISP x)
2603
 
{
2604
 
  return (car (cdr (car (x))));
2605
 
}
2606
 
 
2607
 
LISP
2608
 
caddr (LISP x)
2609
 
{
2610
 
  return (car (cdr (cdr (x))));
2611
 
}
2612
 
 
2613
 
LISP
2614
 
cdaar (LISP x)
2615
 
{
2616
 
  return (cdr (car (car (x))));
2617
 
}
2618
 
 
2619
 
LISP
2620
 
cdadr (LISP x)
2621
 
{
2622
 
  return (cdr (car (cdr (x))));
2623
 
}
2624
 
 
2625
 
LISP
2626
 
cddar (LISP x)
2627
 
{
2628
 
  return (cdr (cdr (car (x))));
2629
 
}
2630
 
 
2631
 
LISP
2632
 
cdddr (LISP x)
2633
 
{
2634
 
  return (cdr (cdr (cdr (x))));
2635
 
}
2636
 
 
2637
 
LISP
2638
 
ash (LISP value, LISP n)
2639
 
{
2640
 
  long m, k;
2641
 
  m = get_c_long (value);
2642
 
  k = get_c_long (n);
2643
 
  if (k > 0)
2644
 
    m = m << k;
2645
 
  else
2646
 
    m = m >> (-k);
2647
 
  return (flocons (m));
2648
 
}
2649
 
 
2650
 
LISP
2651
 
bitand (LISP a, LISP b)
2652
 
{
2653
 
  return (flocons (get_c_long (a) & get_c_long (b)));
2654
 
}
2655
 
 
2656
 
LISP
2657
 
bitor (LISP a, LISP b)
2658
 
{
2659
 
  return (flocons (get_c_long (a) | get_c_long (b)));
2660
 
}
2661
 
 
2662
 
LISP
2663
 
bitxor (LISP a, LISP b)
2664
 
{
2665
 
  return (flocons (get_c_long (a) ^ get_c_long (b)));
2666
 
}
2667
 
 
2668
 
LISP
2669
 
bitnot (LISP a)
2670
 
{
2671
 
  return (flocons (~get_c_long (a)));
2672
 
}
2673
 
 
2674
 
LISP
2675
 
leval_prog1 (LISP args, LISP env)
2676
 
{
2677
 
  LISP retval, l;
2678
 
  retval = leval (car (args), env);
2679
 
  for (l = cdr (args); NNULLP (l); l = cdr (l))
2680
 
    leval (car (l), env);
2681
 
  return (retval);
2682
 
}
2683
 
 
2684
 
LISP
2685
 
leval_cond (LISP * pform, LISP * penv)
2686
 
{
2687
 
  LISP args, env, clause, value, next;
2688
 
  args = cdr (*pform);
2689
 
  env = *penv;
2690
 
  if NULLP
2691
 
    (args)
2692
 
    {
2693
 
      *pform = NIL;
2694
 
      return (NIL);
2695
 
    }
2696
 
  next = cdr (args);
2697
 
  while NNULLP
2698
 
    (next)
2699
 
    {
2700
 
      clause = car (args);
2701
 
      value = leval (car (clause), env);
2702
 
      if NNULLP
2703
 
        (value)
2704
 
        {
2705
 
          clause = cdr (clause);
2706
 
          if NULLP
2707
 
            (clause)
2708
 
            {
2709
 
              *pform = value;
2710
 
              return (NIL);
2711
 
            }
2712
 
          else
2713
 
            {
2714
 
              next = cdr (clause);
2715
 
              while (NNULLP (next))
2716
 
                {
2717
 
                  leval (car (clause), env);
2718
 
                  clause = next;
2719
 
                  next = cdr (next);
2720
 
                }
2721
 
              *pform = car (clause);
2722
 
              return (sym_t);
2723
 
            }
2724
 
        }
2725
 
      args = next;
2726
 
      next = cdr (next);
2727
 
    }
2728
 
  clause = car (args);
2729
 
  next = cdr (clause);
2730
 
  if NULLP
2731
 
    (next)
2732
 
    {
2733
 
      *pform = car (clause);
2734
 
      return (sym_t);
2735
 
    }
2736
 
  value = leval (car (clause), env);
2737
 
  if NULLP
2738
 
    (value)
2739
 
    {
2740
 
      *pform = NIL;
2741
 
      return (NIL);
2742
 
    }
2743
 
  clause = next;
2744
 
  next = cdr (next);
2745
 
  while (NNULLP (next))
2746
 
    {
2747
 
      leval (car (clause), env);
2748
 
      clause = next;
2749
 
      next = cdr (next);
2750
 
    }
2751
 
  *pform = car (clause);
2752
 
  return (sym_t);
2753
 
}
2754
 
 
2755
 
LISP
2756
 
lstrspn (LISP str1, LISP str2)
2757
 
{
2758
 
  return (flocons (strspn (get_c_string (str1), get_c_string (str2))));
2759
 
}
2760
 
 
2761
 
LISP
2762
 
lstrcspn (LISP str1, LISP str2)
2763
 
{
2764
 
  return (flocons (strcspn (get_c_string (str1), get_c_string (str2))));
2765
 
}
2766
 
 
2767
 
LISP
2768
 
substring_equal (LISP str1, LISP str2, LISP start, LISP end)
2769
 
{
2770
 
  char *cstr1, *cstr2;
2771
 
  long len1, n, s, e;
2772
 
  cstr1 = get_c_string_dim (str1, &len1);
2773
 
  cstr2 = get_c_string_dim (str2, &n);
2774
 
  s = NULLP (start) ? 0 : get_c_long (start);
2775
 
  e = NULLP (end) ? n : get_c_long (end);
2776
 
  if ((s < 0) || (s > e) || (e < 0) || (e > n) || ((e - s) != len1))
2777
 
    return (NIL);
2778
 
  return ((memcmp (cstr1, &cstr2[s], e - s) == 0) ? a_true_value () : NIL);
2779
 
}
2780
 
 
2781
 
LISP
2782
 
set_eval_history (LISP len, LISP circ)
2783
 
{
2784
 
  LISP data;
2785
 
  data = NULLP (len) ? len : make_list (len, NIL);
2786
 
  if NNULLP
2787
 
    (circ)
2788
 
      data = nconc (data, data);
2789
 
  setvar (cintern ("*eval-history-ptr*"), data, NIL);
2790
 
  setvar (cintern ("*eval-history*"), data, NIL);
2791
 
  return (len);
2792
 
}
2793
 
 
2794
 
static LISP
2795
 
parser_fasl (LISP ignore)
2796
 
{
2797
 
  return (closure (listn (3,
2798
 
                          NIL,
2799
 
                          cons_array (flocons (100), NIL),
2800
 
                          flocons (0)),
2801
 
                   leval (cintern ("parser_fasl_hook"), NIL)));
2802
 
}
2803
 
 
2804
 
static LISP
2805
 
parser_fasl_hook (LISP env, LISP f)
2806
 
{
2807
 
  LISP result;
2808
 
  setcar (env, f);
2809
 
  result = fast_read (env);
2810
 
  if EQ
2811
 
    (result, env)
2812
 
      return (get_eof_val ());
2813
 
  else
2814
 
    return (result);
2815
 
}
2816
 
 
2817
 
void
2818
 
init_subrs_a (void)
2819
 
{
2820
 
  init_subr_2 ("aref", aref1);
2821
 
  init_subr_3 ("aset", aset1);
2822
 
  init_lsubr ("string-append", string_append);
2823
 
  init_lsubr ("bytes-append", bytes_append);
2824
 
  init_subr_1 ("string-length", string_length);
2825
 
  init_subr_1 ("string-dimension", string_dim);
2826
 
  init_subr_1 ("read-from-string", read_from_string);
2827
 
  init_subr_3 ("print-to-string", print_to_string);
2828
 
  init_subr_2 ("cons-array", cons_array);
2829
 
  init_subr_2 ("sxhash", sxhash);
2830
 
  init_subr_2 ("equal?", equal);
2831
 
  init_subr_2 ("href", href);
2832
 
  init_subr_3 ("hset", hset);
2833
 
  init_subr_2 ("assoc", assoc);
2834
 
  init_subr_2 ("assv", assv);
2835
 
  init_subr_1 ("fast-read", fast_read);
2836
 
  init_subr_2 ("fast-print", fast_print);
2837
 
  init_subr_2 ("make-list", make_list);
2838
 
  init_subr_2 ("fread", lfread);
2839
 
  init_subr_2 ("fwrite", lfwrite);
2840
 
  init_subr_1 ("fflush", lfflush);
2841
 
  init_subr_1 ("length", llength);
2842
 
  init_subr_4 ("number->string", number2string);
2843
 
  init_subr_2 ("string->number", string2number);
2844
 
  init_subr_3 ("substring", substring);
2845
 
  init_subr_2 ("string-search", string_search);
2846
 
  init_subr_1 ("string-trim", string_trim);
2847
 
  init_subr_1 ("string-trim-left", string_trim_left);
2848
 
  init_subr_1 ("string-trim-right", string_trim_right);
2849
 
  init_subr_1 ("string-upcase", string_upcase);
2850
 
  init_subr_1 ("string-downcase", string_downcase);
2851
 
  init_subr_2 ("strcmp", lstrcmp);
2852
 
  init_subr_2 ("strcat", lstrcat);
2853
 
  init_subr_2 ("strcpy", lstrcpy);
2854
 
  init_subr_2 ("strbreakup", lstrbreakup);
2855
 
  init_subr_2 ("unbreakupstr", lstrunbreakup);
2856
 
  init_subr_1 ("string?", stringp);
2857
 
  gc_protect_sym (&sym_e, "e");
2858
 
  gc_protect_sym (&sym_f, "f");
2859
 
  gc_protect_sym (&sym_plists, "*plists*");
2860
 
  setvar (sym_plists, arcons (tc_lisp_array, 100, 1), NIL);
2861
 
  init_subr_3 ("lref-default", lref_default);
2862
 
  init_subr_3 ("larg-default", larg_default);
2863
 
  init_subr_3 ("lkey-default", lkey_default);
2864
 
  init_lsubr ("list", llist);
2865
 
  init_lsubr ("writes", writes);
2866
 
  init_subr_3 ("qsort", lqsort);
2867
 
  init_subr_2 ("string-lessp", string_lessp);
2868
 
  init_lsubr ("mapcar", mapcar);
2869
 
  init_subr_3 ("mapcar2", mapcar2);
2870
 
  init_subr_2 ("mapcar1", mapcar1);
2871
 
  init_subr_3 ("benchmark-funcall1", benchmark_funcall1);
2872
 
  init_lsubr ("benchmark-funcall2", benchmark_funcall2);
2873
 
  init_subr_3 ("benchmark-eval", benchmark_eval);
2874
 
  init_subr_2 ("fmod", lfmod);
2875
 
  init_subr_2 ("subset", lsubset);
2876
 
  init_subr_1 ("base64encode", base64encode);
2877
 
  init_subr_1 ("base64decode", base64decode);
2878
 
  init_subr_3 ("ass", ass);
2879
 
  init_subr_2 ("append2", append2);
2880
 
  init_lsubr ("append", append);
2881
 
  init_subr_4 ("fast-save", fast_save);
2882
 
  init_subr_2 ("fast-load", fast_load);
2883
 
  init_subr_3 ("swrite", swrite);
2884
 
  init_subr_1 ("trunc", ltrunc);
2885
 
  init_subr_2 ("pow", lpow);
2886
 
  init_subr_1 ("exp", lexp);
2887
 
  init_subr_1 ("log", llog);
2888
 
  init_subr_1 ("sin", lsin);
2889
 
  init_subr_1 ("cos", lcos);
2890
 
  init_subr_1 ("tan", ltan);
2891
 
  init_subr_1 ("asin", lasin);
2892
 
  init_subr_1 ("acos", lacos);
2893
 
  init_subr_1 ("atan", latan);
2894
 
  init_subr_2 ("atan2", latan2);
2895
 
  init_subr_1 ("typeof", ltypeof);
2896
 
  init_subr_1 ("caaar", caaar);
2897
 
  init_subr_1 ("caadr", caadr);
2898
 
  init_subr_1 ("cadar", cadar);
2899
 
  init_subr_1 ("caddr", caddr);
2900
 
  init_subr_1 ("cdaar", cdaar);
2901
 
  init_subr_1 ("cdadr", cdadr);
2902
 
  init_subr_1 ("cddar", cddar);
2903
 
  init_subr_1 ("cdddr", cdddr);
2904
 
  setvar (cintern ("*pi*"), flocons (atan (1.0) * 4), NIL);
2905
 
  init_base64_table ();
2906
 
  init_subr_1 ("array->hexstr", hexstr);
2907
 
  init_subr_1 ("hexstr->bytes", hexstr2bytes);
2908
 
  init_subr_3 ("ass", ass);
2909
 
  init_subr_2 ("bit-and", bitand);
2910
 
  init_subr_2 ("bit-or", bitor);
2911
 
  init_subr_2 ("bit-xor", bitxor);
2912
 
  init_subr_1 ("bit-not", bitnot);
2913
 
  init_msubr ("cond", leval_cond);
2914
 
  init_fsubr ("prog1", leval_prog1);
2915
 
  init_subr_2 ("strspn", lstrspn);
2916
 
  init_subr_2 ("strcspn", lstrcspn);
2917
 
  init_subr_4 ("substring-equal?", substring_equal);
2918
 
  init_subr_1 ("butlast", butlast);
2919
 
  init_subr_2 ("ash", ash);
2920
 
  init_subr_2 ("get", getprop);
2921
 
  init_subr_3 ("setprop", setprop);
2922
 
  init_subr_3 ("putprop", putprop);
2923
 
  init_subr_1 ("last", last);
2924
 
  init_subr_2 ("memq", memq);
2925
 
  init_subr_2 ("memv", memv);
2926
 
  init_subr_2 ("member", member);
2927
 
  init_subr_2 ("nth", nth);
2928
 
  init_subr_2 ("nconc", nconc);
2929
 
  init_subr_2 ("set-eval-history", set_eval_history);
2930
 
  init_subr_1 ("parser_fasl", parser_fasl);
2931
 
  setvar (cintern ("*parser_fasl.scm-loaded*"), a_true_value (), NIL);
2932
 
  init_subr_2 ("parser_fasl_hook", parser_fasl_hook);
2933
 
  init_sliba_version ();
2934
 
}