179 lines
5.3 KiB
C
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++;
|
|
}
|
|
}
|