/*
 * vcdiff.c: workaround for emacs' vcdiff on Windows NT.
 *
 * Compile to vcdiff.exe; rename original vcdiff script to vcdiff.sh.
 * Place both in the same working directory (e.g., "C:\emacs\bin\").
 * sh.exe must be able to be found in $PATH.
 *
 * Kenneth B. Russell (kbrussel@alum.mit.edu) - February 2001
 * This software is in the public domain.
 * There is no warranty expressed or implied with this software.
 */

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <process.h>
#include <sys/types.h>
#include <sys/stat.h>

char*
clip_and_append(const char* base_str, const char* cut_point, char sep, const char* suffix)
{
  int result_len;
  char* result;
  int base_len;

  if (cut_point == NULL) {
    base_len = strlen(base_str);
  } else {
    base_len = cut_point - base_str;
  }
  result_len = base_len + strlen(suffix) + 2;
  result = malloc(result_len * sizeof(char));
  strncpy(result, base_str, base_len);
  sprintf(&result[base_len], "%c%s", sep, suffix);
  return result;
}
                
char*
compute_script_pathname_aux(const char* cur_exe_path, const char* script_name, char sep)
{
  char* tmp;

  tmp = strrchr(cur_exe_path, sep);
  if (tmp == NULL) {
    return NULL;
  }

  return clip_and_append(cur_exe_path, tmp, sep, script_name);
}

char*
compute_script_pathname(const char* cur_exe_path, const char* script_name)
{
  char* result;

  if ((result = compute_script_pathname_aux(cur_exe_path, script_name, '\\')) != NULL) {
    return result;
  }

  if ((result = compute_script_pathname_aux(cur_exe_path, script_name, '/')) != NULL) {
    return result;
  }

  return strdup(script_name);
}

char*
find_in_path(const char* exe_name)
{
  char* path = getenv("PATH");
  char* cur_path = path;
  
  while (cur_path != NULL) {
    char* next_path;
    char* cur_exe;
    struct _stat statbuf;

    while (cur_path[0] == ';') {
      cur_path++;
    }

    next_path = strchr(cur_path, ';');
    cur_exe = clip_and_append(cur_path, next_path, '\\', exe_name);

    if (_stat(cur_exe, &statbuf) == 0) {
      return cur_exe;
    }

    free(cur_exe);
    cur_path = next_path;
  }

  // Not found in path
  return NULL;
}

int
main(int argc, char **argv)
{
  char** new_argv;
  char* cmd = "sh.exe";
  char* full_cmd;
  int new_argc;
  int i;
  
  full_cmd = find_in_path(cmd);
  if (full_cmd == NULL) {
    printf("vcdiff.exe: %s not found in $PATH\n", cmd);
    return 1;
  }

  new_argc = argc + 2;
  new_argv = (char**) malloc(new_argc * sizeof(char *));
  new_argv[0] = full_cmd;
  new_argv[1] = compute_script_pathname(argv[0], "vcdiff.sh");
  new_argv[argc + 1] = NULL;
  for (i = 1; i < argc; i++) {
    new_argv[i+1] = argv[i];
  }

  /*
  for (i = 0; new_argv[i] != NULL; i++) {
    printf("Arg %d: %s\n", i, new_argv[i]);
  }
  exit(0);
  */

  /* _execv does not work properly -- behaves as though the subprocess
     were being launched in the background */
  return _spawnv(_P_WAIT, full_cmd, new_argv);
}

