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