saturnng/Chf/chf_gen.c
2022-03-21 11:05:59 +01:00

179 lines
5.3 KiB
C

/* .+
.identifier : $Id: chf_gen.c,v 2.2 2001/01/25 12:10:22 cibrario Exp $
.context : CHF, Condition Handling Facility
.title : $RCSfile: chf_gen.c,v $, condition generation
.kind : C source
.author : Ivan Cibrario B.
.site : CSTV-CNR
.creation : 3-May-1996
.keywords : *
.description :
This module contains the condition generation function of CHF
.include : Chf.h
.notes :
$Log: chf_gen.c,v $
Revision 2.2 2001/01/25 12:10:22 cibrario
Added partial Win32 support (Windows CE only).
Revision 1.1 1996/05/28 12:53:59 cibrario
Initial revision
.- */
#ifndef lint
static char rcs_id[] = "$Id: chf_gen.c,v 2.2 2001/01/25 12:10:22 cibrario Exp $";
#endif
#include <stdio.h>
#include <stdlib.h>
#ifndef _WIN32
#include <errno.h>
#endif
#include <setjmp.h>
#include <stdarg.h>
#include <string.h>
#ifdef _WIN32
#include <windows.h>
#include <tchar.h>
#endif
#include "Chf.h"
#include "ChfPriv.h"
/* .+
.title : ChfGenerate
.kind : C function
.creation : 3-May-1996
.description :
This function generates a condition descriptor for the condition described
by 'module_id', 'file_name', 'line_number', 'condition_code' and 'severity',
and the partial message associated with it, specialized with the additional
arguments '...'; the new condition descriptor is put onto the top of the
condition stack.
If the condition stack is full, this function generates the condition
CHF_F_COND_STACK_FULL and immediately invokes ChfSignal() for the current
condition stack.
NOTE: This function calls the CHF function 'ChfAbort()' to
abort the application if either:
- CHF has not been initialized correctly (abort code CHF_ABORT_INIT)
- there is an overflow in the internal buffer used during the
generation of the partial message associated with the condition
(abort code CHF_ABORT_MSG_OVF)
- there was an attempt to generate a condition while the CHF condition
CHF_F_COND_STACK_FULL (condition stack full) was being signalled
(abort code CHF_ABORT_COND_STACK_OVF)
.call :
ChfGenerate(module_id, file_name, line_number,
condition_code, severity, ...);
.input :
const int module_id, module identifier
const char *file_name, file name
const int line_number, line number
const int condition_code, condition code
const ChfSeverity severity, severity
..., additional arguments
.output :
void
.status_codes :
(*) CHF_F_COND_STACK_FULL, the condition stack is full
.notes :
1.1, 3-May-1996, creation
.- */
void ChfGenerate( /* Generate a condition into the stack */
const int module_id,
const ChfChar *file_name,
const int line_number,
const int condition_code,
const ChfSeverity severity,
...
)
{
ChfDescriptor *new_descriptor;
va_list aux_arg;
/* Check that CHF has been correctly initialized */
if(chf_context.state == CHF_UNKNOWN) ChfAbort(CHF_ABORT_INIT);
/* Prepare the additional arguments list */
va_start(aux_arg, severity);
if((new_descriptor = chf_context.condition_sp) -
chf_context.condition_stack >= chf_context.condition_stack_size)
{
/* The condition stack is full;
generate the CHF_F_COND_STACK_FULL condition and signal it immediately,
using the last available slot of the stack, if it's still empty,
otherwise abort the application.
*/
if(new_descriptor - chf_context.condition_stack ==
chf_context.condition_stack_size)
{
new_descriptor->module_id = CHF_MODULE_ID;
new_descriptor->condition_code = CHF_F_COND_STACK_FULL;
new_descriptor->severity = CHF_FATAL;
new_descriptor->line_number = CHF_UNKNOWN_LINE_NUMBER;
new_descriptor->file_name = CHF_UNKNOWN_FILE_NAME;
ChfStrncpy(new_descriptor->message,
ChfGetMessage(CHF_MODULE_ID, CHF_F_COND_STACK_FULL,
ChfText("Condition stack is full")), CHF_MAX_MESSAGE_LENGTH-1);
new_descriptor->message[CHF_MAX_MESSAGE_LENGTH-1] = '\0';
new_descriptor->next = CHF_NULL_DESCRIPTOR;
chf_context.condition_sp++;
ChfSignal();
}
else
ChfAbort(CHF_ABORT_COND_STACK_OVF);
}
else
{
ChfChar def_message[CHF_DEF_MESSAGE_LENGTH];
ChfChar tmp_message[CHF_TMP_MESSAGE_LENGTH];
new_descriptor->module_id = module_id;
new_descriptor->condition_code = condition_code;
new_descriptor->severity = severity;
new_descriptor->line_number = line_number;
new_descriptor->file_name = file_name;
/* Generate the default message */
ChfSprintf(def_message, CHF_DEF_PARTIAL_MSG_FMT, condition_code);
/* Generate the partial message associated with the condition using a
temporary area
*/
if(
ChfVsprintf(tmp_message,
ChfGetMessage(module_id, condition_code, def_message), aux_arg) >=
CHF_TMP_MESSAGE_LENGTH)
ChfAbort(CHF_ABORT_MSG_OVF);
/* Copy the message into the condition descriptor */
ChfStrncpy(new_descriptor->message, tmp_message, CHF_MAX_MESSAGE_LENGTH-1);
new_descriptor->message[CHF_MAX_MESSAGE_LENGTH-1] = '\0';
/* Link the new descriptor with the current descriptor list, if it
isn't the first descriptor of the list
*/
new_descriptor->next = (new_descriptor == chf_context.condition_base)
? CHF_NULL_DESCRIPTOR : new_descriptor - 1;
chf_context.condition_sp++;
}
}