From a6d55ba754700bd075345dd370157ab976dd8f61 Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Sun, 20 Jul 2003 21:52:37 +0000 Subject: [PATCH] New file, from stable branch. (Haven't checked yet what changes might be 2003-07-20 Tor Lillqvist * gimptool-win32.c.in: New file, from stable branch. (Haven't checked yet what changes might be needed to it here in HEAD.) --- ChangeLog | 5 + gimptool-win32.c.in | 825 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 830 insertions(+) create mode 100644 gimptool-win32.c.in diff --git a/ChangeLog b/ChangeLog index fe698778d3..3825050bc6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2003-07-20 Tor Lillqvist + + * gimptool-win32.c.in: New file, from stable branch. (Haven't + checked yet what changes might be needed to it here in HEAD.) + 2003-07-20 Sven Neumann Generalized text rendering and added a framework for creating diff --git a/gimptool-win32.c.in b/gimptool-win32.c.in new file mode 100644 index 0000000000..61163da149 --- /dev/null +++ b/gimptool-win32.c.in @@ -0,0 +1,825 @@ +/* gimptool in C + * Copyright (C) 2001 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * Gimptool rewritten in C, primarily 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. + * + * Yes, this program leaks dynamically allocated strings without + * hesitation. So what, it runs only for a minimal time. + */ + +#include +#include +#include + +#include + +#include + +static gboolean silent = FALSE; +static gboolean dry_run = FALSE; +static gchar *prefix; +static gchar *exec_prefix; + +static gchar *env_cc; +static gboolean msvc_syntax = FALSE; +static gchar *env_cflags; +static gchar *env_ldflags; +static gchar *env_libs; + +#ifdef G_OS_WIN32 +#define EXEEXT ".exe" +#else +#define EXEEXT "" +#endif + +#ifdef G_OS_WIN32 +#define IS_EXECUTABLE(mode) 1 +#else +#define IS_EXECUTABLE(mode) (S_IXUSR & st.st_mode) +#endif + +#ifdef G_OS_WIN32 +#define USE_PKG_CONFIG yep +#else +#if defined (GLIB_CHECK_VERSION) && GLIB_CHECK_VERSION (1, 3, 10) +#define USE_PKG_CONFIG also yep +#endif +#endif + +#ifdef G_OS_WIN32 +#define COPY win32_command ("copy") +#define REMOVE win32_command ("del") +#else +#define COPY "cp" +#define REMOVE "rm -f" +#endif + +static struct { + gchar *option; + gchar *value; +} dirs[] = { + { "prefix", "@prefix@" }, + { "exec-prefix", "@exec_prefix@" }, + { "bindir", "@bindir@" }, + { "sbindir", "@sbindir@" }, + { "libexecdir", "@libexecdir@" }, + { "datadir", "@datadir@" }, + { "sysconfdir", "@sysconfdir@" }, + { "sharedstatedir", "@sharedstatedir@" }, + { "localstatedir", "@localstatedir@" }, + { "libdir", "@libdir@" }, + { "infodir", "@infodir@" }, + { "mandir", "@mandir@" }, + { "includedir", "@includedir@" }, + { "gimpplugindir", "@gimpplugindir@" }, + { "gimpdatadir", "@gimpdatadir@" } +}; + +#ifdef G_OS_WIN32 + +static gchar * +win32_command (gchar *command) +{ + gchar *comspec = getenv ("COMSPEC"); + + if (!comspec) + comspec = "command.com"; + + return g_strdup_printf ("%s /c %s", comspec, command); +} + +#endif + +static gboolean +starts_with (gchar *string, + gchar *test) +{ + return strncmp (string, test, strlen (test)) == 0; +} + +static gboolean +starts_with_dir (gchar *string, + gchar *test) +{ + return starts_with (string, g_strconcat (test, "/", NULL)) || + strcmp (string, test) == 0; +} + +static gchar * +get_prefix (gchar slash) +{ +#ifdef G_OS_WIN32 + /* Don't use the build-time @prefix@, but deduce the + * installation-time prefix from where gimp.exe can be found. + */ + + char *path; + char *p; + char *q, *r; + struct stat st; + + if (prefix != NULL) + return prefix; + + p = path = g_strdup (g_getenv ("PATH")); + + while ((q = strchr (p, G_SEARCHPATH_SEPARATOR)) != NULL) + { + gchar *test; + *q = '\0'; + + test = g_strconcat (p, G_DIR_SEPARATOR_S, "gimp", EXEEXT, NULL); + if (stat (test, &st) == 0 && + IS_EXECUTABLE (st.st_mode)) + { + r = strrchr (test, G_DIR_SEPARATOR); + if (r != NULL) + { + *r = '\0'; + if (strlen (test) >= 4 && + g_strcasecmp (r - 4, G_DIR_SEPARATOR_S "bin") == 0) + { + r[-4] = '\0'; + prefix = test; +#ifdef G_OS_WIN32 + if (slash == '/') + { + /* Use forward slashes, less quoting trouble in Makefiles */ + while ((p = strchr (prefix, '\\')) != NULL) + *p = '/'; + } +#endif + return prefix; + } + } + } + p = q + 1; + } + + fprintf (stderr, "Cannot find any suitable GIMP executable in PATH\n"); + exit (1); +#else + return "@prefix@"; +#endif +} + +static gchar * +get_exec_prefix (gchar slash) +{ +#ifdef G_OS_WIN32 + if (exec_prefix != NULL) + return 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 (exec_prefix = get_prefix (slash)); +#else + return "@exec_prefix@"; +#endif +} + +static gchar * +expand_and_munge (gchar *value) +{ + if (starts_with_dir (value, "${prefix}")) + value = g_strconcat ("@prefix@", value + strlen ("${prefix}"), NULL); + else if (starts_with_dir (value, "${exec_prefix}")) + value = g_strconcat ("@exec_prefix@", value + strlen ("${exec_prefix}"), NULL); + if (starts_with_dir (value, "@exec_prefix@")) + value = g_strconcat (get_exec_prefix ('/'), value + strlen ("@exec_prefix@"), NULL); + + if (starts_with_dir (value, "@prefix@")) + value = g_strconcat (get_prefix ('/'), value + strlen ("@prefix@"), NULL); + + return value; +} + +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_strncasecmp (env_cc, "cl", 2) == 0) + msvc_syntax = TRUE; + + if ((p = getenv ("CFLAGS")) != NULL) + env_cflags = p; + else if (msvc_syntax && g_strncasecmp ("@CC@", "cl", 2) != 0) + /* Don't use CFLAGS for wrong compiler... */ + env_cflags = ""; + else + env_cflags = "@CFLAGS@"; + + if ((p = getenv ("LDFLAGS")) != NULL) + env_ldflags = p; + else if (msvc_syntax && g_strncasecmp ("@CC@", "cl", 2) != 0) + /* Ditto for LDFLAGS */ + env_ldflags = ""; + else + env_ldflags = "@LDFLAGS@"; + + if ((p = getenv ("LIBS")) != NULL && *p != '\0') + env_libs = p; + else + env_libs = ""; +} + +static void +usage (int exit_status) +{ + printf ("\ +Usage: gimptool [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 site 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 libgumpui, append -nogimpui.\n"); + exit (exit_status); +} + +static gchar * +one_line_output (gchar *program, + gchar *args) +{ + FILE *pipe = popen (g_strconcat (program, " ", args, NULL), "r"); + char line[1000]; + + if (pipe == NULL) + { + fprintf (stderr, "Cannot run %s\n", program); + exit (1); + } + + fgets (line, sizeof (line), pipe); + if (line [strlen (line) - 1] == '\n') + line [strlen (line) - 1] = '\0'; + if (line [strlen (line) - 1] == '\r') + line [strlen (line) - 1] = '\0'; + + pclose (pipe); + + return g_strdup (line); +} + +#ifdef USE_PKG_CONFIG + +static gchar * +pkg_config (gchar *args) +{ + if (msvc_syntax) + return one_line_output ("pkg-config --msvc-syntax", args); + else + return one_line_output ("pkg-config", args); +} + +#endif + +static gchar * +glib_config (gchar *args) +{ +#ifdef USE_PKG_CONFIG + return pkg_config (g_strconcat (args, " glib-2.0", NULL)); +#else + return one_line_output ("glib-config", args); +#endif +} + +static gchar * +gtk_config (gchar *args) +{ +#ifdef USE_PKG_CONFIG +#if defined (G_OS_WIN32) && @GIMP_MAJOR_VERSION@ == 1 && @GIMP_MINOR_VERSION@ == 2 + return pkg_config (g_strconcat (args, " gtk+-1.3-win32-production", NULL)); +#else + return pkg_config (g_strconcat (args, " gtk+-2.0", NULL)); +#endif +#else + return one_line_output ("gtk-config", args); +#endif +} + +static gchar * +get_cflags (void) +{ + gchar *gtk_cflags = gtk_config ("--cflags"); + + /* Yes, do use forward slashes here also on Windows. The compilers + * accept it, and it means less quoting trouble when using backquoted + * invokations of gimptool in Makefiles. + */ + return g_strdup_printf ("%s -I%s/include", gtk_cflags, get_prefix ('/')); +} + +static void +do_cflags (void) +{ + printf ("%s\n", get_cflags ()); +} + +static gchar * +get_cflags_noui (void) +{ + gchar *glib_cflags = glib_config ("--cflags"); + + return g_strdup_printf ("%s -I%s/include", glib_cflags, get_prefix ('/')); +} + +static void +do_cflags_noui (void) +{ + printf ("%s\n", get_cflags_noui ()); +} + +static gchar * +get_libs (void) +{ + gchar *gtk_libs = gtk_config ("--libs"); + + if (msvc_syntax) + return g_strdup_printf ("/libpath:%s/lib gimpui.lib gimp.lib %s", get_prefix ('/'), gtk_libs); + else + return g_strdup_printf ("-L%s/lib -lgimpui -lgimp %s", get_prefix ('/'), gtk_libs); +} + +static void +do_libs (void) +{ + printf ("%s\n", get_libs ()); +} + +static gchar * +get_libs_noui (void) +{ + gchar *glib_libs = glib_config ("--libs"); + + if (msvc_syntax) + return g_strdup_printf ("/libpath:%s/lib gimp.lib %s", get_prefix ('/'), glib_libs); + else + return g_strdup_printf ("-L%s/lib -lgimp %s", get_prefix ('/'), glib_libs); +} + +static void +do_libs_noui (void) +{ + printf ("%s\n", get_libs_noui ()); +} + +static void +maybe_run (gchar *cmd) +{ + if (!silent) + printf ("%s\n", cmd); + + if (!dry_run) + system (cmd); +} + +static void +do_build_2 (gchar *cflags, + gchar *libs, + gchar *install_dir, + gchar *what) +{ + gchar *cmd; + gchar *dest_dir; + gchar *output_flag; + gchar *dest_exe; + gchar *here_comes_linker_flags; + gchar *windows_subsystem_flag; + gchar *p, *q, *r; + + if (install_dir != NULL) + dest_dir = g_strconcat (install_dir, "/", NULL); + else + dest_dir = ""; + + dest_exe = g_strdup (what); + + p = strrchr (dest_exe, '.'); + if (p == NULL || !(strcmp (p, ".c") == 0 || strcmp (p, ".cc") == 0 || strcmp (p, ".cpp") == 0)) + { + fprintf (stderr, "plug-in source %s is not a C or C++ file?\n", what); + exit (1); + } + + *p = '\0'; + q = strrchr (dest_exe, G_DIR_SEPARATOR); +#ifdef G_OS_WIN32 + r = strrchr (dest_exe, '/'); + if (r != NULL && (q == NULL || r > q)) + q = r; +#endif + if (q == NULL) + q = dest_exe; + else + q++; + + dest_exe = g_strconcat (q, EXEEXT, NULL); + + if (msvc_syntax) + { + output_flag = "-Fe"; + here_comes_linker_flags = "-link"; + windows_subsystem_flag = "-subsystem:windows"; + } + else + { + output_flag = "-o "; + here_comes_linker_flags = ""; + windows_subsystem_flag = "-mwindows"; + } + + cmd = g_strdup_printf ("%s %s %s %s%s%s %s %s %s %s %s %s", + env_cc, + env_cflags, + cflags, + output_flag, + dest_dir, + dest_exe, + what, + here_comes_linker_flags, + env_ldflags, + windows_subsystem_flag, + libs, + env_libs); + maybe_run (cmd); +} + +static void +do_build (char *what) +{ + do_build_2 (get_cflags (), get_libs (), NULL, what); +} + +static void +do_build_noui (char *what) +{ + do_build_2 (get_cflags_noui (), get_libs_noui (), NULL, what); +} + +static void +do_build_nogimpui (char *what) +{ + do_build (what); +} + +static gchar * +get_user_plugin_dir (gboolean forward_slashes) +{ +#ifdef G_OS_WIN32 + /* In the --install-bin and --uninstall modes we want + * to use backward slashes on Win32, because we invoke + * the COPY and DEL commands directly with system(). + */ + + const gchar slash = forward_slashes ? '/' : '\\'; +#else + const gchar slash = '/'; +#endif + + return g_strdup_printf ("%s%c@gimpdir@%cplug-ins", + g_get_home_dir (), slash, slash); +} + +static void +do_install (char *what) +{ + do_build_2 (get_cflags (), get_libs (), get_user_plugin_dir (TRUE), what); +} + +static void +do_install_noui (char *what) +{ + do_build_2 (get_cflags_noui (), get_libs_noui (), get_user_plugin_dir (TRUE), what); +} + +static void +do_install_nogimpui (char *what) +{ + do_install (what); +} + +static gchar * +get_sys_plugin_dir (gboolean forward_slashes) +{ +#ifdef G_OS_WIN32 + const gchar slash = forward_slashes ? '/' : '\\'; +#else + const gchar slash = '/'; +#endif + + return g_strdup_printf ("%s%clib%cgimp%c%d.%d%cplug-ins", + get_prefix (slash), + slash, slash, slash, + @GIMP_MAJOR_VERSION@, @GIMP_MINOR_VERSION@, + slash); +} + +static void +do_install_admin (char *what) +{ + do_build_2 (get_cflags (), get_libs (), get_sys_plugin_dir (FALSE), what); +} + +static void +do_install_admin_noui (char *what) +{ + do_build_2 (get_cflags_noui (), get_libs_noui (), get_sys_plugin_dir (FALSE), what); +} + +static void +do_install_admin_nogimpui (char *what) +{ + do_build_2 (get_cflags (), get_libs (), get_sys_plugin_dir (FALSE), what); +} + +static void +do_install_bin_2 (gchar *dir, + gchar *what) +{ + maybe_run (g_strconcat (COPY, " ", what, " ", dir, NULL)); +} + +static void +do_install_bin (char *what) +{ + do_install_bin_2 (get_user_plugin_dir (FALSE), what); +} + +static void +do_install_admin_bin (char *what) +{ + do_install_bin_2 (get_sys_plugin_dir (FALSE), what); +} + +static void +do_uninstall (gchar *dir, + gchar *what) +{ + maybe_run (g_strconcat (REMOVE, " ", dir, G_DIR_SEPARATOR_S, what, NULL)); +} + +static gchar * +maybe_append_exe (gchar *what) +{ +#ifdef G_OS_WIN32 + gchar *p = strrchr (what, '.'); + + if (p == NULL || g_strcasecmp (p, ".exe") != 0) + return g_strconcat (what, ".exe"); +#endif + + return what; +} + +static void +do_uninstall_bin (char *what) +{ + do_uninstall (get_user_plugin_dir (FALSE), maybe_append_exe (what)); +} + +static void +do_uninstall_admin_bin (char *what) +{ + do_uninstall (get_sys_plugin_dir (FALSE), maybe_append_exe (what)); +} + +static gchar * +get_user_script_dir (gboolean forward_slashes) +{ +#ifdef G_OS_WIN32 + const gchar slash = forward_slashes ? '/' : '\\'; +#else + const gchar slash = '/'; +#endif + + return g_strdup_printf ("%s%c@gimpdir@%cscripts", + g_get_home_dir (), slash, slash); +} + +static void +do_install_script (char *what) +{ + do_install_bin_2 (get_user_script_dir (FALSE), what); +} + +static gchar * +get_sys_script_dir (gboolean forward_slashes) +{ +#ifdef G_OS_WIN32 + const gchar slash = forward_slashes ? '/' : '\\'; +#else + const gchar slash = '/'; +#endif + + return g_strdup_printf ("%s%cshare%cgimp%c%d.%d%cscripts", + get_prefix (slash), + slash, slash, slash, + @GIMP_MAJOR_VERSION@, @GIMP_MINOR_VERSION@, + slash); +} + +static void +do_install_admin_script (char *what) +{ + do_install_bin_2 (get_sys_script_dir (FALSE), what); +} + +static void +do_uninstall_script (char *what) +{ + do_uninstall (get_user_script_dir (FALSE), what); +} + +static void +do_uninstall_admin_script (char *what) +{ + do_uninstall (get_sys_script_dir (FALSE), what); +} + +int +main (int argc, + char **argv) +{ + gint argi; + gint i; + + if (argc == 1) + usage (0); + + /* 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 (starts_with (argv[argi], "--prefix=")) + prefix = argv[argi] + strlen ("--prefix="); + else if (starts_with (argv[argi], "--exec-prefix=")) + exec_prefix = argv[argi] + strlen ("--exec_prefix="); + else if (strcmp (argv[argi], "--msvc-syntax") == 0) + msvc_syntax = TRUE; + } + + find_out_env_flags (); + + /* Second pass, actually do something. */ + argi = 0; + while (++argi < argc) + { + for (i = 0; i < G_N_ELEMENTS (dirs); i++) + if (strcmp (argv[argi], g_strconcat ("--", dirs[i].option, NULL)) == 0) + break; + if (i < G_N_ELEMENTS (dirs)) + printf ("%s\n", expand_and_munge (dirs[i].value)); + else if (strcmp (argv[argi], "--help") == 0) + usage (0); + else if (strcmp (argv[argi], "--quiet") == 0 || + strcmp (argv[argi], "--silent") == 0) + silent = TRUE; + else if (strcmp (argv[argi], "--version") == 0) + { + printf ("%d.%d.%d\n", @GIMP_MAJOR_VERSION@, @GIMP_MINOR_VERSION@, @GIMP_MICRO_VERSION@); + exit (0); + } + 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], "--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 (); + else if (strcmp (argv[argi], "--libs") == 0) + do_libs (); + else if (strcmp (argv[argi], "--libs-noui") == 0) + do_libs_noui (); + else if (starts_with (argv[argi], "--prefix=")) + ; + else if (starts_with (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 + { + fprintf (stderr, "Unrecognized switch %s\n", argv[argi]); + usage (1); + } + } + exit (0); +} +/* + * Local Variables: + * mode: c + * End: + */