/*************************************************************************
 *
 *  m a k e :   r e a d e r . c
 *
 *  Read in makefile
 *========================================================================
 * Edition history
 *
 *  #    Date                         Comments                       By
 * --- -------- ---------------------------------------------------- ---
 *   1    ??                                                         ??
 *   2 23.08.89 cast to NULL added                                   RAL
 *   3 30.08.89 indention changed                                    PSH,RAL
 *   4 03.09.89 fixed LZ eliminated                                  RAL
 * ------------ Version 2.0 released ------------------------------- RAL
 * 2.1 22.02.91 RULETABLE support                                    TRH
 *
 *************************************************************************/

#include "h.h"


/*
 *	Syntax error handler.  Print message, with line number, and exits.
 */
void error(msg, a1)
char *msg;
char *a1;
{
  fprintf(stderr, "%s: ", myname);
  fprintf(stderr, msg, a1);
  if (lineno)  fprintf(stderr, " near line %d", lineno);
  fputc('\n', stderr);
  exit(1);
}


/*
 *	Read a line into the supplied string.  Remove
 *	comments, ignore blank lines. Deal with	quoted (\) #, and
 *	quoted newlines.  If EOF return TRUE.
 */
bool getline(strs, fd)
struct str *strs;
FILE *fd;
{
  register char *p;
  register char	*base;
  int		 size;
  int            tmppos;

  strs->pos = 0;
  for (;;) {
	if (strs->pos >= strs->len -128)
		strrealloc(strs);
	base = strs->base + strs->pos;
	size = strs->len - strs->pos;
#ifdef RULETABLE
	if (!rule_gets(base, size))
		/* the next `if' */
#endif
		if (fgets(base, size, fd) == (char *)0)
			return TRUE;		/*  EOF  */
		else
			lineno++;

	while ((p = strchr(base, '\n')) == (char *)0) {
		size = strs->len -1;
		strrealloc(strs);
		base = strs->base + size;
		size = strs->len - size;
#ifdef RULETABLE
		if (!rule_gets(base, size))
		/* the next `if' */
#endif
			if (fgets(base, size, fd) == (char *)0)
				error("Unexpected EOF",(char *)0);
	}

	*p = '\0';	/* rid newline */

	base = strs->base;

	if (quoted(p, base)) {		/* quoted newline */
		p[-1] = '\n';
		strs->pos = p - base;
		continue;
	}

	while (((p = strchr(base, '#')) != (char *)0) &&
	       quoted(p, base))
		base = p;

	if (p != (char *)0)
		*p++ = '\0';

	p = strs->base;
	while (isspace(*p))	/*  Checking for blank  */
		p++;

	if (*p != '\0')
		return FALSE;
	strs->pos = 0;
  }
}


/*
 *	Get a word from the current line, surounded by white space.
 *	return a pointer to it. String returned has no white spaces
 *	in it.
 */
char  *gettok(ptr)
register char **ptr;
{
    /* [TRH] this version does not need a double \0 terminator. */
    register char	*p,
			*base = (char *)0;

    for (p = *ptr;  isspace(*p);  p++); /*  Skip spaces	 */

    if (*p) {				/*  Anything after spaces  */

	base = p;			/*  Word starts here  */

	while (*p && !isspace(*p)) p++; /*  Find end of word  */

	if (*p) *p++ = '\0';		/*  Terminate it  */
    }
    *ptr = p;				/*  Start of next token */
    return(base);
}

/*
 *	Check if character pointed to by p is quoted
 *	with a -single- backslash. If this is the case, de-quote
 *	by copying the tail of the string backwards.
 */
bool
quoted(p, base)
register char	*p, *base;
{
    register bool	esc = FALSE;

    if (p > base && *--p == '\\') {
	strcpy(p, p + 1);		/* copy backward */

	if  (p == base || *--p != '\\') /* quoted backslash */
		esc = TRUE;
    }
    return esc;
}
