/*
 * (c) Copyright 1993 by Panagiotis Tsirigotis
 * All rights reserved.  The file named COPYRIGHT specifies the terms
 * and conditions for redistribution.
 */

static char RCSid[] = "common.c,v 1.4 1995/01/20 23:03:20 hardy Exp";

#ifdef __STRICT_ANSI__
#include <stdarg.h>
#else
#include <varargs.h>
#endif

void exit();
char *malloc();
char *realloc();

#include "sio.h"

#include "defs.h"

/*
 * Skip all characters in the input until you find the character in 'c'
 */
void skip_until(fd, c)
int fd;
int c;
{
	int ic;

	for (;;) {
		NEXT_CHAR(fd, ic);
		if (ic == SIO_EOF || ic == c)
			return;
	}
}


/*
 * Skip procedure definition: we assume that a procedure starts with an
 * open curly bracket.
 */
void skip_bracket(fd, open_bracket, closed_bracket)
int fd;
char open_bracket, closed_bracket;
{
	int c;
	int bracket_level = 1;
	int start_line = line_count;

	while (bracket_level > 0) {
		NEXT_CHAR(fd, c);
		if (c == SIO_EOF)
			error(
				     "Reached EOF while looking for '%c' (search started at line %d)\n",
				     closed_bracket, start_line);
		if (c == closed_bracket)
			bracket_level--;
		else if (c == open_bracket)
			bracket_level++;
	}
}


int next_char(fd)
int fd;
{
	int c;

	NEXT_CHAR(fd, c);
	if (c == SIO_EOF)
		error("Unexpected end of file\n");
	return (c);
}


#define BUF_INCREMENT								1000

static char *outbuf;
static int buflen;
/* static */
int used;
static int replace_space_with_newline;

void printout(c)
int c;
{
	if (outbuf == NULL) {
		buflen = BUF_INCREMENT;
		outbuf = malloc(buflen);
		if (outbuf == NULL)
			error("out of memory\n");
		used = 0;
	}
	if (c == NEWLINE) {
		if (outbuf[used - 1] == '-') {
			used--;	/* remove the '-' */
			replace_space_with_newline = TRUE;
			return;
		}
		if (outbuf[used - 2] == '-' && outbuf[used - 1] == ' ') {
			used -= 2;	/* remove the '- ' */
			replace_space_with_newline = TRUE;
			return;
		}
	} else if (c == SPACE && replace_space_with_newline) {
		c = NEWLINE;
		replace_space_with_newline = FALSE;
	}
	/*
	 * We only output complete lines
	 */
	if (c != NEWLINE) {
		if (used == buflen) {
			char *newbuf;

			buflen += BUF_INCREMENT;
			newbuf = realloc(outbuf, buflen);
			if (newbuf == NULL)
				error("out of memory\n");
			outbuf = newbuf;
		}
		outbuf[used++] = c;
	} else {
		Swrite(1, outbuf, used);
		Sputchar(1, NEWLINE);
		used = 0;
	}
}


void printout_flush()
{
	if (used) {
		Swrite(1, outbuf, used);
		Sputchar(1, NEWLINE);
		used = 0;
	}
}


void start_paragraph()
{
	printout_flush();
	Sputchar(1, NEWLINE);
}


#ifdef __STRICT_ANSI__
void error(char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
#else
void error(fmt, va_alist)
char *fmt;
va_dcl
{
	va_list ap;

	va_start(ap);
#endif
	Sprint(2, "pstext: Line %d: ", line_count);
	Sprintv(2, fmt, ap);
	exit(1);
}


void decode_string(get_char, arg)
int (*get_char) ();
void *arg;
{
	int c;
	int skip_input = FALSE;

	for (;;) {
		if (!skip_input)
			c = (*get_char) (arg);
		skip_input = FALSE;

		if (c == CLOSE_PAREN)
			return;

		if (c != BACKSLASH) {
			printout(c);
			continue;
		}
		/*
		 * Interpret the character after the backslash
		 */
		c = (*get_char) (arg);
		if (c == OPEN_PAREN || c == CLOSE_PAREN)
			printout(c);
		else if (c == 't')
			printout(TAB);
		else if (c == 'n')
			printout(NEWLINE);
		else if (c == BACKSLASH)
			printout(BACKSLASH);
		else if (isdigit(c)) {
			int i;
			int num = NUM(c);

			/*
			 * We ignore numbers; Postscript allows up to 3 digits in \ddd
			 * and we have already consumed one.
			 */
			for (i = 0; i < 2; i++) {
				c = (*get_char) (arg);
				if (isdigit(c)) {
					num *= 8;
					num += NUM(c);
				} else {
					skip_input = TRUE;
					break;
				}
			}

			if (num == 013) {
				printout('f');
				printout('f');
			} else if (num == 016) {
				printout('f');
				printout('f');
				printout('i');
			} else if (num == 0214) {
				printout('f');
				printout('i');
			} else if (num == 0244)
				printout('/');
			else if (num == 0251 || num == 0270)
				printout('\'');
			else if (num == 0252 || num == 0271 || num == 0272)
				printout('"');
			else if (num == 0253) {
				printout('<');
				printout('<');
			} else if (num == 0254)
				printout('<');
			else if (num == 0255)
				printout('>');
			else if (num == 014 || num == 0256) {
				printout('f');
				printout('i');
			} else if (num == 015 || num == 0257) {
				printout('f');
				printout('l');
			} else if (num == 0261)
				printout('-');
			else if (num == 0267)	/* bullet point */
				printout('*');
			else if (num == 0273) {
				printout('>');
				printout('>');
			} else if (num == 274) {
				printout('.');
				printout('.');
				printout('.');
			} else if (num == 0303)
				printout('^');
			else if (num == 0304)
				printout('~');
			else if (isascii(num) && isprint(num))
				printout(num);
		}
	}
}
