%{ CODE HEADER
/*
 * The Termprocessor Kimwitu
 *
 * Copyright (c) 1991 University of Twente, Dept TIOS.
 * All rights reserved.
 *
 */
%}
/*
 * error.k
 */
%{
#if ! (defined(lint) || defined(SABER) || defined(CODECENTER))
  static char error_kAccesSid[] = "@(#)$Id: error.k,v 1.28 1998/03/18 17:52:27 belinfan Rel $";
#endif
%}
/***************************************************************************/
/*
 * For ERROR Reporting
 */

/*
 * we want it global... so include the fndecls in k.h
 */
%{ KC_TYPES_HEADER
#include "error.h"
%}

%{ HEADER
#include "unpk.h" /* for the definition of view */
extern boolean gp_no_fatal_problems;
%}
%{
boolean gp_no_fatal_problems;
%}
%{
#ifndef KC_STDC
  extern void exit(/* int */);
#endif
%}

/* we have three sorts of errors:
 *  Fatal    causes an exit right after they are reported
 *  NonFatal does not cause an immediate exit, but
 *           does reset gp_no_fatal_problems
 *  Warning  does not cause an exit, does not reset gp_no_fatal_problems
 */

error
:	Fatal( fileline problem )
|	NonFatal( fileline problem )
|	Warning( fileline problem )
;

problem
:	Problem1( casestring )
|	Problem1ID( casestring ID )
|	Problem1tID( casestring ID )
|	Problem1we( casestring withexpression )
|	Problem1ID1ID( casestring ID casestring ID )
|	Problem1t1ID( casestring IDtype casestring ID )
|	Problem1INT( casestring INT )
|	Problem1int1( casestring int casestring )
|	Problem1INT1ID( casestring INT casestring ID )
|	Problem1ID1ID1ID( casestring ID casestring ID casestring ID )
|	Problem1INT1ID1ID( casestring INT casestring ID casestring ID )
|	Problem1storageoption1ID( casestring storageoption casestring ID )
|	Problem2( casestring casestring )
|	Problem3( casestring casestring casestring )
|	Problem3int1( casestring casestring casestring int casestring )
|	Problem4( casestring casestring casestring casestring )
|	Problem5( casestring casestring casestring casestring casestring )
|	Problem6( casestring casestring casestring casestring casestring casestring )
;

problem Problem1S( s1 ) char *s1;
{
	return Problem1( mkcasestring( s1 ));
}
problem Problem1S1we( s1, we ) char *s1; withexpression we;
{
	return Problem1we( mkcasestring( s1 ), we );
}
problem Problem1S1ID( s1, id ) char *s1; ID id;
{
	return Problem1ID( mkcasestring( s1 ), id );
}
problem Problem1S1tID( s1, id ) char *s1; ID id;
{
	return Problem1tID( mkcasestring( s1 ), id );
}

problem Problem1S1ID1S1ID( s1, id1, s2, id2 ) char *s1; ID id1; char *s2; ID id2;
{
	return Problem1ID1ID( mkcasestring( s1 ), id1, mkcasestring( s2 ), id2 );
}
problem Problem1S1t1S1ID( s1, id1, s2, id2 ) char *s1; IDtype id1; char *s2; ID id2;
{
	return Problem1t1ID( mkcasestring( s1 ), id1, mkcasestring( s2 ), id2 );
}

problem Problem1S1INT( s1, i1 ) char *s1; INT i1;
{
	return Problem1INT( mkcasestring( s1 ), i1 );
}

problem Problem1S1int1S( s1, i1, s2 ) char *s1; int i1; char *s2;
{
	return Problem1int1( mkcasestring( s1 ), i1, mkcasestring( s2 ) );
}

problem Problem1S1INT1S1ID( s1, i1, s2, id2 ) char *s1; INT i1; char *s2; ID id2;
{
	return Problem1INT1ID( mkcasestring( s1 ), i1, mkcasestring( s2 ), id2 );
}

problem Problem1S1ID1S1ID1S1ID( s1, id1, s2, id2, s3, id3 ) char *s1; ID id1; char *s2; ID id2; char *s3; ID id3;
{
	return Problem1ID1ID1ID( mkcasestring( s1 ), id1, mkcasestring( s2 ), id2, mkcasestring( s3 ), id3 );
}

problem Problem1S1INT1S1ID1S1ID( s1, i1, s2, id2, s3, id3 ) char *s1; INT i1; char *s2; ID id2; char *s3; ID id3;
{
	return Problem1INT1ID1ID( mkcasestring( s1 ), i1, mkcasestring( s2 ), id2, mkcasestring( s3 ), id3 );
}

problem Problem1S1storageoption1S1ID( s1, so, s2, id ) char *s1; storageoption so; char *s2; ID id;
{
	return Problem1storageoption1ID( mkcasestring( s1 ), so, mkcasestring( s2 ), id );
}
problem Problem2S( s1, s2 ) char *s1; char *s2;
{
	return Problem2( mkcasestring( s1 ), mkcasestring( s2 ));
}
problem ProblemSC( s1, s2 ) char *s1;  casestring s2;
{
	return Problem2( mkcasestring( s1 ), s2 );
}
problem Problem3S( s1, s2, s3 ) char *s1; char *s2; char *s3;
{
	return Problem3( mkcasestring( s1 ), mkcasestring( s2 ), mkcasestring( s3 ));
}
problem Problem4S( s1, s2, s3, s4 ) char *s1; char *s2; char *s3; char *s4;
{
	return Problem4( mkcasestring( s1 ), mkcasestring( s2 ), mkcasestring( s3 ), mkcasestring( s4 ) );
}

problem Problem3S1int1S( s1, s2, s3, i1, s4 ) char *s1; char *s2; char *s3; int i1; char *s4;
{
	return Problem3int1( mkcasestring( s1 ), mkcasestring( s2 ), mkcasestring( s3 ), i1, mkcasestring( s4 ) );
}

Problem1( s1 )					-> [ view_error: s1 ];
Problem1we( s1, we1 )				-> [ view_error: s1 " " we1 ];
Problem1ID( s1, id )				-> [ view_error: s1 " " id ];
Problem1tID( s1, id )				-> [ view_error: s1 " " id:view_error_tID ];
Problem1ID1ID( s1, id1, s2, id2 )		-> [ view_error: s1 " " id1 " " s2 " " id2 ];
Problem1t1ID( s1, t, s2, id )			-> [ view_error: s1 " " t " " s2 " " id ];
Problem1INT( s1, i1 )				-> [ view_error: s1 " " i1 ];
Problem1int1( s1, i1, s2 )		-> [ view_error: s1 " " i1 " " s2 ];
Problem1INT1ID( s1, i1, s2, id1 )		-> [ view_error: s1 " " i1 " " s2 " " id1 ];
Problem1ID1ID1ID( s1, id1, s2, id2, s3, id3 )	-> [ view_error: s1 " " id1 " " s2 " " id2 " " s3 " " id3 ];
Problem1INT1ID1ID( s1, i1, s2, id1, s3, id2 )	-> [ view_error: s1 " " i1 " " s2 " " id1 " " s3 " " id2 ];
Problem1storageoption1ID( s1, so, s2, id )	-> [ view_error: s1 " " so " " s2 " " id ];
Problem2( s1, s2 )				-> [ view_error: s1 " " s2 ];
Problem3( s1, s2, s3 )				-> [ view_error: s1 " " s2 " " s3 ];
Problem3int1( s1, s2, s3, i1, s4 )	-> [ view_error: s1 " " s2 " " s3 " " i1 " " s4 ];
Problem4( s1, s2, s3, s4 )			-> [ view_error: s1 " " s2 " " s3 " " s4 ];
Problem5( s1, s2, s3, s4, s5 )			-> [ view_error: s1 " " s2 " " s3 " " s4 " " s5 ];
Problem6( s1, s2, s3, s4, s5, s6 )		-> [ view_error: s1 " " s2 " " s3 " " s4 " " s5 " " s6 ];

Id( uid )					-> [ view_error: uid { if (uid->line != 0) } ${ " (introduced at " uid->file ":" uid->line ")" $} ];
Id( uid )					-> [ view_error_tID:  uid->type " " uid { if (uid->line != 0) } ${ " (introduced at " uid->file ":" uid->line ")" $} ];
ITUnknown()					-> [view_error_tID view_error: {/*EMPTY*/} ];


ITPredefinedPhylum( * ),
ITPredefinedBigatomPhylum( * ),
ITUserPhylum( * ),
ITPredefinedOperator( *, * ),
ITPredefinedStorageClass(),
ITStorageClass(),
ITPredefinedUView(),
ITUserUView(),
ITPredefinedRView(),
ITUserRView(),
ITUserFunction( * ),
ITPatternVariable( *, * )			-> [view_error_tID: "(it's a " $0:view_error ")" ];
ITUserOperator( *, * )				-> [view_error_tID: "(it's an " $0:view_error ")" ];

ITPredefinedBigatomPhylum( * ),
ITPredefinedPhylum( * )				-> [view_error: "predefined phylum" ];
ITUserPhylum( * )				-> [view_error: "phylum" ];
ITPredefinedOperator( *, * )			-> [view_error: "predefined operator" ];
ITUserOperator( *, * )				-> [view_error: "operator" ];
ITPredefinedStorageClass()			-> [view_error: "predefined storageclass" ];
ITStorageClass()				-> [view_error: "storageclass" ];
ITPredefinedUView()				-> [view_error: "predefined unparse view" ];
ITUserUView()					-> [view_error: "unparse view" ];
ITPredefinedRView()				-> [view_error: "predefined rewrite view" ];
ITUserRView()					-> [view_error: "rewrite view" ];
ITUserFunction( * )				-> [view_error: "function" ];
ITPatternVariable( *, * )			-> [view_error: "pattern variable" ];

WEVariable( i )					-> [view_error: i ];
WECexpression( ce )				-> [view_error: ce ];
ConsCexpression( h, t )			-> [view_error: t h ];
NilCexpression()				-> [view_error: {/*EMPTY*/} ];
CExpressionPart( s )			-> [view_error: s ];
CExpressionDollarvar( i )		-> [view_error: "$" i ];
CExpressionNl( * )				-> [view_error: " " ];
CExpressionDQ( cedq )			-> [view_error: "\"" cedq "\"" ];
CExpressionSQ( cesq )			-> [view_error: "'" cesq "'" ];
CExpressionPack( ce )			-> [view_error: "(" ce ")" ];
CExpressionArray( ce )			-> [view_error: "[" ce "]" ];
ConsCexpressionDQ( h, t )		-> [view_error: t h ];
NilCexpressionDQ()				-> [view_error: {/*EMPTY*/} ];
CExpressionDQPart( s )			-> [view_error: s ];
CExpressionDQNl( * )			-> [view_error: " " ];
ConsCexpressionSQ( h, t )		-> [view_error: t h ];
NilCexpressionSQ()				-> [view_error: {/*EMPTY*/} ];
CExpressionSQPart( s )			-> [view_error: s ];
CExpressionSQNl( * )			-> [view_error: " " ];

Str( cs )					-> [ view_error: cs ];
Int( i )					-> [ view_error: i ];
NoStorageOption()		  		-> [ view_error: {/*EMPTY*/} ];
NegativeStorageOption( id )			-> [ view_error: "{! " id/*:base_view*/ " } at " id->file ":" id->line ];
PositiveStorageOption( id )			-> [ view_error: "{ " id/*:base_view*/ " } at " id->file ":" id->line ];

/*
 * This can be easier if we are allowed to use strings/ints
 * in the pattern
 */
FileLine( f, l ) -> [ view_error:
			 { if (l != 0) } ${
			       " at "
			       { if (strcmp(f->name, "") != 0) } ${
			       	    f
			       $}
			       ":" l
			 $} { else  if (pg_lineno != 0) } ${
			       " at "
			       { if (strcmp(pg_filename->name, "") != 0) } ${
			            (casestring)pg_filename
			       $}
			       ":" (int)pg_lineno
			 $}
		   ]
;

NoFileLine() -> [ view_error:
			 { if (pg_lineno != 0) } ${
			       " at "
			       { if (strcmp(pg_filename->name, "") != 0) } ${
			            (casestring)pg_filename
			       $}
			       ":" (int)pg_lineno
			 $}
		   ]
;

PosNoFileLine() -> [ view_error:
			 { if (pg_lineno != 0) } ${
			       " at "
			       { if (strcmp(pg_filename->name, "") != 0) } ${
			            (casestring)pg_filename
			       $}
			       ":" (int)pg_lineno
			       " col:" (int)pg_column
			 $}
		   ]
;

%{ KC_UNPARSE
#include "main.h" /* for the definition of leave */
%}

Fatal( fl, e ) -> [ view_error:
			 { gp_no_fatal_problems=False; }
			 (casestring)g_progname
			 ": fatal error" fl ": " e "\n"
			 { leave( 1 ); }
	      ]
;

NonFatal( fl, e ) -> [ view_error:
			 { gp_no_fatal_problems=False; }
			 (casestring)g_progname
			 ": error" fl ": " e "\n"
	      ]
;

Warning( fl, e ) -> [ view_error:
			 (casestring)g_progname
			 ": warning" fl ": " e "\n"
	      ]
;

void v_report( e ) error e;
{
	unparse_error( e, v_stderr_printer, view_error );
}

/*ARGSUSED*/
static void v_stderr_printer( s, v ) char *s; view v;
{	KC_LINTUSE(v);
	(void)fflush( stdout );
	(void)fprintf( stderr, "%s", s );
	(void)fflush( stderr );
}


/*
 * HACK to get rid of backslash problems
 */
%{
#define QUOTEDBACKSLASH '\\'
%}

%{
#ifndef KC_MAX_STRING_LEN
# define KC_MAX_STRING_LEN 200
#endif /* !KC_MAX_STRING_LEN */

viewnameoption ug_viewnameopt;
%}
%{ KC_TYPES_HEADER
extern viewnameoption ug_viewnameopt;
%}

static void v_file_printer( char *s, view v, int *lineno, char **filename, int *no_of_printed_string_chars, boolean *doit, FILE *file, void (*printer_fn)(char *dummy1, uview dummy2) )
{	char c;

	/*SUPPRESS 622*/
	assert(file != 0);

	switch( (int)v ) {
	case (int) view_no_of_printed_string_chars_reset:
	    *no_of_printed_string_chars = 0;
	    break;
	case (int)view_printer_reset:
	    *lineno = 1;
	    *filename = s;
	    break;
	case (int)view_printer_outputfileline:
	    (void)fprintf( file, "\n" ); *lineno = *lineno +1;
	    (void)fprintf( file, "#line %d \"%s\"\n", (*lineno)+1, *filename ); *lineno = *lineno +1;
	    break;
	default:
	    while(/*SUPPRESS 254*/ (c=*s++)) {
		switch( c ) {
		case '\0': return;
		case '\n': /* if (*s == QUOTEDBACKSLASH) s++; */
		           *lineno = *lineno +1;
		     /* NO break */
	        default:
			 if (v == view_gen_unpstr_c) {
			    if (*no_of_printed_string_chars >= KC_MAX_STRING_LEN) {
			        if (*doit) {
				   (void)fprintf( file, "\", " );
				   unparse_viewnameoption( ug_viewnameopt, printer_fn, view_gen_unparsedefs_other_c );
				   (void)fprintf( file, " );\n		  (*kc_printer)(\"" );
			           *lineno = *lineno +1;
				   *no_of_printed_string_chars = 0;
				   *doit = False;
				} else {
			           switch( c ) {
				   case '\\':
				   case '\n':
					break;
				   default:
					*doit = True;
			    }  }   }
			    *no_of_printed_string_chars = *no_of_printed_string_chars +1;
			 } else if (v == view_filename) {
			 	/* duplicate (= escape) backslashes in file names.
			 	 * we do this to help those that work on windows etc.
			 	 */
				if (c == QUOTEDBACKSLASH) { /* we have to quote it! */
					(void)putc( c, file );
				}
			}
			 (void)putc( c, file );
}	}   }   }

static void v_stdout_printer( s, v ) char *s; view v;
{	static int lineno = 0;
	static char *filename;
	static int no_of_printed_string_chars = 0; /* to split long double-quoted strings */
	static boolean doit = False;

	v_file_printer( s, v, &lineno, &filename, &no_of_printed_string_chars, &doit, stdout, v_stdout_printer );
}

void v_hfile_printer( s, v ) char *s; view v;
{	static int lineno;
	static char *filename;
	static int no_of_printed_string_chars = 0; /* to split long double-quoted strings */
	static boolean doit = False;

	v_file_printer( s, v, &lineno, &filename, &no_of_printed_string_chars, &doit, g_hfile, v_hfile_printer );
}

void v_cfile_printer( s, v ) char *s; view v;
{	static int lineno;
	static char *filename;
	static int no_of_printed_string_chars = 0; /* to split long double-quoted strings */
	static boolean doit = False;

	v_file_printer( s, v, &lineno, &filename, &no_of_printed_string_chars, &doit, g_cfile, v_cfile_printer );
}

/*ARGSUSED*/
void v_null_printer( s, v ) char *s; view v;
{	KC_LINTUSE(s); KC_LINTUSE(v);
}
