]> git.donarmstrong.com Git - lilypond.git/blob - lily/program-option.cc
* lily/program-option.cc: rename from scm-option.cc
[lilypond.git] / lily / program-option.cc
1 /*
2   scm-option.cc -- implement option setting from Scheme
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2001--2005  Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "program-option.hh"
10
11 #include <cstdio>
12 #include <string.h>
13
14 #include "string-convert.hh"
15 #include "protected-scm.hh"
16 #include "parse-scm.hh"
17 #include "warn.hh"
18 #include "main.hh"
19
20
21 /* Write midi as formatted ascii stream? */
22 bool do_midi_debugging_global;
23
24 /*
25   Backwards compatibility.
26 */
27 bool lily_1_8_relative = false;
28 bool lily_1_8_compatibility_used = false;
29
30 /*
31   crash if internally the wrong type is used for a grob property.
32 */
33 bool do_internal_type_checking_global;
34
35
36 static Lilypond_option_init options[] = {
37   {"point-and-click", "#t",
38    "use point & click"},
39   {"midi-debug", "#f",
40    "generate human readable MIDI",},
41   {"internal-type-checking", "#f",
42    "check every property assignment for types"},
43   {"parse-protect", "#t",
44    "continue when finding errors in inline\n" 
45    "scheme are caught in the parser. If off, halt \n"
46    "on errors, and print a stack trace."},
47   {"old-relative", "#f",
48    "relative for simultaneous music works\n"
49    "similar to chord syntax"},
50   {"resolution", "90",
51    "resolution for generating bitmaps"},
52   {"preview-include-book-title", "#t",
53    "include book-titles in preview images."},
54   {"gs-font-load", "#f",
55    "load fonts via Ghostscript."},
56   {0,0,0},
57 };
58
59 Protected_scm option_hash_;
60
61 void internal_set_option (SCM var, SCM val)
62 {
63   scm_hashq_set_x (option_hash_, var, val);
64   
65   if (var == ly_symbol2scm ("midi-debug"))
66     {
67       do_midi_debugging_global = to_boolean (val);
68       val = scm_from_bool (to_boolean (val));
69     }
70   else if (var == ly_symbol2scm ("point-and-click"))
71     {
72       point_and_click_global = to_boolean (val);
73       val = scm_from_bool (to_boolean (val));
74     }
75   else if (var == ly_symbol2scm ("parse-protect"))
76     {
77       parse_protect_global = to_boolean (val);
78       val = scm_from_bool (to_boolean (val));
79     }
80   else if (var == ly_symbol2scm ("internal-type-checking"))
81     {
82       do_internal_type_checking_global = to_boolean (val);
83       val = scm_from_bool (to_boolean (val));
84     }
85   else if (var == ly_symbol2scm ("old-relative"))
86     {
87       lily_1_8_relative = to_boolean (val);
88       /*  Needs to be reset for each file that uses this option.  */
89       lily_1_8_compatibility_used = to_boolean (val);
90       val = scm_from_bool (to_boolean (val));
91     }
92 }
93
94 const int HELP_INDENT = 30; 
95 const int INDENT = 2; 
96 const int SEPARATION = 5; 
97
98 static String
99 get_help_string ()
100 {
101   String help ("Options supported by ly:set-option\n\n");
102   for (Lilypond_option_init *p = options; p->name_; p ++)
103     {
104       String opt_spec =
105         String_convert::char_string (' ', INDENT)
106         + String (p->name_)
107         + " ("
108         + String (p->init_)
109         + ")";
110         
111
112       if (opt_spec.length () + SEPARATION > HELP_INDENT)
113         {
114           opt_spec += "\n"
115             + String_convert::char_string (' ', HELP_INDENT);
116         }
117       else
118         opt_spec += String_convert::char_string (' ', HELP_INDENT - opt_spec.length ());
119       
120       String opt_help = p->descr_;
121       opt_help.substitute (String ("\n"),
122                            String ("\n")
123                            + String_convert::char_string (' ', HELP_INDENT));
124       
125       help += opt_spec + opt_help + "\n";
126     }
127   
128   help += String ("\n");
129   return help;
130 }
131
132 static void
133 init_program_options ()
134 {
135   option_hash_ = scm_c_make_hash_table (11);
136
137   for (Lilypond_option_init *p = options; p->name_; p ++)
138     {
139       SCM sym = ly_symbol2scm (p->name_);
140       SCM val = scm_c_eval_string (p->init_);
141
142       internal_set_option (sym, val);
143     }
144
145   String help = get_help_string ();
146
147
148
149   internal_set_option (ly_symbol2scm ("help"),
150                        scm_makfrom0str (help.to_str0 ()));
151 }
152
153 ADD_SCM_INIT_FUNC(scm_option, init_program_options);
154
155
156 /*
157   This interface to option setting is meant for setting options are
158   useful to a limited audience. The reason for this interface is that
159   making command line options clutters up the command-line option name
160   space.
161
162 */
163
164 Protected_scm command_line_settings = SCM_EOL;
165
166 LY_DEFINE (ly_option_usage, "ly:option-usage", 0, 0, 0, (),
167            "Print ly:set-option usage")
168 {
169   SCM stdout = scm_current_output_port();
170   scm_display (ly_get_option (ly_symbol2scm ("help")), stdout);
171   exit (0);
172   return SCM_UNSPECIFIED;
173 }
174
175 LY_DEFINE (ly_set_option, "ly:set-option", 1, 1, 0, (SCM var, SCM val),
176            "Set a program option. Try setting 'help for a help string.")
177 {
178   SCM_ASSERT_TYPE (scm_is_symbol (var), var, SCM_ARG1,
179                    __FUNCTION__,  "symbol");
180
181   if (ly_symbol2scm ("help") == var)
182     {
183       ly_option_usage ();
184     }
185
186   if (val == SCM_UNDEFINED)
187     val = SCM_BOOL_T;
188
189   String  varstr = ly_scm2string (scm_symbol_to_string (var));
190   if (varstr.left_string (3) == String ("no-"))
191     {
192       var = ly_symbol2scm (varstr.nomid_string (0, 3).to_str0 ());
193       val = scm_from_bool (!to_boolean (val));
194     }
195   
196   SCM handle = scm_hashq_get_handle (option_hash_, var);
197   if (handle == SCM_BOOL_F)
198     {
199       warning (_f ("no such internal option: %s", varstr.to_str0 ()));
200     }
201
202   internal_set_option (var, val);
203   return SCM_UNSPECIFIED;
204 }
205
206 LY_DEFINE (ly_get_option, "ly:get-option", 1, 0, 0, (SCM var),
207            "Get a global option setting.")
208 {
209   SCM_ASSERT_TYPE (scm_is_symbol (var), var,
210                    SCM_ARG1, __FUNCTION__,  "symbol");
211   return scm_hashq_ref (option_hash_, var, SCM_BOOL_F);
212 }