You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by ma...@apache.org on 2004/06/29 14:41:11 UTC

cvs commit: apr/build jlibtool.c

martin      2004/06/29 05:41:11

  Added:       build    jlibtool.c
  Log:
  Commit the missing jlibtool.c from Justin's http://www.apache.org/~jerenkrantz/jlibtool.c --
  It was referenced by "configure --enable-experimental-libtool" already.
  Also, it helps in building on platforms not directly supported by libtool
  (for those, libtools behaves utterly stupidly).
  
  Obtained from: http://www.apache.org/~jerenkrantz/jlibtool.c
  Reviewed by:	<jfclere apache.org>
  
  Revision  Changes    Path
  1.1                  apr/build/jlibtool.c
  
  Index: jlibtool.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  #include <stdio.h>
  #include <string.h>
  #include <stdlib.h>
  #include <sys/stat.h>
  #include <sys/types.h>
  #include <sys/wait.h>
  #include <unistd.h>
  #include <dirent.h>
  #include <errno.h>
  #include <assert.h>
  
  #ifdef __EMX__
  #  define SHELL_CMD  "sh"
  #  define GEN_EXPORTS "emxexp"
  #  define DEF2IMPLIB_CMD "emximp"
  #  define SHARE_SW   "-Zdll -Zmtd"
  #  define USE_OMF 1
  #  define TRUNCATE_DLL_NAME
  #  define DYNAMIC_LIB_EXT "dll"
  #  define EXE_EXT ".exe"
  
  #  if USE_OMF
       /* OMF is the native format under OS/2 */
  #    define STATIC_LIB_EXT "lib"
  #    define OBJECT_EXT     "obj"
  #    define LIBRARIAN      "emxomfar"
  #    define LIBRARIAN_OPTS "cr"
  #  else
       /* but the alternative, a.out, can fork() which is sometimes necessary */
  #    define STATIC_LIB_EXT "a"
  #    define OBJECT_EXT     "o"
  #    define LIBRARIAN      "ar"
  #    define LIBRARIAN_OPTS "cr"
  #  endif
  #endif
  
  #if defined(__APPLE__)
  #  define SHELL_CMD  "/bin/sh"
  #  define DYNAMIC_LIB_EXT "dylib"
  #  define MODULE_LIB_EXT  "so"
  #  define STATIC_LIB_EXT "a"
  #  define OBJECT_EXT     "o"
  #  define LIBRARIAN      "ar"
  #  define LIBRARIAN_OPTS "cr"
  /* man libtool(1) documents ranlib option of -c.  */
  #  define RANLIB "ranlib"
  #  define PIC_FLAG "-fPIC -fno-common"
  #  define RPATH "-rpath"
  #  define SHARED_OPTS "-dynamiclib"
  #  define MODULE_OPTS "-bundle"
  #  define DYNAMIC_LINK_OPTS "-flat_namespace -undefined suppress"
  #  define dynamic_link_version_func darwin_dynamic_link_function
  #  define DYNAMIC_INSTALL_NAME "-install_name"
  //-install_name  /Users/jerenk/apache-2.0-cvs/lib/libapr.0.dylib -compatibility_version 1 -current_version 1.0
  #endif
  
  #if defined(__linux__)
  #  define SHELL_CMD  "/bin/sh"
  #  define DYNAMIC_LIB_EXT "so"
  #  define MODULE_LIB_EXT  "so"
  #  define STATIC_LIB_EXT "a"
  #  define OBJECT_EXT     "o"
  #  define LIBRARIAN      "ar"
  #  define LIBRARIAN_OPTS "cr"
  #  define RANLIB "ranlib"
  #  define PIC_FLAG "-fPIC"
  #  define RPATH "-rpath"
  #  define DYNAMIC_LINK_OPTS "-shared"
  #  define LINKER_FLAG_PREFIX "-Wl,"
  #endif
  
  #ifdef __EMX__
  #include <process.h>
  #endif
  
  #ifndef PATH_MAX
  #define PATH_MAX 1024
  #endif
  
  /* We want to say we are libtool 1.4 for shlibtool compatibility. */
  #define VERSION "1.4"
  
  enum tool_mode_t {
      mUnknown,
      mCompile,
      mLink,
      mInstall,
  };
  
  enum output_t {
      otGeneral,
      otObject,
      otProgram,
      otLibrary,
      otStaticLibraryOnly,
      otDynamicLibraryOnly,
      otModule,
  };
  
  enum pic_mode_e {
      UNKNOWN,
      PREFER,
      AVOID,
  };
  
  typedef struct {
      const char **vals;
      int num; 
  } count_chars;
  
  typedef struct {
      const char *normal;
      const char *install;
  } library_name;
  
  typedef struct {
      count_chars *normal;
      count_chars *install;
      count_chars *dependencies;
  } library_opts;
  
  typedef struct {
      int silent;
      int shared;
      int export_all;
      int dry_run;
      enum pic_mode_e pic_mode;
      int export_dynamic;
  } options_t;
  
  typedef struct {
      enum tool_mode_t mode;
      enum output_t output;
      options_t options;
  
      char *output_name;
      char *fake_output_name;
      char *basename;
  
      const char *install_path;
      const char *compiler;
      const char *program;
      count_chars *program_opts;
  
      count_chars *arglist;
      count_chars *tmp_dirs;
      count_chars *obj_files;
      count_chars *dep_rpaths;
      count_chars *rpaths;
  
      library_name static_name;
      library_name shared_name;
      library_name module_name;
  
      library_opts static_opts;
      library_opts shared_opts;
  
      const char *version_info;
  } command_t;
  
  void init_count_chars(count_chars *cc)
  {
      cc->vals = (const char**)malloc(PATH_MAX);
      cc->num = 0;
  }
  
  void clear_count_chars(count_chars *cc)
  {
      int i;
      for (i = 0; i < cc->num; i++) {
          cc->vals[i] = 0;
      }
  
      cc->num = 0;
  }
  
  void push_count_chars(count_chars *cc, const char *newval)
  {
      cc->vals[cc->num++] = newval;
  }
  
  void insert_count_chars(count_chars *cc, const char *newval, int position)
  {
      int i;
  
      for (i = cc->num; i > position; i--) {
          cc->vals[i] = cc->vals[i-1];
      }
  
      cc->vals[position] = newval;
      cc->num++;
  }
  
  void append_count_chars(count_chars *cc, count_chars *cctoadd)
  {
      int i;
      for (i = 0; i < cctoadd->num; i++) {
          if (cctoadd->vals[i]) {
              push_count_chars(cc, cctoadd->vals[i]);
          }
      }
  }
  
  const char *flatten_count_chars(count_chars *cc)
  {
      int i, size;
      char *newval;
  
      size = 0;
      for (i = 0; i < cc->num; i++) {
          if (cc->vals[i]) {
              size += strlen(cc->vals[i]) + 1;
          }
      }
  
      newval = (char*)malloc(size + 1);
      newval[size] = 0;
  
      for (i = 0; i < cc->num; i++) {
          if (cc->vals[i]) {
              strcat(newval, cc->vals[i]);
              strcat(newval, " ");
          }
      }
  
      return newval;
  }
  
  char *shell_esc(const char *str)
  {
      char *cmd;
      unsigned char *d;
      const unsigned char *s;
  
      cmd = (char *)malloc(2 * strlen(str) + 1);
      d = (unsigned char *)cmd;
      s = (const unsigned char *)str;
  
      for (; *s; ++s) {
          if (*s == '"' || *s == '\\') {
              *d++ = '\\';
          }
          *d++ = *s;
      }
  
      *d = '\0';
      return cmd;
  }
  
  int external_spawn(command_t *cmd, const char *file, const char **argv)
  {
      if (!cmd->options.silent) {
          const char **argument = argv;
          printf("Executing: ");
          while (*argument) {
              printf("%s ", *argument);
              argument++;
          }
          puts("");
      }
  
      if (cmd->options.dry_run) {
          return 0;
      }
  #ifdef __EMX__
      return spawnvp(P_WAIT, file, argv);
  #else
      {
          pid_t pid;
          pid = fork();
          if (pid == 0) {
              return execvp(argv[0], (char**)argv);
          }
          else {
              int statuscode;
              waitpid(pid, &statuscode, 0);
              if (WIFEXITED(statuscode)) {
                  return WEXITSTATUS(statuscode);
              }
              return 0;
          }
      }
  #endif
  }
  
  int run_command(command_t *cmd_data, count_chars *cc)
  {
      char *command;
      const char *spawn_args[4];
      count_chars tmpcc;
  
      init_count_chars(&tmpcc);
  
      if (cmd_data->program) {
          push_count_chars(&tmpcc, cmd_data->program);
      }
  
      append_count_chars(&tmpcc, cmd_data->program_opts);
  
      append_count_chars(&tmpcc, cc);
  
      command = shell_esc(flatten_count_chars(&tmpcc));
  
      spawn_args[0] = SHELL_CMD;
      spawn_args[1] = "-c";
      spawn_args[2] = command;
      spawn_args[3] = NULL;
      return external_spawn(cmd_data, spawn_args[0], (const char**)spawn_args);
  }
  
  int parse_long_opt(char *arg, command_t *cmd_data)
  {
      char *equal_pos = strchr(arg, '=');
      char var[50];
      char value[500];
  
      if (equal_pos) {
          strncpy(var, arg, equal_pos - arg);
          var[equal_pos - arg] = 0;
          strcpy(value, equal_pos + 1);
      } else {
          strcpy(var, arg);
      }
  
      if (strcmp(var, "silent") == 0) {
          cmd_data->options.silent = 1;
      } else if (strcmp(var, "mode") == 0) {
          if (strcmp(value, "compile") == 0) {
              cmd_data->mode = mCompile;
              cmd_data->output = otObject;
          }
  
          if (strcmp(value, "link") == 0) {
              cmd_data->mode = mLink;
              cmd_data->output = otLibrary;
          }
  
          if (strcmp(value, "install") == 0) {
              cmd_data->mode = mInstall;
          }
      } else if (strcmp(var, "shared") == 0) {
          if (cmd_data->mode == mLink) {
              cmd_data->output = otDynamicLibraryOnly;
          }
          cmd_data->options.shared = 1;
      } else if (strcmp(var, "export-all") == 0) {
          cmd_data->options.export_all = 1;
      } else if (strcmp(var, "dry-run") == 0) {
          printf("Dry-run mode on!\n");
          cmd_data->options.dry_run = 1;
      } else if (strcmp(var, "version") == 0) {
          printf("Version " VERSION "\n");
      } else if (strcmp(var, "help") == 0) {
          printf("Sorry.  No help available.\n");
      } else {
          return 0;
      }
  
      return 1;
  }
  
  /* Return 1 if we eat it. */
  int parse_short_opt(char *arg, command_t *cmd_data)
  {
      if (strcmp(arg, "export-dynamic") == 0) {
          cmd_data->options.export_dynamic = 1;
          return 1;
      }
  
      if (strcmp(arg, "module") == 0) {
          cmd_data->output = otModule;
          return 1;
      }
  
      if (strcmp(arg, "Zexe") == 0) {
          return 1;
      }
  
      if (strcmp(arg, "avoid-version") == 0) {
          return 1;
      }
  
      if (strcmp(arg, "prefer-pic") == 0) {
          cmd_data->options.pic_mode = PREFER;
          return 1;
      }
  
      if (strcmp(arg, "prefer-non-pic") == 0) {
          cmd_data->options.pic_mode = AVOID;
          return 1;
      }
  
      if (strcmp(arg, "static") == 0) {
          /* Don't respect it for now. */
          return 1;
      }
  
      if (cmd_data->mode == mLink) {
          if (arg[0] == 'L' || arg[0] == 'l') {
              /* Hack... */
              arg--;
              push_count_chars(cmd_data->shared_opts.dependencies, arg);
              return 1;
          }
      }
      return 0;
  }
  
  char *truncate_dll_name(char *path)
  {
      /* Cut DLL name down to 8 characters after removing any mod_ prefix */
      char *tmppath = strdup(path);
      char *newname = strrchr(tmppath, '/') + 1;
      char *ext = strrchr(tmppath, '.');
      int len;
  
      if (ext == NULL)
          return tmppath;
  
      len = ext - newname;
  
      if (strncmp(newname, "mod_", 4) == 0) {
          strcpy(newname, newname + 4);
          len -= 4;
      }
  
      if (len > 8) {
          strcpy(newname + 8, strchr(newname, '.'));
      }
  
      return tmppath;
  }
  
  long safe_strtol(const char *nptr, const char **endptr, int base)
  {
      long rv;
  
      errno = 0;
  
      rv = strtol(nptr, (char**)endptr, 10);
  
      if (errno == ERANGE) {
          return 0;
      }
  
      return rv; 
  }
  
  /* version_info is in the form of MAJOR:MINOR:PATCH */
  const char *darwin_dynamic_link_function(const char *version_info)
  {
      char *newarg;
      long major, minor, patch;
  
      major = 0;
      minor = 0;
      patch = 0;
  
      if (version_info) {
          major = safe_strtol(version_info, &version_info, 10);
  
          if (version_info) {
              if (version_info[0] == ':') {
                  version_info++;
              }
  
              minor = safe_strtol(version_info, &version_info, 10);
  
              if (version_info) {
                  if (version_info[0] == ':') {
                      version_info++;
                  }
  
                  patch = safe_strtol(version_info, &version_info, 10);
  
              }
          }
      }
  
      /* Avoid -dylib_compatibility_version must be greater than zero errors. */
      if (major == 0) {
          major = 1;
      }
      newarg = (char*)malloc(100);
      snprintf(newarg, 99,
               "-compatibility_version %ld -current_version %ld.%ld",
               major, major, minor);
  
      return newarg;
  }
  
  /* genlib values
   * 0 - static
   * 1 - dynamic
   * 2 - module
   */
  char *gen_library_name(const char *name, int genlib)
  {
      char *newarg, *newext;
  
      newarg = (char *)malloc(strlen(name) + 10);
      strcpy(newarg, ".libs/");
  
      if (genlib == 2 && strncmp(name, "lib", 3) == 0) {
          name += 3;
      }
  
      strcat(newarg, name);
  
      newext = strrchr(newarg, '.') + 1;
  
      switch (genlib) {
      case 0:
          strcpy(newext, STATIC_LIB_EXT);
          break;
      case 1:
          strcpy(newext, DYNAMIC_LIB_EXT);
          break;
      case 2:
          strcpy(newext, MODULE_LIB_EXT);
          break;
      }
  
      return newarg;
  }
  
  /* genlib values
   * 0 - static
   * 1 - dynamic
   * 2 - module
   */
  char *gen_install_name(const char *name, int genlib)
  {
      struct stat sb;
      char *newname;
      int rv;
  
      newname = gen_library_name(name, genlib);
  
      /* Check if it exists. If not, return NULL.  */
      rv = stat(newname, &sb);
  
      if (rv) {
          return NULL;
      }
  
      return newname;
  }
  
  char *check_object_exists(command_t *cmd, const char *arg, int arglen)
  {
      char *newarg, *ext;
      int pass, rv;
  
      newarg = (char *)malloc(arglen + 10);
      memcpy(newarg, arg, arglen);
      newarg[arglen] = 0;
      ext = newarg + arglen;
  
      pass = 0;
  
      do {
          struct stat sb;
  
          switch (pass) {
          case 0:
              strcpy(ext, OBJECT_EXT);
              break;
  /*
          case 1:
              strcpy(ext, NO_PIC_EXT);
              break;
  */
          default:
              break;
          } 
  
          if (!cmd->options.silent) {
              printf("Checking: %s\n", newarg);
          }
          rv = stat(newarg, &sb);
      }
      while (rv != 0 && ++pass < 1);
  
      if (rv == 0) {
          if (pass == 1) {
              cmd->options.pic_mode = AVOID;
          }
          return newarg;
      }
  
      return NULL;
  }
  
  /* libdircheck values:
   * 0 - no .libs suffix
   * 1 - .libs suffix
   */
  char *check_library_exists(command_t *cmd, const char *arg, int pathlen,
                             int libdircheck)
  {
      char *newarg, *ext;
      int pass, rv, newpathlen;
  
      newarg = (char *)malloc(strlen(arg) + 10);
      strcpy(newarg, arg);
      newarg[pathlen] = 0;
  
      newpathlen = pathlen;
      if (libdircheck) {
          strcat(newarg, ".libs/");
          newpathlen += sizeof(".libs/") - 1;
      }
  
      strcpy(newarg+newpathlen, arg+pathlen);
      ext = strrchr(newarg, '.') + 1;
  
      pass = 0;
  
      do {
          struct stat sb;
  
          switch (pass) {
          case 0:
              if (cmd->options.pic_mode != AVOID || cmd->options.shared) {
                  strcpy(ext, DYNAMIC_LIB_EXT);
                  break;
              }
              pass = 1;
          case 1:
              strcpy(ext, STATIC_LIB_EXT);
              break;
          case 2:
              strcpy(ext, MODULE_LIB_EXT);
              break;
          case 3:
              strcpy(ext, OBJECT_EXT);
              break;
          default:
              break;
          } 
  
          if (!cmd->options.silent) {
              printf("Checking: %s\n", newarg);
          }
          rv = stat(newarg, &sb);
      }
      while (rv != 0 && ++pass < 4);
  
      if (rv == 0) {
          return newarg;
      }
  
      return NULL;
  }
  
  void add_linker_flag_prefix(count_chars *cc, const char *arg)
  {
  #ifndef LINKER_FLAG_PREFIX
      push_count_chars(cc, arg);
  #else
      char *newarg;
      newarg = (char*)malloc(strlen(arg) + sizeof(LINKER_FLAG_PREFIX));
      strcpy(newarg, LINKER_FLAG_PREFIX);
      strcpy(newarg, arg);
      push_count_chars(cc, newarg);
  #endif
  }
  
  int parse_input_file_name(char *arg, command_t *cmd_data)
  {
      char *ext = strrchr(arg, '.');
      char *name = strrchr(arg, '/');
      int pathlen;
      char *newarg;
  
      if (!ext) {
          return 0;
      }
  
      ext++;
  
      if (name == NULL) {
          name = strrchr(arg, '\\');
  
          if (name == NULL) {
              name = arg;
          } else {
              name++;
          }
      } else {
          name++;
      }
  
      pathlen = name - arg;
  
      if (strcmp(ext, "lo") == 0) {
          newarg = check_object_exists(cmd_data, arg, ext - arg);
          if (!newarg) {
              printf("Can not find suitable object file for %s\n", arg);
              exit(1);
          }
          if (cmd_data->mode != mLink) {
              push_count_chars(cmd_data->arglist, newarg);
          }
          else {
              push_count_chars(cmd_data->obj_files, newarg);
          }
          return 1;
      }
  
      if (strcmp(ext, "la") == 0) {
          switch (cmd_data->mode) {
          case mLink:
              /* Try the .libs dir first! */
              newarg = check_library_exists(cmd_data, arg, pathlen, 1);
              if (!newarg) {
                  /* Try the normal dir next. */
                  newarg = check_library_exists(cmd_data, arg, pathlen, 0);
                  if (!newarg) {
                      printf("Can not find suitable library for %s\n", arg);
                      exit(1);
                  }
              }
  
              if (cmd_data->mode != mLink) {
                  push_count_chars(cmd_data->arglist, newarg);
              }
              else {
                  push_count_chars(cmd_data->shared_opts.dependencies, newarg);
              }
              break;
          case mInstall:
              /* If we've already recorded a library to install, we're most
               * likely getting the .la file that we want to install as.
               * The problem is that we need to add it as the directory,
               * not the .la file itself.  Otherwise, we'll do odd things.
               */
              if (cmd_data->output == otLibrary) {
                  arg[pathlen] = '\0';
                  push_count_chars(cmd_data->arglist, arg);
              }
              else {
                  cmd_data->output = otLibrary;
                  cmd_data->output_name = arg;
                  cmd_data->static_name.install = gen_install_name(arg, 0);
                  cmd_data->shared_name.install = gen_install_name(arg, 1);
                  cmd_data->module_name.install = gen_install_name(arg, 2);
              }
              break;
          default:
              break;
          }
          return 1;
      }
  
      if (strcmp(ext, "c") == 0) {
          /* If we don't already have an idea what our output name will be. */
          if (cmd_data->basename == NULL) {
              cmd_data->basename = (char *)malloc(strlen(arg) + 4);
              strcpy(cmd_data->basename, arg);
              strcpy(strrchr(cmd_data->basename, '.') + 1, "lo");
  
              cmd_data->fake_output_name = strrchr(cmd_data->basename, '/');
              if (cmd_data->fake_output_name) {
                  cmd_data->fake_output_name++;
              }
              else {
                  cmd_data->fake_output_name = cmd_data->basename;
              }
          }
      }
  
      return 0;
  }
  
  int parse_output_file_name(char *arg, command_t *cmd_data)
  {
      char *name = strrchr(arg, '/');
      char *ext = strrchr(arg, '.');
      char *newarg = NULL;
      int pathlen;
  
      cmd_data->fake_output_name = arg;
  
      if (name) {
          name++;
      }
      else {
          name = strrchr(arg, '\\');
  
          if (name == NULL) {
              name = arg;
          }
          else {
              name++;
          }
      }
  
      if (!ext) {
          cmd_data->basename = arg;
          cmd_data->output = otProgram;
          newarg = (char *)malloc(strlen(arg) + 5);
          strcpy(newarg, arg);
  #ifdef EXE_EXT
          strcat(newarg, EXE_EXT);
  #endif
          cmd_data->output_name = newarg;
          return 1;
      }
  
      ext++;
      pathlen = name - arg;
  
      if (strcmp(ext, "la") == 0) {
          assert(cmd_data->mode == mLink);
  
          cmd_data->basename = arg;
          cmd_data->static_name.normal = gen_library_name(arg, 0);
          cmd_data->shared_name.normal = gen_library_name(arg, 1);
          cmd_data->module_name.normal = gen_library_name(arg, 2);
          cmd_data->static_name.install = gen_install_name(arg, 0);
          cmd_data->shared_name.install = gen_install_name(arg, 1);
          cmd_data->module_name.install = gen_install_name(arg, 2);
  
  #ifdef TRUNCATE_DLL_NAME
          if (shared) {
            arg = truncate_dll_name(arg);
          }
  #endif
  
          cmd_data->output_name = arg;
          return 1;
      }
  
      if (strcmp(ext, "lo") == 0) {
          cmd_data->basename = arg;
          cmd_data->output = otObject;
          newarg = (char *)malloc(strlen(arg) + 2);
          strcpy(newarg, arg);
          ext = strrchr(newarg, '.') + 1;
          strcpy(ext, OBJECT_EXT);
          cmd_data->output_name = newarg;
          return 1;
      }
  
      return 0;
  }
  
  /* returns just a file's name without path or extension */
  char *nameof(char *fullpath)
  {
      char buffer[1024];
      char *ext;
      char *name = strrchr(fullpath, '/');
  
      if (name == NULL) {
          name = strrchr(fullpath, '\\');
      }
  
      if (name == NULL) {
          name = fullpath;
      } else {
          name++;
      }
  
      strcpy(buffer, name);
      ext = strrchr(buffer, '.');
  
      if (ext) {
          *ext = 0;
          return strdup(buffer);
      }
  
      return name;
  }
  
  void parse_args(int argc, char *argv[], command_t *cmd_data)
  {
      int a;
      char *arg;
      int argused;
  
      for (a=1; a < argc; a++) {
          arg = argv[a];
          argused = 1;
  
          if (arg[0] == '-') {
              if (arg[1] == '-') {
                  argused = parse_long_opt(arg + 2, cmd_data);
              }
              else {
                  argused = parse_short_opt(arg + 1, cmd_data);
              }
  
              /* We haven't done anything with it yet, try some of the
               * more complicated short opts... */
              if (argused == 0 && a + 1 < argc) {
                  if (arg[1] == 'o' && !arg[2]) {
                      arg = argv[++a];
                      argused = parse_output_file_name(arg, cmd_data);
                  } else if (strcmp(arg+1, "rpath") == 0) {
                      /* Aha, we should try to link both! */
                      cmd_data->install_path = argv[++a];
                      argused = 1;
                  } else if (strcmp(arg+1, "version-info") == 0) {
                      /* Store for later deciphering */
                      cmd_data->version_info = argv[++a];
                      argused = 1;
                  }
              }
          } else {
              argused = parse_input_file_name(arg, cmd_data);
          }
  
          if (!argused) {
              if (!cmd_data->options.silent) {
                  printf("Adding: %s\n", arg);
              }
              push_count_chars(cmd_data->arglist, arg);
          }
      }
  
  }
  
  int explode_static_lib(const char *lib, command_t *cmd_data)
  {
      char tmpdir[1024];
      char savewd[1024];
      char cmd[1024];
      const char *name;
      DIR *dir;
      struct dirent *entry;
  
      /* Bah! */
      if (cmd_data->options.dry_run) {
          return 0;
      }
  
      strcpy(tmpdir, lib);
      strcat(tmpdir, ".exploded");
  
      mkdir(tmpdir, 0);
      push_count_chars(cmd_data->tmp_dirs, strdup(tmpdir));
      getcwd(savewd, sizeof(savewd));
  
      if (chdir(tmpdir) != 0)
          return 1;
  
      strcpy(cmd, LIBRARIAN " x ");
      name = strrchr(lib, '/');
  
      if (name) {
          name++;
      } else {
          name = lib;
      }
  
      strcat(cmd, "../");
      strcat(cmd, name);
      system(cmd);
      chdir(savewd);
      dir = opendir(tmpdir);
  
      while ((entry = readdir(dir)) != NULL) {
          if (entry->d_name[0] != '.') {
              strcpy(cmd, tmpdir);
              strcat(cmd, "/");
              strcat(cmd, entry->d_name);
              push_count_chars(cmd_data->arglist, strdup(cmd));
          }
      }
  
      closedir(dir);
      return 0;
  }
  
  #ifdef GEN_EXPORTS
  void generate_def_file(command_t *cmd_data)
  {
      char def_file[1024];
      char implib_file[1024];
      char *ext;
      FILE *hDef;
      char *export_args[1024];
      int num_export_args = 0;
      char *cmd;
      int cmd_size = 0;
      int a;
  
      if (cmd_data->output_name) {
          strcpy(def_file, cmd_data->output_name);
          strcat(def_file, ".def");
          hDef = fopen(def_file, "w");
  
          if (hDef != NULL) {
              fprintf(hDef, "LIBRARY '%s' INITINSTANCE\n", nameof(cmd_data->output_name));
              fprintf(hDef, "DATA NONSHARED\n");
              fprintf(hDef, "EXPORTS\n");
              fclose(hDef);
  
              for (a = 0; a < cmd_data->num_obj_files; a++) {
                  cmd_size += strlen(cmd_data->obj_files[a]) + 1;
              }
  
              cmd_size += strlen(GEN_EXPORTS) + strlen(def_file) + 3;
              cmd = (char *)malloc(cmd_size);
              strcpy(cmd, GEN_EXPORTS);
  
              for (a=0; a < cmd_data->num_obj_files; a++) {
                  strcat(cmd, " ");
                  strcat(cmd, cmd_data->obj_files[a] );
              }
  
              strcat(cmd, ">>");
              strcat(cmd, def_file);
              puts(cmd);
              export_args[num_export_args++] = SHELL_CMD;
              export_args[num_export_args++] = "-c";
              export_args[num_export_args++] = cmd;
              export_args[num_export_args++] = NULL;
              external_spawn(cmd_data, export_args[0], (const char**)export_args);
              cmd_data->arglist[cmd_data->num_args++] = strdup(def_file);
  
              /* Now make an import library for the dll */
              num_export_args = 0;
              export_args[num_export_args++] = DEF2IMPLIB_CMD;
              export_args[num_export_args++] = "-o";
  
              strcpy(implib_file, ".libs/");
              strcat(implib_file, cmd_data->basename);
              ext = strrchr(implib_file, '.');
  
              if (ext)
                  *ext = 0;
  
              strcat(implib_file, ".");
              strcat(implib_file, STATIC_LIB_EXT);
  
              export_args[num_export_args++] = implib_file;
              export_args[num_export_args++] = def_file;
              export_args[num_export_args++] = NULL;
              external_spawn(cmd_data, export_args[0], (const char**)export_args);
  
          }
      }
  }
  #endif
  
  const char* expand_path(const char *relpath)
  {
      char foo[PATH_MAX], *newpath;
  
      getcwd(foo, PATH_MAX-1);
      newpath = (char*)malloc(strlen(foo)+strlen(relpath)+2);
      strcat(newpath, foo);
      strcat(newpath, "/");
      strcat(newpath, relpath);
      return newpath;
  }
  
  void link_fixup(command_t *c)
  {
      /* If we were passed an -rpath directive, we need to build
       * shared objects too.  Otherwise, we should only create static
       * libraries.
       */
      if (!c->install_path && (c->output == otDynamicLibraryOnly ||
          c->output == otModule || c->output == otLibrary)) {
          c->output = otStaticLibraryOnly;
      }
  
      if (c->output == otDynamicLibraryOnly ||
          c->output == otModule ||
          c->output == otLibrary) {
  
          push_count_chars(c->shared_opts.normal, "-o");
          if (c->output == otModule) {
              push_count_chars(c->shared_opts.normal, c->module_name.normal);
          }
          else {
              char *tmp;
              push_count_chars(c->shared_opts.normal, c->shared_name.normal);
  #ifdef DYNAMIC_INSTALL_NAME
              push_count_chars(c->shared_opts.normal, DYNAMIC_INSTALL_NAME);
  
              tmp = (char*)malloc(PATH_MAX);
              strcat(tmp, c->install_path);
              strcat(tmp, strrchr(c->shared_name.normal, '/'));
              push_count_chars(c->shared_opts.normal, tmp);
  #endif
          }
  
          append_count_chars(c->shared_opts.normal, c->obj_files);
          append_count_chars(c->shared_opts.normal, c->shared_opts.dependencies);
  
          if (c->options.export_all) {
  #ifdef GEN_EXPORTS
              generate_def_file(c);
  #endif
          }
      }
  
      if (c->output == otLibrary || c->output == otStaticLibraryOnly) {
          push_count_chars(c->static_opts.normal, "-o");
          push_count_chars(c->static_opts.normal, c->output_name);
      }
  
      if (c->output == otProgram) {
          if (c->output_name) {
              push_count_chars(c->arglist, "-o");
              push_count_chars(c->arglist, c->output_name);
              append_count_chars(c->arglist, c->obj_files);
              append_count_chars(c->arglist, c->shared_opts.dependencies);
  #ifdef DYNAMIC_LINK_OPTS
              if (c->options.pic_mode != AVOID) {
                  push_count_chars(c->arglist, DYNAMIC_LINK_OPTS);
              }
  #endif
          }
      }
  }
  
  void post_parse_fixup(command_t *cmd_data)
  {
      switch (cmd_data->mode)
      {
      case mCompile:
  #ifdef PIC_FLAG
          if (cmd_data->options.pic_mode != AVOID) {
              push_count_chars(cmd_data->arglist, PIC_FLAG);
          }
  #endif
          if (cmd_data->output_name) {
              push_count_chars(cmd_data->arglist, "-o");
              push_count_chars(cmd_data->arglist, cmd_data->output_name);
          }
          break;
      case mLink:
          link_fixup(cmd_data);
          break;
      case mInstall:
          if (cmd_data->output == otLibrary) {
              link_fixup(cmd_data);
          }
      default:
          break;
      }
  
  #if USE_OMF
      if (cmd_data->output == otObject ||
          cmd_data->output == otProgram ||
          cmd_data->output == otLibrary ||
          cmd_data->output == otDynamicLibraryOnly) {
          push_count_chars(cmd_data->arglist, "-Zomf");
      }
  #endif
  
      if (cmd_data->options.shared &&
              (cmd_data->output == otObject ||
               cmd_data->output == otLibrary ||
               cmd_data->output == otDynamicLibraryOnly)) {
  #ifdef SHARE_SW
          push_count_chars(cmd_data->arglist, SHARE_SW);
  #endif
      }
  }
  
  int run_mode(command_t *cmd_data)
  {
      int rv;
      count_chars *cctemp;
  
      cctemp = (count_chars*)malloc(sizeof(count_chars));
      init_count_chars(cctemp);
  
      switch (cmd_data->mode)
      {
      case mCompile:
          rv = run_command(cmd_data, cmd_data->arglist);
          if (rv) {
              return rv;
          }
          break;
      case mInstall:
          /* Well, we'll assume it's a file going to a directory... */
          /* For brain-dead install-sh based scripts, we have to repeat
           * the command N-times.  install-sh should die.
           */
          if (!cmd_data->output_name) {
              rv = run_command(cmd_data, cmd_data->arglist);
              if (rv) {
                  return rv;
              }
          }
          if (cmd_data->output_name) {
              append_count_chars(cctemp, cmd_data->arglist);
              insert_count_chars(cctemp,
                                 cmd_data->output_name,
                                 cctemp->num - 1);
              rv = run_command(cmd_data, cctemp);
              if (rv) {
                  return rv;
              }
              clear_count_chars(cctemp);
          }
          if (cmd_data->static_name.install) {
              append_count_chars(cctemp, cmd_data->arglist);
              insert_count_chars(cctemp,
                                 cmd_data->static_name.install,
                                 cctemp->num - 1);
              rv = run_command(cmd_data, cctemp);
              if (rv) {
                  return rv;
              }
              clear_count_chars(cctemp);
          }
          if (cmd_data->shared_name.install) {
              append_count_chars(cctemp, cmd_data->arglist);
              insert_count_chars(cctemp,
                                 cmd_data->shared_name.install,
                                 cctemp->num - 1);
              rv = run_command(cmd_data, cctemp);
              if (rv) {
                  return rv;
              }
              clear_count_chars(cctemp);
          }
          if (cmd_data->module_name.install) {
              append_count_chars(cctemp, cmd_data->arglist);
              insert_count_chars(cctemp,
                                 cmd_data->module_name.install,
                                 cctemp->num - 1);
              rv = run_command(cmd_data, cctemp);
              if (rv) {
                  return rv;
              }
              clear_count_chars(cctemp);
          }
          break;
      case mLink:
          if (!cmd_data->options.dry_run) {
              /* Check first to see if the dir already exists! */
              mode_t old_umask;
  
              old_umask = umask(0);
              umask(old_umask);
  
              mkdir(".libs", ~old_umask);
          }
  
          if (cmd_data->output == otStaticLibraryOnly ||
              cmd_data->output == otLibrary) {
  #ifdef RANLIB
              const char *lib_args[3];
  #endif
              /* Removes compiler! */
              cmd_data->program = LIBRARIAN;
              push_count_chars(cmd_data->program_opts, LIBRARIAN_OPTS);
              push_count_chars(cmd_data->program_opts,
                               cmd_data->static_name.normal);
  
              rv = run_command(cmd_data, cmd_data->obj_files);
              if (rv) {
                  return rv;
              }
  
  #ifdef RANLIB
              lib_args[0] = RANLIB;
              lib_args[1] = cmd_data->static_name.normal;
              lib_args[2] = NULL;
              external_spawn(cmd_data, RANLIB, lib_args);
  #endif
              if (!cmd_data->options.dry_run) {
                  //link(
              }
          }
  
          if (cmd_data->output == otDynamicLibraryOnly ||
              cmd_data->output == otModule ||
              cmd_data->output == otLibrary) {
              cmd_data->program = NULL;
              clear_count_chars(cmd_data->program_opts);
  
              append_count_chars(cmd_data->program_opts, cmd_data->arglist);
              if (cmd_data->output != otModule) {
  #ifdef SHARED_OPTS
                  push_count_chars(cmd_data->program_opts, SHARED_OPTS);
  #endif
  #ifdef dynamic_link_version_func
                  push_count_chars(cmd_data->program_opts,
                               dynamic_link_version_func(cmd_data->version_info));
  #endif
              }
              if (cmd_data->output == otModule) {
  #ifdef MODULE_OPTS
                  push_count_chars(cmd_data->program_opts, MODULE_OPTS);
  #endif
              }
  #ifdef DYNAMIC_LINK_OPTS
              if (cmd_data->options.pic_mode != AVOID) {
                  push_count_chars(cmd_data->program_opts,
                                   DYNAMIC_LINK_OPTS);
              }
  #endif
              rv = run_command(cmd_data, cmd_data->shared_opts.normal);
              if (rv) {
                  return rv;
              }
          }
          if (cmd_data->output == otProgram) {
              rv = run_command(cmd_data, cmd_data->arglist);
              if (rv) {
                  return rv;
              }
          }
          break;
      default:
          break;
      } 
  
      return 0;
  }
  
  void cleanup_tmp_dir(const char *dirname)
  {
      DIR *dir;
      struct dirent *entry;
      char fullname[1024];
  
      dir = opendir(dirname);
  
      if (dir == NULL)
          return;
  
      while ((entry = readdir(dir)) != NULL) {
          if (entry->d_name[0] != '.') {
              strcpy(fullname, dirname);
              strcat(fullname, "/");
              strcat(fullname, entry->d_name);
              remove(fullname);
          }
      }
  
      rmdir(dirname);
  }
  
  void cleanup_tmp_dirs(command_t *cmd_data)
  {
      int d;
  
      for (d = 0; d < cmd_data->tmp_dirs->num; d++) {
          cleanup_tmp_dir(cmd_data->tmp_dirs->vals[d]);
      }
  }
  
  int ensure_fake_uptodate(command_t *cmd_data)
  {
      /* FIXME: could do the stat/touch here, but nah... */
      const char *touch_args[3];
  
      if (cmd_data->mode == mInstall) {
          return 0;
      }
  
      touch_args[0] = "touch";
      touch_args[1] = cmd_data->fake_output_name;
      touch_args[2] = NULL;
      return external_spawn(cmd_data, "touch", touch_args);
  }
  
  int main(int argc, char *argv[])
  {
      int rc;
      command_t cmd_data;
  
      memset(&cmd_data, 0, sizeof(cmd_data));
  
      cmd_data.options.pic_mode = UNKNOWN;
  
      cmd_data.program_opts = (count_chars*)malloc(sizeof(count_chars));
      init_count_chars(cmd_data.program_opts);
      cmd_data.arglist = (count_chars*)malloc(sizeof(count_chars));
      init_count_chars(cmd_data.arglist);
      cmd_data.tmp_dirs = (count_chars*)malloc(sizeof(count_chars));
      init_count_chars(cmd_data.tmp_dirs);
      cmd_data.obj_files = (count_chars*)malloc(sizeof(count_chars));
      init_count_chars(cmd_data.obj_files);
      cmd_data.dep_rpaths = (count_chars*)malloc(sizeof(count_chars));
      init_count_chars(cmd_data.dep_rpaths);
      cmd_data.rpaths = (count_chars*)malloc(sizeof(count_chars));
      init_count_chars(cmd_data.rpaths);
      cmd_data.static_opts.normal = (count_chars*)malloc(sizeof(count_chars));
      init_count_chars(cmd_data.static_opts.normal);
      cmd_data.shared_opts.normal = (count_chars*)malloc(sizeof(count_chars));
      init_count_chars(cmd_data.shared_opts.normal);
      cmd_data.shared_opts.dependencies = (count_chars*)malloc(sizeof(count_chars));
      init_count_chars(cmd_data.shared_opts.dependencies);
  
      cmd_data.mode = mUnknown;
      cmd_data.output = otGeneral;
  
      parse_args(argc, argv, &cmd_data);
      post_parse_fixup(&cmd_data);
  
      if (cmd_data.mode == mUnknown) {
          exit(0);
      }
  
      rc = run_mode(&cmd_data);
  
      if (!rc) {
         ensure_fake_uptodate(&cmd_data);
      }
  
      cleanup_tmp_dirs(&cmd_data);
      return rc;
  }
  
  
  

Re: cvs commit: apr/build jlibtool.c

Posted by Greg Stein <gs...@lyra.org>.
That license needs to be updated.

On Tue, Jun 29, 2004 at 12:41:11PM -0000, martin@apache.org wrote:
> martin      2004/06/29 05:41:11
> 
>   Added:       build    jlibtool.c
>   Log:
>   Commit the missing jlibtool.c from Justin's http://www.apache.org/~jerenkrantz/jlibtool.c --
>   It was referenced by "configure --enable-experimental-libtool" already.
>   Also, it helps in building on platforms not directly supported by libtool
>   (for those, libtools behaves utterly stupidly).
>   
>   Obtained from: http://www.apache.org/~jerenkrantz/jlibtool.c
>   Reviewed by:	<jfclere apache.org>
>   
>   Revision  Changes    Path
>   1.1                  apr/build/jlibtool.c
>   
>   Index: jlibtool.c
>   ===================================================================
>   /* ====================================================================
>    * The Apache Software License, Version 1.1
>    *
>    * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
>    * reserved.
>    *
>    * Redistribution and use in source and binary forms, with or without
>    * modification, are permitted provided that the following conditions
>    * are met:
>    *
>    * 1. Redistributions of source code must retain the above copyright
>    *    notice, this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the above copyright
>    *    notice, this list of conditions and the following disclaimer in
>    *    the documentation and/or other materials provided with the
>    *    distribution.
>    *
>    * 3. The end-user documentation included with the redistribution,
>    *    if any, must include the following acknowledgment:
>    *       "This product includes software developed by the
>    *        Apache Software Foundation (http://www.apache.org/)."
>    *    Alternately, this acknowledgment may appear in the software itself,
>    *    if and wherever such third-party acknowledgments normally appear.
>    *
>    * 4. The names "Apache" and "Apache Software Foundation" must
>    *    not be used to endorse or promote products derived from this
>    *    software without prior written permission. For written
>    *    permission, please contact apache@apache.org.
>    *
>    * 5. Products derived from this software may not be called "Apache",
>    *    nor may "Apache" appear in their name, without prior written
>    *    permission of the Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
>    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>    * SUCH DAMAGE.
>    * ====================================================================
>    *
>    * This software consists of voluntary contributions made by many
>    * individuals on behalf of the Apache Software Foundation.  For more
>    * information on the Apache Software Foundation, please see
>    * <http://www.apache.org/>.
>    */

-- 
Greg Stein, http://www.lyra.org/

Re: cvs commit: apr/build jlibtool.c

Posted by David Reid <da...@jetnet.co.uk>.
> --On Tuesday, June 29, 2004 3:31 PM +0200 "Roy T. Fielding"
> <fi...@gbiv.com> wrote:
>
> > Hello?  What makes you think you can do that?  Aside from having the
> > wrong license, you don't have the right to commit Justin's code unless
> > he tells you to do so on the public mailing list.  You should ask him
> > to do the commit himself, since that makes it a donation by the author
> > rather than a copy by someone else.
> >
> > -1 to that commit.  +1 to Justin fixing the license and committing
> > the code.
>
> Wow.  Yah.  Why did this get committed?  And why now?  Was there a
particular
> reason that you wanted this?  I'm fairly sure that there wasn't a
discussion
> about this on dev@apr.  So where did this review happen?  *scratches head*

Sums up my own reaction.

> I'm not totally against relicensing and committing it, but especially so
close
> to APR 1.0, I'd at least like to know why now.  I believe in the past the
> feeling was that jlibtool should not be in the tree - Jeff and several
others
> have their own libtool replacements, so, at the last ApacheCon, we had
> discussed taking a real effort and support all of them.  *shrug*  -- 
justin

Actually I wasn't going to tag this for 1.0 anyways for the exact reasons
you state.

david


Re: cvs commit: apr/build jlibtool.c

Posted by Justin Erenkrantz <ju...@erenkrantz.com>.
--On Tuesday, June 29, 2004 3:31 PM +0200 "Roy T. Fielding" 
<fi...@gbiv.com> wrote:

> Hello?  What makes you think you can do that?  Aside from having the
> wrong license, you don't have the right to commit Justin's code unless
> he tells you to do so on the public mailing list.  You should ask him
> to do the commit himself, since that makes it a donation by the author
> rather than a copy by someone else.
>
> -1 to that commit.  +1 to Justin fixing the license and committing
> the code.

Wow.  Yah.  Why did this get committed?  And why now?  Was there a particular 
reason that you wanted this?  I'm fairly sure that there wasn't a discussion 
about this on dev@apr.  So where did this review happen?  *scratches head*

I'm not totally against relicensing and committing it, but especially so close 
to APR 1.0, I'd at least like to know why now.  I believe in the past the 
feeling was that jlibtool should not be in the tree - Jeff and several others 
have their own libtool replacements, so, at the last ApacheCon, we had 
discussed taking a real effort and support all of them.  *shrug*  -- justin

Re: cvs commit: apr/build jlibtool.c

Posted by "Roy T. Fielding" <fi...@gbiv.com>.
On Tuesday, June 29, 2004, at 02:41  PM, martin@apache.org wrote:

> martin      2004/06/29 05:41:11
>
>   Added:       build    jlibtool.c
>   Log:
>   Commit the missing jlibtool.c from Justin's 
> http://www.apache.org/~jerenkrantz/jlibtool.c --
>   It was referenced by "configure --enable-experimental-libtool" 
> already.
>   Also, it helps in building on platforms not directly supported by 
> libtool
>   (for those, libtools behaves utterly stupidly).
>
>   Obtained from: http://www.apache.org/~jerenkrantz/jlibtool.c
>   Reviewed by:	<jfclere apache.org>

Hello?  What makes you think you can do that?  Aside from having the
wrong license, you don't have the right to commit Justin's code unless
he tells you to do so on the public mailing list.  You should ask him
to do the commit himself, since that makes it a donation by the author
rather than a copy by someone else.

-1 to that commit.  +1 to Justin fixing the license and committing
the code.

....Roy