228 lines
5.4 KiB
C
228 lines
5.4 KiB
C
|
/* .+
|
||
|
|
||
|
.identifier : $Id: chf_st.c,v 2.2 2001/01/25 14:08:45 cibrario Exp $
|
||
|
.context : CHF, Condition Handling Facility
|
||
|
.title : $RCSfile: chf_st.c,v $, condition generation
|
||
|
.kind : C source
|
||
|
.author : Ivan Cibrario B.
|
||
|
.site : CSTV-CNR
|
||
|
.creation : 24-May-1996
|
||
|
.keywords : *
|
||
|
.description :
|
||
|
This module implements the CHF initialization function ChfStaticInit()
|
||
|
|
||
|
.include : Chf.h
|
||
|
|
||
|
.notes :
|
||
|
$Log: chf_st.c,v $
|
||
|
Revision 2.2 2001/01/25 14:08:45 cibrario
|
||
|
Added partial Win32 support (Windows CE only).
|
||
|
|
||
|
Revision 1.1 1996/05/28 12:56:14 cibrario
|
||
|
Initial revision
|
||
|
|
||
|
|
||
|
.- */
|
||
|
|
||
|
#ifndef lint
|
||
|
static char rcs_id[] = "$Id: chf_st.c,v 2.2 2001/01/25 14:08:45 cibrario Exp $";
|
||
|
#endif
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#ifndef _WIN32
|
||
|
#include <errno.h>
|
||
|
#endif
|
||
|
#include <setjmp.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#ifdef _WIN32
|
||
|
#include <windows.h>
|
||
|
#include <tchar.h>
|
||
|
#endif
|
||
|
|
||
|
#include "Chf.h"
|
||
|
#include "ChfPriv.h"
|
||
|
|
||
|
|
||
|
/* -------------------------------------------------------------------------
|
||
|
Global and static variables
|
||
|
------------------------------------------------------------------------- */
|
||
|
|
||
|
/* -------------------------------------------------------------------------
|
||
|
Private type definitions
|
||
|
------------------------------------------------------------------------- */
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
const ChfTable *table;
|
||
|
size_t size;
|
||
|
}
|
||
|
ChfStaticContext;
|
||
|
|
||
|
|
||
|
/* -------------------------------------------------------------------------
|
||
|
Private functions
|
||
|
------------------------------------------------------------------------- */
|
||
|
|
||
|
#ifdef _WIN32
|
||
|
/* Win32 does not have bsearch();
|
||
|
provide a simple one from glibc here.
|
||
|
*/
|
||
|
static void *bsearch(
|
||
|
const void *key,
|
||
|
const void *base,
|
||
|
size_t nmemb,
|
||
|
size_t size,
|
||
|
int (*compar)(const void *, const void *)
|
||
|
)
|
||
|
{
|
||
|
size_t l, u, idx;
|
||
|
const void *p;
|
||
|
int comparison;
|
||
|
|
||
|
l = 0;
|
||
|
u = nmemb;
|
||
|
while (l < u)
|
||
|
{
|
||
|
idx = (l + u) / 2;
|
||
|
p = (void *) (((const char *) base) + (idx * size));
|
||
|
comparison = (*compar) (key, p);
|
||
|
if (comparison < 0)
|
||
|
u = idx;
|
||
|
else if (comparison > 0)
|
||
|
l = idx + 1;
|
||
|
else
|
||
|
return (void *) p;
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#define GT 1
|
||
|
#define LT -1
|
||
|
#define EQ 0
|
||
|
|
||
|
static int Search(
|
||
|
const void *l,
|
||
|
const void *r
|
||
|
)
|
||
|
{
|
||
|
if(((ChfTable *)l)->module > ((ChfTable *)r)->module)
|
||
|
return(GT);
|
||
|
|
||
|
else if(((ChfTable *)l)->module < ((ChfTable *)r)->module)
|
||
|
return(LT);
|
||
|
|
||
|
else if(((ChfTable *)l)->code > ((ChfTable *)r)->code)
|
||
|
return(GT);
|
||
|
|
||
|
else if(((ChfTable *)l)->code < ((ChfTable *)r)->code)
|
||
|
return(LT);
|
||
|
|
||
|
return(EQ);
|
||
|
}
|
||
|
|
||
|
static const ChfChar *StGetMessage(
|
||
|
void *private_context,
|
||
|
const int module_id,
|
||
|
const int condition_code,
|
||
|
const ChfChar *default_message
|
||
|
)
|
||
|
{
|
||
|
ChfTable key;
|
||
|
ChfTable *res;
|
||
|
|
||
|
key.module = module_id;
|
||
|
key.code = condition_code;
|
||
|
|
||
|
if((res = bsearch(&key, ((ChfStaticContext *)private_context)->table,
|
||
|
((ChfStaticContext *)private_context)->size, sizeof(ChfTable), Search)) ==
|
||
|
(void *)NULL)
|
||
|
return(default_message);
|
||
|
|
||
|
return(((ChfTable *)res)->msg_template);
|
||
|
}
|
||
|
|
||
|
static void ExitMessage(
|
||
|
void *private_context
|
||
|
)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -------------------------------------------------------------------------
|
||
|
Public functions
|
||
|
------------------------------------------------------------------------- */
|
||
|
|
||
|
/* .+
|
||
|
|
||
|
.title : ChfStaticInit
|
||
|
.kind : C function
|
||
|
.creation : 24-May-1996
|
||
|
.description :
|
||
|
This function initializes CHF and returns to the caller a condition code;
|
||
|
that code will be either CHF_S_OK if the initialization was succesful,
|
||
|
or one of the other values listed below.
|
||
|
|
||
|
It's necessary to invoke succesfully either ChfStaticInit() or one of the
|
||
|
other CHF initialization routines before using any other CHF function.
|
||
|
|
||
|
NOTE: This function will call ChfAbort() with abort code CHF_ABORT_DUP_INIT
|
||
|
if CHF has already been initialized before.
|
||
|
|
||
|
.call :
|
||
|
cc = ChfStaticInit(app_name, options,
|
||
|
table, table_size,
|
||
|
condition_stack_size, handler_stack_size,
|
||
|
exit_code);
|
||
|
.input :
|
||
|
const char *app_name, Application's name
|
||
|
const ChfOptions options, Options
|
||
|
const ChfTable *table, pointer to the static message table
|
||
|
const size_t table_size, size of the table (# of entries)
|
||
|
const int condition_stack_size, Size of the condition stack
|
||
|
const int handler_stack_size, Size of the handler stack
|
||
|
const int exit_code, Abnormal exit code
|
||
|
.output :
|
||
|
int cc, condition code
|
||
|
.status_codes :
|
||
|
CHF_F_MALLOC, FATAL, memory allocation failed
|
||
|
.notes :
|
||
|
1.1, 27-May-1996, creation
|
||
|
|
||
|
.- */
|
||
|
int ChfStaticInit( /* Initialization with static message tables */
|
||
|
const ChfChar *app_name, /* Application's name */
|
||
|
const ChfOptions options, /* Options */
|
||
|
const ChfTable *table, /* Static message table */
|
||
|
const size_t table_size, /* Size of the message table */
|
||
|
const int condition_stack_size, /* Size of the condition stack */
|
||
|
const int handler_stack_size, /* Size of the handler stack */
|
||
|
const int exit_code /* Abnormal exit code */
|
||
|
)
|
||
|
{
|
||
|
ChfStaticContext *private_context;
|
||
|
int cc;
|
||
|
|
||
|
if((private_context =
|
||
|
(ChfStaticContext *)malloc(sizeof(ChfStaticContext))) ==
|
||
|
(ChfStaticContext *)NULL)
|
||
|
cc = CHF_F_MALLOC;
|
||
|
|
||
|
else if((cc = ChfInit(app_name, options, (void *)private_context,
|
||
|
StGetMessage, ExitMessage, condition_stack_size, handler_stack_size,
|
||
|
exit_code)) != CHF_S_OK)
|
||
|
free(private_context);
|
||
|
|
||
|
else
|
||
|
{
|
||
|
private_context->table = table;
|
||
|
private_context->size = table_size;
|
||
|
cc = CHF_S_OK;
|
||
|
}
|
||
|
|
||
|
return cc;
|
||
|
}
|