/* SCOTT.C	Scott Layson's personal miscellaneous-function
			library

	This code is in the public domain.
	Created from functions in STDLIB?.C 81.10.29 Gyro

*/


#include "bdscio.h"


	/* This deletes elements in the array <ary>, which consists of
        <len> elements of <eltsize> bytes; elements from <dello>
        through <delhi> - 1 are deleted. */
arydel (ary, len, eltsize, dello, delhi)
	char *ary;
	int len, eltsize, dello, delhi;
{
	movmem (ary + delhi * eltsize,
		   ary + dello * eltsize,
		   (len - delhi) * eltsize);
	}


match (s1, s2)				/* case-independent null-term compare */
	char *s1, *s2;
{
	do if (toupper (*s1) != toupper (*s2)) return (FALSE);
		while ((s1++, *s2++));
	return (TRUE);
	}


upcase (str)			/* convert a string to upper case */
	char *str;
{
	for (;*str; ++str) *str = toupper (*str);
	}


/* The version of this in STDLIB2.C is bugous!!! */
int
fscanf(iobuf,format)
char *format;
struct _buf *iobuf;
{
	char text[MAXLINE];
	if (!fgets(text,iobuf)) return /* 0 NO!!! */ -1;
	return _scn(text,&format);
}


/* This is the standard one, except: if the character after "%s" in the format
string is a '%', the %s breaks on any whitespace.  */
int
_scn(line,fmt)
char *line, **fmt;
{
	char sf, c, base, n, *sptr, *format, matchchar;
	int sign, val, **args;

	format = *fmt++;	/* fmt first points to the format string */
	args = fmt;		/* now it points to the arg list */

	n = 0;
	while (c = *format++) {
	   _igs (&line);
	   if (!*line) return n;	/* if end of input string, return */
	   if (isspace(c)) continue;	/* skip white space in format string */
	   if (c != '%') {		/* if not %, must match text */
		if (c != _igs(&line)) return n;
		else line++;
	    }
	   else {			/* process conversion */
		sign = 1;
		base = 10;
		sf = 0;
		if ((c = *format++) == '*') {
			sf++;		/* if "*" given, supress assignment */
			c = *format++;
		 }
		switch (toupper(c)) {
		   case 'X': base = 16;
			     goto doval;

		   case 'O': base = 8;
			     goto doval;

		   case 'D': if (_igs(&line) == '-') {
				sign = -1;
				line++;
			      }

	   doval:  case 'U': val = 0;
			     if (_bc(_igs(&line),base) == ERROR)
				return n;
			     while ((c = _bc(*line++,base)) != 255)
				val = val * base + c;
			     line--;
			     break;

		   case 'S': _igs(&line);
			     sptr = *args;
				if (*format != '%') matchchar = *format++;
				else matchchar = '\0';
			     while (c = *line++)   {
					if (matchchar ? c == matchchar : isspace (c)) break;
					if (!sf) *sptr++ = c;
			      }				
			     if (!sf) {
				n++;
				*sptr = '\0';
				args++;
			      }
			     continue;

		   case 'C': if (!sf) {
				poke(*args++, *line);
				n++;
			     }
			     line++;
			     continue;

		   default:  return n;
		 }
		if (!sf) {
			**args++ = val * sign;
			n++;
		 }
	}}
	return n;
}


/* This one doesn't leave a trailing newline on the end.  It also doesn't
   care about CRs at all. */
char *
fgets(s,iobuf)
	char *s;
	struct _buf *iobuf;
{
	int count, c;
	char *cptr;
	
	count = (MAXLINE - 1);
	cptr = s;
	if ((c = getc(iobuf)) == CPMEOF  ||  c == EOF) return NULL;
	do {
		if (c == '\r') continue;
		if (c == '\n') break;
		*cptr++ = c;
		}
		while (--count  &&  (c = getc(iobuf)) != EOF  &&  c != CPMEOF);
	if (c == CPMEOF) ungetc(c,iobuf);	/* push back control-Z */
	*cptr = '\0';
	return s;
}



/* End of SCOTT.C */
