diff options
Diffstat (limited to 'tools/gimptool.c')
-rw-r--r-- | tools/gimptool.c | 1142 |
1 files changed, 1142 insertions, 0 deletions
diff --git a/tools/gimptool.c b/tools/gimptool.c new file mode 100644 index 0000000..21fc043 --- /dev/null +++ b/tools/gimptool.c @@ -0,0 +1,1142 @@ +/* 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" +#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 gchar * +win32_command (const gchar *command) +{ + const gchar *comspec = getenv ("COMSPEC"); + + if (!comspec) + comspec = "cmd.exe"; + + return g_strdup_printf ("%s /c %s", comspec, command); +} + +#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+-2.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+-2.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 behaviour 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: + */ |