/* error.c  94.01.02
 * Copyright 1983-1992   Albert Davis
 * Error handler.
 * Collection of functions to handle all types of errors
 * including user interrupts, system errors, overflow, etc.
 * Also, some user patience functions like "pause" and "comment".
 * (that don't really belong here)
 */
#include "ecah.h"
#include "error.h"
#include "io.h"
#include "options.h"
#include <signal.h>
#include "declare.h"
/*--------------------------------------------------------------------------*/
	void	stubmess(void);
	void	syntax_check(const char*,int*,int);
	void	syntax_msg(const char*,int*,int);
	void	error(int,const char*,...);
	void	cmd_pause(const char*,int*);
	void	cmd_comment(const char*,int*);
/*--------------------------------------------------------------------------*/
extern const struct ioctrl io;
extern const struct options opt;
extern int cmdcount;
extern jmp_buf envp;
static int count;
/*--------------------------------------------------------------------------*/
/* stubmess: generic function that doesn't work
 */
void stubmess()
{
 error(bDISASTER, "stub mess\n");
}
/*--------------------------------------------------------------------------*/
/* syntax_check: handle syntax errors
 * called on parsing an input string when nothing else matches.
 * if the rest of the line is nothing, just return
 * if comment, increment *cnt, so what is left is a valid comment string
 * otherwise, it is an error (the arrow pointing at the offending word)
 */
void syntax_check(const char *cmd, int *cnt, int badness)
{
 char cc;

 skipbl(cmd,cnt);
 cc = cmd[*cnt];
 switch (cc){
    case '\'':
       (*cnt)++;
    case '\0':
       break;
    default:
       syntax_msg(cmd,cnt,badness);
       break;
 }
}
/*--------------------------------------------------------------------------*/
/* syntax_msg: print syntax error message
 * echo a portion of the input with an arrow pointing to the current place
 */
void syntax_msg(const char *cmd, int *cnt, int badness)
{
 if (badness >= opt.picky){
    if (*cnt < 20){
       mprintf(io.mstderr, "%.40s\n", cmd);
       mtab(*cnt, io.mstderr);
       error(badness,"^ ?\n");
    }else{
       mprintf(io.mstderr, "... %.36s\n", &cmd[(*cnt)-16]);
       mtab(20, io.mstderr);
       error(badness,"^ ?\n");
    }
 }
}
/*--------------------------------------------------------------------------*/
/* error: error message printer
 * print it, if severe enough
 * terminate command, if really bad
 */
void error(int badness, const char *fmt, ...)
{
 char buffer[BIGBUFLEN];
 va_list arg_ptr;

 if (badness >= opt.picky) {
    va_start(arg_ptr,fmt);
    vsprintf(buffer,fmt,arg_ptr);
    va_end(arg_ptr);
    mputs(buffer,io.mstderr);
 }
 if (badness >= bDISASTER)
    abort();
 if (badness >= bEXIT)
    exit(badness);
 if (badness >= bERROR)
    longjmp(envp,1);
}
/*--------------------------------------------------------------------------*/
/* cmd_pause: user command
 */
/*ARGSUSED*/
void cmd_pause(const char *cmd, int *cnt)
{
 register int ch;

 count = cmdcount;
 mprintf( io.mstderr, "Continue? " );
 ch = getchar();
 if ( ch=='n' || ch=='N' || ch=='C'-'@' || ch=='['-'@' ) {
    error(bERROR, "\r");
 }
}
/*--------------------------------------------------------------------------*/
/* cmd_comment: user command
 * if there are two consecutive comments, exit graphics mode
 * (this is a kluge)
 * the syntax check exists because this is called whenever nothing else is,
 * by the command interpreter.  another kluge.
 */
void cmd_comment(const char *cmd, int *cnt)
{
 if (cmdcount == count+1)
    plclear();
 count = cmdcount;
 syntax_check(cmd,cnt,bWARNING);
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
