/* Copyright (C) 1993,1994 by the author(s).
 
 This software is published in the hope that it will be useful, but
 WITHOUT ANY WARRANTY for any part of this software to work correctly
 or as described in the manuals. See the ShapeTools Public License
 for details.

 Permission is granted to use, copy, modify, or distribute any part of
 this software but only under the conditions described in the ShapeTools 
 Public License. A copy of this license is supposed to have been given
 to you along with ShapeTools in a file named LICENSE. Among other
 things, this copyright notice and the Public License must be
 preserved on all copies.
 */
/*
 * ststring.c -- ShapeTools toolkit library
 *
 * Authors: Axel Mahler (Axel.Mahler@cs.tu-berlin.de)
 *          Andreas Lampen (Andreas.Lampen@cs.tu-berlin.de)
 *
 *  $Header: ststring.c[4.0] Fri Nov  5 14:11:05 1993 andy@cs.tu-berlin.de frozen $
 */

#include <ctype.h>
#include "config.h"
#include "sttk.h"

/*=================================
 *  convertPattern
 *=================================*/

EXPORT char *stConvertPattern (pattern)
     char *pattern;
     /* converts "sh" pattern to "ed" pattern */
{
  static char resultPattern[NAME_MAX+1];
  char *patPtr = pattern, *resPtr = resultPattern;

  if (!pattern || !(*pattern))
    return ("");

  *resPtr++ = '^';

  while (*patPtr) {
    switch (*patPtr) {
    case '?':
      *resPtr++ = '.';
      break;
    case '*':
      *resPtr++ = '.';
      *resPtr++ = '*';
      break;
    case '.':
      *resPtr++ = '\\';
      *resPtr++ = '.';
      break;
    case '!':
      /* should check if there is a closing square bracket */
      if ((patPtr > pattern) || (*(patPtr-1) == '['))
	*resPtr++ = '^';
      else
	*resPtr++ = *patPtr;
      break;
    default:
      *resPtr++ = *patPtr;
    }
    patPtr++;
  }
  *resPtr++ = '$';
  *resPtr++ = '\0';
  return (resultPattern);
}

EXPORT char *stSubstituteString (subject, oldStr, newStr)
     char *subject, *oldStr, *newStr; {
       /*
        * replace all occurrences of substring "oldStr" in "subject" by
	* string "newStr". Return a pointer to a statically allocated 
	* string that is the result of this operation. Return NULL 
	* if anything goes seriously wrong.
	*/

       int subject_len, old_len, new_len;
       char *result;
       register char *p, *s;
       register int j;

       if (subject == NULL)
	 return "";
       else
	 subject_len = strlen (subject);

       old_len = oldStr ? strlen (oldStr) : 0;
       new_len = newStr ? strlen (newStr) : 0;

       
       if ((result = (char *)malloc (subject_len + 1)) == (char *)NULL)
	 return (char *)NULL;

       if ((old_len == 0) || (old_len > subject_len)) {
	 (void) strcpy (result, subject);
	 return result;
       }

       p = subject;
       s = oldStr;
       j = 0;

       while (*p) {
	 register int i;

	 i = 0;
	 while (*s && (*(p+i) == *s)) { s++; i++; }
	 if (*s) {
	   result[j++] = *p++;
	 }
	 else {
	   p += old_len;
	   result[j] = '\0';
	   if (j+new_len >= subject_len) {
	     if ((result = (char *)realloc (result, j+new_len+subject_len) )
		 == (char *)NULL)
	       return (char *)NULL;
	   }
	   (void) strcat (result, newStr);
	   j += new_len;
	 }
	 s = oldStr;
       }
       result[j] = '\0';
       return result;
     }

EXPORT char *stStrtok (str) char *str; {
  /*
   * considers the string str to consist of a sequence of zero or more
   * text tokens separated by whitespace. The first call (with pointer
   * str specified) returns a pointer to the first character of the
   * first token, and will have written a null character into str
   * immediately following the returned token. The function keeps
   * track of its position between separate calls, so that subsequent
   * calls (which must be made with the str argument set to NULL) will
   * work through the string immediately following that token. In
   * this way subsequent calls will work through the string until no
   * tokens remain. When no token remains in str, a NULL pointer is
   * returned. 
   */
  static int buf_is_initialized, bufsiz;
  static char *buf, *thistoken = NULL, *nexttoken = NULL;
  register int i;

  if (str) {
    int strsiz = strlen (str);

    if (buf_is_initialized) {
      if (bufsiz < strsiz+1) {
	buf = realloc (buf, strsiz+1);
	if (!buf) 
	  return (char *)NULL;
      }
    }
    else {
      buf = malloc (strsiz+1);
      if (!buf) 
	return (char *)NULL;
    }
    (void) strcpy (buf, str);
    bufsiz = strsiz+1;
    buf_is_initialized = TRUE;
    thistoken = buf;
    while (*thistoken && isspace (*thistoken)) thistoken++;
  }
  else {
    thistoken = nexttoken;
  }

  if (thistoken) {
    i = 0;
    while (thistoken[i] && !isspace(thistoken[i])) i++;
    if (thistoken[i]) {
      thistoken[i++] = '\0';
      while (isspace(thistoken[i])) i++;
    }
    nexttoken = &thistoken[i];
  }
  return (thistoken && *thistoken) ? thistoken : (char *)NULL;
}
