/* AUXILTOO.C -- More pf auxilliary routines **********************************

	(C) 1982 Perfect Software, Inc.

	01/26/82	Version 1.00 by Barry A. Dobyns

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

#include "pf.gbl"

#ifndef CPM
MICA Width();
char MatchOpen();
FLAG IsNum(), IsType();
#endif

/* -------------------------------------------------- */

TITLELIST *
AddToC()						/* add a Table of Contents entry */
{
	TITLELIST *tptr;

	MemSpace(EndSpace);
	tptr=MemGet(sizeof(*tptr));
	if (!titlehead) titletail=titlehead=tptr;
	else {
		titletail->entnextptr=tptr;
		titletail=tptr;
		}
	tptr->entnextptr=NULL;
	tptr->entname=GetOneArg(RETURN);
	MemSpace(PageSpace);
	return(tptr);
	}

BreakLine()
{
	BreakTok();
	LBreakLine();
	}

BreakTok()				/* process a token break */
{
	STRING *token;
	char *SSToC();

	if (*SSToC(token=IGetBuf())!=NUL) {
		IClearBuf();
		LPutToken(token);
		}
	else SFree(token);
	}

DoSent()					/* Process an sentence break if desired */
{
	STRING *token;
	char *SSToC();

	if (islower(*SSToC(token=IGetBuf()))) PutOneCh(SENTENCEBREAK);
	SFree(token);
	}

VALLIST *
FindVar(name)					/* find a variable */
	STRING *name;
{
	VALLIST *ptr;

	for (ptr=valhead; ptr && !SComp(ptr->valname,name); ptr=ptr->valnextptr);
	return(ptr);
	}

FlushWhite()				/* flush whitespace after paragraph breaks */
{
	do {
		INextTok();
		} while (IsType(WHITESPACE,NEWLINE,NUL));
	IUnGet();
	}

int
GetNumVal(name)				/* return a numeric value or zero */
	STRING *name;
{
	VALLIST *vptr;

	if (!(vptr=FindVar(name))) return(0);
	if (vptr->valtype=='s' && !IsNum(vptr->value)) {
		TError("Non-numeric value '",SSToC(name),"'.");
		return(0);
		}
	if (vptr->valtype=='s') return(SSToN(vptr->value));
	return(vptr->value);
	}

int
Index(token,str)			/* look up token in str */
	STRING *token;
	char *str;
{
	int indx;
	char *cptr;

	indx=0;
	while (*str--) {
		cptr=SSToC(token)-1;
		do {
			++str;
			++cptr;
			} while (tolower(*str)==tolower(*cptr));
		if (*str==SP && !*cptr) break;
		while (*str++ != SP);
		++indx;
		}
	return(indx);
	}

FLAG
IsNum(str)					/* does the string look like a number? */
	STRING *str;
{
	char *cptr;

	cptr=SSToC(str);
	if (*cptr=='+' || *cptr=='-') cptr++;
	while (*cptr && isdigit(*cptr)) cptr++;
	return(!*cptr);
	}

FLAG
IsType(args)				/* are we any of these? */
	int args;
{
	int *argp;

	for (argp= &args; *argp; ++argp) if (*argp==IGetType()) return(TRUE);
	return(FALSE);
	}

char
MatchOpen(a)				/* return the matching close character */
	char a;
{
	switch (a) {

	case '(':
		return(')');
	case '[':
		return(']');
	case '{':
		return('}');
	case '<':
		return('>');
	case '"':
		return('"');
	case '`':
	case '\'':
		return('\'');
	default:
		return(NUL);
		}
	}

ProcessSuffix(name,suffix,force)	/* munge a file name */
	char *name, *suffix;
	FLAG force;
{
	char *indx;

	for (indx=name; *indx && *indx!='.'; ++indx);
	if (force) *indx=NUL;
	if (*indx==NUL) strcat(name,suffix);
	}

SecStart(level)			/* initialize the sectioning counters */
	char level;
{
	VALLIST *SetVar();

	if (level=='p') return;
	paragraph->value=0;
	SetVar("paragraphtitle",'s',SCToS(""));
	if (level=='b') return;
	subsection->value=0;
	SetVar("subsectiontitle",'s',SCToS(""));
	if (level=='s' || level=='n') return;
	asection->value=0;
	SetVar("appendixsectiontitle",'s',SCToS(""));
	section->value=0;
	SetVar("sectiontitle",'s',SCToS(""));
	}

VALLIST *
SetVar(name,type,val)			/* set a variable to a value, creating */
	char *name;				/* it if necessary */
	char type;
	int val;
{
	VALLIST *vptr;
	STRING *token;

	token=SCToS(name);
	if (!(vptr=FindVar(token))) {
		vptr=MemGet(sizeof(*vptr));
		if (!valhead) valtail=valhead=vptr;
		else {
			valtail->valnextptr=vptr;
			valtail=vptr;
			}
		vptr->valnextptr=NULL;
		vptr->valname=token;
		}
	else {
		if (vptr->valtype=='s' && vptr->value) SFree(vptr->value);
		SFree(token);
		}
	vptr->valtype=type;
	vptr->value=val;
	return(vptr);
	}

MICA
TabWidth(col)					/* return the width of a Tab */
	MICA col;
{
	int i;

	for (i=0; i<MAXTABS && sty.tabcolumns[i]<=col; i++);
		return((i>=MAXTABS) ? dev.stdhoriz : (sty.tabcolumns[i]-col));
	}

Template(what)					/* outputs a section number */
	char what;
{
	char *tmp;

	PutInit();
	if (sty.ischapter) {
		if (what=='a' || what=='n') PutOneCh('A'-1+appendix->value);
		else PutNum(NULL,chapter->value,NULL);
		tmp=".";
		}
	else tmp=NULL;

	if (what=='n') PutNum(tmp,asection->value,NULL);
	if (what=='s' || what=='b' || what=='p') PutNum(tmp,section->value,NULL);
	if (what=='b' || what=='p') PutNum(".",subsection->value,NULL);
	if (what=='p') PutNum(".",paragraph->value,NULL);
	PutFini();
	}

MICA
Width(chr)					/* return the width of the character */
	char chr;					/* chr cannot be a Tab */
{
	if (chr>=SP && chr<=DEL)
		if (dev.isprop) return(widthtable[chr]);
		else return(dev.stdhoriz);
	return(0);
	}

/* -------------------------------------------------- */

TBell()				/* ring the bell */
{
	TPut(BELL);
	}

TError(a,b,c)			/* print an error message */
	char *a, *b, *c;
{
	TPuts("\nError: ");
	if (a) TPuts(a);
	if (b) TPuts(b);
	if (c) TPuts(c);
	TRstErr();
	}

TIntError(msg)			/* print an internal error message */
	char *msg;
{
	TPuts("\nInternal Error:  ");
	TPuts(msg);
	TRstErr();
	}

TRstErr()
{
	termerrf = TRUE;
	TPuts("\nerror was on line ");
	TPutn(IGetLine());
	TPuts(" of ");
	TPuts(IGetFile());
	TNL();
	}

TFini()				/* finish up writing things */
{
	}

char
TGetChr()				/* get a character */
{
	char chr;

#ifdef CPM
	chr=bios(3);
#endif
#ifdef LATTICE
	chr=getch();
#endif
#ifdef UNIX
	chr=getchar();
#endif
	if (chr==3) {
		menu();
		}
	return(chr);
	}

TInit()				/* initialize the terminal */
{
	termrow=0;
	}

TNL()				/* send a Newline */
{
	TPut('\n');
	}

TPut(chr)				/* put a character */
	char chr;
{
	putchar(chr);
#ifdef LATTICE
	fflush(stdout);
#endif
	if (chr == '\n') {
		termrow++;
		if ((termrow > 22) && !pausehack && termerrf){
			TypeACR();
			termrow=0;
			}
		}
	}

TypeACR()
{
	puts ("<Type any character when ready> ");
#ifdef LATTICE
	getch();
#else
	getchar();
#endif
	putchar('\n');
	}

TPutn(n)				/* print n on the terminal */
	unsigned n;
{
	if (n>9) TPutn(n/10);
	putchar(n%10+'0');
#ifdef LATTICE
	fflush(stdout);
#endif
	}

TPuts(str)			/* put a string */
	char *str;
{
	while (*str) TPut(*str++);
#ifdef LATTICE
	fflush(stdout);
#endif
	}

puts(str)
char *str;
{
	TPuts(str);
	}

/* end of AUXILTOO.C */
