]> git.donarmstrong.com Git - lilypond.git/blob - lily/ly-module.cc
*** empty log message ***
[lilypond.git] / lily / ly-module.cc
1 /*
2   ly-module.cc -- implement guile module stuff.
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2002--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "lily-guile.hh"
10 #include "warn.hh"
11 #include "main.hh"
12 #include "string.hh"
13
14 #define FUNC_NAME __FUNCTION__
15
16 static int module_count;
17
18 void
19 ly_init_anonymous_module (void *data)
20 {
21   (void) data;
22 }
23
24 SCM
25 ly_make_anonymous_module (bool safe)
26 {
27   SCM mod = SCM_EOL;
28   if (!safe)
29     {
30       String s = "*anonymous-ly-" + to_string (module_count++) + "*";
31       mod = scm_c_define_module (s.to_str0 (), ly_init_anonymous_module, 0);
32       ly_use_module (mod, global_lily_module);
33     }
34   else
35     {
36       SCM proc = ly_lily_module_constant ("make-safe-lilypond-module");
37       mod = scm_call_0 (proc);
38     }
39   return mod;
40 }
41
42 SCM
43 ly_use_module (SCM mod, SCM used)
44 {
45   SCM expr
46     = scm_list_3 (ly_symbol2scm ("module-use!"),
47                   mod,
48                   scm_list_2 (ly_symbol2scm ("module-public-interface"),
49                               used));
50
51   return scm_eval (expr, global_lily_module);
52 }
53
54 #define FUNC_NAME __FUNCTION__
55
56 static SCM
57 module_define_closure_func (void *closure, SCM key, SCM val, SCM result)
58 {
59   (void) result;
60   SCM module = (SCM) closure;
61   if (scm_variable_bound_p (val) == SCM_BOOL_T)
62     scm_module_define (module, key, scm_variable_ref (val));
63   return SCM_EOL;
64 }
65
66 /* Ugh signature of scm_internal_hash_fold () is inaccurate.  */
67 typedef SCM (*Hash_cl_func) ();
68
69 /*
70   If a variable in changed in SRC, we DEST doesn't see the
71   definitions.
72 */
73 LY_DEFINE (ly_module_copy, "ly:module-copy",
74            2, 0, 0, (SCM dest, SCM src),
75            "Copy all bindings from module SRC into DEST.")
76 {
77   SCM_VALIDATE_MODULE (1, src);
78   scm_internal_hash_fold ((Hash_cl_func) & module_define_closure_func,
79                           (void *) dest,
80                           SCM_EOL, SCM_MODULE_OBARRAY (src));
81   return SCM_UNSPECIFIED;
82 }
83
84 static SCM
85 accumulate_symbol (void *closure, SCM key, SCM val, SCM result)
86 {
87   (void) closure;
88   (void) val;
89   return scm_cons (key, result);
90 }
91
92 SCM
93 ly_module_symbols (SCM mod)
94 {
95   SCM_VALIDATE_MODULE (1, mod);
96
97   SCM obarr = SCM_MODULE_OBARRAY (mod);
98   return scm_internal_hash_fold ((Hash_cl_func) & accumulate_symbol,
99                                  NULL, SCM_EOL, obarr);
100 }
101
102 static SCM
103 entry_to_alist (void *closure, SCM key, SCM val, SCM result)
104 {
105   (void) closure;
106   if (scm_variable_bound_p (val) == SCM_BOOL_T)
107     return scm_cons (scm_cons (key, scm_variable_ref (val)), result);
108   programming_error ("unbound variable in module");
109   return result;
110 }
111
112 LY_DEFINE (ly_module2alist, "ly:module->alist",
113            1, 0, 0, (SCM mod),
114            "Dump the contents of  module @var{mod} as an alist.")
115 {
116   SCM_VALIDATE_MODULE (1, mod);
117   SCM obarr = SCM_MODULE_OBARRAY (mod);
118
119   return scm_internal_hash_fold ((Hash_cl_func) & entry_to_alist, NULL, SCM_EOL, obarr);
120 }
121
122 /* Lookup SYM, but don't give error when it is not defined.  */
123 SCM
124 ly_module_lookup (SCM module, SCM sym)
125 {
126 #define FUNC_NAME __FUNCTION__
127   SCM_VALIDATE_MODULE (1, module);
128
129   return scm_sym2var (sym, scm_module_lookup_closure (module), SCM_BOOL_F);
130 #undef FUNC_NAME
131 }
132
133 /* Lookup SYM in a list of modules, which do not have to be related.
134    Return the first instance. */
135 LY_DEFINE (ly_modules_lookup, "ly:modules-lookup",
136            2, 1, 0,
137            (SCM modules, SCM sym, SCM def),
138            "Lookup @var{sym} in the list @var{modules}, "
139            "returning the first occurence.  "
140            "If not found, return @var{default}, or @code{#f}.")
141 {
142   for (SCM s = modules; scm_is_pair (s); s = scm_cdr (s))
143     {
144       SCM mod = scm_car (s);
145       SCM v = ly_module_lookup (mod, sym);
146       if (SCM_VARIABLEP (v) && SCM_VARIABLE_REF (v) != SCM_UNDEFINED)
147         return scm_variable_ref (v);
148     }
149
150   if (def != SCM_UNDEFINED)
151     return def;
152   return SCM_BOOL_F;
153 }
154
155 void
156 ly_export (SCM module, SCM namelist)
157 {
158   static SCM export_function;
159   if (!export_function)
160     export_function = scm_permanent_object (scm_c_lookup ("module-export!"));
161
162   scm_call_2 (SCM_VARIABLE_REF (export_function), module, namelist);
163 }
164
165 void
166 ly_reexport_module (SCM mod)
167 {
168   ly_export (mod, ly_module_symbols (mod));
169 }