DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T a

⟦e3608b6c2⟧ TextFile

    Length: 6476 (0x194c)
    Types: TextFile
    Names: »alias.c«

Derivation

└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89
    └─⟦ca1f037a2⟧ »./bash-1.04.tar.Z« 
        └─⟦46465a4db⟧ 
            └─⟦this⟧ »bash-1.04/alias.c« 

TextFile

/* alias.c -- Not a full alias, but just the kind that we use in the
   shell.  Csh style alias is somewhere else. */

/* Copyright (C) 1987,1989 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 1, 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; see the file COPYING.  If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */

#include "config.h"
#include "general.h"
#include "alias.h"

/* The number of slots to allocate when we need new slots. */
#define alias_list_grow_amount 50

/* 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. */
ASSOC **aliases = (ASSOC **)NULL;

/* The number of slots in the above list. */
static int aliases_size = 0;

/* The number of aliases that are in existence. */
static int aliases_length = 0;

/* The last alias index found with find_alias (). */
static int last_alias_index = 0;

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

  for (i = 0; i < aliases_length; i++)
    if (strcmp (name, aliases[i]->name) == 0)
      return (aliases[last_alias_index = i]);

  return ((ASSOC *)NULL);
}

/* Return the value of the alias for NAME, or NULL if there is none. */
char *
get_alias_value (name)
     char *name;
{
  ASSOC *alias = find_alias (name);
  if (alias)
    return (alias->value);
  else
    return ((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;
{
  ASSOC *temp = find_alias (name);

  if (temp)
    {
      free (temp->value);
      temp->value = savestring (value);
    }
  else
    {
      temp = (ASSOC *)xmalloc (sizeof (ASSOC));
      temp->name = savestring (name);
      temp->value = savestring (value);

      if ((aliases_length + 1) >= aliases_size)
	{
	  if (!aliases)
	    aliases =
	      (ASSOC **)xmalloc ((aliases_size = alias_list_grow_amount)
				 * sizeof (ASSOC *));
	  else
	    aliases =
	      (ASSOC **)xrealloc (aliases,
				  (aliases_size += alias_list_grow_amount)
				  * sizeof (ASSOC *));
	}
      aliases[aliases_length++] = temp;
      aliases[aliases_length] = (ASSOC *)NULL;
    }
}

/* Remove the alias with name NAME from the alias list.  Returns
   the index of the removed alias, or -1 if the alias didn't exist. */
int
remove_alias (name)
     char *name;
{
  register int i;

  if (!find_alias (name))
    return (-1);

  i = last_alias_index;
  free (aliases[i]->name);
  free (aliases[i]->value);
  free (aliases[i]);

  for (; i < aliases_length; i++)
    aliases[i] = aliases[i + 1];

  aliases_length--;
  aliases[aliases_length] = (ASSOC *)NULL;

  return (last_alias_index);
}

/* Return non-zero if CHARACTER is a member of the class of characters
   that are self-delimiting in the shell. */
self_delimiting (character)
     int character;
{
  return (member (character, " \t\n\r;|&"));
}

/* Return a new line, with any aliases substituted. */
char *
alias_expand (string)
     char *string;
{
  int line_len = 1 + strlen (string);
  char *line = (char *)xmalloc (line_len);
  register int i, j, start;
  char *token = (char *)alloca (line_len);
  int tl, real_start, in_command_position;
  int expand_next = 1;
  ASSOC *alias;

  line[0] = i = 0;

  /* 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. */

 next_word:

  token[0] = 0;
  /* Skip leading whitespace (or separator characters).
     But save it in the output.  */
  for (start = i; string[i]; i++)
    {
      if (whitespace (string[i]))
	continue;

      if (self_delimiting (string[i]))
	{
	  expand_next++;
	  continue;
	}
      break;
    }

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

  j = strlen (line);
  if (1 + j + (i - start) >= line_len)
    line = (char *)xrealloc (line, line_len += (50 + (i - start)));
  strncpy (line + j, string + start, i - start);
  line[j + (i - start)] = '\0';

  real_start = i;

  in_command_position = (self_delimiting (string[i]) || expand_next);
  expand_next = 0;

 re_token:
  /* From here to next separator character is a token. */
  for (start = i; string[i] &&
		  !(whitespace (string[i]) || self_delimiting (string[i])); i++);
  tl = strlen (token);
  strncpy (token + tl, string + start, i - start);
  token [tl += (i - start)] = '\0';

  /* Fix for backslashed whitespace.  If it was escaped, add it
     (and following text) to TOKEN. */
  if (token[tl - 1] == '\\' && string[i])
    {
      token[tl - 1] = string[i++];
      goto re_token;
    }
  
  /* See if this word has a substitution.  If it does, do the expansion,
     but only if we are expanding all words, or if we are in a location
     where am expansion is supposed to take place. */
  alias = find_alias (token);

  if (alias && (in_command_position || alias_expand_all))
    {
      char *v = alias->value;
      int l = strlen (v);
      
      /* +3 because we possibly add one more character below. */
      if ((l + 3) > line_len - strlen (line))
	line = (char *)xrealloc (line, line_len += (50 + l));

      strcat (line, v);

      if ((l && whitespace (v[l - 1])) || alias_expand_all)
	{
	  if (l && whitespace (v[l -1]))
	    line[strlen (line) - 1] = '\0';
	  
	  expand_next = 1;
	}
    }
  else
    {
      int ll = strlen (line), tl = i - real_start;
      /* int tl = strlen (token); */

      if (ll + tl + 2 > line_len)
	line = (char *)xrealloc (line, line_len += 50 + ll + tl);

      strncpy (line + ll, string + real_start, tl);
      line[ll + tl] = '\0';
      /* strcat (line, token); */
    }
  goto next_word;
}