diff options
author | Jeffrey H. Kingston <jeff@it.usyd.edu.au> | 2010-09-14 19:21:41 +0000 |
---|---|---|
committer | Jeffrey H. Kingston <jeff@it.usyd.edu.au> | 2010-09-14 19:21:41 +0000 |
commit | 71bdb35d52747e6d7d9f55df4524d57c2966be94 (patch) | |
tree | 480ee5eefccc40d5f3331cc52d66f722fd19bfb9 /z28.c | |
parent | b41263ea7578fa9742486135c762803b52794105 (diff) | |
download | lout-71bdb35d52747e6d7d9f55df4524d57c2966be94.tar.gz |
Lout 3.17.
git-svn-id: http://svn.savannah.nongnu.org/svn/lout/trunk@2 9365b830-b601-4143-9ba8-b4a8e2c3339c
Diffstat (limited to 'z28.c')
-rw-r--r-- | z28.c | 259 |
1 files changed, 259 insertions, 0 deletions
@@ -0,0 +1,259 @@ +/*@z28.c:Error Service:ErrorInit(), ErrorSeen()@******************************/ +/* */ +/* THE LOUT DOCUMENT FORMATTING SYSTEM (VERSION 3.17) */ +/* COPYRIGHT (C) 1991, 1999 Jeffrey H. Kingston */ +/* */ +/* Jeffrey H. Kingston (jeff@cs.usyd.edu.au) */ +/* Basser Department of Computer Science */ +/* The University of Sydney 2006 */ +/* AUSTRALIA */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either Version 2, or (at your option) */ +/* any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA */ +/* */ +/* FILE: z28.c */ +/* MODULE: Error Service */ +/* EXTERNS: ErrorInit(), Error(), ErrorSeen() */ +/* */ +/*****************************************************************************/ +#include "externs.h" + +#define MAX_BLOCKS 20 /* max number of error blocks */ +#define MAX_ERRORS 20 /* max number of held error messages */ + +static BOOLEAN print_block[MAX_BLOCKS]; /* TRUE if print this block */ +static int start_block[MAX_BLOCKS]; /* first message of block */ +static char message[MAX_ERRORS][MAX_BUFF]; /* the error messages */ +static int message_fnum[MAX_ERRORS]; /* file number of error mess */ +static FILE *fp = NULL; /* file pointer of log file */ +static BOOLEAN error_seen = FALSE; /* TRUE after first error */ +static int block_top = 0; /* first free error block */ +static int mess_top = 0; /* first free error message */ + + +/*****************************************************************************/ +/* */ +/* ErrorInit(str) */ +/* */ +/* Open log file str and initialise this module. */ +/* */ +/*****************************************************************************/ + +void ErrorInit(FULL_CHAR *str) +{ if( fp != NULL ) + Error(28, 1, "-e argument appears twice in command line", FATAL, no_fpos); + fp = StringFOpen(str, WRITE_TEXT); + if( fp == NULL ) + Error(28, 2, "cannot open error file %s", FATAL, no_fpos, str); +} /* end ErrorInit */ + + +/*****************************************************************************/ +/* */ +/* BOOLEAN ErrorSeen() */ +/* */ +/* TRUE once an error has been found. */ +/* */ +/*****************************************************************************/ + +BOOLEAN ErrorSeen(void) +{ return error_seen; +} /* end ErrorSeen */ + + +/*****************************************************************************/ +/* */ +/* PrintFileBanner(fnum) */ +/* */ +/* If fnum was not the subject of the previous call to PrintFileBanner, */ +/* print a file banner for fnum. */ +/* */ +/*****************************************************************************/ + +static void PrintFileBanner(int fnum) +{ static int CurrentFileNum = -1; + if( fnum != CurrentFileNum ) + { fprintf(fp, "lout%s:\n", EchoFileSource(fnum)); + CurrentFileNum = fnum; + } +} /* end PrintFileBanner */ + + +/*@::EnterErrorBlock(), LeaveErrorBlock()@************************************/ +/* */ +/* EnterErrorBlock(ok_to_print) */ +/* */ +/* Start off a new block of error messages. If ok_to_print, they do not */ +/* need to be held for a later commit. */ +/* */ +/*****************************************************************************/ + +void EnterErrorBlock(BOOLEAN ok_to_print) +{ if( block_top < MAX_BLOCKS ) + { print_block[block_top] = ok_to_print; + start_block[block_top] = mess_top; + block_top++; + } + else Error(28, 3, "too many levels of error messages", FATAL, no_fpos); +} /* end EnterErrorBlock */ + + +/*****************************************************************************/ +/* */ +/* LeaveErrorBlock(commit) */ +/* */ +/* Finish off a block of error messages. If commit is true, print them, */ +/* otherwise discard them. */ +/* */ +/*****************************************************************************/ + +void LeaveErrorBlock(BOOLEAN commit) +{ int i; + debug0(DYY, D, " leaving error block"); + assert( block_top > 0, "LeaveErrorBlock: no matching EnterErrorBlock!" ); + assert( commit || !print_block[block_top - 1], "LeaveErrorBlock: commit!" ); + if( fp == NULL ) fp = stderr; + if( commit ) + { for( i = start_block[block_top - 1]; i < mess_top; i++ ) + { + if( AltErrorFormat ) + { fputs(message[i], fp); + } + else + { PrintFileBanner(message_fnum[i]); + fputs(message[i], fp); + } + } + } + block_top--; + mess_top = start_block[block_top]; +} /* end LeaveErrorBlock */ + + +/*****************************************************************************/ +/* */ +/* CheckErrorBlocks() */ +/* */ +/* Check (at end of run) that all error blocks have been unstacked. */ +/* */ +/*****************************************************************************/ + +void CheckErrorBlocks(void) +{ assert( block_top == 0, "CheckErrorBlocks: block_top != 0!" ); +} /* end CheckErrorBlocks */ + + +/*@::Error()@*****************************************************************/ +/* */ +/* Error(etype, pos, str, p1, p2, p3, p4, p5, p6) */ +/* */ +/* Report error of type etype at position *pos in input. */ +/* The error message is str with parameters p1 - p6. */ +/* */ +/*****************************************************************************/ + +POINTER Error(int set_num, int msg_num, char *str, int etype, FILE_POS *pos, ...) +{ + va_list ap; + char val[MAX_BUFF]; + va_start(ap, pos); + vsprintf(val, condcatgets(MsgCat, set_num, msg_num, str), ap); + if( fp == NULL ) fp = stderr; + switch( etype ) + { + + case INTERN: + + while( block_top > 0 ) LeaveErrorBlock(TRUE); + if( AltErrorFormat ) + { + fprintf(fp, condcatgets(MsgCat, 28, 7, "%s internal error: %s\n"), + EchoAltFilePos(pos), val); + /* for estrip's benefit: Error(28, 7, "%s internal error: %s\n") */ + } + else + { + PrintFileBanner(file_num(*pos)); + fprintf(fp, condcatgets(MsgCat, 28, 4, " %6s internal error: %s\n"), + EchoFileLine(pos), val); + /* for estrip's benefit: Error(28, 4, " %6s internal error: %s\n") */ + } +#if DEBUG_ON + abort(); +#else + exit(1); +#endif + break; + + + case FATAL: + + while( block_top > 0 ) LeaveErrorBlock(TRUE); + if( AltErrorFormat ) + { + fprintf(fp, condcatgets(MsgCat, 28, 8, "%s: fatal error: %s\n"), + EchoAltFilePos(pos), val); + } + else + { + PrintFileBanner(file_num(*pos)); + fprintf(fp, condcatgets(MsgCat, 28, 5, " %6s: fatal error: %s\n"), + EchoFileLine(pos), val); + } + /* for estrip's benefit: Error(28, 5, " %6s: fatal error: %s\n") */ + /* for estrip's benefit: Error(28, 8, "%s: fatal error: %s\n") */ + exit(1); + break; + + + case WARN: + + if( block_top == 0 || print_block[block_top - 1] ) + { + if( AltErrorFormat ) + { + fprintf(fp, "%s: %s\n", EchoAltFilePos(pos), val); + } + else + { + PrintFileBanner(file_num(*pos)); + fprintf(fp, " %6s: %s\n", EchoFileLine(pos), val); + } + } + else if( mess_top < MAX_ERRORS ) + { + if( AltErrorFormat ) + { + sprintf(message[mess_top++], "%s: %s\n", EchoAltFilePos(pos), val); + } + else + { message_fnum[mess_top] = file_num(*pos); + sprintf(message[mess_top++], " %6s: %s\n", + EchoFileLine(pos), val); + } + } + else Error(28, 6, "too many error messages", FATAL, pos); + error_seen = TRUE; + break; + + + default: + + assert(FALSE, "Error: invalid error type"); + break; + + } + va_end(ap); + return 0; +} /* end Error */ |