/* gimptool in C
* Copyright (C) 2001-2007 Tor Lillqvist
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/*
* Gimptool rewritten in C, originally for Win32, where end-users who
* might want to build and install a plug-in from source don't
* necessarily have any Bourne-compatible shell to run the gimptool
* script in. Later fixed up to replace the gimptool script on all
* platforms.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <gio/gio.h>
#include "libgimpbase/gimpbase.h"
#ifdef G_OS_WIN32
#include "libgimpbase/gimpwin32-io.h"
#ifndef HAVE_UNISTD_H
#include <io.h>
#define popen _popen
#define pclose _pclose
#endif
#endif
static gboolean silent =
FALSE;
static gboolean dry_run =
FALSE;
static const gchar *cli_prefix;
static const gchar *cli_exec_prefix;
static gboolean msvc_syntax =
FALSE;
static const gchar *env_cc;
static const gchar *env_cflags;
static const gchar *env_ldflags;
static const gchar *env_libs;
#ifdef G_OS_WIN32
#define EXEEXT
".exe"
#else
#define EXEEXT
""
#endif
#ifdef G_OS_WIN32
#define COPY win32_command (
"copy")
#define REMOVE win32_command (
"del")
#define REMOVE_DIR win32_command (
"rd /s /q")
#else
#define COPY
"cp"
#define REMOVE
"rm -f"
#define REMOVE_DIR
"rm -Rf"
#endif
static struct {
const gchar *option;
const gchar *value;
} dirs[] = {
{
"prefix", PREFIX },
{
"exec-prefix", EXEC_PREFIX },
{
"bindir", BINDIR },
{
"sbindir", SBINDIR },
{
"libexecdir", LIBEXECDIR },
{
"datadir", DATADIR },
{
"datarootdir", DATAROOTDIR },
{
"sysconfdir", SYSCONFDIR },
{
"sharedstatedir", SHAREDSTATEDIR },
{
"localstatedir", LOCALSTATEDIR },
{
"libdir", LIBDIR },
{
"infodir", INFODIR },
{
"mandir", MANDIR },
#if 0
/* For --includedir we want the includedir of the developer package,
* not an includedir under the runtime installation prefix.
*/
{
"includedir", INCLUDEDIR },
#endif
{
"gimpplugindir", GIMPPLUGINDIR },
{
"gimpdatadir", GIMPDATADIR }
};
static void usage (
int exit_status) G_GNUC_NORETURN;
#ifdef G_OS_WIN32
static const gchar *
win32_command (
const gchar *command)
{
static gchar *cmd = NULL;
const gchar *comspec = getenv (
"COMSPEC");
if (comspec == NULL)
comspec =
"cmd.exe";
g_free (cmd);
cmd = g_strdup_printf (
"%s /c %s", comspec, command);
return (
const gchar *) cmd;
}
/* Windows shells break with auto-quote. See: https://gitlab.gnome.org/GNOME/gimp/-/issues/6378 */
static gchar *
hollow_g_shell_quote (
const gchar *input)
{
return g_strdup (input);
}
#define g_shell_quote hollow_g_shell_quote
#endif
static gboolean
starts_with_dir (
const gchar *string,
const gchar *dir)
{
gchar *dirslash = g_strconcat (dir,
"/", NULL);
gboolean retval;
retval = (g_str_has_prefix (string, dirslash) ||
g_strcmp0 (string, dir) ==
0);
g_free (dirslash);
return retval;
}
static gchar *
one_line_output (
const gchar *program,
const gchar *args)
{
gchar *command = g_strconcat (program,
" ", args, NULL);
FILE *pipe = popen (command,
"r");
gchar line[
4096];
if (pipe == NULL)
{
g_printerr (
"Cannot run '%s'\n", command);
g_free (command);
exit (EXIT_FAILURE);
}
if (fgets (line,
sizeof (line), pipe) == NULL)
line[
0] =
'\0';
if (strlen (line) >
0 && line [strlen (line) -
1] ==
'\n')
line [strlen (line) -
1] =
'\0';
if (strlen (line) >
0 && line [strlen (line) -
1] ==
'\r')
line [strlen (line) -
1] =
'\0';
pclose (pipe);
if (strlen (line) ==
0)
{
g_printerr (
"No output from '%s'\n", command);
g_free (command);
exit (EXIT_FAILURE);
}
g_free (command);
return g_strdup (line);
}
static gchar *
pkg_config (
const gchar *args)
{
#ifdef G_OS_WIN32
if (msvc_syntax)
return one_line_output (
"pkg-config --msvc-syntax", args);
#endif
return one_line_output (
"pkg-config", args);
}
static gchar *
get_runtime_prefix (gchar slash)
{
#ifdef G_OS_WIN32
/* Don't use the developer package prefix, but deduce the
* installation-time prefix from where gimp-x.y.exe can be found.
*/
gchar *path;
gchar *p, *r;
path = g_find_program_in_path (
"gimp-" GIMP_APP_VERSION
".exe");
if (path == NULL)
path = g_find_program_in_path (
"gimp.exe");
if (path != NULL)
{
r = strrchr (path, G_DIR_SEPARATOR);
if (r != NULL)
{
*r =
'\0';
if (strlen (path) >=
4 &&
g_ascii_strcasecmp (r -
4, G_DIR_SEPARATOR_S
"bin") ==
0)
{
r[-
4] =
'\0';
if (slash ==
'/')
{
/* Use forward slashes, less quoting trouble in Makefiles */
while ((p = strchr (path,
'\\')) != NULL)
*p =
'/';
}
return path;
}
}
}
g_printerr (
"Cannot determine GIMP " GIMP_APP_VERSION
" installation location\n");
exit (EXIT_FAILURE);
#else
/* On Unix assume the executable package is in the same prefix as the developer stuff */
return pkg_config (
"--variable=prefix gimp-" GIMP_PKGCONFIG_VERSION);
#endif
}
static gchar *
get_exec_prefix (gchar slash)
{
#ifdef G_OS_WIN32
if (cli_exec_prefix != NULL)
return g_strdup (cli_exec_prefix);
/* On Win32, exec_prefix is always same as prefix. Or is it? Maybe not,
* but at least in tml's prebuilt stuff it is. If somebody else does
* it another way, feel free to hack this.
*/
return get_runtime_prefix (slash);
#else
return g_strdup (EXEC_PREFIX);
#endif
}
static gchar *
expand_and_munge (
const gchar *value)
{
gchar *retval;
if (starts_with_dir (value,
"${prefix}"))
retval = g_strconcat (PREFIX, value + strlen (
"${prefix}"), NULL);
else if (starts_with_dir (value,
"${exec_prefix}"))
retval = g_strconcat (EXEC_PREFIX, value + strlen (
"${exec_prefix}"), NULL);
else
retval = g_strdup (value);
if (starts_with_dir (retval, EXEC_PREFIX))
{
gchar *exec_prefix = get_exec_prefix (
'/');
retval = g_strconcat (exec_prefix, retval + strlen (EXEC_PREFIX), NULL);
g_free (exec_prefix);
}
if (starts_with_dir (retval, PREFIX))
{
gchar *runtime_prefix = get_runtime_prefix (
'/');
retval = g_strconcat (runtime_prefix, retval + strlen (PREFIX), NULL);
g_free (runtime_prefix);
}
return retval;
}
static void
find_out_env_flags (
void)
{
gchar *p;
if ((p = getenv (
"CC")) != NULL && *p !=
'\0')
env_cc = p;
else if (msvc_syntax)
env_cc =
"cl -MD";
else
env_cc = CC;
if (g_ascii_strncasecmp (env_cc,
"cl",
2) ==
0 &&
g_ascii_strncasecmp (env_cc,
"clang",
5) !=
0)
msvc_syntax =
TRUE;
if ((p = getenv (
"CFLAGS")) != NULL)
env_cflags = p;
else
env_cflags =
"";
if ((p = getenv (
"LDFLAGS")) != NULL)
env_ldflags = p;
else
env_ldflags =
"";
if ((p = getenv (
"LIBS")) != NULL && *p !=
'\0')
env_libs = p;
else
env_libs =
"";
}
static void
usage (
int exit_status)
{
g_print (
"\
Usage: gimptool-
" GIMP_TOOL_VERSION " [OPTION]...\n\
\n\
General options:\n\
--help print
this message\n\
--quiet, --silent don
't echo build commands\n\
--version print the version of GIMP associated with
this script\n\
-n, --just-print, --dry-run, --recon\n\
don
't actually run any commands; just print them\n\
Developer options:\n\
--cflags print the compiler flags that are necessary to\n\
compile a plug-in\n\
--libs print the linker flags that are necessary to link a\n\
plug-in\n\
--prefix=PREFIX use PREFIX instead of the installation prefix that\n\
GIMP was built when computing the output
for --cflags\n\
and --libs\n\
--exec-prefix=PREFIX use PREFIX instead of the installation exec prefix\n\
that GIMP was built when computing the output
for\n\
--cflags
and --libs\n\
--msvc-syntax print flags in MSVC syntax\n\
\n\
Installation directory options:\n\
--prefix --exec-prefix --bindir --sbindir --libexecdir --datadir --sysconfdir\n\
--sharedstatedir --localstatedir --libdir --infodir --mandir --includedir\n\
--gimpplugindir --gimpdatadir\n\
\n\
The --cflags
and --libs options can be appended with -noui to get appropriate\n\
settings
for plug-ins which
do not use GTK+.\n\
\n\
User options:\n\
--build plug-in.c build a plug-in from a source file\n\
--install plug-in.c same as --build, but installs the built\n\
plug-in as well\n\
--install-bin plug-in install a compiled plug-in\n\
--install-script script.scm install a script-fu script\n\
\n\
--uninstall-bin plug-in remove a plug-in again\n\
--uninstall-script plug-in remove a script-fu script\n\
\n\
The --install
and --uninstall options have \
"admin\" counterparts (with\n\
prefix --install-admin instead of --install) that can be used instead to\n\
install/uninstall a plug-in
or script in the machine directory instead of a\n\
user directory.\n\
\n\
For plug-ins which
do not use GTK+, the --build
and --install options can be\n\
appended with -noui
for appropriate settings.
For plug-ins that use GTK+ but\n\
not libgimpui, append -nogimpui.\n
");
exit (exit_status);
}
static gchar *
get_includedir (
void)
{
return pkg_config (
"--variable=includedir gimp-" GIMP_PKGCONFIG_VERSION);
}
static void
do_includedir (
void)
{
gchar *includedir = get_includedir ();
g_print (
"%s\n", includedir);
g_free (includedir);
}
static gchar *
get_cflags (
void)
{
return pkg_config (
"--cflags gimpui-" GIMP_PKGCONFIG_VERSION);
}
static void
do_cflags (
void)
{
gchar *cflags = get_cflags ();
g_print (
"%s\n", cflags);
g_free (cflags);
}
static gchar *
get_cflags_noui (
void)
{
return pkg_config (
"--cflags gimp-" GIMP_PKGCONFIG_VERSION);
}
static void
do_cflags_noui (
void)
{
gchar *cflags = get_cflags_noui ();
g_print (
"%s\n", cflags);
g_free (cflags);
}
static gchar *
get_cflags_nogimpui (
void)
{
return pkg_config (
"--cflags gimp-" GIMP_PKGCONFIG_VERSION
" gtk+-3.0");
}
static void
do_cflags_nogimpui (
void)
{
gchar *cflags = get_cflags_nogimpui ();
g_print (
"%s\n", cflags);
g_free (cflags);
}
static gchar *
get_libs (
void)
{
return pkg_config (
"--libs gimpui-" GIMP_PKGCONFIG_VERSION);
}
static void
do_libs (
void)
{
gchar *libs = get_libs ();
g_print (
"%s\n", libs);
g_free (libs);
}
static gchar *
get_libs_noui (
void)
{
return pkg_config (
"--libs gimp-" GIMP_PKGCONFIG_VERSION);
}
static void
do_libs_noui (
void)
{
gchar *libs = get_libs_noui ();
g_print (
"%s\n", libs);
g_free (libs);
}
static gchar *
get_libs_nogimpui (
void)
{
return pkg_config (
"--libs gimp-" GIMP_PKGCONFIG_VERSION
" gtk+-3.0");
}
static void
do_libs_nogimpui (
void)
{
gchar *libs = get_libs_nogimpui ();
g_print (
"%s\n", libs);
g_free (libs);
}
static void
maybe_run (gchar *cmd)
{
if (!silent)
g_print (
"%s\n", cmd);
/* system() declared with attribute warn_unused_result.
* Trick to get rid of the compilation warning without using the result.
*/
if (dry_run || system (cmd))
;
}
static void
do_build_2 (
const gchar *cflags,
const gchar *libs,
const gchar *install_dir,
const gchar *what)
{
const gchar *lang_flag =
"";
const gchar *output_flag;
const gchar *here_comes_linker_flags =
"";
const gchar *windows_subsystem_flag =
"";
gchar *cmd;
gchar *dest_dir;
gchar *dest_exe;
gchar *source = g_shell_quote (what);
gchar *tmp;
gchar *p, *q;
if (install_dir != NULL)
dest_dir = g_strconcat (install_dir,
"/", NULL);
else
dest_dir = g_strdup (
"");
dest_exe = g_strdup (what);
p = strrchr (dest_exe,
'.');
if (p == NULL ||
!(strcmp (p,
".c") ==
0 ||
strcmp (p,
".cc") ==
0 ||
strcmp (p,
".cpp") ==
0))
{
/* If the file doesn't have a "standard" C/C++ suffix and:
* 1) if the compiler is known as a C++ compiler, then treat the file as a
* C++ file if possible.
* It's known that G++ and Clang++ treat a file as a C file if they are
* run with the "-x c++" option.
* 2) if the compiler is known as a C compiler or a multiple-language
* compiler, then treat the file as a C file if possible.
* It's known that GCC and Clang treat a file as a C file if they are
* run with the "-x c" option.
* TODO We may want to further support compilation with a source file
* without a standard suffix in more compilers as far as possible.
*/
if (strcmp (env_cc,
"g++") ==
0 ||
strncmp (env_cc,
"g++-",
sizeof (
"g++-") -
1) ==
0 ||
strcmp (env_cc,
"clang++") ==
0 ||
strncmp (env_cc,
"clang++-",
sizeof (
"clang++-") -
1) ==
0)
lang_flag =
"-x c++ ";
else if (strcmp (env_cc,
"gcc") ==
0 ||
strncmp (env_cc,
"gcc-",
sizeof (
"gcc-") -
1) ==
0)
{
/* It's known GCC recognizes .CPP and .cxx, so bypass these suffixes */
if (p != NULL && strcmp (p,
".CPP") !=
0 && strcmp (p,
".cxx") !=
0)
lang_flag =
"-x c ";
}
else if (strcmp (env_cc,
"clang") ==
0 ||
strncmp (env_cc,
"clang-",
sizeof (
"clang-") -
1) ==
0)
{
/* It's known Clang recognizes .CC, .CPP, .cxx and .CXX,
* so bypass these suffixes
*/
if (p != NULL && strcmp (p,
".CC") !=
0 && strcmp (p,
".CPP") !=
0 &&
strcmp (p,
".cxx") !=
0 && strcmp (p,
".CXX") !=
0)
lang_flag =
"-x c ";
}
else
{
g_printerr (
"The source file (%s) doesn't have a \"standard\
" C or C++ suffix, "
"and the tool failed to confirm the language of the file.\n"
"Please be explicit about the language of the file "
"by renaming it with one of the suffixes: .c .cc .cpp\n",
what);
exit (EXIT_FAILURE);
}
}
if (p)
*p =
'\0';
q = strrchr (dest_exe, G_DIR_SEPARATOR);
#ifdef G_OS_WIN32
{
gchar *r = strrchr (dest_exe,
'/');
if (r != NULL && (q == NULL || r > q))
q = r;
}
#endif
if (q == NULL)
q = dest_exe;
else
q++;
if (install_dir)
{
tmp = dest_dir;
dest_dir = g_strconcat (dest_dir, q, G_DIR_SEPARATOR_S, NULL);
g_free (tmp);
g_mkdir_with_parents (dest_dir,
S_IRUSR | S_IXUSR | S_IWUSR |
S_IRGRP | S_IXGRP |
S_IROTH | S_IXOTH);
}
tmp = g_strconcat (dest_dir, q, NULL);
g_free (dest_dir);
dest_exe = g_shell_quote (tmp);
g_free (tmp);
if (msvc_syntax)
{
output_flag =
"-Fe";
here_comes_linker_flags =
" -link";
windows_subsystem_flag =
" -subsystem:windows";
}
else
{
output_flag =
"-o ";
#ifdef G_OS_WIN32
windows_subsystem_flag =
" -mwindows";
#endif
}
cmd = g_strdup_printf (
"%s %s%s %s %s%s %s%s %s%s %s %s",
env_cc,
lang_flag,
env_cflags,
cflags,
output_flag,
dest_exe,
source,
here_comes_linker_flags,
env_ldflags,
windows_subsystem_flag,
libs,
env_libs);
maybe_run (cmd);
g_free (dest_exe);
g_free (source);
}
static void
do_build (
const gchar *what)
{
gchar *cflags = get_cflags ();
gchar *libs = get_libs ();
do_build_2 (cflags, libs, NULL, what);
g_free (cflags);
g_free (libs);
}
static void
do_build_noui (
const gchar *what)
{
gchar *cflags = get_cflags_noui ();
gchar *libs = get_libs_noui ();
do_build_2 (cflags, libs, NULL, what);
g_free (cflags);
g_free (libs);
}
static void
do_build_nogimpui (
const gchar *what)
{
do_build (what);
}
static gchar *
get_user_plugin_dir (
void)
{
return g_build_filename (gimp_directory (),
"plug-ins",
NULL);
}
static gchar *
get_plugin_dir (
const gchar *base_dir,
const gchar *what)
{
gchar *separator, *dot, *plugin_name, *plugin_dir;
gchar *tmp = g_strdup (what);
separator = strrchr (tmp, G_DIR_SEPARATOR);
#ifdef G_OS_WIN32
{
gchar *alt_separator = strrchr (tmp,
'/');
if (alt_separator != NULL &&
(separator == NULL || alt_separator > separator))
{
separator = alt_separator;
}
}
#endif
dot = strrchr (tmp,
'.');
if (separator)
plugin_name = separator +
1;
else
plugin_name = tmp;
if (dot)
*dot =
'\0';
plugin_dir = g_strconcat (base_dir,
G_DIR_SEPARATOR_S,
plugin_name,
NULL);
g_free (tmp);
return plugin_dir;
}
static void
do_install (
const gchar *what)
{
gchar *cflags = get_cflags ();
gchar *libs = get_libs ();
gchar *dir = get_user_plugin_dir ();
do_build_2 (cflags, libs, dir, what);
g_free (cflags);
g_free (libs);
g_free (dir);
}
static void
do_install_noui (
const gchar *what)
{
gchar *cflags = get_cflags_noui ();
gchar *libs = get_libs_noui ();
gchar *dir = get_user_plugin_dir ();
do_build_2 (cflags, libs, dir, what);
g_free (cflags);
g_free (libs);
g_free (dir);
}
static void
do_install_nogimpui (
const gchar *what)
{
do_install (what);
}
static gchar *
get_sys_plugin_dir (gboolean forward_slashes)
{
gchar *dir;
#ifdef G_OS_WIN32
gchar *rprefix;
rprefix = get_runtime_prefix (forward_slashes ?
'/' : G_DIR_SEPARATOR);
dir = g_build_path (forward_slashes ?
"/" : G_DIR_SEPARATOR_S,
rprefix,
"lib",
"gimp",
GIMP_PLUGIN_VERSION,
"plug-ins",
NULL);
g_free (rprefix);
#else
dir = g_build_path (forward_slashes ?
"/" : G_DIR_SEPARATOR_S,
LIBDIR,
"gimp",
GIMP_PLUGIN_VERSION,
"plug-ins",
NULL);
#endif
return dir;
}
static void
do_install_admin (
const gchar *what)
{
gchar *cflags = get_cflags ();
gchar *libs = get_libs ();
gchar *dir = get_sys_plugin_dir (
TRUE);
do_build_2 (cflags, libs, dir, what);
g_free (cflags);
g_free (libs);
g_free (dir);
}
static void
do_install_admin_noui (
const gchar *what)
{
gchar *cflags = get_cflags_noui ();
gchar *libs = get_libs_noui ();
gchar *dir = get_sys_plugin_dir (
TRUE);
do_build_2 (cflags, libs, dir, what);
g_free (cflags);
g_free (libs);
g_free (dir);
}
static void
do_install_admin_nogimpui (
const gchar *what)
{
gchar *cflags = get_cflags ();
gchar *libs = get_libs ();
gchar *dir = get_sys_plugin_dir (
TRUE);
do_build_2 (cflags, libs, dir, what);
g_free (cflags);
g_free (libs);
g_free (dir);
}
static void
do_install_bin_2 (
const gchar *dir,
const gchar *what)
{
gchar *cmd;
gchar *quoted_src;
gchar *quoted_dir;
gchar *dest_dir = g_strconcat (dir, G_DIR_SEPARATOR_S, NULL);
g_mkdir_with_parents (dest_dir,
S_IRUSR | S_IXUSR | S_IWUSR |
S_IRGRP | S_IXGRP |
S_IROTH | S_IXOTH);
quoted_src = g_shell_quote (what);
quoted_dir = g_shell_quote (dest_dir);
cmd = g_strconcat (COPY,
" ", quoted_src,
" ", quoted_dir, NULL);
maybe_run (cmd);
g_free (dest_dir);
g_free (cmd);
g_free (quoted_src);
g_free (quoted_dir);
}
static void
do_install_bin (
const gchar *what)
{
gchar *dir = get_user_plugin_dir ();
gchar *plugin_dir = get_plugin_dir (dir, what);
do_install_bin_2 (plugin_dir, what);
g_free (plugin_dir);
g_free (dir);
}
static void
do_install_admin_bin (
const gchar *what)
{
gchar *dir = get_sys_plugin_dir (
FALSE);
gchar *plugin_dir = get_plugin_dir (dir, what);
do_install_bin_2 (dir, what);
g_free (plugin_dir);
g_free (dir);
}
static void
do_uninstall (
const gchar *dir)
{
gchar *cmd;
gchar *quoted_src;
quoted_src = g_shell_quote (dir);
cmd = g_strconcat (REMOVE_DIR,
" ", quoted_src, NULL);
maybe_run (cmd);
g_free (cmd);
g_free (quoted_src);
}
static void
do_uninstall_script_2 (
const gchar *dir,
const gchar *what)
{
gchar *cmd;
gchar *quoted_src;
gchar *src;
src = g_strconcat (dir, G_DIR_SEPARATOR_S, what, NULL);
quoted_src = g_shell_quote (src);
cmd = g_strconcat (REMOVE,
" ", quoted_src, NULL);
maybe_run (cmd);
g_free (cmd);
g_free (quoted_src);
g_free (src);
}
static gchar *
maybe_append_exe (
const gchar *what)
{
#ifdef G_OS_WIN32
gchar *p = strrchr (what,
'.');
if (p == NULL || g_ascii_strcasecmp (p,
".exe") !=
0)
return g_strconcat (what,
".exe", NULL);
#endif
return g_strdup (what);
}
static void
do_uninstall_bin (
const gchar *what)
{
gchar *dir = get_user_plugin_dir ();
gchar *exe = maybe_append_exe (what);
gchar *plugin_dir = get_plugin_dir (dir, what);
do_uninstall (plugin_dir);
g_free (plugin_dir);
g_free (dir);
g_free (exe);
}
static void
do_uninstall_admin_bin (
const gchar *what)
{
gchar *dir = get_sys_plugin_dir (
FALSE);
gchar *exe = maybe_append_exe (what);
gchar *plugin_dir = get_plugin_dir (dir, what);
do_uninstall (plugin_dir);
g_free (plugin_dir);
g_free (dir);
g_free (exe);
}
static gchar *
get_user_script_dir (
void)
{
return g_build_filename (gimp_directory (),
"scripts",
NULL);
}
static void
do_install_script (
const gchar *what)
{
gchar *dir = get_user_script_dir ();
do_install_bin_2 (dir, what);
g_free (dir);
}
static gchar *
get_sys_script_dir (
void)
{
gchar *dir;
gchar *prefix = get_runtime_prefix (G_DIR_SEPARATOR);
dir = g_build_filename (prefix,
"share",
"gimp",
GIMP_PLUGIN_VERSION,
"scripts",
NULL);
g_free (prefix);
return dir;
}
static void
do_install_admin_script (
const gchar *what)
{
gchar *dir = get_sys_script_dir ();
do_install_bin_2 (dir, what);
g_free (dir);
}
static void
do_uninstall_script (
const gchar *what)
{
gchar *dir = get_user_script_dir ();
do_uninstall_script_2 (dir, what);
g_free (dir);
}
static void
do_uninstall_admin_script (
const gchar *what)
{
gchar *dir = get_sys_script_dir ();
do_uninstall_script_2 (dir, what);
g_free (dir);
}
int
main (
int argc,
char **argv)
{
gint argi;
gint i;
if (argc ==
1)
usage (EXIT_SUCCESS);
/* First scan for flags that affect our behavior globally, but
* are still allowed late on the command line.
*/
argi =
0;
while (++argi < argc)
{
if (strcmp (argv[argi],
"-n") ==
0 ||
strcmp (argv[argi],
"--just-print") ==
0 ||
strcmp (argv[argi],
"--dry-run") ==
0 ||
strcmp (argv[argi],
"--recon") ==
0)
{
dry_run =
TRUE;
}
else if (strcmp (argv[argi],
"--help") ==
0)
{
usage (EXIT_SUCCESS);
}
else if (g_str_has_prefix (argv[argi],
"--prefix="))
{
cli_prefix = argv[argi] + strlen (
"--prefix=");
}
else if (g_str_has_prefix (argv[argi],
"--exec-prefix="))
{
cli_exec_prefix = argv[argi] + strlen (
"--exec_prefix=");
}
else if (strcmp (argv[argi],
"--msvc-syntax") ==
0)
{
#ifdef G_OS_WIN32
msvc_syntax =
TRUE;
#else
g_printerr (
"Ignoring --msvc-syntax\n");
#endif
}
}
find_out_env_flags ();
/* Second pass, actually do something. */
argi =
0;
while (++argi < argc)
{
for (i =
0; i < G_N_ELEMENTS (dirs); i++)
{
gchar *test = g_strconcat (
"--", dirs[i].option, NULL);
if (strcmp (argv[argi], test) ==
0)
{
g_free (test);
break;
}
else
{
g_free (test);
}
}
if (i < G_N_ELEMENTS (dirs))
{
gchar *expanded = expand_and_munge (dirs[i].value);
g_print (
"%s\n", expanded);
g_free (expanded);
}
else if (strcmp (argv[argi],
"--quiet") ==
0 ||
strcmp (argv[argi],
"--silent") ==
0)
{
silent =
TRUE;
}
else if (strcmp (argv[argi],
"--version") ==
0)
{
g_print (
"%d.%d.%d\n",
GIMP_MAJOR_VERSION, GIMP_MINOR_VERSION, GIMP_MICRO_VERSION);
exit (EXIT_SUCCESS);
}
else if (strcmp (argv[argi],
"-n") ==
0 ||
strcmp (argv[argi],
"--just-print") ==
0 ||
strcmp (argv[argi],
"--dry-run") ==
0 ||
strcmp (argv[argi],
"--recon") ==
0)
;
/* Already handled */
else if (strcmp (argv[argi],
"--includedir") ==
0)
do_includedir ();
else if (strcmp (argv[argi],
"--cflags") ==
0)
do_cflags ();
else if (strcmp (argv[argi],
"--cflags-noui") ==
0)
do_cflags_noui ();
else if (strcmp (argv[argi],
"--cflags-nogimpui") ==
0)
do_cflags_nogimpui ();
else if (strcmp (argv[argi],
"--libs") ==
0)
do_libs ();
else if (strcmp (argv[argi],
"--libs-noui") ==
0)
do_libs_noui ();
else if (strcmp (argv[argi],
"--libs-nogimpui") ==
0)
do_libs_nogimpui ();
else if (g_str_has_prefix (argv[argi],
"--prefix="))
;
else if (g_str_has_prefix (argv[argi],
"--exec-prefix="))
;
else if (strcmp (argv[argi],
"--msvc-syntax") ==
0)
;
else if (strcmp (argv[argi],
"--build") ==
0)
do_build (argv[++argi]);
else if (strcmp (argv[argi],
"--build-noui") ==
0)
do_build_noui (argv[++argi]);
else if (strcmp (argv[argi],
"--build-nogimpui") ==
0)
do_build_nogimpui (argv[++argi]);
else if (strcmp (argv[argi],
"--install") ==
0)
do_install (argv[++argi]);
else if (strcmp (argv[argi],
"--install-noui") ==
0)
do_install_noui (argv[++argi]);
else if (strcmp (argv[argi],
"--install-nogimpui") ==
0)
do_install_nogimpui (argv[++argi]);
else if (strcmp (argv[argi],
"--install-admin") ==
0)
do_install_admin (argv[++argi]);
else if (strcmp (argv[argi],
"--install-admin-noui") ==
0)
do_install_admin_noui (argv[++argi]);
else if (strcmp (argv[argi],
"--install-admin-nogimpui") ==
0)
do_install_admin_nogimpui (argv[++argi]);
else if (strcmp (argv[argi],
"--install-bin") ==
0)
do_install_bin (argv[++argi]);
else if (strcmp (argv[argi],
"--install-admin-bin") ==
0)
do_install_admin_bin (argv[++argi]);
else if (strcmp (argv[argi],
"--uninstall-bin") ==
0)
do_uninstall_bin (argv[++argi]);
else if (strcmp (argv[argi],
"--uninstall-admin-bin") ==
0)
do_uninstall_admin_bin (argv[++argi]);
else if (strcmp (argv[argi],
"--install-script") ==
0)
do_install_script (argv[++argi]);
else if (strcmp (argv[argi],
"--install-admin-script") ==
0)
do_install_admin_script (argv[++argi]);
else if (strcmp (argv[argi],
"--uninstall-script") ==
0)
do_uninstall_script (argv[++argi]);
else if (strcmp (argv[argi],
"--uninstall-admin-script") ==
0)
do_uninstall_admin_script (argv[++argi]);
else
{
g_printerr (
"Unrecognized switch %s\n", argv[argi]);
usage (EXIT_FAILURE);
}
}
exit (EXIT_SUCCESS);
}
/*
* Local Variables:
* mode: c
* End:
*/