#include <cstdio>
#include <ctype.h>
#include <cstring> /* memset */
+#include <glib.h>
using namespace std;
#include "dimensions.hh"
return scm_take_locale_stringn (result, len);
}
+
+int
+ly_run_command (char *argv[], char **standard_output, char **standard_error)
+{
+ GError *error = 0;
+ int exit_status = 0;
+ int flags = G_SPAWN_SEARCH_PATH;
+ if (!standard_output)
+ flags |= G_SPAWN_STDOUT_TO_DEV_NULL;
+ if (!standard_error)
+ flags |= G_SPAWN_STDERR_TO_DEV_NULL;
+ if (!g_spawn_sync (0, argv, 0, GSpawnFlags (flags),
+ 0, 0,
+ standard_output, standard_error,
+ &exit_status, &error))
+ {
+ fprintf (stderr, "failed (%d): %s: %s\n", exit_status, argv[0], error->message);
+ g_error_free (error);
+ if (!exit_status)
+ exit_status = -1;
+ }
+
+ return exit_status;
+}
+
+LY_DEFINE (ly_spawn, "ly:spawn",
+ 1, 0, 1, (SCM command, SCM rest),
+ "Simple interface to g_spawn_sync"
+ " @var{str}."
+ " The error is formatted with @code{format} and @var{rest}.")
+
+{
+ LY_ASSERT_TYPE (scm_is_string, command, 1);
+
+ int argc = scm_is_pair (rest) ? scm_ilength (rest) : 0;
+ char **argv = new char*[argc + 2];
+
+ int n = 0;
+ argv[n++] = ly_scm2str0 (command);
+ for (SCM s = rest; scm_is_pair (s); s = scm_cdr (s))
+ argv[n++] = ly_scm2str0 (scm_car (s));
+ argv[n] = 0;
+
+ char *standard_output = 0;
+ char *standard_error = 0;
+ int exit_status = be_verbose_global
+ ? ly_run_command (argv, &standard_output, &standard_error)
+ : ly_run_command (argv, 0, 0);
+
+ if (be_verbose_global)
+ {
+ fprintf (stderr, "\n%s", standard_output);
+ fprintf (stderr, "%s", standard_error);
+ }
+
+ for (int i = 0; i < n; i++)
+ free (argv[i]);
+ delete[] argv;
+
+ return scm_from_int (exit_status);
+}
Drul_array<Real> ly_scm2realdrul (SCM);
Slice int_list_to_slice (SCM l);
SCM ly_interval2scm (Drul_array<Real>);
-char *ly_scm2newstr (SCM str, size_t *lenp);
+char *ly_scm2str0 (SCM str);
Real robust_scm2double (SCM, double);
int robust_scm2int (SCM, int);
str.length ());
}
-
char *
-ly_scm2newstr (SCM str, size_t *lenp)
+ly_scm2str0 (SCM str)
{
- char* p = scm_to_locale_stringn(str, lenp);
- return p;
+ return scm_to_locale_string (str);
}
/*
(scm paper-system)
(ice-9 optargs))
-(define-public (ly:system command . rest)
- (let* ((status 0)
- (dev-null "/dev/null")
- (silenced (if (or (ly:get-option 'verbose)
- (not (access? dev-null W_OK)))
- command
- (format #f "~a > ~a 2>&1 " command dev-null))))
- (if (ly:get-option 'verbose)
- (begin
- (ly:message (_ "Invoking `~a'...") command))
- (ly:progress "\n"))
-
- (set! status
- (if (pair? rest)
- (system-with-env silenced (car rest))
- (system silenced)))
-
+(define-public (ly:system command)
+ (if (ly:get-option 'verbose)
+ (begin
+ (ly:message (_ "Invoking `~a'...") (string-join command)))
+ (ly:progress "\n"))
+ (let ((status (apply ly:spawn command)))
(if (> status 0)
(begin
(ly:message (_ "`~a' failed (~a)") command status)
;; hmmm. what's the best failure option?
(throw 'ly-file-failed)))))
-(define-public (system-with-env cmd env)
-
- "Execute CMD in fork, with ENV (a list of strings) as the environment"
- (let*
- ;; laziness: should use execle?
-
- ((pid (primitive-fork)))
- (if (= 0 pid)
- ;; child
- (begin
- (environ env)
- (system cmd))
-
- ;; parent
- (cdr (waitpid pid)))))
-
(define-public (sanitize-command-option str)
"Kill dubious shell quoting"
(dir-basename name ".ps" ".eps")
".pdf"))
(is-eps (string-match "\\.eps$" name))
- (paper-size-string (if is-eps
- "-dEPSCrop"
- (ly:format "-dDEVICEWIDTHPOINTS=~$\
- -dDEVICEHEIGHTPOINTS=~$"
- paper-width paper-height)))
-
- (cmd (ly:format
- "~a\
- ~a\
- ~a\
- ~a\
- -dCompatibilityLevel=1.4\
- -dNOPAUSE\
- -dBATCH\
- -r1200\
- -sDEVICE=pdfwrite\
- -sOutputFile=~S\
- -c .setpdfwrite\
- -f ~S\
-"
- (search-gs)
- (if (ly:get-option 'verbose) "" "-q")
- (if (or (ly:get-option 'gs-load-fonts)
- (ly:get-option 'gs-load-lily-fonts))
- "-dNOSAFER"
- "-dSAFER")
- paper-size-string
- pdf-name
- name)))
- ;; The wrapper on windows cannot handle `=' signs,
- ;; gs has a workaround with #.
- (if (eq? PLATFORM 'windows)
- (begin
- (set! cmd (string-regexp-substitute "=" "#" cmd))
- (set! cmd (string-regexp-substitute "-dSAFER " "" cmd))))
+ (*unspecified* (if #f #f))
+ (cmd
+ (remove (lambda (x) (eq? x *unspecified*))
+ (list
+ (search-gs)
+ (if (ly:get-option 'verbose) *unspecified* "-q")
+ (if (or (ly:get-option 'gs-load-fonts)
+ (ly:get-option 'gs-load-lily-fonts)
+ (eq? PLATFORM 'windows))
+ "-dNOSAFER"
+ "-dSAFER")
+
+ (if is-eps
+ "-dEPSCrop"
+ (ly:format "-dDEVICEWIDTHPOINTS=~$" paper-width))
+ (if is-eps
+ *unspecified*
+ (ly:format "-dDEVICEHEIGHTPOINTS=~$" paper-height))
+ "-dCompatibilityLevel=1.4"
+ "-dNOPAUSE"
+ "-dBATCH"
+ "-r1200"
+ "-sDEVICE=pdfwrite"
+ (string-append "-sOutputFile=" pdf-name)
+ "-c.setpdfwrite"
+ (string-append "-f" name)))))
(ly:message (_ "Converting to `~a'...") pdf-name)
(ly:progress "\n")
(let* ((dir-name (tmpnam))
(files '())
(status 0)
- (embed #f))
+ (embed #f)
+ (cwd (getcwd)))
(mkdir dir-name #o700)
- (set! status (ly:system
- (format "cd ~a && fondu -force '~a'" dir-name filename)))
+ (chdir dir-name)
+ (set! status (ly:system (list "fondu" "-force" file-name)))
+ (chdir cwd)
(set! files (dir-listing dir-name))
(for-each
(lambda (f)
(lily)
)
+;; FIXME: use backend-library for duplicates and stubs; lilypond-ps2png.scm is no more
+
(define-public _ gettext)
(define PLATFORM