/* .+ .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 #include #ifndef _WIN32 #include #endif #include #include #include #ifdef _WIN32 #include #include #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++; } }