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 g

⟦e978737dd⟧ TextFile

    Length: 10197 (0x27d5)
    Types: TextFile
    Names: »general.c«

Derivation

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

TextFile

/* general.c -- Stuff that is used by all files. */

/* 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 <stdio.h>
#include <errno.h>

#include "shell.h"
#ifdef SYSV
#include <string.h>
#else
#include <strings.h>
#endif  /* SYSV */

#ifndef NULL
#define NULL 0x0
#endif


/* **************************************************************** */
/*								    */
/*		   Memory Allocation and Deallocation.		    */
/*								    */
/* **************************************************************** */

char *
xmalloc (size)
     int size;
{
  register char *temp = (char *)malloc (size);
  if (!temp)
    fatal_error ("Out of virtual memory!");
  return (temp);
}

char *
xrealloc (pointer, size)
     register char *pointer;
     int size;
{
  pointer = (char *)realloc (pointer, size);
  if (!pointer)
    fatal_error ("Out of virtual memory!");
  return (pointer);
}


/* **************************************************************** */
/*								    */
/*			Generic List Functions			    */
/*								    */
/* **************************************************************** */

/* Call FUNCTION on every member of LIST, a generic list. */
map_over_list (list, function)
     GENERIC_LIST *list;
     Function *function;
{
  while (list) {
    (*function) (list);
    list = list->next;
  }
}

/* Call FUNCTION on every string in WORDS. */
map_over_words (words, function)
     WORD_LIST *words;
     Function *function;
{
  while (words) {
    (*function)(words->word->word);
    words = words->next;
  }
}

/* Reverse the chain of structures in LIST.  Output the new head
   of the chain.  You should always assign the output value of this
   function to something, or you will lose the chain. */
GENERIC_LIST *
reverse_list (list)
     register GENERIC_LIST *list;
{
  register GENERIC_LIST *next, *prev = (GENERIC_LIST *)NULL;

  while (list) {
    next = list->next;
    list->next = prev;
    prev = list;
    list = next;
  }
  return (prev);
}

/* Return the number of elements in LIST, a generic list. */
list_length (list)
     register GENERIC_LIST *list;
{
  register int i;

  for (i = 0; list; list = list->next, i++);
  return (i);
}

/* Delete the element of LIST which satisfies the predicate function COMPARER.
   Returns the element that was deleted, so you can dispose of it, or -1 if
   the element wasn't found.  COMPARER is called with the list element and
   then ARG.  Note that LIST contains the address of a variable which points
   to the list.  You might call this function like this:
   
   SHELL_VAR *elt = delete_element (&variable_list, check_var_has_name, "foo");
   dispose_variable (elt);
*/
GENERIC_LIST *
delete_element (list, comparer, arg)
     GENERIC_LIST **list;
     Function *comparer;
{
  register GENERIC_LIST *prev = (GENERIC_LIST *)NULL;
  register GENERIC_LIST *temp = *list;

  while (temp) {
    if ((*comparer) (temp, arg)) {
      if (prev) prev->next = temp->next;
      else *list = temp->next;
      return (temp);
    }
    prev = temp;
    temp = temp->next;
  }
  return ((GENERIC_LIST *)-1);
}

/* Find NAME in ARRAY.  Return the index of NAME, or -1 if not present.
   ARRAY shoudl be NULL terminated. */
find_name_in_list (name, array)
     char *name, *array[];
{
  int i;

  for (i=0; array[i]; i++)
    if (strcmp (name, array[i]) == 0)
      return (i);

  return (-1);
}

/* Return the length of ARRAY, a NULL terminated array of char *. */
array_len (array)
     register char **array;
{
  register int i;
  for (i=0; array[i]; i++);
  return (i);
}

/* Free the contents of ARRAY, a NULL terminated array of char *. */
free_array (array)
     register char **array;
{
  register int i = 0;

  if (!array) return;

  while (array[i]) free (array[i++]);
  free (array);
}

/* Append LIST2 to LIST1.  Return the header of the list. */
GENERIC_LIST *
list_append (head, tail)
     GENERIC_LIST *head, *tail;
{
  register GENERIC_LIST *t_head = head;

  if (!t_head)
    return (tail);

  while (t_head->next) t_head = t_head->next;
  t_head->next = tail;
  return (head);
}

/* Some random string stuff. */

/* Remove all leading whitespace from STRING.  This includes
   newlines.  STRING should be terminated with a zero. */
strip_leading (string)
     char *string;
{
  char *start = string;

  while (*string && (whitespace (*string) || *string == '\n')) string++;

  if (string != start) {
    int len = strlen (string);
    bcopy (string, start, len);
    start[len] = '\0';
  }
}

/* Remove all trailing whitespace from STRING.  This includes
   newlines.  STRING should be terminated with a zero. */
strip_trailing (string)
     char *string;
{
  int len = strlen (string);

  while (len--)
    if (!whitespace (string[len]) && string[len] != '\n') {
      string[len + 1] = '\0';
      return;
    }
}

/* Turn STRING (a pathname) into an absolute pathname, assuming that
   DOT_PATH contains the symbolic location of '.'.  This always
   returns a new string, even if STRING was an absolute pathname to
   begin with. */

#ifndef MAXPATHLEN
#define MAXPATHLEN 1024
#endif

static char current_path[MAXPATHLEN];

char *
make_absolute (string, dot_path)
     char *string, *dot_path;
{
  register char *cp;

  if (!dot_path || *string == '/')
    return (savestring (string));

  strcpy (current_path, dot_path);

  if (!current_path[0])
    strcpy (current_path, "./");

  cp = current_path + (strlen (current_path) - 1);

  if (*cp++ != '/')
    *cp++ = '/';

  *cp = '\0';

  while (*string)
    {
      if (*string == '.')
	{
	  if (!string[1])
	    return (savestring (current_path));

	  if (string[1] == '/')
	    {
	      string += 2;
	      continue;
	    }

	  if (string[1] == '.' && (string[2] == '/' || !string[2]))
	    {
	      string += 2;

	      if (*string)
		string++;

	      pathname_backup (current_path, 1);
	      cp = current_path + strlen (current_path);
	      continue;
	    }
	}

      while (*string && *string != '/')
	*cp++ = *string++;

      if (*string)
	*cp++ = *string++;

      *cp = '\0';
    }
  return (savestring (current_path));
}

/* Remove the last N directories from PATH.  Do not leave a blank path.
   PATH must contain enough space for MAXPATHLEN characters. */
pathname_backup (path, n)
     char *path;
     int n;
{
  register char *p = path + strlen (path);

  if (*path)
    p--;

  while (n--)
    {
      while (*p == '/')
	p--;

      while (*p != '/')
	p--;

      *++p = '\0';
    }
}

/* Return 1 if STRING contains an absolute pathname, else 0. */
absolute_pathname (string)
     char *string;
{
  if (!string || !strlen (string))
    return (0);

  if (*string == '/')
    return (1);

  if (*string++ == '.')
    {
      if ((!*string) || *string == '/')
	return (1);

      if (*string++ == '.')
	if (!*string || *string == '/')
	  return (1);
    }
  return (0);
}

/* Determine if s2 occurs in s1.  If so, return a pointer to the
   match in s1.  The compare is case insensitive. */
char *
strindex (s1, s2)
     register char *s1, *s2;
{
  register int i, l = strlen (s2);
  register int len = strlen (s1);

  for (i = 0; (len - i) >= l; i++)
    if (strnicmp (&s1[i], s2, l) == 0)
      return (s1 + i);
  return ((char *)NULL);
}


#ifndef to_upper
#define lowercase_p(c) (((c) > ('a' - 1) && (c) < ('z' + 1)))
#define uppercase_p(c) (((c) > ('A' - 1) && (c) < ('Z' + 1)))
#define pure_alphabetic(c) (lowercase_p(c) || uppercase_p(c))
#define to_upper(c) (lowercase_p(c) ? ((c) - 32) : (c))
#define to_lower(c) (uppercase_p(c) ? ((c) + 32) : (c))
#endif

/* Compare at most COUNT characters from string1 to string2.  Case
   doesn't matter. */
int
strnicmp (string1, string2, count)
     char *string1, *string2;
{
  register char ch1, ch2;

  while (count) {
    ch1 = *string1++;
    ch2 = *string2++;
    if (to_upper(ch1) == to_upper(ch2))
      count--;
    else break;
  }
  return (count);
}

/* strcmp (), but caseless. */
int
stricmp (string1, string2)
     char *string1, *string2;
{
  register char ch1, ch2;

  while (*string1 && *string2) {
    ch1 = *string1++;
    ch2 = *string2++;
    if (to_upper(ch1) != to_upper(ch2))
      return (1);
  }
  return (*string1 | *string2);
}

#if defined (SONY)

char *
strchr (s, c)
     char *s;
     int c;
{
  char *index ();
  return (index (s, c));
}

#endif /* SONY */

extern int errno;
#include <errno.h>
#include <fcntl.h>

#ifdef NO_DUP2
dup2 (fd1, fd2)
     int fd1, fd2;
{
  if (fcntl (fd1, F_GETFL, 0) == -1)	/* fd1 is an invalid fd */
    return (-1);
  if (fd2 < 0 || fd2 >= NOFILE)
    {
      errno = EBADF;
      return (-1);
    }
  if (fd1 == fd2)
    return (0);
  (void) close (fd2);
  return (fcntl (fd1, F_DUPFD, fd2));
}
#endif /* NO_DUP */

#ifdef SYSV
#include <sys/utsname.h>
bcopy(s,d,n) char *d,*s; { while(n--) *d++ = *s++; }
char *getwd(s) char *s; { getcwd(s,MAXPATHLEN); return s; }
char *index(s,c) char *s; { char *strchr(); return strchr(s,c); }
char *rindex(s,c) char *s; { char *strrchr(); return strrchr(s,c); }
     
gethostname (name, namelen) 
     char *name;
     int namelen;
{
  int i;
  struct utsname uts;

  --namelen;

  uname (&uts);
  i = strlen (uts.nodename) + 1;
  strncpy (name, uts.nodename, i < namelen ? i : namelen);
  name[namelen] = '\0';
  return (0);
}

int
sysv_getc (stream)
     FILE *stream;
{
  int result;
  char c;

  while (1)
    {
      result = read (fileno (stream), &c, sizeof (char));
      if (result == sizeof (char))
	return (c);

      if (errno != EINTR)
	return (EOF);
    }
}
#endif  /* SYSV */