]> git.donarmstrong.com Git - lilypond.git/blob - lily/ly-module.cc
* lily/stencil.cc (translate): remove absolute dimension.
[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--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "ly-module.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_scheme_function ("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 ly_module_define (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   Check me. This is NOT an actual import. It just copies the
71   definitions.
72
73   If a variable in changed in SRC, we DEST doesn't see the
74   definitions.
75  */
76 LY_DEFINE (ly_import_module, "ly:import-module",
77            2, 0, 0, (SCM dest, SCM src),
78            "Import all bindings from module SRC into DEST.")
79 {
80   SCM_VALIDATE_MODULE (1, src);
81   scm_internal_hash_fold ((Hash_cl_func) &ly_module_define, (void*) dest,
82                           SCM_EOL, SCM_MODULE_OBARRAY (src));
83   return SCM_UNSPECIFIED;
84 }
85
86 static SCM
87 accumulate_symbol (void *closure, SCM key, SCM val, SCM result)
88 {
89   (void) closure;
90   (void) val;
91   return scm_cons (key, result);
92 }
93
94 SCM
95 ly_module_symbols (SCM mod)
96 {
97   SCM_VALIDATE_MODULE (1, mod);
98   
99   SCM obarr= SCM_MODULE_OBARRAY (mod);
100   return scm_internal_hash_fold ((Hash_cl_func) &accumulate_symbol,
101                                  NULL, SCM_EOL, obarr); 
102 }
103
104 static SCM
105 entry_to_alist (void *closure, SCM key, SCM val, SCM result)
106 {
107   (void) closure;
108   if (scm_variable_bound_p  (val) == SCM_BOOL_T)
109     {
110       return scm_cons (scm_cons (key, scm_variable_ref (val)), result);
111     }
112   else
113     {
114       programming_error ("Unbound variable in module."); 
115       return result;
116     }
117 }
118
119 LY_DEFINE (ly_module2alist, "ly:module->alist",
120            1, 0, 0, (SCM mod),
121            "Dump the contents of  module @var{mod} as an alist.")
122 {
123   SCM_VALIDATE_MODULE (1, mod);
124   SCM obarr= SCM_MODULE_OBARRAY (mod);
125
126   return scm_internal_hash_fold ((Hash_cl_func) &entry_to_alist, NULL, SCM_EOL, obarr); 
127 }
128
129 /* Lookup SYM, but don't give error when it is not defined.  */
130 SCM
131 ly_module_lookup (SCM module, SCM sym)
132 {
133 #define FUNC_NAME __FUNCTION__
134   SCM_VALIDATE_MODULE (1, module);
135
136   return scm_sym2var (sym, scm_module_lookup_closure (module), SCM_BOOL_F);
137 #undef FUNC_NAME
138 }
139
140 /* Lookup SYM in a list of modules, which do not have to be related.
141    Return the first instance. */
142 LY_DEFINE (ly_modules_lookup, "ly:modules-lookup",
143            2, 1, 0,
144            (SCM modules, SCM sym, SCM def),
145            "Lookup @var{sym} in the list @var{modules}, "
146            "returning the first occurence.  "
147            "If not found, return @var{default}, or @code{#f}.")
148 {
149   for (SCM s = modules; scm_is_pair (s); s = scm_cdr (s))
150     {
151       SCM mod = scm_car (s);
152       SCM v = ly_module_lookup (mod, sym);
153       if (SCM_VARIABLEP (v) && SCM_VARIABLE_REF (v) != SCM_UNDEFINED)
154         return scm_variable_ref(v);
155     }
156
157   if (def != SCM_UNDEFINED)
158     return def;
159   return SCM_BOOL_F;
160 }
161
162 void
163 ly_export (SCM module, SCM namelist)
164 {
165   static SCM export_function;
166   if (!export_function)
167     export_function = scm_permanent_object (scm_c_lookup ("module-export!"));
168   
169   scm_call_2 (SCM_VARIABLE_REF (export_function), module, namelist);
170 }
171
172 void
173 ly_reexport_module (SCM mod)
174 {
175   ly_export (mod, ly_module_symbols (mod));
176 }