/*
 *  hap -- a mail notification program
 * 
 *  copyright 1995 by Eric Fischer, etaoin@uchicago.edu
 * 
 *  copies of hap may be redistributed under the terms of the
 *  GNU public license, copies of which are available from
 *  the Free Software Foundation, 59 Temple Place, Boston, MA
 *  02111 USA.
 *
 */

#include "hap.h"

/*************************************************************************

   STRING MANIPULATION STUFF

*************************************************************************/

/* use malloc() to allocate enough space for the string 'what', copy
   it into there, and return a pointer to it.  This because NeXT (like
   other 4.3 systems, I think) is missing strdup().
*/

char *
strdupe (what)
	char *what;
{
	char *s;

	if (what == 0) return 0;

	s = xmalloc ((strlen (what) + 1) * sizeof (char));

	strcpy (s, what);
	return s;
}

/* return the last word of the pathname 'what'.  returns a pointer into
   the string we were passed.
*/

char *
mybasename (what)
	char *what;
{
	char *yes = what;

	while (*what) {
		if (*what == '/') yes = what+1;
		what++;
	}

	return yes;
}

/* modify the string 's' we were given to end at the first newline. */

void
chop (s)
	char *s;
{
	while (*s) {
		if (*s == '\n') *s = 0;
		s++;
	}
}

/* return true if string 'l' begins with 's', false otherwise. */

int
starts (l, s)
	char *l;
	char *s;
{
	while (*s) {
		if (*l != *s) return 0;
		l++, s++;
	}
	return 1;
}

int
cstarts (l, s)
	char *l;
	char *s;
{
	return (strncasecmp (l, s, strlen (s)) == 0);
}

/* return true if string 'l' ends with 's', false otherwise */

int
ends (l, s)
	char *l;
	char *s;
{
	int x = strlen (l) - strlen (s);

	if (x < 0) return 0;
	return same (l + x, s);
}

/* return ptr if the string 's' contains the character 'what', false
   otherwise.  yeah, it's like index/strchr, but it seemed easier
   this way...
*/

char *
contains (s, what)
	char *s;
	int what;   /* really a char, but -Wall complains */
{
	while (*s) {
		if (*s == what) return s;
		s++;
	}
	return 0;
}

char *
scontains (s, what)
	char *s;
	char *what;
{
	while (*s) {
		if (starts (s, what)) return s;
		s++;
	}
	return 0;
}

char *
cscontains (s, what)
	char *s;
	char *what;
{
	while (*s) {
		if (cstarts (s, what)) return s;
		s++;
	}
	return 0;
}

/* return the number of newline characters in the string 'what'. */

int
numlns (what)
	char *what;
{
	int x = 0;

	while (*what) {
		if (*what == '\n') x++;
		what++;
	}
	return x;
}

/* return a pointer inside the string 'what' to the start of the (num-1)th
   line.
*/

char *
skiplines (what, num)
	char *what;
	int num;
{
	while (*what && num) {
		if (*what == '\n') num--;
		what++;
	}
	return what;
}

/* return a new string containing the concatenation of 'one' and 'two'.
   the string is only valid until the next call to conc(), so copy it
   if you need to keep it.
*/

char *
conc (one, two)
	char *one;
	char *two;
{
	static char *ya = 0;
	if (ya) free (ya), ya = 0;

	ya = xmalloc (strlen (one) + strlen (two) + 1);
	strcpy (ya, one);
	strcat (ya, two);
	return ya;
}

char *
truncstr (x, maxlen)
	char *x;
	int maxlen;
{
	static char *str = 0;
	int len = strlen (x);

	if (str) free (str), str = 0;
	str = strdupe (x);

	if (len <= maxlen) return str;
	if (maxlen < 5) {
		str[maxlen] = 0;
		return str;
	}

	{
		int lastspace = -1;
		int firstspace = -1;
		int i;

		for (i = 0; i < len; i++) {
			if (isspace (str[i])
			&& !isspace (str[i+1])
			&& !isdigit (str[i+1])) lastspace = i + 1;
		}

		/* give up if there were no spaces at all, or
		   if the last word was enormously long
		*/

		if (lastspace == -1
		||  (len - lastspace) > maxlen / 2) {
			strcpy (str + maxlen - 3, "...");
			return str;
		}

		for (i = lastspace - 1; i > 4; i--) {
			if (isspace (str[i])) {
				if (i + 3 + strlen(str + lastspace) < maxlen) {
					firstspace = i;
					break;
				}
			}
		}

		/* if it's all one enormously long word, give up
		   in despair
		*/

		if (firstspace == -1) {
			strcpy (str + maxlen - 3, "...");
			return str;
		}

		strcpy (str + firstspace, "... ");
		strcat (str, str + lastspace);

		return str;
	}
}

