/*
 *	errors.c
 */

#include <stdio.h>
#ifdef __STDC__
#  include <stdlib.h>
#endif
#include "texchk.h"


   static void
print_error_line ()
{
  int j;

  /* Line_Buffer enthaelt '\n', danach 3+1 Spaces fuer die naechste */
  /* Zeile wegen 'l.' und Space und mind. 1 Ziffer fuer Current_line */
  printf("l.%ld %s    ", (long)Current_Line, Line_Buffer);
  j = Current_Line / 10;
  while( j >= 1 ) {
     putchar(' ');
     j /= 10;
  }
  for (j = 0; j < Current_Char-1; j++)
     putchar(' ');
  fputs("^\n", stdout);
}


   void
eof_error ()
{
  fputs(
"\nActual end of file before logical end of input.\nCurrent environment:\n",
	stdout);
  print_stack();
}


   void
stack_empty_error (etype,keyword)
   envtype etype;
   char *keyword;
{
  char *s, *e;

  switch (etype) {
    case ESCAPE_END :
      s = "\\begin";  e = "\\end";
      break;
    case RIGHT_SQUARE_BRACKET :
      s = "[";  e = "]";
      break;
    case RIGHT_CURLY_BRACKET :
      s = "{";  e = "}";
      break;
    default :
      if (*keyword == ')') {
	s = "\\(";  e = "\\)";
	break;
      } else if (*keyword == ']') {
	s = "\\[";  e = "\\]";
	break;
      } else {
	fprintf(stderr,"Impossible etype argument to stack_empty_error\n");
	exit(1);
      }
  }
  printf("\nNo matching %s to go with %s\n", s, e);
  print_error_line();
}


   void
no_brace_after_begin_end_error ()
{
  fputs("\n'\\begin' or '\\end' construct has no '{' immediately following\n",
	stdout);
  print_error_line();
}


   void
warning_blanks_in_cb ()
{
  fputs("\n\
Warning:  probable error.\n\
LaTeX does not like initial or terminating blanks\n\
inside of \\begin{} or \\end{} constructs\n", stdout);
  print_error_line();
}


   void
warning_close_brace ()
{
  fputs("\n\
Warning:  texchk cannot handle environment names that\n\
span more than one line...\n", stdout);
  print_error_line();
}


   void
bad_char_error (ch, abort)
   int ch;
   int abort;
{
  printf("\nIllegal character: integer value = %d\n", ch);
  print_error_line();
  if (abort)
	exit(1);
}


   void
line_too_long_error ()
{
  printf("\nToo many characters: line = %ld\n", (long)Current_Line);
}


   void
blank_begin_end_error ()
{
  fputs("\nNo environment defined in '\\begin{}' or '\\end{}'\n", stdout);
  print_error_line();
}


   void
keyword_error (keyword)
   char *keyword;
{
  printf("\nWarning: unrecognized command name: \\%s\n", keyword);
  print_error_line();
}


   void
math_keyword_error (keyword)
   char *keyword;
{
  printf("\nError: 'Math mode only' command used outside math mode: \\%s\n",
	keyword);
   print_error_line();
}


   void
nest_error (s, e, oldlinenum, current_key)
   char *s, *e;
   long oldlinenum;
   char *current_key;
{
  printf("\nNo matching %s for %s at current nesting level\n", s, e);
  print_error_line();
  printf("Current nesting is '%s' at line %ld\n",
	current_key, (long)oldlinenum);
}


   void
keyword_length_error ()
{
  fputs("\nLaTeX command too long\n", stdout);
  print_error_line();
}


   void
single_char_command_error (ch)
   char ch;
{
  printf("\nThe command \\%c is not legal LaTeX\n", ch);
  print_error_line();
}


   void
print_stack ()
{
  int j;

  fputs("\n\nTEXCHK ENVIRONMENT STACK:\n\n", stdout);
  for (j = 0; j <= Lex_TOS; j++) {
      switch (Lex_Stack[j].etype) {
        case ESCAPE_BEGIN :
          printf("\\begin{%s}\n", Lex_Stack[j].keyword);
          break;
        case LEFT_SQUARE_BRACKET :
          fputs("[\n", stdout);
          break;
        case LEFT_CURLY_BRACKET :
          fputs("{\n", stdout);
          break;
        case MATH :
          printf("Math Mode: %s\n", Lex_Stack[j].keyword);
          break;
        case DOUBLE_MATH :
          fputs("Display Math Mode\n", stdout);
          break;
        default :
          fputs("Stack corrupted...\n", stdout);
          texit();
      }
  }
  putchar('\n');
}


   void
eof_verbatim_error ()
{
  fputs("\nError: EOF in middle of verbatim/verb environment\n", stdout);
}


   void
verb_error (ch)
   char ch;
{
  printf("Error: Illegal character after \\verb command: %c\n", ch);
  print_error_line();
}
