Fequal_including_properties fix
[bpt/emacs.git] / src / guile.c
CommitLineData
6376ba30
BT
1/* Guile utilities.
2
3Copyright (C) 2013 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19
20#include <config.h>
21#include "lisp.h"
22
23scm_t_bits c_closure_tag;
24
25typedef SCM (*c_closure_0_t) (void *);
26typedef SCM (*c_closure_1_t) (void *, SCM);
27typedef SCM (*c_closure_2_t) (void *, SCM, SCM);
28typedef SCM (*c_closure_3_t) (void *, SCM, SCM, SCM);
29typedef SCM (*c_closure_4_t) (void *, SCM, SCM, SCM, SCM);
30typedef SCM (*c_closure_5_t) (void *, SCM, SCM, SCM, SCM, SCM);
31typedef SCM (*c_closure_6_t) (void *, SCM, SCM, SCM, SCM, SCM, SCM);
32typedef SCM (*c_closure_7_t) (void *, SCM, SCM, SCM, SCM, SCM, SCM, SCM);
33
34SCM
35make_c_closure (SCM (*func) (), void *data, int req, int opt)
36{
37 SCM smob;
38
39 if (req > 3 || opt > 1)
40 emacs_abort ();
41
42 SCM_NEWSMOB2 (smob, c_closure_tag, func, data);
43 SCM_SET_SMOB_FLAGS (smob, req | (opt << 2));
44 return smob;
45}
46
47static SCM
48apply_c_closure (SCM c_closure, SCM args)
49{
50 int req, opt;
51 SCM cargs[7];
52 long nargs = scm_to_long (scm_length (args));
53 scm_t_bits flags = SCM_SMOB_FLAGS (c_closure);
54 scm_t_bits func = SCM_SMOB_DATA (c_closure);
55 void *data = (void *) SCM_SMOB_DATA_2 (c_closure);
56
57 req = flags & 3;
58 opt = (flags >> 2) & 1;
59
60 for (int i = 0; i < req + opt; i++)
61 {
62 if (scm_is_pair (args))
63 {
64 cargs[i] = scm_car (args);
65 args = scm_cdr (args);
66 }
67 else if (opt)
68 {
69 cargs[i] = SCM_UNDEFINED;
70 }
71 else
72 scm_wrong_num_args (c_closure);
73 }
74
75 switch (req + opt)
76 {
77 case 0: return ((c_closure_0_t) func) (data);
78 case 1: return ((c_closure_1_t) func) (data, cargs[0]);
79 case 2: return ((c_closure_2_t) func) (data, cargs[0], cargs[1]);
80 case 3: return ((c_closure_3_t) func) (data, cargs[0], cargs[1], cargs[2]);
81 case 4: return ((c_closure_4_t) func) (data, cargs[0], cargs[1], cargs[2], cargs[3]);
82 default:
83 emacs_abort ();
84 }
85}
86
87void
88init_guile (void)
89{
90 c_closure_tag = scm_make_smob_type ("c-closure", 0);
91 scm_set_smob_apply (c_closure_tag, apply_c_closure, 0, 0, 1);
92}