/* $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred. */

/*	Copyright (c) 1986,1989 AT&T	*/
/*	  All Rights Reserved  	*/

/*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*/
/*	The copyright notice above does not evidence any   	*/
/*	actual or intended publication of such source code.	*/

#ident "$Header: suppt.c 1.1 90/01/11 $ @(#)setterm:suppt.c 2.1 89/02/14 AT&T-UP"

/*
 * suppt.c	Support routines for "setterm".
 */

#include <stdio.h>

#include "header.h"

extern char *prog, *infoptr;
extern int verify;

/*
 * getline	Get the next line from file "fp" and put it in "line".
 *		Return TRUE on success, FALSE on failure or EOF.  We
 *		understand "backslash-newline", but no other escape
 *		sequences.
 */

getline(fp, line)

	FILE *fp;
	char *line;
{
	register int c;
	char *hold;

	hold = line;
	*line = '\0';
commnt:
	if ((c = fgetc(fp)) == EOF) {
		*line = '\0';
		return FALSE;
	}
	else
		ungetc(c, fp);
	while ((c = fgetc(fp)) != '\n' && c != EOF) {
		if (c == '\\') {
			switch (c = fgetc(fp)) {
				case '\n': c = ' '; break;
				default:  break;
			}
		}
		*line++ = c;
	}
	*line++ = '\0';
	if (*hold == '#') {	/* see if the line is a comment */
		line = hold;
		goto commnt;
	}
	return TRUE;
}

/*
 * getdevt	Extract a device type from the beginning of "line"
 *		and put it at "where".  Return the pointer to command part.
 */

char *
getdevt(line, where)

	char *line, *where;
{
	register char *tmp, *tmptmp;

	tmptmp = where;
	tmp = line;
	while (*tmp && (*tmp != ' ') && (*tmp != '\t') && (*tmp != '\n'))
		++tmp;
	while (line < tmp)
		*where++ = *line++;
	*where = '\0';
	while (*line == ' ' || *line == '\t')
		++line;
	return line;
}

/*
 * getcom	Take a pointer to a line AFTER "devt" and return the
 *		next command on the line into the "com" structure.
 *		Return pointer after the gotten command from "line",
 *		or (char *0) for error.
 */

char *
getcom(com, line)

	struct cmd *com;
	char *line;
{
	register char *type;
	register int i;

	while ((*line == ' ') || (*line == '\t'))
		++line;
	if (*line)
		type = line;
	else
		return (char *) 0;
	while ((*line) && (*line != ',') && (*line != '\n') &&
		(*line != ' ') && (*line != '\t'))
		++line;
	if ((type == line) && ((*line == '\n') || (*line == '\0'))) {
		return (char *) 0;	/* done */
	}
	/*
	 * If non-arg command comes as end of line, make sure we
	 * don't pick up any stray stuff still left in the "line"
	 * buffer from previous lines.  Do this by putting in some
	 * extra NULLS, so that an increment past the command word
	 * won't put us on a non-NULL character...
	 */
	if (*line == '\0') {
		*(line+1) = '\0'; *(line+2) = '\0';
	}
	*line = '\0';	/* truncate after command word. */
	++line;		/* move to argument part of command */
	while ((*line) && (*line == ' ') || (*line == '\t') || (*line == ','))
		++line;
	if (!strcmp(type, "set")) {
		com->comtype = CMD_SET;
		com->action[0] = *line++;
		com->action[1] = '\0';
		return line;
	}
	if (!strcmp(type, "pop")) {
		com->comtype = CMD_POP;
		com->action[0] = '\0';
		return line;
	}
	if (!strcmp(type, "popall")) {
		com->comtype = CMD_POPALL;
		com->action[0] = '\0';
		return line;
	}
	if (!strcmp(type, "popto")) {
		com->comtype = CMD_POPTO;
		i = 0;
		while (*line && (*line != ' ') && (*line != '\t'))
			com->action[i++] = *line++;
		com->action[i] = '\0';
		return line;
	}
	if (!strcmp(type, "push")) {
		com->comtype = CMD_PUSH;
		i = 0;
		while (*line && (*line != ' ') && (*line != '\t'))
			com->action[i++] = *line++;
		com->action[i] = '\0';
		return line;
	}
	if (!strcmp(type, "if")) {
		com->comtype = CMD_IF;
		i = 0;
		while (*line && (*line != ' ') && (*line != '\t'))
			com->action[i++] = *line++;
		com->action[i] = '\0';
		return line;
	}
	if (!strcmp(type, "test")) {
		com->comtype = CMD_TEST;
		i = 0;
		while (*line && (*line != ' ') && (*line != '\t'))
			com->action[i++] = *line++;
		com->action[i] = '\0';
		return line;
	}
	if (!strcmp(type, "run")) {
		com->comtype = CMD_RUN;
		if (*line != '{')
			fatal(BAD_RUN);
		else
			++line;
		i = 0;
		while (*line && (*line != '}')) {
			if (*line == '\\')	/* allow "\}" escapes */
				++line;
			com->action[i++] = *line++;
		}
		com->action[i] = '\0';
		if (*line == '}')
			++line;
		return line;
	}
	if (!strcmp(type, "select")) {
		com->comtype = CMD_SEL;
		i = 0;
		while (*line && (*line != ' ') && (*line != '\t'))
			com->action[i++] = *line++;
		com->action[i] = '\0';
		return line;
	}
	if (!strcmp(type, "throw")) {
		com->comtype = CMD_THROW;
		com->action[0] = '\0';
		return line;
	}
	if (!strcmp(type, "catch")) {
		com->comtype = CMD_CATCH;
		com->action[0] = '\0';
		return line;
	}
	fatal(BAD_COM);	/* unrecognized command! */
}

/*
 * devequal	Take a device typename (devt) and a string-to-scan
 *		(chk).  See if "devt" matches any of the possibly "|"
 *		separated words in "chk". Return TRUE on successful match,
 *		else FALSE.  Can basically be used to compare a regular
 *		string for matches to an element of a string with
 *		internal "|" delimiters, e.g., comparing "junk" to
 *		"mod|junk|more" returns TRUE.
 */

devequal(devt, chk)

	char *devt, *chk;
{
	char *start, *stop, hold;

	/* printf("deveq entered (%s, %s)\n", devt, chk); */
	start = stop = chk;
	/*
	 * Loop until nothing more to look at... we'll break lower
	 * down it we find a match.
	 */
	while (*start != '\0') {
		/* move end pointer down to next delimiter. */
		while (*stop != '\0' && *stop != '|')
			++stop;
		/* save the delimiter and make it null */
		hold = *stop;
		*stop = '\0';
		/* compare what we found with the devt */
		if (strcmp(devt, start) == 0) {
			*stop = hold;	/* restore delimiter! */
			return TRUE; /* found it */
		}
		/* restore the delimiter */
		*stop = hold;
		/* move stop pointer forward past delimiter */
		if (*stop == '|')
			++stop;
		/*
		 * Move start pointer to next place.  If it goes
		 * null at the top of the loop, we're done and
		 * haven't found it.
		 */
		start = stop;
	}
	return FALSE;	/* not found */
}
