/* alias.c -- Not a full alias, but just the kind that we use in the
   shell.  Csh style alias is somewhere else (`over there, in a box'). */

/* Copyright (C) 1987-2009 Free Software Foundation, Inc.

   This file is part of GNU Bash, the Bourne Again SHell.

   Bash 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.

   Bash 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 Bash.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "config.h"

#if defined (ALIAS)

#if defined (HAVE_UNISTD_H)
#  ifdef _MINIX
#    include <sys/types.h>
#  endif
#  include <unistd.h>
#endif

#include <stdio.h>
#include "chartypes.h"
#include "bashansi.h"
#include "command.h"
#include "general.h"
#include "externs.h"
#include "alias.h"

#if defined (PROGRAMMABLE_COMPLETION)
#  include "pcomplete.h"
#endif

#define ALIAS_HASH_BUCKETS	16	/* must be power of two */

typedef int sh_alias_map_func_t __P((alias_t *));

static void free_alias_data __P((PTR_T));
static alias_t **map_over_aliases __P((sh_alias_map_func_t *));
static void sort_aliases __P((alias_t **));
static int qsort_alias_compare __P((alias_t **, alias_t **));

#if defined (READLINE)
static int skipquotes __P((char *, int));
static int skipws __P((char *, int));
static int rd_token __P((char *, int));
#endif

/* Non-zero means expand all words on the line.  Otherwise, expand
   after first expansion if the expansion ends in a space. */
int alias_expand_all = 0;

/* The list of aliases that we have. */
HASH_TABLE *aliases = (HASH_TABLE *)NULL;

void
initialize_aliases ()
{
  if (aliases == 0)
    aliases = hash_create (ALIAS_HASH_BUCKETS);
}

/* Scan the list of aliases looking for one with NAME.  Return NULL
   if the alias doesn't exist, else a pointer to the alias_t. */
alias_t *
find_alias (name)
     char *name;
{
  BUCKET_CONTENTS *al;

  if (aliases == 0)
    return ((alias_t *)NULL);

  al = hash_search (name, aliases, 0);
  return (al ? (alias_t *)al->data : (alias_t *)NULL);
}

/* Return the value of the alias for NAME, or NULL if there is none. */
char *
get_alias_value (name)
     char *name;
{
  alias_t *alias;

  if (aliases == 0)
    return ((char *)NULL);

  alias = find_alias (name);
  return (alias ? alias->value : (char *)NULL);
}

/* Make a new alias from NAME and VALUE.  If NAME can be found,
   then replace its value. */
void
add_alias (name, value)
     char *name, *value;
{
  BUCKET_CONTENTS *elt;
  alias_t *temp;
  int n;

  if (!aliases)
    {
      initialize_aliases ();
      temp = (alias_t *)NULL;
    }
  else
    temp = find_alias (name);

  if (temp)
    {
      free (temp->value);
      temp->value = savestring (value);
      temp->flags &= ~AL_EXPANDNEXT;
      n = value[strlen (value) - 1];
      if (n == ' ' || n == '\t')
	temp->flags |= AL_EXPANDNEXT;
    }
  else
    {
      temp = (alias_t *)xmalloc (sizeof (alias_t));
      temp->name = savestring (name);
      temp->value = savestring (value);
      temp->flags = 0;

      n = value[strlen (value) - 1];
      if (n == ' ' || n == '\t')
	temp->flags |= AL_EXPANDNEXT;

      elt = hash_insert (savestring (name), aliases, HASH_NOSRCH);
      elt->data = temp;
#if defined (PROGRAMMABLE_COMPLETION)
      set_itemlist_dirty (&it_aliases);
#endif
    }
}

/* Delete a single alias structure. */
static void
free_alias_data (data)
     PTR_T data;
{
  register alias_t *a;

  a = (alias_t *)data;
  free (a->value);
  free (a->name);
  free (data);
}

/* Remove the alias with name NAME from the alias table.  Returns
   the number of aliases left in the table, or -1 if the alias didn't
   exist. */
int
remove_alias (name)
     char *name;
{
  BUCKET_CONTENTS *elt;

  if (aliases == 0)
    return (-1);

  elt = hash_remove (name, aliases, 0);
  if (elt)
    {
      free_alias_data (elt->data);
      free (elt->key);		/* alias name */
      free (elt);		/* XXX */
#if defined (PROGRAMMABLE_COMPLETION)
      set_itemlist_dirty (&it_aliases);
#endif
      return (aliases->nentries);
    }
  return (-1);
}

/* Delete all aliases. */
void
delete_all_aliases ()
{
  if (aliases == 0)
    return;

  hash_flush (aliases, free_alias_data);
  hash_dispose (aliases);
  aliases = (HASH_TABLE *)NULL;
#if defined (PROGRAMMABLE_COMPLETION)
  set_itemlist_dirty (&it_aliases);
#endif
}

/* Return an array of aliases that satisfy the conditions tested by FUNCTION.
   If FUNCTION is NULL, return all aliases. */
static alias_t **
map_over_aliases (function)
     sh_alias_map_func_t *function;
{
  register int i;
  register BUCKET_CONTENTS *tlist;
  alias_t *alias, **list;
  int list_index;

  i = HASH_ENTRIES (aliases);
  if (i == 0)
    return ((alias_t **)NULL);

  list = (alias_t **)xmalloc ((i + 1) * sizeof (alias_t *));
  for (i = list_index = 0; i < aliases->nbuckets; i++)
    {
      for (tlist = hash_items (i, aliases); tlist; tlist = tlist->next)
	{
	  alias = (alias_t *)tlist->data;

	  if (!function || (*function) (alias))
	    {
	      list[list_index++] = alias;
	      list[list_index] = (alias_t *)NULL;
	    }
	}
    }
  return (list);
}

static void
sort_aliases (array)
     alias_t **array;
{
  qsort (array, strvec_len ((char **)array), sizeof (alias_t *), (QSFUNC *)qsort_alias_compare);
}

static int
qsort_alias_compare (as1, as2)
     alias_t **as1, **as2;
{
  int result;

  if ((result = (*as1)->name[0] - (*as2)->name[0]) == 0)
    result = strcmp ((*as1)->name, (*as2)->name);

  return (result);
}

/* Return a sorted list of all defined aliases */
alias_t **
all_aliases ()
{
  alias_t **list;

  if (aliases == 0 || HASH_ENTRIES (aliases) == 0)
    return ((alias_t **)NULL);

  list = map_over_aliases ((sh_alias_map_func_t *)NULL);
  if (list)
    sort_aliases (list);
  return (list);
}

char *
alias_expand_word (s)
     char *s;
{
  alias_t *r;

  r = find_alias (s);
  return (r ? savestring (r->value) : (char *)NULL);
}

/* Readline support functions -- expand all aliases in a line. */

#if defined (READLINE)

/* Return non-zero if CHARACTER is a member of the class of characters
   that are self-delimiting in the shell (this really means that these
   characters delimit tokens). */
#define self_delimiting(character) (member ((character), " \t\n\r;|&()"))

/* Return non-zero if CHARACTER is a member of the class of characters
   that delimit commands in the shell. */
#define command_separator(character) (member ((character), "\r\n;|&("))

/* If this is 1, we are checking the next token read for alias expansion
   because it is the first word in a command. */
static int command_word;

/* This is for skipping quoted strings in alias expansions. */
#define quote_char(c)  (((c) == '\'') || ((c) == '"'))

/* Consume a quoted string from STRING, starting at string[START] (so
   string[START] is the opening quote character), and return the index
   of the closing quote character matching the opening quote character.
   This handles single matching pairs of unquoted quotes; it could afford
   to be a little smarter... This skips words between balanced pairs of
   quotes, words where the first character is quoted with a `\', and other
   backslash-escaped characters. */

static int
skipquotes (string, start)
     char *string;
     int start;
{
  register int i;
  int delimiter = string[start];

  /* i starts at START + 1 because string[START] is the opening quote
     character. */
  for (i = start + 1 ; string[i] ; i++)
    {
      if (string[i] == '\\')
	{
	  i++;		/* skip backslash-quoted quote characters, too */
	  if (string[i] == 0)
	    break;
	  continue;
	}

      if (string[i] == delimiter)
	return i;
    }
  return (i);
}

/* Skip the white space and any quoted characters in STRING, starting at
   START.  Return the new index into STRING, after zero or more characters
   have been skipped. */
static int
skipws (string, start)
     char *string;
     int start;
{
  register int i;
  int pass_next, backslash_quoted_word;
  unsigned char peekc;

  /* skip quoted strings, in ' or ", and words in which a character is quoted
     with a `\'. */
  i = backslash_quoted_word = pass_next = 0;

  /* Skip leading whitespace (or separator characters), and quoted words.
     But save it in the output.  */

  for (i = start; string[i]; i++)
    {
      if (pass_next)
	{
	  pass_next = 0;
	  continue;
	}

      if (whitespace (string[i]))
	{
	  backslash_quoted_word = 0; /* we are no longer in a backslash-quoted word */
	  continue;
	}

      if (string[i] == '\\')
	{
	  peekc = string[i+1];
	  if (peekc == 0)
	    break;
	  if (ISLETTER (peekc))
	    backslash_quoted_word++;	/* this is a backslash-quoted word */
	  else
	    pass_next++;
	  continue;
	}

      /* This only handles single pairs of non-escaped quotes.  This
	 overloads backslash_quoted_word to also mean that a word like
	 ""f is being scanned, so that the quotes will inhibit any expansion
	 of the word. */
      if (quote_char(string[i]))
	{
	  i = skipquotes (string, i);
	  /* This could be a line that contains a single quote character,
	     in which case skipquotes () terminates with string[i] == '\0'
	     (the end of the string).  Check for that here. */
	  if (string[i] == '\0')
	    break;

	  peekc = string[i + 1];
	  if (ISLETTER (peekc))
	    backslash_quoted_word++;
	  continue;
	}

      /* If we're in the middle of some kind of quoted word, let it
	 pass through. */
      if (backslash_quoted_word)
	continue;

      /* If this character is a shell command separator, then set a hint for
	 alias_expand that the next token is the first word in a command. */

      if (command_separator (string[i]))
	{
	  command_word++;
	  continue;
	}
      break;
    }
  return (i);
}

/* Characters that may appear in a token.  Basically, anything except white
   space and a token separator. */
#define token_char(c)	(!((whitespace (string[i]) || self_delimiting (string[i]))))

/* Read from START in STRING until the next separator character, and return
   the index of that separator.  Skip backslash-quoted characters.  Call
   skipquotes () for quoted strings in the middle or at the end of tokens,
   so all characters show up (e.g. foo'' and foo""bar) */
static int
rd_token (string, start)
     char *string;
     int start;
{
  register int i;

  /* From here to next separator character is a token. */
  for (i = start; string[i] && token_char (string[i]); i++)
    {
      if (string[i] == '\\')
	{
	  i++;	/* skip backslash-escaped character */
	  if (string[i] == 0)
	    break;
	  continue;
	}

      /* If this character is a quote character, we want to call skipquotes
	 to get the whole quoted portion as part of this word.  That word
	 will not generally match an alias, even if te unquoted word would
	 have.  The presence of the quotes in the token serves then to
	 inhibit expansion. */
      if (quote_char (string[i]))
	{
	  i = skipquotes (string, i);
	  /* This could be a line that contains a single quote character,
	     in which case skipquotes () terminates with string[i] == '\0'
	     (the end of the string).  Check for that here. */
	  if (string[i] == '\0')
	    break;

	  /* Now string[i] is the matching quote character, and the
	     quoted portion of the token has been scanned. */
	  continue;
	}
    }
  return (i);
}

/* Return a new line, with any aliases substituted. */
char *
alias_expand (string)
     char *string;
{
  register int i, j, start;
  char *line, *token;
  int line_len, tl, real_start, expand_next, expand_this_token;
  alias_t *alias;

  line_len = strlen (string) + 1;
  line = (char *)xmalloc (line_len);
  token = (char *)xmalloc (line_len);

  line[0] = i = 0;
  expand_next = 0;
  command_word = 1; /* initialized to expand the first word on the line */

  /* Each time through the loop we find the next word in line.  If it
     has an alias, substitute the alias value.  If the value ends in ` ',
     then try again with the next word.  Else, if there is no value, or if
     the value does not end in space, we are done. */

  for (;;)
    {

      token[0] = 0;
      start = i;

      /* Skip white space and quoted characters */
      i = skipws (string, start);

      if (start == i && string[i] == '\0')
	{
	  free (token);
	  return (line);
	}

      /* copy the just-skipped characters into the output string,
	 expanding it if there is not enough room. */
      j = strlen (line);
      tl = i - start;	/* number of characters just skipped */
      RESIZE_MALLOCED_BUFFER (line, j, (tl + 1), line_len, (tl + 50));
      strncpy (line + j, string + start, tl);
      line[j + tl] = '\0';

      real_start = i;

      command_word = command_word || (command_separator (string[i]));
      expand_this_token = (command_word || expand_next);
      expand_next = 0;

      /* Read the next token, and copy it into TOKEN. */
      start = i;
      i = rd_token (string, start);

      tl = i - start;	/* token length */

      /* If tl == 0, but we're not at the end of the string, then we have a
	 single-character token, probably a delimiter */
      if (tl == 0 && string[i] != '\0')
	{
	  tl = 1;
	  i++;		/* move past it */
	}

      strncpy (token, string + start, tl);
      token [tl] = '\0';

      /* If there is a backslash-escaped character quoted in TOKEN,
	 then we don't do alias expansion.  This should check for all
	 other quoting characters, too. */
      if (mbschr (token, '\\'))
	expand_this_token = 0;

      /* If we should be expanding here, if we are expanding all words, or if
	 we are in a location in the string where an expansion is supposed to
	 take place, see if this word has a substitution.  If it does, then do
	 the expansion.  Note that we defer the alias value lookup until we
	 are sure we are expanding this token. */

      if ((token[0]) &&
	  (expand_this_token || alias_expand_all) &&
	  (alias = find_alias (token)))
	{
	  char *v;
	  int vlen, llen;

	  v = alias->value;
	  vlen = strlen (v);
	  llen = strlen (line);

	  /* +3 because we possibly add one more character below. */
	  RESIZE_MALLOCED_BUFFER (line, llen, (vlen + 3), line_len, (vlen + 50));

	  strcpy (line + llen, v);

	  if ((expand_this_token && vlen && whitespace (v[vlen - 1])) ||
	      alias_expand_all)
	    expand_next = 1;
	}
      else
	{
	  int llen, tlen;

	  llen = strlen (line);
	  tlen = i - real_start; /* tlen == strlen(token) */

	  RESIZE_MALLOCED_BUFFER (line, llen, (tlen + 1), line_len, (llen + tlen + 50));

	  strncpy (line + llen, string + real_start, tlen);
	  line[llen + tlen] = '\0';
	}
      command_word = 0;
    }
}
#endif /* READLINE */
#endif /* ALIAS */
