]> git.donarmstrong.com Git - lilypond.git/blob - lily/ly-module.cc
* lily/modified-font-metric.cc (text_dimension): try
[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_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     {
108       return scm_cons (scm_cons (key, scm_variable_ref (val)), result);
109     }
110   else
111     {
112       programming_error ("Unbound variable in module."); 
113       return result;
114     }
115 }
116
117 LY_DEFINE (ly_module2alist, "ly:module->alist",
118            1, 0, 0, (SCM mod),
119            "Dump the contents of  module @var{mod} as an alist.")
120 {
121   SCM_VALIDATE_MODULE (1, mod);
122   SCM obarr = SCM_MODULE_OBARRAY (mod);
123
124   return scm_internal_hash_fold ((Hash_cl_func) &entry_to_alist, NULL, SCM_EOL, obarr); 
125 }
126
127 /* Lookup SYM, but don't give error when it is not defined.  */
128 SCM
129 ly_module_lookup (SCM module, SCM sym)
130 {
131 #define FUNC_NAME __FUNCTION__
132   SCM_VALIDATE_MODULE (1, module);
133
134   return scm_sym2var (sym, scm_module_lookup_closure (module), SCM_BOOL_F);
135 #undef FUNC_NAME
136 }
137
138 /* Lookup SYM in a list of modules, which do not have to be related.
139    Return the first instance. */
140 LY_DEFINE (ly_modules_lookup, "ly:modules-lookup",
141            2, 1, 0,
142            (SCM modules, SCM sym, SCM def),
143            "Lookup @var{sym} in the list @var{modules}, "
144            "returning the first occurence.  "
145            "If not found, return @var{default}, or @code{#f}.")
146 {
147   for (SCM s = modules; scm_is_pair (s); s = scm_cdr (s))
148     {
149       SCM mod = scm_car (s);
150       SCM v = ly_module_lookup (mod, sym);
151       if (SCM_VARIABLEP (v) && SCM_VARIABLE_REF (v) != SCM_UNDEFINED)
152         return scm_variable_ref(v);
153     }
154
155   if (def != SCM_UNDEFINED)
156     return def;
157   return SCM_BOOL_F;
158 }
159
160 void
161 ly_export (SCM module, SCM namelist)
162 {
163   static SCM export_function;
164   if (!export_function)
165     export_function = scm_permanent_object (scm_c_lookup ("module-export!"));
166   
167   scm_call_2 (SCM_VARIABLE_REF (export_function), module, namelist);
168 }
169
170 void
171 ly_reexport_module (SCM mod)
172 {
173   ly_export (mod, ly_module_symbols (mod));
174 }