/**	Util.c
  *
  *	Implement some basic utility functions for rexxarplib.library.
  *
  *   AUTHOR/DATE:  W.G.J. Langeveld, November 1987.
  *   ============
  *
  *	CURRENT VERSION:
  *
  *	This version has been converted to SAS C 6.5 format. It has been modified
  *	for modern definition sequences for ANSI compilation. This no longer works
  *	with OS versions prior to 2.04.
  *
  *	SC 6.5 #define's "index" and "rindex" to be aliased to strchr and strrchr
  *	respectively. This rather destroyed the behavior of the subroutines below.
  *	Hence the conditional undefs for index and rindex.
  *
  *   AUTHOR/DATE:  Joanne Dow, jdow@bix.com, June 1998.
  *   ============
  *
  **/
#include <functions.h>
#include "ralprotos.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <simpreq.h>
#include <proto/rexxsyslib.h>

/**
 *
 *   Case insensitive compare
 *
**/
strcmpu( char *s, char *t )
{
	for ( ; toupper(*s) == toupper(*t); s++, t++)
	if (*s == '\0')
		return(0);
	
	return(toupper(*s) - toupper(*t));
}

strncmpu( char *s, char *t, int n)
{
	n--;
	for ( ; (toupper(*s) == toupper(*t)) && n; s++, t++, n--)
	if (*s == '\0')
		return(0);
	
	return(toupper(*s) - toupper(*t));
}

/*
 *   index and rindex	== strchr and strrchr via defines in 6.5 strings.h
 *		Since these two provide a NULL return on testing for '\0' we have
 *		to undefine index and rindex to that these compiled versions work.
 */
#ifdef index
#undef index
#endif

char *index( const char *s, int c )
{
	if (c == 0)
		return(NULL);
	return(strchr(s, c));
}

#ifdef rindex
#undef rindex
#endif

char *rindex( const char *s, int c )
{
	if (c == 0)
		return(NULL);
	return(strrchr(s, c));
}

/**
 *
 *   Convert a long to an ascii string. sprintf is too much...
 *
**/
#define BASE 10

char *ltoa( char *str, long n )
{
	static char nums[] = "0123456789ABCDEF";
	int i, j, s = 0, c;
	
	if (n < 0L) 
	{
		s = 1;
		n = - n;
	}
	j = -1;
	if (n == 0L) 
	{
		j++;
		str[0] = '0';
	}
	while (n) 
	{
		j++;
		i = n % BASE;
		str[j] = nums[i];
		n /= BASE;
	}
	if (s) 
	{
		j++;
		str[j] = '-';
	}
	str[j + 1] = '\0';
	for (i = 0; i < j; i++, j--) 
	{
		c = str[i];
		str[i] = str[j];
		str[j] = c;
	}
	
	return(str);
}

/**
 *
 *   Find index of t in s (K&R index function, K&R page 67).
 *   Modifications: returns pointer to position in s, not numeric index.
 *                  This makes it compatible with ANSI strstr(), but this one is
 *                  case insensitive.
 *
**/
char *strstr( const char s[], const char t[] )
{
	int i,j,k;
	
	for (i = 0; s[i] != '\0'; i++) 
	{
		for (j = i, k = 0;
			t[k] != '\0' && tolower(s[j]) == tolower(t[k]); j++, k++)
		;
		if (t[k] == '\0')
			return(&s[i]);
	}
	return(0L);
}


/**
 *
 *   Interface to CreateArgstring()
 *   Note, that this can't be a macro since "a" may be an expression and the
 *   order of evaluation wouldn't be guaranteed.
 *
**/
char *CAS( char *a )
{
	char *CreateArgstring();
	
	return((char *) CreateArgstring( a, (long) strlen(a)) );
}

/**
 *
 *   Check whether the specified number of arguments are non-null
 *
**/
long checkargs( int n, char *args[] )
{
	int i;
	
	if (args == 0L)
		return(17L);
	
	for (i = 0; i < n; i++) 
	{
		if (args[i] == 0L)
			return(12L);
	}
	
	return(0);
}

/**
 *
 *   Function to decode a string into substrings using \ as newline.
 *
**/
DecodeAutoText( char *s, char *t[], char *ps )
{
	int i;
	char *ind;
	
	if (s == 0L)
		return;
	if (t == 0L)
		return;
	if (ps == 0L)
		return;
	
	strcpy(ps, s);
	ind = ps;
	for (i = 0; i < SR_MAXPROMPTS; i++) 
	{
		t[i] = ind;
		ind = index(ind, '\\');
		if (ind == 0L)
			break;
		else
			*ind = '\0';
		ind++;
	}
	
	return;
}

/**
 *
 *   Make a stem variable out of parts
 *
**/
MakeStem(char *s, char *name, int n)
{
	char numbuff[10];
	
	if (s && name) 
	{
		ltoa(numbuff, (long) n);
		strcpy(s, name);
		strcat(s, ".");
		strcat(s, numbuff);
	}
}

MakeStemS( char *s, char *name, char *field )
{
	if (s && name && field) 
	{
		strcpy(s, name);
		strcat(s, ".");
		strcat(s, field);
	}
}

