2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1997--2014 Han-Wen Nienhuys <hanwen@xs4all.nl>
6 LilyPond is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 LilyPond is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
30 #include <sys/types.h>
43 #include "all-font-metrics.hh"
44 #include "file-name.hh"
45 #include "freetype.hh"
46 #include "getopt-long.hh"
47 #include "global-ctor.hh"
48 #include "international.hh"
49 #include "lily-version.hh"
51 #include "output-def.hh"
52 #include "program-option.hh"
53 #include "relocate.hh"
54 #include "string-convert.hh"
59 * Global options that can be overridden through command line.
62 /* Names of header fields to be dumped to a separate file. */
63 //vector<string> dump_header_fieldnames_global; // moved to global-data.cc
65 /* Name of initialisation file. */
66 //string init_name_global; // moved to global-data.cc
68 /* Output formats to generate. */
69 //string output_format_global = ""; // moved to global-data.cc
71 /* Current output name. */
72 //string output_name_global; // moved to global-data.cc
74 /* Run in safe mode? */
75 //bool be_safe_global = false; // moved to global-data.cc
77 /* Provide URI links to the original file */
78 bool point_and_click_global = true;
80 /* Scheme code to execute before parsing, after .scm init.
81 This is where -e arguments are appended to. */
82 //string init_scheme_code_global; // moved to global-data.cc
83 //string init_scheme_variables_global; // moved to global-data.cc
85 //bool relocate_binary = true; // moved to global-data.cc
88 * Miscellaneous global stuff.
90 //File_path global_path; // moved to global-data.cc
96 static char const *AUTHORS
97 = " Han-Wen Nienhuys <hanwen@xs4all.nl>\n"
98 " Jan Nieuwenhuizen <janneke@gnu.org>\n";
100 static char const *PROGRAM_NAME = "lilypond";
101 static char const *PROGRAM_URL = "http://lilypond.org";
103 static char const *NOTICE
104 = _i ("This program is free software. It is covered by the GNU General Public\n"
105 "License and you are welcome to change it and/or distribute copies of it\n"
106 "under certain conditions. Invoke as `%s --warranty' for more\n"
109 static char const *WARRANTY
110 = _i (" This program is free software; you can redistribute it and/or\n"
111 "modify it under the terms of the GNU General Public License as \n"
112 "published by the Free Software Foundation, either version 3 of\n"
113 "the License, or (at your option) any later version.\n"
115 " This program is distributed in the hope that it will be useful,\n"
116 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
117 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
118 "General Public License for more details.\n"
120 " You should have received a copy of the\n"
121 "GNU General Public License along with this program; if not, write to\n"
122 "the Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n"
123 "Boston, MA 02111-1307, USA.\n");
125 /* Where the init files live. Typically:
126 LILYPOND_DATADIR = /usr/share/lilypond
128 //string lilypond_datadir; // moved to global-data.cc
130 /* The jail specification: USER, GROUP, JAIL, DIR. */
133 /* The option parser */
134 static Getopt_long *option_parser = 0;
136 /* Internationalisation kludge in two steps:
137 * use _i () to get entry in POT file
138 * call gettext () explicitly for actual "translation" */
141 Data to be used to display when
142 -h command line option is detected.
144 static Long_option_init options_static[]
148 _i ("SYM[=VAL]"), "define-default", 'd',
149 _i ("set Scheme option SYM to VAL (default: #t).\n"
150 "Use -dhelp for help.")
153 {_i ("EXPR"), "evaluate", 'e', _i ("evaluate scheme code")},
154 /* Bug in option parser: --output =foe is taken as an abbreviation
155 for --output-format. */
156 {_i ("FORMATs"), "formats", 'f', _i ("dump FORMAT,... Also as separate options:")},
157 {0, "pdf", 0, _i ("generate PDF (default)")},
158 {0, "png", 0, _i ("generate PNG")},
159 {0, "ps", 0, _i ("generate PostScript")},
160 {0, "help", 'h', _i ("show this help and exit")},
162 _i ("FIELD"), "header", 'H', _i ("dump header field FIELD to file\n"
163 "named BASENAME.FIELD")
165 {_i ("DIR"), "include", 'I', _i ("add DIR to search path")},
166 {_i ("FILE"), "init", 'i', _i ("use FILE as init file")},
169 _i ("USER, GROUP, JAIL, DIR"), "jail", 'j', _i ("chroot to JAIL, become USER:GROUP\n"
174 _i ("LOGLEVEL"), "loglevel", 'l', _i ("print log messages according to"
175 " LOGLEVEL. Possible values are:\n"
176 "NONE, ERROR, WARNING, BASIC, PROGRESS, INFO (default) and DEBUG.")
178 {_i ("FILE"), "output", 'o', _i ("write output to FILE (suffix will be added)")},
179 {0, "relocate", 0, _i ("relocate using directory of lilypond program")},
180 {0, "silent", 's', _i ("no progress, only error messages (equivalent to loglevel=ERROR)")},
181 {0, "version", 'v', _i ("show version number and exit")},
182 {0, "verbose", 'V', _i ("be verbose (equivalent to loglevel=DEBUG)")},
183 {0, "warranty", 'w', _i ("show warranty and copyright")},
187 char const *LILYPOND_DATADIR = PACKAGE_DATADIR "/" TOPLEVEL_VERSION;
189 /* x86 defaults to using 80-bit extended precision arithmetic. This can cause
190 problems because the truncation from 80 bits to 64 bits can occur in
191 unpredictable places. To get around this, we tell the x87 FPU to use only
192 double precision. Note that this is not needed for x86_64 because that uses
193 the SSE unit by default instead of the x87 FPU. */
194 #if ((defined (__x86__) || defined (__i386__)) \
195 && defined (HAVE_FPU_CONTROL_H) && (HAVE_FPU_CONTROL_H == 1))
197 #include <fpu_control.h>
201 fpu_control_t fpu_control = 0x027f;
202 _FPU_SETCW (fpu_control);
212 #endif /* defined(__x86__) || defined(__i386__) */
215 env_var_info (FILE *out, char const *key)
217 * Retrieve value of an OS environment variable.
219 * key, the name of an environment variable.
222 if (char const *value = getenv (key))
223 fprintf (out, "%s=\"%s\"\n", key, value);
229 * Print out information re directories being used by LilyPond
234 fprintf (out, "LILYPOND_DATADIR=\"%s\"\n", LILYPOND_DATADIR);
235 env_var_info (out, "LILYPONDPREFIX");
236 env_var_info (out, "LILYPOND_DATADIR");
237 fprintf (out, "LOCALEDIR=\"%s\"\n", LOCALEDIR);
239 fprintf (out, "\nEffective prefix: \"%s\"\n", lilypond_datadir.c_str ());
243 env_var_info (out, "FONTCONFIG_FILE");
244 env_var_info (out, "FONTCONFIG_PATH");
245 env_var_info (out, "GS_FONTPATH");
246 env_var_info (out, "GS_LIB");
247 env_var_info (out, "GUILE_LOAD_PATH");
248 env_var_info (out, "PANGO_RC_FILE");
249 env_var_info (out, "PANGO_PREFIX");
250 env_var_info (out, "PATH");
257 * Print out LilyPond copyright info.
260 /* Do not update the copyright years here, run `make grand-replace' */
261 printf ("%s", (_f ("Copyright (c) %s by\n%s and others.", "1996--2014",
269 * Print out LilyPond version string.
272 fputs (gnu_lilypond_version_string ().c_str (), out);
278 * Print copyright and program name
286 puts (_f (NOTICE, PROGRAM_NAME).c_str ());
289 LY_DEFINE (ly_usage, "ly:usage",
291 "Print usage message.")
293 * ly_usage: Routine to output standard information when LilyPond is run without a
294 * source file to compile.
295 * Also callable as ly:usage from Scheme.
298 /* No version number or newline here. It confuses help2man. */
299 printf ("%s", (_f ("Usage: %s [OPTION]... FILE...", PROGRAM_NAME).c_str ()));
301 printf ("%s", (_ ("Typeset music and/or produce MIDI from FILE.").c_str ()));
303 printf ("%s", (_ ("LilyPond produces beautiful music notation.").c_str ()));
305 printf ("%s", (_f ("For more information, see %s", PROGRAM_URL).c_str ()));
307 printf ("%s", (_ ("Options:").c_str ()));
309 printf ("%s", Long_option_init::table_string (options_static).c_str ());
311 /* Translators, please translate this string as
312 "Report bugs in English via %s",
313 or if there is a LilyPond users list or forum in your language
314 "Report bugs in English via %s or in YOUR_LANG via URI" */
315 printf ("%s", (_f ("Report bugs via %s",
316 "http://post.gmane.org/post.php?group=gmane.comp.gnu.lilypond.bugs"
320 return SCM_UNSPECIFIED;
326 * Prints out LilyPond warranty information
333 printf ("%s", (_ (WARRANTY).c_str ()));
337 prepend_scheme_list (const string &dir, const string &scmlist)
339 * Inserts an item at the front of a Scheme list, e.g. %load-path
341 * dir: The directory to add to the front of the list
342 * scmlist: The Scheme list onto which to prepend the directory
345 SCM var = scm_c_lookup (scmlist.c_str());
346 scm_variable_set_x (var, scm_cons (scm_from_locale_string (dir.c_str()),
347 scm_variable_ref (var)));
349 "(set! " + scmlist + " (cons \"" + dir + "\" " + scmlist +"))";
350 scm_c_eval_string (setcmd.c_str());*/
353 void init_global_tweak_registry ();
354 void init_fontconfig ();
360 /* Now we chroot, setuid/setgrp and chdir. If something goes wrong,
361 we exit (this is a security-sensitive area). First we split
362 jail_spec into its components, then we retrieve the user/group id
363 (necessarily *before* chroot'ing) and finally we perform the
368 USER_NAME, GROUP_NAME, JAIL, DIR, JAIL_MAX
371 vector<string> components = string_split (jail_spec, ',');
372 if (components.size () != JAIL_MAX)
374 error (_f ("expected %d arguments with jail, found: %u", JAIL_MAX,
375 (unsigned) components.size ()));
383 if (passwd *passwd = getpwnam (components[USER_NAME].c_str ()))
384 uid = passwd->pw_uid;
388 error (_f ("no such user: %s", components[USER_NAME]));
390 error (_f ("cannot get user id from user name: %s: %s",
391 components[USER_NAME],
400 if (group *group = getgrnam (components[GROUP_NAME].c_str ()))
405 error (_f ("no such group: %s", components[GROUP_NAME]));
407 error (_f ("cannot get group id from group name: %s: %s",
408 components[GROUP_NAME],
413 if (chroot (components[JAIL].c_str ()))
415 error (_f ("cannot chroot to: %s: %s", components[JAIL],
422 error (_f ("cannot change group id to: %d: %s", gid, strerror (errno)));
428 error (_f ("cannot change user id to: %d: %s", uid, strerror (errno)));
432 if (chdir (components[DIR].c_str ()))
434 error (_f ("cannot change working directory to: %s: %s", components[DIR],
442 main_with_guile (void *, int, char **)
444 * main-with-guile is invoked as a callback via scm_boot_guile from
446 * scm_boot_guile will have passed its data, argc and argv parameters
447 * to main_with_guile.
450 /* Engravers use lily.scm contents, so we need to make Guile find it.
451 Prepend onto GUILE %load-path.
452 %load-path is the symbol Guile searches for .scm files
453 %load-compiled-path is the symbol Guile V2 searches for .go files
455 string scm_pct_load_path = "%load-path";
456 string scm_pct_load_compiled_path = "%load-compiled-path";
458 prepend_scheme_list (lilypond_datadir, scm_pct_load_path );
459 prepend_scheme_list (lilypond_datadir + "/scm", scm_pct_load_path);
463 Just as ughy - prepend "/scm/out" onto GUILE V2+Â %load-compiled-path
464 and set %compile-fallback-path to our scm/out directory
467 %load-compiled-path is the symbol Guile V2 searches for .go files
469 prepend_scheme_list (lilypond_datadir + "/scm/out",
470 scm_pct_load_compiled_path);
472 %compile-fallback-path is the guile cache root for auto-compiled files
475 string scm_pct_fallback_path = "%compile-fallback-path";
476 string ly_scm_go_dir = lilypond_datadir + "/scm/out";
477 //string scm_pct_set_fallback = "(set! " + scm_pct_fallback_path +
478 // " \"" + lilypond_datadir + "/scm/out\")";
479 //scm_c_eval_string (scm_pct_set_fallback.c_str() );
481 (scm_list_3 (scm_from_locale_symbol ("set!"),
482 scm_from_locale_symbol ("%compile-fallback-path"),
483 scm_from_locale_string (ly_scm_go_dir.c_str())));
486 if (is_loglevel (LOG_DEBUG))
489 init_scheme_variables_global = "(list " + init_scheme_variables_global + ")";
490 init_scheme_code_global = "(begin " + init_scheme_code_global + ")";
493 call_constructors ();
497 ly_reset_all_fonts ();
500 We accept multiple independent music files on the command line to
501 reduce compile time when processing lots of small files.
502 This way we don't have to start the Guile/Scheme interpreter more than once, as
503 starting the GUILE engine is very time consuming.
508 while (char const *arg = option_parser->get_next_arg ())
510 *tail = scm_cons (scm_from_locale_string (arg), SCM_EOL);
511 tail = SCM_CDRLOC (*tail);
514 delete option_parser;
518 if (!jail_spec.empty ())
522 Now execute the Scheme entry-point declared in
523 lily.scm (lilypond-main)
525 // These commands moved to lily_guile_v2.scm
526 // SCM rep_mod = scm_c_resolve_module ("system repl repl");
527 // scm_c_use_module ("system repl repl");
528 // SCM err_handling_mod = scm_c_resolve_module ("system repl error-handling");
529 // SCM call_with_error_handling = scm_c_module_lookup (err_handling_mod, "call-with-error-handling");
530 // SCM result = scm_call_1 (
531 // scm_variable_ref (call_with_error_handling),
532 // scm_call_1 (ly_lily_module_constant ("lilypond-main"), files));
533 SCM result = scm_call_1 (ly_lily_module_constant ("lilypond-main"), files);
541 setup_localisation ()
543 * Set up local language text locale (if available from configure)
545 * HAVE_GETTEXT: Internationalization available for a local language.
550 setlocale (LC_ALL, "");
552 /* FIXME: check if this is still true.
553 Disable localisation of float values. */
554 setlocale (LC_NUMERIC, "C");
556 string localedir = LOCALEDIR;
557 if (char const *env = getenv ("LILYPOND_LOCALEDIR"))
560 bindtextdomain ("lilypond", localedir.c_str ());
561 textdomain ("lilypond");
566 add_output_format (const string &format)
568 * Capture information internally from command-line options
573 if (output_format_global != "")
574 output_format_global += ",";
575 output_format_global += format;
579 parse_argv (int argc, char **argv)
581 * Parse command-line options
582 * also, if -h (help), -v (version) or -w (warranty) is detected,
583 * output the usage information and exit.
586 bool show_help = false;
587 option_parser = new Getopt_long (argc, argv, options_static);
588 while (Long_option_init const *opt = (*option_parser) ())
590 switch (opt->shortname_char_)
593 if (string (opt->longname_str0_) == "pdf"
594 || string (opt->longname_str0_) == "png"
595 || string (opt->longname_str0_) == "ps")
596 add_output_format (opt->longname_str0_);
597 else if (string (opt->longname_str0_) == "relocate")
598 relocate_binary = true;
603 string arg (option_parser->optional_argument_str0_);
604 ssize eq = arg.find ('=');
611 key = arg.substr (0, eq);
612 val = arg.substr (eq + 1, arg.length () - 1);
615 init_scheme_variables_global
616 += "(cons \'" + key + " '" + val + ")\n";
626 string s = option_parser->optional_argument_str0_;
627 File_name file_name (s);
628 output_name_global = file_name.to_string ();
632 jail_spec = option_parser->optional_argument_str0_;
636 init_scheme_code_global
637 += option_parser->optional_argument_str0_ + string (" ");
646 vector<string> components
647 = string_split (option_parser->optional_argument_str0_, ',');
648 for (vsize i = 0; i < components.size (); i++)
649 add_output_format (components[i]);
654 dump_header_fieldnames_global
655 .push_back (option_parser->optional_argument_str0_);
658 global_path.append (option_parser->optional_argument_str0_);
661 init_name_global = option_parser->optional_argument_str0_;
667 set_loglevel (LOGLEVEL_DEBUG);
670 set_loglevel (LOGLEVEL_ERROR);
673 set_loglevel (option_parser->optional_argument_str0_);
676 programming_error (to_string ("unhandled short option: %c",
677 opt->shortname_char_));
683 if (output_format_global == "")
684 output_format_global = "pdf";
689 if (is_loglevel (LOG_DEBUG))
696 T1686 Add two new routines called by setup_guile_env
700 setup_guile_gc_env ()
702 * Set up environment variables relevant to the
706 char const *yield = getenv ("LILYPOND_GC_YIELD");
707 bool overwrite = true;
714 sane_putenv ("GUILE_MIN_YIELD_1", yield, overwrite);
715 sane_putenv ("GUILE_MIN_YIELD_2", yield, overwrite);
716 sane_putenv ("GUILE_MIN_YIELD_MALLOC", yield, overwrite);
718 sane_putenv ("GUILE_INIT_SEGMENT_SIZE_1",
719 "10485760", overwrite);
720 sane_putenv ("GUILE_MAX_SEGMENT_SIZE",
721 "104857600", overwrite);
726 setup_guile_v2_env ()
728 * Set up environment variables relevant to compiling
729 * Scheme files for Guile V2.
732 sane_putenv("GUILE_AUTO_COMPILE", "0", true); // disable auto-compile
733 sane_putenv("GUILE_WARN_DEPRECATED",
734 "detailed", "true"); // set Guile to info re deprecation
736 Set root for Guile %compile-fallback to
737 Lilypond root for its data.
739 sane_putenv("XDG_CACHE_HOME",
740 lilypond_datadir, true);
746 * Set up environment variables relevant to Scheme
750 setup_guile_gc_env (); // configure garbage collector
752 setup_guile_v2_env (); // configure Guile V2 behaviour
756 //vector<string> start_environment_global;
759 main (int argc, char **argv, char **envp)
761 * Main entry-point for LilyPond executable image
763 * argc: Count of arguments on the command line
764 * argv: Vector of string arguments on command line
765 * envp: Point to vector of OS environment variables
770 Process environment variables
772 for (char **p = envp; *p; p++)
773 start_environment_global.push_back (*p);
775 Handle old-style environment equivalent to
776 old-style -V or --verbose command arguments.
777 Set it to the equivalent for --loglevel-DEBUG
779 if (getenv ("LILYPOND_VERBOSE"))
780 set_loglevel (LOGLEVEL_DEBUG);
781 if (getenv ("LILYPOND_LOGLEVEL"))
782 set_loglevel (getenv ("LILYPOND_LOGLEVEL"));
784 setup_localisation ();
785 parse_argv (argc, argv);
786 if (isatty (STDIN_FILENO) && (is_loglevel (LOG_BASIC)))
789 setup_paths (argv[0]);
790 setup_guile_env (); // set up environment variables to pass into Guile API
792 * Start up Guile API using main_with_guile as a callback.
796 Set it on by default for Guile V2
797 while migration in progress.
801 scm_boot_guile (argc, argv, main_with_guile, 0);
805 error (_f ("exception caught: %s", e.what ()));
808 scm_boot_guile (argc, argv, main_with_guile, 0);
811 /* Only reachable if GUILE exits. That is an error. */