pgplus/bin/
pgplus/help_files/
pgplus/port_redirector/
pgplus/src/configure/makefiles/
/*
 * Playground+ - xstring.c
 * Xtra string related functions (c) phypor 1998
 * ---------------------------------------------------------------------------
 */

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>

/* this is the only thing we need from the talker, so instead of including
   all the files and shat, we just extern this
 */
extern void lower_case(char *);
extern char *end_string(char *);
extern char *stack;


/*
   like strstr, but case insenstive
 */
char *strcasestr(char *haystack, char *needle)
{
  char s[5], *nptr, *hptr;

  if (!needle || !*needle)
    return (char *) NULL;

  memset(s, 0, 5);
  strncpy(s, needle, 4);
  lower_case(s);

  while (*haystack)
  {
    if (tolower(*haystack) == s[0])
    {
      if (!s[1])
	return haystack;
      if (*(haystack + 1) && tolower(*(haystack + 1)) == s[1])
      {
	if (!s[2])
	  return haystack;
	if (*(haystack + 2) && tolower(*(haystack + 2)) == s[2])
	{
	  if (!s[3])
	    return haystack;
	  if (*(haystack + 3) && tolower(*(haystack + 3)) == s[3])
	  {
	    hptr = haystack + 4;
	    nptr = needle + 4;
	    for (; *nptr && *hptr; nptr++, hptr++)
	      if (tolower(*nptr) != tolower(*hptr))
		break;
	    if (!*nptr)
	      return haystack;
	  }
	}
      }
    }
    haystack++;
  }
  /* strstr returns NULL, not an actual char that is NULL...
     so we will follow its way
   */
  return (char *) NULL;
}


/*
   given a string to search in (haystack),
   a list of search strings new line terminated (needles),
   check each line seperately to see if it occurs,
   case insensitive
   returns a pointer to occurance in haystack
 */

char *strcaseline(char *haystack, char *needles)
{
  char *lf = needles, *re;
  char ln[160];
  int i = 0;

  if (!lf || !*lf)
    return (char *) NULL;

  for (memset(ln, 0, 160); *lf; memset(ln, 0, 160), i = 0)
  {
    while (*lf && *lf != '\n' && i < 158)
      ln[i++] = *lf++;
    if ((re = strcasestr(haystack, ln)))
      return re;
    if (*lf == '\n')
      lf++;
  }
  return (char *) NULL;
}

/*
   given a string to search in (haystack),
   a list of search strings new line terminated (needles),
   check each line seperately to see if it occurs,
   case sensitive
   returns a pointer to occurance in haystack
 */

char *strline(char *haystack, char *needles)
{
  char *lf = needles, *re;
  char ln[160];
  int i = 0;

  if (!lf || !*lf)
    return (char *) NULL;

  for (memset(ln, 0, 160); *lf; memset(ln, 0, 160), i = 0)
  {
    while (*lf && *lf != '\n' && i < 158)
      ln[i++] = *lf++;
    if ((re = strstr(haystack, ln)))
      return re;
    if (*lf == '\n')
      lf++;
  }
  return (char *) NULL;
}

/*
   the large static vars appear to be a kludge,
   however in this peticular instance they are
   the most effective means to get it done

   overflow checking could be better, but
   buffers are so large, there shouldnt be any
   way to overwrite...(watch out for possible
   recursive replaces tho, those are killers)
 */

char *single_replace(char *str, char *find, char *rep)
{
  static char buf[51200];
  char *ptr;
  int i = 0;
  int m = 0;
  int n = 0;
  int c = 0;

  if (strlen(str) > 38400)
    return str;

  if (!(ptr = strstr(str, find)))
    return str;

  memset(buf, 0, 51200);

  c = strlen(str) - strlen(ptr);

  for (i = 0; i < c; i++)
    buf[i] = str[i];

  for (n = 0, m = i; rep[n]; n++, m++)
    buf[m] = rep[n];

  for (n = 0; n < strlen(find); n++)
    i++;

  for (; str[i]; m++, i++)
    buf[m] = str[i];

  return buf;
}


char *replace(char *str, char *find, char *rep)
{
  static char returnstr[51200];

  if (strlen(str) > 38400)
    return str;

  if (strstr(str, find))
  {
    /* seed */
    strncpy(returnstr, single_replace(str, find, rep), 51100);

    /* recursion */
    while (strstr(returnstr, find))
      strncpy(returnstr, single_replace(returnstr, find, rep), 51100);

    return returnstr;
  }
  return str;

}



/* given a multiple strings to check the first of each line  (haystacks),
   a string for which to search (needle),
   return where needle is in the haystacks
 */

char *linestr(char *haystacks, char *needle)
{
  char *ptr;

  if (!haystacks || !*haystacks)
    return (char *) NULL;

  ptr = haystacks;
  while ((ptr = strcasestr(ptr, needle)))
    if (ptr == haystacks || *(ptr - 1) == '\n')
      return ptr;
    else
      ptr++;

  return (char *) NULL;
}


/*
   given a string of lines with
   identifier1:        value
   identifier2:        value
   identifiern:        value

   given an identifier ...

   return the value assoicated with the identifer
 */


char *lineval(char *where, char *identifier)
{
  char *oldstack = stack, *line;
  static char buf[1024];

  sprintf(stack, "%s:", identifier);
  stack = end_string(stack);
  line = linestr(where, oldstack);
  stack = oldstack;


  if (!line || !*line)
    return (char *) NULL;

  memset(buf, 0, 1024);

  while (*line && *line++ != ':');

  while (*line && (*line == ' ' || *line == '\t'))
    line++;

  strncpy(buf, line, 1023);
  line = buf;

  while (!NULL)
  {
    while (*line && *line != '\n')	/* dont do it all in one line so we */
      line++;			/* dont finish ahead of the \n      */

    if (*line && *(line + 1) == '\t')
    {
      line++;			/* past the \n */
      while (*line == '\t')	/* turn tabs into spaces */
	*line++ = ' ';
    }
    else
      break;
  }
  *line = '\0';

  if (*(line - 1) == ' ')	/* a blank line? */
  {
    line--;
    while (*line == ' ')
      line--;
    if (*line == '\n')
      *++line = '\0';
  }

  return buf;
}