/* Screen editor:  general utilities
 *		   C/80 version
 *
 * Source:  ed9.c
 * Version: May 15, 1981.
 */

/* define global constants and variables */

#include ed1.h

/* return: is first token in args a number ? */
/* return value of number in *val            */

number(args,val) char *args; int *val;
{
char c;
	c= *args++;
	if ((c<'0')||(c>'9')) {
		return(NO);
	}
	*val=c-'0';
	while (c= *args++) {
		if ((c<'0')||(c>'9')) {
			break;
		}
		*val=(*val*10)+c-'0';
	}
	return(YES);
}

/* convert character buffer to numeric */

ctoi(buf,index) char *buf; int index;
{
int k;
	while ( (buf[index]==' ')||
		(buf[index]==TAB) ) {
		index++;
	}
	k=0;
	while ((buf[index]>='0')ff(buf[index]<='9')) {
		k=(k*10)+buf[index]-'0';
		index++;
	}
	return(k);
}


/* put decimal integer n in field width >= w.
 * left justify the number in the field.
 */

putdec(n,w) int n,w;
{
char chars[10];
int i,nd;
	nd=itoc(n,chars,10);
	i=0;
	while (i<nd) {
		syscout(chars[i++]);
	}
	i=nd;
	while (i++<w) {
		syscout(' ');
	}
}

/* convert integer n to character string in str */

itoc(n,str,size) int n; char *str; int size;
{
int absval;
int len;
int i,j,k;
	absval=abs(n);
	/* generate digits */
	str[0]=0;
	i=1;
	while (i<size) {
		str[i++]=(absval%10)+'0';
		absval=absval/10;
		if (absval==0) {
			break;
		}
	}
	/* generate sign */
	if ((i<size)ff(n<0)) {
		str[i++]='-';
	}
	len=i-1;
	/* reverse sign, digits */
	i--;
	j=0;
	while (j<i) {
		k=str[i];
		str[i]=str[j];
		str[j]=k;
		i--;
		j++;
	}
	return(len);
}

/* system error routine */

syserr(s) char *s;
{
	pmtmess("system error: ",s);
}

/* user error routine */

error(s) char *s;
{
	pmtmess("error: ",s);
}

/* disk error routine */

diskerr(s) char *s;
{
	pmtmess("disk error: ",s);
}

/* read the next line of the file into
 * the buffer of size n that p points to.
 * Successive calls to readline() read the file
 * from front to back.
 */

readline(file,p,n) int file; char *p; int n;
{
int c;
int k;
	k=0;
	while (1) {
		c=sysrdch(file);
		if (c==ERR) {
			return(ERR);
		}
		if (c==EOF) {
			/* ignore line without CR */
			return (EOF);
		}
		if (c==CR) {
			return(k);
		}
		if (k<n) {
			/* move char to buffer */
			*p++=c;
		}
		/* always bump count */
		k++;
	}
}

/* push (same as write) line to end of file.
 * line is in the buffer of size n that p points to.
 * lines written by this routine may be read by
 * either readline() or popline().
 */

pushline(file,p,n) int file; char *p; int n;
{
	/* write all but trailing CR */
	while ((n--)>0) {
		if (syspshch(*p++,file)==ERR) {
			return(ERR);
		}
	}
	/* write trailing CR */
	return(syspshch(CR,file));
}

/* pop a line from the back of the file.
 * the line should have been pushed using pushline().
 */

popline(file,p,n) int file; char *p; int n;
{
int c;
int k, kmax, t;
	/* first char must be CR */
	c=syspopch(file);
	if (c==EOF) {
		/* at START of file */
		return(EOF);
	}
	if (c==CR) {
		/* put into buffer */
		*p++=CR;
		k=1;
	}
	else {
		syserr("popline: missing CR");
		return(ERR);
	}
	/* pop line into buffer in reverse order */
	while (1) {
		c=syspopch(file);
		if (c==ERR) {
			return(ERR);
		}
		if (c==EOF) {
			break;
		}
		if (c==CR) {
			/* this ends ANOTHER line */
			/* push it back           */
			if (syspshch(CR,file)==ERR) {
				return(ERR);
			}
			break;
		}
		/* non-special case */
		if (k<n) {
			/* put into buffer */
			*p++=c;
		}
		/* always bump count */
		k++;
	}
	/* remember if we truncated the line */
	kmax=k;
	/* reverse the buffer */
	k=min(k,n-1);
	t=0;
	while (k>t) {
		/* swap p[t], p[k] */
		c=p[k];
		p[k]=p[t];
		p[t]=c;
		k--;
		t++;
	}
	return(kmax);
}
