~ubuntu-branches/ubuntu/maverick/uim/maverick

« back to all changes in this revision

Viewing changes to uim/uim-scm.c

  • Committer: Bazaar Package Importer
  • Author(s): Masahito Omote
  • Date: 2008-06-25 19:56:33 UTC
  • mfrom: (3.1.18 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080625195633-8jljph4rfq00l8o7
Tags: 1:1.5.1-2
* uim-tcode: provide tutcode-custom.scm, tutcode-bushudic.scm
  and tutcode-rule.scm (Closes: #482659)
* Fix FTBFS: segv during compile (Closes: #483078).
  I personally think this bug is not specific for uim but is a optimization
  problem on gcc-4.3.1. (https://bugs.freedesktop.org/show_bug.cgi?id=16477)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 
3
 
  Copyright (c) 2003-2006 uim Project http://uim.freedesktop.org/
4
 
 
5
 
  All rights reserved.
6
 
 
7
 
  Redistribution and use in source and binary forms, with or without
8
 
  modification, are permitted provided that the following conditions
9
 
  are met:
10
 
 
11
 
  1. Redistributions of source code must retain the above copyright
12
 
     notice, this list of conditions and the following disclaimer.
13
 
  2. Redistributions in binary form must reproduce the above copyright
14
 
     notice, this list of conditions and the following disclaimer in the
15
 
     documentation and/or other materials provided with the distribution.
16
 
  3. Neither the name of authors nor the names of its contributors
17
 
     may be used to endorse or promote products derived from this software
18
 
     without specific prior written permission.
19
 
 
20
 
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
21
 
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 
  ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
24
 
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 
  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 
  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 
  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 
  SUCH DAMAGE.
31
 
 
32
 
*/
33
 
 
34
 
#include <config.h>
35
 
 
36
 
#include <stdio.h>
37
 
#include <stdlib.h>
38
 
#include <string.h>
39
 
#include <ctype.h>
40
 
 
41
 
#include "siod.h"
42
 
#include "uim-stdint.h"
43
 
#include "uim-scm.h"
44
 
#include "uim-compat-scm.h"
45
 
#include "uim-internal.h"
46
 
 
47
 
/*
48
 
  To avoid namespace pollution, all siod functions are defined as
49
 
  static and wrapped into uim-scm.c by direct inclusion rather than
50
 
  linked via public symbols. After elaboration of uim-scm API, the
51
 
  Scheme interpreter implementation can be switched to another one
52
 
  such as uim-scm-tinyscheme.c or uim-scm-gauche.c. But *.[hc] under
53
 
  uim/ and *.scm are still depending on siod in several ways. At least
54
 
  full test suite for *.scm files are required to migrate to another
55
 
  Scheme implementation.  -- YamaKen 2004-12-21, 2005-01-10
56
 
*/
57
 
#include "slib.c"
58
 
#ifdef UIM_COMPAT_SCM
59
 
#include "uim-compat-scm.c"
60
 
#endif
61
 
 
62
 
static void siod_init_subr(const char *name, long type, SUBR_FUNC fcn);
63
 
 
64
 
#if UIM_SCM_GCC4_READY_GC
65
 
static int uim_scm_c_int_internal(uim_lisp integer);
66
 
static const char *uim_scm_refer_c_str_internal(uim_lisp str);
67
 
static uim_lisp uim_scm_eval_internal(uim_lisp obj);
68
 
static void siod_init_subr_internal(const char *name, long type, SUBR_FUNC fcn);
69
 
static uim_lisp uim_scm_eval_c_string_internal(const char *str);
70
 
#endif
71
 
 
72
 
static uim_lisp true_sym;
73
 
static uim_lisp false_sym;
74
 
static uim_lisp protected_arg0;
75
 
 
76
 
static int uim_siod_fatal;
77
 
static FILE *uim_output = NULL;
78
 
 
79
 
#if UIM_SCM_GCC4_READY_GC
80
 
/* See also the comment about these variables in uim-scm.h */
81
 
uim_lisp *(*volatile uim_scm_gc_current_stack_ptr)(void)
82
 
  = &uim_scm_gc_current_stack_internal;
83
 
uim_lisp *(*volatile uim_scm_gc_protect_stack_ptr)(uim_lisp *)
84
 
  = &uim_scm_gc_protect_stack_internal;
85
 
#endif /* UIM_SCM_GCC4_READY_GC */
86
 
 
87
 
 
88
 
FILE *
89
 
uim_scm_get_output(void)
90
 
{
91
 
  return uim_output;
92
 
}
93
 
 
94
 
void
95
 
uim_scm_set_output(FILE *fp)
96
 
{
97
 
  uim_output = fp;
98
 
}
99
 
 
100
 
uim_bool
101
 
uim_scm_c_bool(uim_lisp val)
102
 
{
103
 
  return UIM_SCM_NFALSEP(val);
104
 
}
105
 
 
106
 
uim_lisp
107
 
uim_scm_make_bool(uim_bool val)
108
 
{
109
 
  return (val) ? uim_scm_t() : uim_scm_f();
110
 
}
111
 
 
112
 
int
113
 
uim_scm_c_int(uim_lisp integer)
114
 
#if UIM_SCM_GCC4_READY_GC
115
 
{
116
 
  int ret;
117
 
 
118
 
  UIM_SCM_GC_PROTECTED_CALL(ret, int, uim_scm_c_int_internal, (integer));
119
 
 
120
 
  return ret;
121
 
}
122
 
 
123
 
static int
124
 
uim_scm_c_int_internal(uim_lisp integer)
125
 
#endif
126
 
{
127
 
  int c_int;
128
 
#if !UIM_SCM_GCC4_READY_GC
129
 
  uim_lisp stack_start;
130
 
 
131
 
  /* stack protection is required for my_err() */
132
 
  uim_scm_gc_protect_stack(&stack_start);
133
 
#endif
134
 
 
135
 
  protected_arg0 = integer;
136
 
  c_int = get_c_int((LISP)integer);
137
 
 
138
 
#if !UIM_SCM_GCC4_READY_GC
139
 
  uim_scm_gc_unprotect_stack(&stack_start);
140
 
#endif
141
 
 
142
 
  return c_int;
143
 
}
144
 
 
145
 
uim_lisp
146
 
uim_scm_make_int(int integer)
147
 
{
148
 
  return (uim_lisp)intcons(integer);
149
 
}
150
 
 
151
 
char *
152
 
uim_scm_c_str(uim_lisp str)
153
 
{
154
 
  const char *c_str;
155
 
 
156
 
  c_str = uim_scm_refer_c_str(str);
157
 
 
158
 
  return (c_str) ? strdup(c_str) : NULL;
159
 
}
160
 
 
161
 
const char *
162
 
uim_scm_refer_c_str(uim_lisp str)
163
 
#if UIM_SCM_GCC4_READY_GC
164
 
{
165
 
  const char *ret;
166
 
 
167
 
  UIM_SCM_GC_PROTECTED_CALL(ret, const char *, uim_scm_refer_c_str_internal, (str));
168
 
 
169
 
  return ret;
170
 
}
171
 
 
172
 
static const char *
173
 
uim_scm_refer_c_str_internal(uim_lisp str)
174
 
#endif
175
 
{
176
 
  char *c_str;
177
 
#if !UIM_SCM_GCC4_READY_GC
178
 
  uim_lisp stack_start;
179
 
 
180
 
  /* stack protection is required for my_err() */
181
 
  uim_scm_gc_protect_stack(&stack_start);
182
 
#endif
183
 
 
184
 
  protected_arg0 = str;
185
 
  c_str = get_c_string((LISP)str);
186
 
 
187
 
#if !UIM_SCM_GCC4_READY_GC
188
 
  uim_scm_gc_unprotect_stack(&stack_start);
189
 
#endif
190
 
 
191
 
  return c_str;
192
 
}
193
 
 
194
 
uim_lisp
195
 
uim_scm_make_str(const char *str)
196
 
{
197
 
  int unknown_strlen = -1;
198
 
  return (uim_lisp)strcons(unknown_strlen, str);
199
 
}
200
 
 
201
 
char *
202
 
uim_scm_c_symbol(uim_lisp symbol)
203
 
{
204
 
  /* siod dependent */
205
 
  return uim_scm_c_str(symbol);
206
 
}
207
 
 
208
 
uim_lisp
209
 
uim_scm_make_symbol(const char *str)
210
 
{
211
 
  return (uim_lisp)rintern(str);
212
 
}
213
 
 
214
 
void *
215
 
uim_scm_c_ptr(uim_lisp ptr)
216
 
{
217
 
  return get_c_pointer((LISP)ptr);
218
 
}
219
 
 
220
 
uim_lisp
221
 
uim_scm_make_ptr(void *ptr)
222
 
{
223
 
  return (uim_lisp)ptrcons(ptr);
224
 
}
225
 
 
226
 
uim_func_ptr
227
 
uim_scm_c_func_ptr(uim_lisp func_ptr)
228
 
{
229
 
  return get_c_func_pointer((LISP)func_ptr);
230
 
}
231
 
 
232
 
uim_lisp
233
 
uim_scm_make_func_ptr(uim_func_ptr func_ptr)
234
 
{
235
 
  return (uim_lisp)funcptrcons(func_ptr);
236
 
}
237
 
 
238
 
void
239
 
uim_scm_gc_protect(uim_lisp *location)
240
 
{
241
 
  siod_gc_protect((LISP *)location);
242
 
}
243
 
 
244
 
void
245
 
uim_scm_gc_unprotect_stack(uim_lisp *stack_start)
246
 
{
247
 
  siod_gc_unprotect_stack((LISP *)stack_start);
248
 
}
249
 
 
250
 
#if UIM_SCM_GCC4_READY_GC
251
 
/* uim_scm_gc_current_stack_internal() is separated from
252
 
 * uim_scm_gc_protect_stack_internal() to avoid returning inaccurate
253
 
 * stack-start address. Don't add any code fragments such as
254
 
 * assertions or printfs to this function. It may alter the stack address.
255
 
 *   -- YamaKen 2006-06-04 */
256
 
uim_lisp *
257
 
uim_scm_gc_current_stack_internal(void)
258
 
{
259
 
  /*
260
 
   * &stack_start will be relocated to start of the frame of subsequent
261
 
   * function call
262
 
   */
263
 
  LISP stack_start;
264
 
 
265
 
  /* intentionally returns invalidated local address with a warning
266
 
   * suppression workaround */
267
 
  return (void *)(((uintptr_t)&stack_start | 1) ^ 1);
268
 
}
269
 
 
270
 
uim_lisp *
271
 
uim_scm_gc_protect_stack_internal(uim_lisp *stack_start)
272
 
{
273
 
  siod_gc_protect_stack((LISP *)stack_start);
274
 
 
275
 
  return (uim_lisp *)stack_start_ptr;
276
 
}
277
 
#else /* UIM_SCM_GCC4_READY_GC */
278
 
void
279
 
uim_scm_gc_protect_stack(uim_lisp *stack_start)
280
 
{
281
 
  siod_gc_protect_stack((LISP *)stack_start);
282
 
}
283
 
#endif /* UIM_SCM_GCC4_READY_GC */
284
 
 
285
 
uim_bool
286
 
uim_scm_is_alive(void)
287
 
{
288
 
  return (!uim_siod_fatal);
289
 
}
290
 
 
291
 
long
292
 
uim_scm_get_verbose_level(void)
293
 
{
294
 
  return siod_verbose_level;
295
 
}
296
 
 
297
 
void
298
 
uim_scm_set_verbose_level(long new_value)
299
 
{
300
 
  siod_verbose_level = new_value;
301
 
}
302
 
 
303
 
void
304
 
uim_scm_set_lib_path(const char *path)
305
 
{
306
 
  siod_set_lib_path(path);
307
 
}
308
 
 
309
 
uim_bool
310
 
uim_scm_load_file(const char *fn)
311
 
{
312
 
  uim_bool succeeded;
313
 
 
314
 
  if (!fn)
315
 
    return UIM_FALSE;
316
 
 
317
 
  UIM_EVAL_FSTRING1(NULL, "(*catch 'errobj (load \"%s\" #f #f))", fn);
318
 
  succeeded = UIM_SCM_FALSEP(uim_scm_return_value()); /* has not been caught */
319
 
 
320
 
  return succeeded;
321
 
}
322
 
 
323
 
uim_lisp
324
 
uim_scm_t(void)
325
 
{
326
 
  return (uim_lisp)true_sym;
327
 
}
328
 
 
329
 
uim_lisp
330
 
uim_scm_f(void)
331
 
{
332
 
  return (uim_lisp)false_sym;
333
 
}
334
 
 
335
 
uim_lisp
336
 
uim_scm_null_list(void)
337
 
{
338
 
  return (uim_lisp)NIL;
339
 
}
340
 
 
341
 
uim_bool
342
 
uim_scm_nullp(uim_lisp obj)
343
 
{
344
 
  return NULLP((LISP)obj);
345
 
}
346
 
 
347
 
uim_bool
348
 
uim_scm_consp(uim_lisp obj)
349
 
{
350
 
  return CONSP((LISP)obj);
351
 
}
352
 
 
353
 
uim_bool
354
 
uim_scm_integerp(uim_lisp obj)
355
 
{
356
 
  return INTNUMP((LISP)obj);
357
 
}
358
 
 
359
 
uim_bool
360
 
uim_scm_stringp(uim_lisp obj)
361
 
{
362
 
  return STRINGP((LISP)obj);
363
 
}
364
 
 
365
 
uim_bool
366
 
uim_scm_eq(uim_lisp a, uim_lisp b)
367
 
{
368
 
  return EQ(a, b);
369
 
}
370
 
 
371
 
uim_bool
372
 
uim_scm_string_equal(uim_lisp a, uim_lisp b)
373
 
{
374
 
  return UIM_SCM_NFALSEP((uim_lisp)string_equal((LISP)a, (LISP)b));
375
 
}
376
 
 
377
 
uim_lisp
378
 
uim_scm_eval(uim_lisp obj)
379
 
#if UIM_SCM_GCC4_READY_GC
380
 
{
381
 
  uim_lisp ret;
382
 
 
383
 
  UIM_SCM_GC_PROTECTED_CALL(ret, uim_lisp, uim_scm_eval_internal, (obj));
384
 
 
385
 
  return ret;
386
 
}
387
 
 
388
 
static uim_lisp
389
 
uim_scm_eval_internal(uim_lisp obj)
390
 
#endif
391
 
{
392
 
  uim_lisp ret;  /* intentionally outside of next stack_start */
393
 
#if !UIM_SCM_GCC4_READY_GC
394
 
  uim_lisp stack_start;
395
 
 
396
 
  uim_scm_gc_protect_stack(&stack_start);
397
 
#endif
398
 
 
399
 
  ret = (uim_lisp)leval((LISP)obj, NIL);
400
 
 
401
 
#if !UIM_SCM_GCC4_READY_GC
402
 
  uim_scm_gc_unprotect_stack(&stack_start);
403
 
#endif
404
 
 
405
 
  return ret;
406
 
}
407
 
 
408
 
uim_lisp
409
 
uim_scm_eval_c_string(const char *str)
410
 
#if UIM_SCM_GCC4_READY_GC
411
 
{
412
 
  uim_lisp ret;
413
 
 
414
 
  UIM_SCM_GC_PROTECTED_CALL(ret, uim_lisp, uim_scm_eval_c_string_internal, (str));
415
 
 
416
 
  return ret;
417
 
}
418
 
 
419
 
static uim_lisp
420
 
uim_scm_eval_c_string_internal(const char *str)
421
 
#endif
422
 
{
423
 
  repl_c_string((char *)str, 0, 0);
424
 
  return uim_scm_return_value();
425
 
}
426
 
 
427
 
uim_lisp
428
 
uim_scm_return_value(void)
429
 
{
430
 
  return (uim_lisp)siod_return_value();
431
 
}
432
 
 
433
 
uim_lisp
434
 
uim_scm_car(uim_lisp cell)
435
 
{
436
 
  return (uim_lisp)car((LISP)cell);
437
 
}
438
 
 
439
 
uim_lisp
440
 
uim_scm_cdr(uim_lisp cell)
441
 
{
442
 
  return (uim_lisp)cdr((LISP)cell);
443
 
}
444
 
 
445
 
uim_lisp
446
 
uim_scm_cadr(uim_lisp cell)
447
 
{
448
 
  return (uim_lisp)cadr((LISP)cell);
449
 
}
450
 
 
451
 
uim_lisp
452
 
uim_scm_caar(uim_lisp cell)
453
 
{
454
 
  return (uim_lisp)caar((LISP)cell);
455
 
}
456
 
 
457
 
uim_lisp
458
 
uim_scm_cdar(uim_lisp cell)
459
 
{
460
 
  return (uim_lisp)cdar((LISP)cell);
461
 
}
462
 
 
463
 
uim_lisp
464
 
uim_scm_cddr(uim_lisp cell)
465
 
{
466
 
  return (uim_lisp)cddr((LISP)cell);
467
 
}
468
 
 
469
 
uim_lisp
470
 
uim_scm_cons(uim_lisp car, uim_lisp cdr)
471
 
{
472
 
  return (uim_lisp)cons((LISP)car, (LISP)cdr);
473
 
}
474
 
 
475
 
uim_lisp
476
 
uim_scm_length(uim_lisp list)
477
 
{
478
 
  /*
479
 
    although nlength() of siod returns length of anything, this
480
 
    function should be called only for list
481
 
  */
482
 
  return (uim_lisp)uim_scm_make_int(nlength((LISP)list));
483
 
}
484
 
 
485
 
uim_lisp
486
 
uim_scm_reverse(uim_lisp cell)
487
 
{
488
 
  return (uim_lisp)reverse((LISP)cell);
489
 
}
490
 
 
491
 
uim_bool
492
 
uim_scm_require_file(const char *fn)
493
 
{
494
 
  uim_bool succeeded;
495
 
 
496
 
  if (!fn)
497
 
    return UIM_FALSE;
498
 
 
499
 
  UIM_EVAL_FSTRING2(NULL, "(eq? '*%s-loaded* (*catch 'errobj (require \"%s\")))", fn, fn);
500
 
  succeeded = uim_scm_c_bool(uim_scm_return_value());
501
 
 
502
 
  return succeeded;
503
 
}
504
 
 
505
 
static void
506
 
siod_init_subr(const char *name, long type, SUBR_FUNC fcn)
507
 
#if UIM_SCM_GCC4_READY_GC
508
 
{
509
 
  UIM_SCM_GC_PROTECTED_CALL_VOID(siod_init_subr_internal, (name, type, fcn));
510
 
}
511
 
 
512
 
static void
513
 
siod_init_subr_internal(const char *name, long type, SUBR_FUNC fcn)
514
 
{
515
 
  init_subr(name, type, fcn);
516
 
}
517
 
#else
518
 
{
519
 
  uim_lisp stack_start;
520
 
 
521
 
  uim_scm_gc_protect_stack(&stack_start);
522
 
  init_subr(name, type, fcn);
523
 
  uim_scm_gc_unprotect_stack(&stack_start);
524
 
}
525
 
#endif
526
 
 
527
 
void
528
 
uim_scm_init_subr_0(const char *name, uim_lisp (*fcn)(void))
529
 
{
530
 
  siod_init_subr(name, tc_subr_0, (SUBR_FUNC)fcn);
531
 
}
532
 
 
533
 
void
534
 
uim_scm_init_subr_1(const char *name, uim_lisp (*fcn)(uim_lisp))
535
 
{
536
 
  siod_init_subr(name, tc_subr_1, (SUBR_FUNC)fcn);
537
 
}
538
 
 
539
 
void
540
 
uim_scm_init_subr_2(const char *name, uim_lisp (*fcn)(uim_lisp, uim_lisp))
541
 
{
542
 
  siod_init_subr(name, tc_subr_2, (SUBR_FUNC)fcn);
543
 
}
544
 
 
545
 
void
546
 
uim_scm_init_subr_3(const char *name, uim_lisp (*fcn)(uim_lisp, uim_lisp, uim_lisp))
547
 
{
548
 
  siod_init_subr(name, tc_subr_3, (SUBR_FUNC)fcn);
549
 
}
550
 
 
551
 
void
552
 
uim_scm_init_subr_4(const char *name, uim_lisp (*fcn)(uim_lisp, uim_lisp, uim_lisp,
553
 
                                                uim_lisp))
554
 
{
555
 
  siod_init_subr(name, tc_subr_4, (SUBR_FUNC)fcn);
556
 
}
557
 
 
558
 
void
559
 
uim_scm_init_subr_5(const char *name, uim_lisp (*fcn)(uim_lisp, uim_lisp, uim_lisp,
560
 
                                                uim_lisp, uim_lisp))
561
 
{
562
 
  siod_init_subr(name, tc_subr_5, (SUBR_FUNC)fcn);
563
 
}
564
 
 
565
 
static void
566
 
exit_hook(void)
567
 
{
568
 
  uim_siod_fatal = 1;
569
 
}
570
 
 
571
 
void
572
 
uim_scm_init(const char *verbose_level)
573
 
{
574
 
  char *siod_argv[] =
575
 
    {
576
 
      "siod",
577
 
      "-v2",          /* siod_verbose_level */
578
 
      "-h16384:64",   /* heap_size(unit: lisp objects):nheaps */
579
 
      "-t16384",      /* heap_alloc_threshold (unit: lisp objects) */
580
 
      "-o1024",       /* obarray_dim (hash size of symbol table) */
581
 
      "-s262144",     /* stack_size (unit: bytes) */
582
 
      "-n128"         /* inums_dim (preallocated fixnum objects) */
583
 
    };
584
 
  char verbose_argv[] = "-v2";
585
 
  int siod_argc, warnflag = 1;
586
 
 
587
 
  if (!uim_output) {
588
 
    uim_output = stderr;
589
 
  }
590
 
 
591
 
  if (verbose_level) {
592
 
    if (isdigit((int)verbose_level[0])) {
593
 
      if (isdigit((int)verbose_level[1]))
594
 
        verbose_argv[2] = '9';  /* SIOD's max verbose level is 5 */
595
 
      else
596
 
        verbose_argv[2] = verbose_level[0];
597
 
    }
598
 
    siod_argv[1] = verbose_argv;
599
 
  }
600
 
  /* init siod */
601
 
  siod_argc = sizeof(siod_argv) / sizeof(char *);
602
 
  siod_init(siod_argc, siod_argv, warnflag, uim_output);
603
 
  set_fatal_exit_hook(exit_hook);
604
 
 
605
 
  true_sym  = (uim_lisp)siod_true_value();
606
 
#if 0
607
 
  false_sym = (uim_lisp)siod_false_value();
608
 
#else
609
 
  /* false_sym has to be NIL until bug #617 and #642 are fixed
610
 
   * -- YamaKen
611
 
   */
612
 
  false_sym = (uim_lisp)NIL;
613
 
#endif
614
 
  uim_scm_gc_protect(&true_sym);
615
 
  uim_scm_gc_protect(&false_sym);
616
 
 
617
 
  protected_arg0 = uim_scm_f();
618
 
  uim_scm_gc_protect(&protected_arg0);
619
 
}
620
 
 
621
 
void
622
 
uim_scm_quit(void)
623
 
{
624
 
  siod_quit();
625
 
  uim_output = NULL;
626
 
}