/*
This file is part of LilyPond, the GNU music typesetter.
- Copyright (C) 1997--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ Copyright (C) 1997--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
LilyPond is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
*/
#include "main.hh"
+#include "lily-guile.hh"
#include <cassert>
#include <clocale>
#include "string-convert.hh"
#include "version.hh"
#include "warn.hh"
+#include "lily-imports.hh"
/*
* Global options that can be overridden through command line.
*/
/* Names of header fields to be dumped to a separate file. */
-vector<string> dump_header_fieldnames_global;
+//vector<string> dump_header_fieldnames_global; // moved to global-data.cc
/* Name of initialisation file. */
-string init_name_global;
+//string init_name_global; // moved to global-data.cc
/* Output formats to generate. */
-string output_format_global = "";
+//string output_format_global = ""; // moved to global-data.cc
/* Current output name. */
-string output_name_global;
+//string output_name_global; // moved to global-data.cc
/* Run in safe mode? */
-bool be_safe_global = false;
+//bool be_safe_global = false; // moved to global-data.cc
/* Provide URI links to the original file */
bool point_and_click_global = true;
-/* Verbose progress indication? */
-bool be_verbose_global = false;
-
/* Scheme code to execute before parsing, after .scm init.
This is where -e arguments are appended to. */
-string init_scheme_code_global;
-string init_scheme_variables_global;
+//string init_scheme_code_global; // moved to global-data.cc
+//string init_scheme_variables_global; // moved to global-data.cc
-bool relocate_binary = true;
+//bool relocate_binary = true; // moved to global-data.cc
/*
* Miscellaneous global stuff.
*/
-File_path global_path;
+//File_path global_path; // moved to global-data.cc
/*
* File globals.
/* Where the init files live. Typically:
LILYPOND_DATADIR = /usr/share/lilypond
*/
-string lilypond_datadir;
+//string lilypond_datadir; // moved to global-data.cc
/* The jail specification: USER, GROUP, JAIL, DIR. */
string jail_spec;
* use _i () to get entry in POT file
* call gettext () explicitly for actual "translation" */
+/*
+ Data to be used to display when
+ -h command line option is detected.
+*/
static Long_option_init options_static[]
=
{
{0, "pdf", 0, _i ("generate PDF (default)")},
{0, "png", 0, _i ("generate PNG")},
{0, "ps", 0, _i ("generate PostScript")},
+ {0, "bigpdfs", 'b', _i("generate big PDF files")},
{0, "help", 'h', _i ("show this help and exit")},
{
_i ("FIELD"), "header", 'H', _i ("dump header field FIELD to file\n"
"and cd into DIR")
},
#endif
+ {
+ _i ("LOGLEVEL"), "loglevel", 'l', _i ("print log messages according to"
+ " LOGLEVEL. Possible values are:\n"
+ "NONE, ERROR, WARNING, BASIC, PROGRESS, INFO (default) and DEBUG.")
+ },
{_i ("FILE"), "output", 'o', _i ("write output to FILE (suffix will be added)")},
{0, "relocate", 0, _i ("relocate using directory of lilypond program")},
+ {0, "silent", 's', _i ("no progress, only error messages (equivalent to loglevel=ERROR)")},
{0, "version", 'v', _i ("show version number and exit")},
- {0, "verbose", 'V', _i ("be verbose")},
+ {0, "verbose", 'V', _i ("be verbose (equivalent to loglevel=DEBUG)")},
{0, "warranty", 'w', _i ("show warranty and copyright")},
{0, 0, 0, 0}
};
static void
env_var_info (FILE *out, char const *key)
+/*
+ * Retrieve value of an OS environment variable.
+ * Parameter:
+ * key, the name of an environment variable.
+ */
{
if (char const *value = getenv (key))
fprintf (out, "%s=\"%s\"\n", key, value);
static void
dir_info (FILE *out)
+/*
+ * Print out information re directories being used by LilyPond
+ * for this session.
+ */
{
fputs ("\n", out);
fprintf (out, "LILYPOND_DATADIR=\"%s\"\n", LILYPOND_DATADIR);
static void
copyright ()
+/*
+ * Print out LilyPond copyright info.
+ */
{
/* Do not update the copyright years here, run `make grand-replace' */
- printf ("%s", (_f ("Copyright (c) %s by\n%s and others.", "1996--2011",
+ printf ("%s", (_f ("Copyright (c) %s by\n%s and others.", "1996--2015",
AUTHORS).c_str ()));
printf ("\n");
}
static void
identify (FILE *out)
+/*
+ * Print out LilyPond version string.
+ */
{
fputs (gnu_lilypond_version_string ().c_str (), out);
fputs ("\n", out);
}
static void
+/*
+ * Print copyright and program name
+ */
notice ()
{
identify (stdout);
LY_DEFINE (ly_usage, "ly:usage",
0, 0, 0, (),
"Print usage message.")
+/*
+ * ly_usage: Routine to output standard information when LilyPond is run without a
+ * source file to compile.
+ * Also callable as ly:usage from Scheme.
+ */
{
/* No version number or newline here. It confuses help2man. */
printf ("%s", (_f ("Usage: %s [OPTION]... FILE...", PROGRAM_NAME).c_str ()));
static void
warranty ()
+/*
+ * Prints out LilyPond warranty information
+ */
{
identify (stdout);
printf ("\n");
}
static void
-prepend_load_path (string dir)
+prepend_scheme_list (const string &dir, const string &scmlist)
+/*
+ * Inserts an item at the front of a Scheme list, e.g. %load-path
+ * Parameters:
+ * dir: The directory to add to the front of the list
+ * scmlist: The Scheme list onto which to prepend the directory
+ */
{
- string s = "(set! %load-path (cons \"" + dir + "\" %load-path))";
- scm_c_eval_string (s.c_str ());
+ SCM var = scm_c_lookup (scmlist.c_str());
+ scm_variable_set_x (var, scm_cons (scm_from_locale_string (dir.c_str()),
+ scm_variable_ref (var)));
+ /* string setcmd =
+ "(set! " + scmlist + " (cons \"" + dir + "\" " + scmlist +"))";
+ scm_c_eval_string (setcmd.c_str());*/
}
void init_global_tweak_registry ();
static void
main_with_guile (void *, int, char **)
+/*
+ * main-with-guile is invoked as a callback via scm_boot_guile from
+ * main.
+ * scm_boot_guile will have passed its data, argc and argv parameters
+ * to main_with_guile.
+ */
{
- /* Engravers use lily.scm contents, need to make Guile find it.
- Prepend onto GUILE %load-path, very ugh. */
-
- prepend_load_path (lilypond_datadir);
- prepend_load_path (lilypond_datadir + "/scm");
+ /* Engravers use lily.scm contents, so we need to make Guile find it.
+ Prepend onto GUILE %load-path.
+ %load-path is the symbol Guile searches for .scm files
+ %load-compiled-path is the symbol Guile V2 searches for .go files
+ */
+ string scm_pct_load_path = "%load-path";
+ string scm_pct_load_compiled_path = "%load-compiled-path";
+
+ prepend_scheme_list (lilypond_datadir, scm_pct_load_path );
+ prepend_scheme_list (lilypond_datadir + "/scm", scm_pct_load_path);
+
+#if (GUILE2)
+ /*
+ Just as ughy - prepend "/scm/out" onto GUILE V2+ %load-compiled-path
+ and set %compile-fallback-path to our scm/out directory
+ */
+ /*
+ %load-compiled-path is the symbol Guile V2 searches for .go files
+ */
+ prepend_scheme_list (lilypond_datadir + "/scm/out",
+ scm_pct_load_compiled_path);
+ /*
+ %compile-fallback-path is the guile cache root for auto-compiled files
+ */
+
+ string scm_pct_fallback_path = "%compile-fallback-path";
+ string ly_scm_go_dir = lilypond_datadir + "/scm/out";
+ //string scm_pct_set_fallback = "(set! " + scm_pct_fallback_path +
+ // " \"" + lilypond_datadir + "/scm/out\")";
+ //scm_c_eval_string (scm_pct_set_fallback.c_str() );
+ scm_primitive_eval
+ (scm_list_3 (scm_from_latin1_symbol ("set!"),
+ scm_from_latin1_symbol ("%compile-fallback-path"),
+ scm_from_locale_string (ly_scm_go_dir.c_str())));
+#endif
- if (be_verbose_global)
+ if (is_loglevel (LOG_DEBUG))
dir_info (stderr);
init_scheme_variables_global = "(list " + init_scheme_variables_global + ")";
init_freetype ();
ly_reset_all_fonts ();
- /* We accept multiple independent music files on the command line to
+ /*
+ We accept multiple independent music files on the command line to
reduce compile time when processing lots of small files.
- Starting the GUILE engine is very time consuming. */
+ This way we don't have to start the Guile/Scheme interpreter more than once, as
+ starting the GUILE engine is very time consuming.
+ */
SCM files = SCM_EOL;
SCM *tail = &files;
if (!jail_spec.empty ())
do_chroot_jail ();
#endif
-
- SCM result = scm_call_1 (ly_lily_module_constant ("lilypond-main"), files);
- (void) result;
+ /*
+ Now execute the Scheme entry-point declared in
+ lily.scm (lilypond-main)
+ */
+ // These commands moved to lily_guile_v2.scm
+ // SCM rep_mod = scm_c_resolve_module ("system repl repl");
+ // scm_c_use_module ("system repl repl");
+ // SCM err_handling_mod = scm_c_resolve_module ("system repl error-handling");
+ // SCM call_with_error_handling = scm_c_module_lookup (err_handling_mod, "call-with-error-handling");
+ // SCM result = scm_call_1 (
+ // scm_variable_ref (call_with_error_handling),
+ // scm_call_1 (ly_lily_module_constant ("lilypond-main"), files));
+
+ Lily::lilypond_main (files);
/* Unreachable. */
exit (0);
static void
setup_localisation ()
+/*
+ * Set up local language text locale (if available from configure)
+ * Implicit inputs:
+ * HAVE_GETTEXT: Internationalization available for a local language.
+ */
{
#if HAVE_GETTEXT
/* Enable locales */
Disable localisation of float values. */
setlocale (LC_NUMERIC, "C");
+#if GUILEV2
+ // In order not to have this porting aid backfire to GUILE1 usage,
+ // this is only compiled in the GUILEV2 version. It should
+ // eventually be replaced with proper multibyte communication with
+ // GUILE2, but in the mean time it seems that this is the least
+ // invasive path to get comparable results between the
+ // not-really-multibyte-supporting GUILE1 and GUILE2
+
+ /* Disable character sets */
+ setlocale (LC_CTYPE, "C");
+ /* But our text domain is in UTF-8 */
+ bind_textdomain_codeset ("lilypond", "UTF-8");
+#endif
+
string localedir = LOCALEDIR;
if (char const *env = getenv ("LILYPOND_LOCALEDIR"))
localedir = env;
}
static void
-add_output_format (string format)
+add_output_format (const string &format)
+/*
+ * Capture information internally from command-line options
+ * re output format.
+ *
+ */
{
if (output_format_global != "")
output_format_global += ",";
static void
parse_argv (int argc, char **argv)
+/*
+ * Parse command-line options
+ * also, if -h (help), -v (version) or -w (warranty) is detected,
+ * output the usage information and exit.
+ */
{
bool show_help = false;
option_parser = new Getopt_long (argc, argv, options_static);
relocate_binary = true;
break;
+ case 'b':
+ bigpdfs = true;
+ break;
+
case 'd':
{
string arg (option_parser->optional_argument_str0_);
show_help = true;
break;
case 'V':
- be_verbose_global = true;
+ set_loglevel (LOGLEVEL_DEBUG);
+ break;
+ case 's':
+ set_loglevel (LOGLEVEL_ERROR);
+ break;
+ case 'l':
+ set_loglevel (option_parser->optional_argument_str0_);
break;
default:
programming_error (to_string ("unhandled short option: %c",
if (show_help)
{
ly_usage ();
- if (be_verbose_global)
+ if (is_loglevel (LOG_DEBUG))
dir_info (stdout);
exit (0);
}
}
+/*
+ T1686 Add two new routines called by setup_guile_env
+*/
+
void
-setup_guile_env ()
+setup_guile_gc_env ()
+/*
+ * Set up environment variables relevant to the
+ * Garbage Collector
+ */
{
char const *yield = getenv ("LILYPOND_GC_YIELD");
bool overwrite = true;
"104857600", overwrite);
}
-vector<string> start_environment_global;
+
+void
+setup_guile_v2_env ()
+/*
+ * Set up environment variables relevant to compiling
+ * Scheme files for Guile V2.
+ */
+{
+ sane_putenv("GUILE_AUTO_COMPILE", "0", true); // disable auto-compile
+ sane_putenv("GUILE_WARN_DEPRECATED",
+ "detailed", "true"); // set Guile to info re deprecation
+ /*
+ Set root for Guile %compile-fallback to
+ Lilypond root for its data.
+ */
+ sane_putenv("XDG_CACHE_HOME",
+ lilypond_datadir, true);
+}
+
+void
+setup_guile_env ()
+/*
+ * Set up environment variables relevant to Scheme
+ */
+{
+
+ setup_guile_gc_env (); // configure garbage collector
+#if (GUILEV2)
+ setup_guile_v2_env (); // configure Guile V2 behaviour
+#endif
+}
+
+//vector<string> start_environment_global;
int
main (int argc, char **argv, char **envp)
+/*
+ * Main entry-point for LilyPond executable image
+ * Parameters:
+ * argc: Count of arguments on the command line
+ * argv: Vector of string arguments on command line
+ * envp: Point to vector of OS environment variables
+ */
{
configure_fpu ();
-
+ /*
+ Process environment variables
+ */
for (char **p = envp; *p; p++)
start_environment_global.push_back (*p);
-
+ /*
+ Handle old-style environment equivalent to
+ old-style -V or --verbose command arguments.
+ Set it to the equivalent for --loglevel-DEBUG
+ */
if (getenv ("LILYPOND_VERBOSE"))
- be_verbose_global = true;
+ set_loglevel (LOGLEVEL_DEBUG);
+ if (getenv ("LILYPOND_LOGLEVEL"))
+ set_loglevel (getenv ("LILYPOND_LOGLEVEL"));
setup_localisation ();
parse_argv (argc, argv);
- if (isatty (STDIN_FILENO))
+ if (isatty (STDIN_FILENO) && (is_loglevel (LOG_BASIC)))
identify (stderr);
setup_paths (argv[0]);
- setup_guile_env ();
-
-#if 0
- /* Debugging aid. */
+ setup_guile_env (); // set up environment variables to pass into Guile API
+ /*
+ * Start up Guile API using main_with_guile as a callback.
+ */
+#if (GUILEV2)
+ /* Debugging aid.
+ Set it on by default for Guile V2
+ while migration in progress.
+ */
try
{
scm_boot_guile (argc, argv, main_with_guile, 0);