/*************************************************
*                      Smailmon                  *
*************************************************/

/* Copyright (c) University of Cambridge 1995. */

/* P. Hazel, February 1995*/
/* Last Modified: March 1995 */

#include "smailmon.h"

/* This module contains a number of utility functions for doing
things to strings that are not available in ANSI C. */


/*************************************************
*            Copy and save string                *
*************************************************/

char *copystring(char *s)
{
char *ss = (char *)malloc((int)strlen(s) + 1);
strcpy(ss, s);
return ss;
}


/*************************************************
*         Case-independent strncmp() function    *
*************************************************/

int strncmpic(char *s, char *t, int n)
{
while (n--)
  {
  int c = tolower(*s++) - tolower(*t++);
  if (c) return c;  
  } 
return 0;
}



/*************************************************
*         Case-independent strstr() function     *
*************************************************/

/* The third argument specifies whether whitespace is required
to follow the matched string. */

char *strstric(char *s, char *t, int space_follows)
{
char *p = t;
char *yield = NULL;
int cl = tolower(*p);
int cu = toupper(*p);

while (*s)
  {
  if (*s == cl || *s == cu)
    {
    if (yield == NULL) yield = s; 
    if (*(++p) == 0) 
      {
      if (!space_follows || s[1] == ' ' || s[1] == '\n' ) return yield;
      yield = NULL;
      p = t;  
      } 
    cl = tolower(*p);
    cu = toupper(*p); 
    }
  else if (yield != NULL)
    {
    yield = NULL;
    p = t;
    cl = tolower(*p);
    cu = toupper(*p); 
    }       
  s++;
  } 
return NULL;
}


/*************************************************
*           Remove part of a string              *
*************************************************/

/* If the second argument is NULL, then the first argument is
removed if present; otherwise everything between the first
and the second arguments, inclusive, is removed. */

void str_remove(char *s, char *start, char *end)
{
char *p = strstr(s, start);
char *q;
if (p == NULL) return;
if (end != NULL)
  {
  q = strstr(s, end);
  if (q == NULL) return;
  q += (int)strlen(end);   
  }
else q = p + (int)strlen(start);
memmove(p, q, (int)strlen(s) - (q - s) + 1);
}



/*************************************************
*        Extract keyed field from a string       *
*************************************************/

/* The second argument is the key: everything following it up 
to the next <words> occurrence of white space is returned as 
the value, in bit of substr storage (see below). Leading spaces 
are included in the data. Intermediate white spaces cannot be 
newlines. If there is no match, return an empty string. */

char *str_subfield(char *s, char *k, int words)
{
char *q;
char *p = strstric(s, k, FALSE);
if (p == NULL) return "";
q = p += (int)strlen(k);
while (*q == ' ') q++;
while (*q && (*q != ' ' || --words > 0) && *q != '\n') q++;
return substr(s, p - s, q - p);
}




/***********************************************************
*                       Substring handling                 *
***********************************************************/

/* A number of the smailmon routines need to extract substrings from
longer strings, and we do this into a large block of store that just
gets used up as we go along. There's a reset routine that reclaims
this store; this is called at the start of each smailmon routine
that is going to extract ephemeral substrings. */

#define substr_buffer_size 4096

static char *substr_buffer = NULL;
static char *substr_ptr;


/*************************************************
*             Set up store for substrings        *
*************************************************/

void substr_reset(void)
{
if (substr_buffer == NULL)
  substr_buffer = (char *)malloc(substr_buffer_size);
substr_ptr = substr_buffer;
}


/*************************************************
*             Extract one substring              *
*************************************************/

char *substr(char *s, int start, int len)
{
char *ss = substr_ptr;
strncpy(substr_ptr, s + start, len);
substr_ptr[len] = 0;
substr_ptr += len + 1;
return ss;
}

/* End of string.c */
