/* gui_string_util.c - String utilities used by the GUI system.  */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
 *
 *  GRUB 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.
 *
 *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <grub/gui_string_util.h>
#include <grub/types.h>
#include <grub/misc.h>
#include <grub/mm.h>

/* Create a new NUL-terminated string on the heap as a substring of BUF.
   The range of buf included is the half-open interval [START,END).
   The index START is inclusive, END is exclusive.  */
char *
grub_new_substring (const char *buf,
                    grub_size_t start, grub_size_t end)
{
  if (end < start)
    return 0;
  grub_size_t len = end - start;
  char *s = grub_malloc (len + 1);
  if (! s)
    return 0;
  grub_memcpy (s, buf + start, len);
  s[len] = '\0';
  return s;
}

/* Eliminate "." and ".." path elements from PATH.  A new heap-allocated
   string is returned.  */
static char *
canonicalize_path (const char *path)
{
  int i;
  const char *p;
  char *newpath = 0;

  /* Count the path components in path.  */
  int components = 1;
  for (p = path; *p; p++)
    if (*p == '/')
      components++;

  char **path_array = grub_malloc (components * sizeof (*path_array));
  if (! path_array)
    return 0;

  /* Initialize array elements to NULL pointers; in case once of the
     allocations fails, the cleanup code can just call grub_free() for all
     pointers in the array.  */
  for (i = 0; i < components; i++)
    path_array[i] = 0;

  /* Parse the path into path_array.  */
  p = path;
  for (i = 0; i < components && p; i++)
    {
      /* Find the end of the path element.  */
      const char *end = grub_strchr (p, '/');
      if (!end)
        end = p + grub_strlen (p);

      /* Copy the element.  */
      path_array[i] = grub_new_substring (p, 0, end - p);
      if (! path_array[i])
        goto cleanup;

      /* Advance p to point to the start of the next element, or NULL.  */
      if (*end)
        p = end + 1;
      else
        p = 0;
    }

  /* Eliminate '.' and '..' elements from the path array.  */
  int newpath_length = 0;
  for (i = components - 1; i >= 0; --i)
    {
      if (! grub_strcmp (path_array[i], "."))
        {
          grub_free (path_array[i]);
          path_array[i] = 0;
        }
      else if (! grub_strcmp (path_array[i], "..")
               && i > 0)
        {
          /* Delete the '..' and the prior path element.  */
          grub_free (path_array[i]);
          path_array[i] = 0;
          --i;
          grub_free (path_array[i]);
          path_array[i] = 0;
        }
      else
        {
          newpath_length += grub_strlen (path_array[i]) + 1;
        }
    }

  /* Construct a new path string.  */
  newpath = grub_malloc (newpath_length + 1);
  if (! newpath)
    goto cleanup;

  newpath[0] = '\0';
  char *newpath_end = newpath;
  int first = 1;
  for (i = 0; i < components; i++)
    {
      char *element = path_array[i];
      if (element)
        {
          /* For all components but the first, prefix with a slash.  */
          if (! first)
            newpath_end = grub_stpcpy (newpath_end, "/");
          newpath_end = grub_stpcpy (newpath_end, element);
          first = 0;
        }
    }

cleanup:
  for (i = 0; i < components; i++)
    grub_free (path_array[i]);
  grub_free (path_array);

  return newpath;
}

/* Return a new heap-allocated string representing to absolute path
   to the file referred to by PATH.  If PATH is an absolute path, then
   the returned path is a copy of PATH.  If PATH is a relative path, then
   BASE is with PATH used to construct the absolute path.  */
char *
grub_resolve_relative_path (const char *base, const char *path)
{
  char *abspath;
  char *canonpath;
  char *p;
  grub_size_t l;

  /* If PATH is an absolute path, then just use it as is.  */
  if (path[0] == '/' || path[0] == '(')
    return canonicalize_path (path);

  abspath = grub_malloc (grub_strlen (base) + grub_strlen (path) + 3);
  if (! abspath)
    return 0;

  /* Concatenate BASE and PATH.  */
  p = grub_stpcpy (abspath, base);
  l = grub_strlen (abspath);
  if (l == 0 || abspath[l-1] != '/')
    {
      *p = '/';
      p++;
      *p = 0;
    }
  grub_stpcpy (p, path);

  canonpath = canonicalize_path (abspath);
  if (! canonpath)
    return abspath;

  grub_free (abspath);
  return canonpath;
}

/* Get the path of the directory where the file at FILE_PATH is located.
   FILE_PATH should refer to a file, not a directory.  The returned path
   includes a trailing slash.
   This does not handle GRUB "(hd0,0)" paths properly yet since it only
   looks at slashes.  */
char *
grub_get_dirname (const char *file_path)
{
  int i;
  int last_slash;

  last_slash = -1;
  for (i = grub_strlen (file_path) - 1; i >= 0; --i)
    {
      if (file_path[i] == '/')
        {
          last_slash = i;
          break;
        }
    }
  if (last_slash == -1)
    return grub_strdup ("/");

  return grub_new_substring (file_path, 0, last_slash + 1);
}
