Beispiel #1
0
char *
single_path_relocation(const char *from, const char *to)
{
#if defined(__MINGW32__)
  char exe_path[PATH_MAX];
  get_executable_path (NULL, &exe_path[0], sizeof(exe_path)/sizeof(exe_path[0]));
  if (strrchr (exe_path, '/') != NULL)
  {
     strrchr (exe_path, '/')[1] = '\0';
  }
  char * rel_to_datadir = get_relative_path (from, to);
  strcat (exe_path, rel_to_datadir);
  simplify_path (&exe_path[0]);
  return malloc_copy_string(exe_path);
#else
  return malloc_copy_string(to);
#endif
}
Beispiel #2
0
void
simplify_path_debug (const char * input, const char * expected)
{
  char * input_copy = malloc_copy_string (input);
  if ( input_copy == NULL )
  {
    _exit(1);
  }
  simplify_path (input_copy);
  int ok = (strcmp(input_copy, expected) == 0) ? 1 : 0;
  if (ok)
  {
    printf ("PASS: %s simplifies to %s\n", input, input_copy);
  }
  else
  {
    printf ("FAIL: %s simplifies to %s, should be %s\n", input, input_copy, expected);
    _exit(1);
  }
  free ((void *)input_copy);
}
Beispiel #3
0
char *
get_relative_path(char const * from_in, char const * to_in)
{
  size_t from_size = (from_in == NULL) ? 0 : strlen (from_in);
  size_t to_size = (to_in == NULL) ? 0 : strlen (to_in);
  size_t max_size = (from_size + to_size) * 2 + 4;
  char * scratch_space = (char *) alloca (from_size + 1 + to_size + 1 + max_size + max_size);
  char * from;
  char * to;
  char * common_part;
  char * result;
  size_t count;

  /* No to, return "./" */
  if (to_in == NULL)
  {
    return malloc_copy_string ("./");
  }

  /* If alloca failed or no from was given return a copy of to */
  if (   from_in == NULL
      || scratch_space == NULL )
  {
    return malloc_copy_string (to_in);
  }

  from = scratch_space;
  strcpy (from, from_in);
  to = from + from_size + 1;
  strcpy (to, to_in);
  common_part = to + to_size + 1;
  result = common_part + max_size;
  simplify_path (from);
  simplify_path (to);

  result[0] = '\0';

  size_t match_size_dirsep = 0;  /* The match size up to the last /. Always wind back to this - 1 */
  size_t match_size = 0;         /* The running (and final) match size. */
  size_t largest_size = (from_size > to_size) ? from_size : to_size;
  int to_final_is_slash = (to[to_size-1] == '/') ? 1 : 0;
  char from_c;
  char to_c;
  for (match_size = 0; match_size < largest_size; ++match_size)
  {
    /* To simplify the logic, always pretend the strings end with '/' */
    from_c = (match_size < from_size) ? from[match_size] : '/';
    to_c =   (match_size <   to_size) ?   to[match_size] : '/';

    if (from_c != to_c)
    {
      if (from_c != '\0' || to_c != '\0')
      {
        match_size = match_size_dirsep;
      }
      break;
    }
    else if (from_c == '/')
    {
      match_size_dirsep = match_size;
    }
  }
  strncpy (common_part, from, match_size);
  common_part[match_size] = '\0';
  from += match_size;
  to += match_size;
  size_t ndotdots = 0;
  char const* from_last = from + strlen(from) - 1;
  while ((from = strchr (from, '/')) && from != from_last)
  {
    ++ndotdots;
    ++from;
  }
  for (count = 0; count < ndotdots; ++count)
  {
    strcat(result, "../");
  }
  if (strlen(to) > 0)
  {
    strcat(result, to+1);
  }
  /* Make sure that if to ends with '/' result does the same, and
     vice-versa. */
  size_t size_result = strlen(result);
  if ((to_final_is_slash == 1)
      && (!size_result || result[size_result-1] != '/'))
  {
    strcat (result, "/");
  }
  else if (!to_final_is_slash
           && size_result && result[size_result-1] == '/')
  {
    result[size_result-1] = '\0';
  }

  return malloc_copy_string (result);
}